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 67KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820
  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. * SVN: $Id$
  23. */
  24. package org.ownage.dmdirc.parser;
  25. import java.io.BufferedReader;
  26. import java.io.IOException;
  27. import java.io.InputStreamReader;
  28. import java.io.PrintWriter;
  29. import java.net.Socket;
  30. import java.net.UnknownHostException;
  31. import java.util.ArrayList;
  32. import java.util.Arrays;
  33. import java.util.Hashtable;
  34. import java.util.Enumeration;
  35. /**
  36. * IRC Parser.
  37. *
  38. * @author Shane Mc Cormack
  39. * @version $Id$
  40. */
  41. public class IRCParser implements Runnable {
  42. public static final int ndInfo = 1; // Information
  43. public static final int ndSocket = 2; // Socket Errors
  44. // public static final int ndSomething = 4; //Next thingy
  45. public static final int errFatal = 1; // Error is potentially Fatal. Desync 99% Guarenteed!
  46. public static final int errError = 2; // Error is not fatal, but is more severe than a warning
  47. public static final int errWarning = 4; // This was an unexpected occurance, but shouldn't be anything to worry about
  48. public static final int errCanContinue = 8; // If an Error has this flag, it means the parser is able to continue running
  49. // Most errWarnings should have this flag. if Fatal or Error are not accomanied
  50. // with this flag, you should disconnect or risk problems further on.
  51. // Development Debugging info - Outputs directly to console.
  52. // This is used for debugging info that is generally of no use to most people
  53. // If this is set to false, self-test and any the "useless" debugging that relies on
  54. // this being true are not compiled.
  55. protected static final boolean bDebug = true;
  56. private Socket socket = null;
  57. private PrintWriter out = null;
  58. private BufferedReader in = null;
  59. public MyInfo me = new MyInfo(); // This is what the user wants, nickname here is *not* fact.
  60. public ServerInfo server = new ServerInfo(); // Server Info requested by user
  61. protected String sServerName;
  62. protected String sThinkNickname; // This is what we want the nickname to be.
  63. protected boolean TriedAlt = false;
  64. protected boolean Got001 = false;
  65. protected boolean HasBegan = false;
  66. protected boolean IsFirst = true;
  67. // Better alternative to hashtable?
  68. // Valid Boolean Modes are stored as Hashtable.pub('m',1); where 'm' is the mode and 1 is a numeric value
  69. // Numeric values are powers of 2. This allows up to 32 modes at present (expandable to 64)
  70. // ChannelInfo/ChannelClientInfo etc provide methods to view the modes in a human way.
  71. // PrefixModes are o/v etc Prefix map contains 2 pairs for each mode. (eg @ => o and o => @)
  72. protected Hashtable<Character,Integer> hPrefixModes = new Hashtable<Character,Integer>();
  73. protected Hashtable<Character,Character> hPrefixMap = new Hashtable<Character,Character>();
  74. protected int nNextKeyPrefix = 1;
  75. protected Hashtable<Character,Integer> hUserModes = new Hashtable<Character,Integer>();
  76. protected int nNextKeyUser = 1;
  77. protected Hashtable<Character,Integer> hChanModesBool = new Hashtable<Character,Integer>();
  78. protected int nNextKeyCMBool = 1;
  79. // Non Boolean Modes (for Channels) are stored together in this arraylist, the value param
  80. // is used to show the type of variable. (List (1), Param just for set (2), Param for Set and Unset (2+4=6))
  81. protected Hashtable<Character,Byte> hChanModesOther = new Hashtable<Character,Byte>();
  82. protected static final byte cmList = 1;
  83. protected static final byte cmSet = 2;
  84. protected static final byte cmUnset = 4;
  85. // Channel Prefixs
  86. // The value for these is always true.
  87. protected Hashtable<Character,Boolean> hChanPrefix = new Hashtable<Character,Boolean>();
  88. protected Hashtable<String,ClientInfo> hClientList = new Hashtable<String,ClientInfo>();
  89. protected Hashtable<String,ChannelInfo> hChannelList = new Hashtable<String,ChannelInfo>();
  90. protected ClientInfo cMyself = null;
  91. protected Hashtable<String,String> h005Info = new Hashtable<String,String>();
  92. // Events
  93. // TODO: This would probably be more efficient as hashtables.
  94. public interface IDebugInfo { public void onDebug(IRCParser tParser, int nLevel, String sData); }
  95. ArrayList<IDebugInfo> cbDebugInfo = new ArrayList<IDebugInfo>();
  96. public interface IMOTDEnd { public void onMOTDEnd(IRCParser tParser); }
  97. ArrayList<IMOTDEnd> cbEndOfMOTD = new ArrayList<IMOTDEnd>();
  98. public interface IDataIn { public void onDataIn(IRCParser tParser, String sData); }
  99. ArrayList<IDataIn> cbDataIn = new ArrayList<IDataIn>();
  100. public interface IDataOut { public void onDataOut(IRCParser tParser, String sData, boolean FromParser); }
  101. ArrayList<IDataOut> cbDataOut = new ArrayList<IDataOut>();
  102. public interface INickInUse { public void onNickInUse(IRCParser tParser); }
  103. ArrayList<INickInUse> cbNickInUse = new ArrayList<INickInUse>();
  104. public interface IErrorInfo { public void onError(IRCParser tParser, int nLevel, String sData); }
  105. ArrayList<IErrorInfo> cbErrorInfo = new ArrayList<IErrorInfo>();
  106. public interface IChannelJoin { public void onJoinChannel(IRCParser tParser, ChannelInfo cChannel, ChannelClientInfo cChannelClient ); }
  107. ArrayList<IChannelJoin> cbChannelJoin = new ArrayList<IChannelJoin>();
  108. public interface IChannelPart { public void onPartChannel(IRCParser tParser, ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sReason ); }
  109. ArrayList<IChannelPart> cbChannelPart = new ArrayList<IChannelPart>();
  110. public interface IChannelQuit { public void onQuitChannel(IRCParser tParser, ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sReason ); }
  111. ArrayList<IChannelQuit> cbChannelQuit = new ArrayList<IChannelQuit>();
  112. public interface IChannelTopic { public void onTopic(IRCParser tParser, ChannelInfo cChannel, boolean bIsNewTopic); }
  113. ArrayList<IChannelTopic> cbChannelTopic = new ArrayList<IChannelTopic>();
  114. public interface IChannelModesChanged { public void onModeChange(IRCParser tParser, ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sHost); }
  115. ArrayList<IChannelModesChanged> cbChannelModesChanged = new ArrayList<IChannelModesChanged>();
  116. public interface IUserModesChanged { public void onUserModeChange(IRCParser tParser, ClientInfo cClient, String sSetBy); }
  117. ArrayList<IUserModesChanged> cbUserModesChanged = new ArrayList<IUserModesChanged>();
  118. public interface INickChanged { public void onNickChanged(IRCParser tParser, ClientInfo cClient, String sOldNick); }
  119. ArrayList<INickChanged> cbNickChanged = new ArrayList<INickChanged>();
  120. public interface IChannelKick { public void onChannelKick(IRCParser tParser, ChannelInfo cChannel, ChannelClientInfo cKickedClient, ChannelClientInfo cKickedByClient, String sReason, String sKickedByHost); }
  121. ArrayList<IChannelKick> cbChannelKick = new ArrayList<IChannelKick>();
  122. public interface IChannelMessage { public void onChannelMessage(IRCParser tParser, ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sMessage, String sHost ); }
  123. ArrayList<IChannelMessage> cbChannelMessage = new ArrayList<IChannelMessage>();
  124. public interface IChannelAction { public void onChannelAction(IRCParser tParser, ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sMessage, String sHost ); }
  125. ArrayList<IChannelAction> cbChannelAction = new ArrayList<IChannelAction>();
  126. public interface IChannelNotice { public void onChannelNotice(IRCParser tParser, ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sMessage, String sHost ); }
  127. ArrayList<IChannelNotice> cbChannelNotice = new ArrayList<IChannelNotice>();
  128. public interface IPrivateMessage { public void onPrivateMessage(IRCParser tParser, ClientInfo cClient, String sMessage, String sHost ); }
  129. ArrayList<IPrivateMessage> cbPrivateMessage = new ArrayList<IPrivateMessage>();
  130. public interface IPrivateAction { public void onPrivateAction(IRCParser tParser, ClientInfo cClient, String sMessage, String sHost ); }
  131. ArrayList<IPrivateAction> cbPrivateAction = new ArrayList<IPrivateAction>();
  132. public interface IPrivateNotice { public void onPrivateNotice(IRCParser tParser, ClientInfo cClient, String sMessage, String sHost ); }
  133. ArrayList<IPrivateNotice> cbPrivateNotice = new ArrayList<IPrivateNotice>();
  134. public interface IUnknownMessage { public void onUnknownMessage(IRCParser tParser, ClientInfo cClient, String sMessage, String sHost ); }
  135. ArrayList<IUnknownMessage> cbUnknownMessage = new ArrayList<IUnknownMessage>();
  136. public interface IUnknownAction { public void onUnknownAction(IRCParser tParser, ClientInfo cClient, String sMessage, String sHost ); }
  137. ArrayList<IUnknownAction> cbUnknownAction = new ArrayList<IUnknownAction>();
  138. public interface IUnknownNotice { public void onUnknownNotice(IRCParser tParser, ClientInfo cClient, String sMessage, String sHost ); }
  139. ArrayList<IUnknownNotice> cbUnknownNotice = new ArrayList<IUnknownNotice>();
  140. public interface IChannelCTCP { public void onChannelCTCP(IRCParser tParser, ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sType, String sMessage, String sHost ); }
  141. ArrayList<IChannelCTCP> cbChannelCTCP = new ArrayList<IChannelCTCP>();
  142. public interface IPrivateCTCP { public void onPrivateCTCP(IRCParser tParser, ClientInfo cClient, String sType, String sMessage, String sHost ); }
  143. ArrayList<IPrivateCTCP> cbPrivateCTCP = new ArrayList<IPrivateCTCP>();
  144. public interface IUnknownCTCP { public void onUnknownCTCP(IRCParser tParser, ClientInfo cClient, String sType, String sMessage, String sHost ); }
  145. ArrayList<IUnknownCTCP> cbUnknownCTCP = new ArrayList<IUnknownCTCP>();
  146. public interface IChannelCTCPReply { public void onChannelCTCPReply(IRCParser tParser, ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sType, String sMessage, String sHost ); }
  147. ArrayList<IChannelCTCPReply> cbChannelCTCPReply = new ArrayList<IChannelCTCPReply>();
  148. public interface IPrivateCTCPReply { public void onPrivateCTCPReply(IRCParser tParser, ClientInfo cClient, String sType, String sMessage, String sHost ); }
  149. ArrayList<IPrivateCTCPReply> cbPrivateCTCPReply = new ArrayList<IPrivateCTCPReply>();
  150. public interface IUnknownCTCPReply { public void onUnknownCTCPReply(IRCParser tParser, ClientInfo cClient, String sType, String sMessage, String sHost ); }
  151. ArrayList<IUnknownCTCPReply> cbUnknownCTCPReply = new ArrayList<IUnknownCTCPReply>();
  152. public interface IQuit { public void onQuit(IRCParser tParser, ClientInfo cClient, String sReason ); }
  153. ArrayList<IQuit> cbQuit = new ArrayList<IQuit>();
  154. public interface IGotNames { public void onGotNames(IRCParser tParser, ChannelInfo cChannel); }
  155. ArrayList<IGotNames> cbGotNames = new ArrayList<IGotNames>();
  156. @SuppressWarnings("unchecked")
  157. private void AddCallback(Object eMethod, ArrayList CallbackList) {
  158. for (int i = 0; i < CallbackList.size(); i++) {
  159. if (eMethod.equals(CallbackList.get(i))) { return; }
  160. }
  161. CallbackList.add(eMethod);
  162. }
  163. private void DelCallback(Object eMethod, ArrayList CallbackList) {
  164. for (int i = 0; i < CallbackList.size(); i++) {
  165. if (eMethod.equals(CallbackList.get(i))) { CallbackList.remove(i); break; }
  166. }
  167. }
  168. /**
  169. * Add callback for DebugInfo (onDebug).
  170. *
  171. * @param eMethod Reference to object that handles the callback
  172. */
  173. public void AddDebugInfo(Object eMethod) { AddCallback(eMethod, cbDebugInfo); }
  174. /**
  175. * Delete callback for DebugInfo (onDebug).
  176. *
  177. * @param eMethod Reference to object that handles the callback
  178. */
  179. public void DelDebugInfo(Object eMethod) { DelCallback(eMethod, cbDebugInfo); }
  180. protected boolean CallDebugInfo(int level, String data) {
  181. if (bDebug) { System.out.printf("[DEBUG] {%d} %s\n", level, data); }
  182. boolean bResult = false;
  183. for (int i = 0; i < cbDebugInfo.size(); i++) {
  184. cbDebugInfo.get(i).onDebug(this, level, data);
  185. bResult = true;
  186. }
  187. return bResult;
  188. }
  189. /**
  190. * Add callback for MOTDEnd (onMOTDEnd).
  191. *
  192. * @param eMethod Reference to object that handles the callback
  193. */
  194. public void AddMOTDEnd(Object eMethod) { AddCallback(eMethod, cbEndOfMOTD); }
  195. /**
  196. * Delete callback for MOTDEnd (onMOTDEnd).
  197. *
  198. * @param eMethod Reference to object that handles the callback
  199. */
  200. public void DelMOTDEnd(Object eMethod) { DelCallback(eMethod, cbEndOfMOTD); }
  201. protected boolean CallMOTDEnd() {
  202. boolean bResult = false;
  203. for (int i = 0; i < cbEndOfMOTD.size(); i++) {
  204. cbEndOfMOTD.get(i).onMOTDEnd(this);
  205. bResult = true;
  206. }
  207. return bResult;
  208. }
  209. /**
  210. * Add callback for DataIn (onDataIn).
  211. *
  212. * @param eMethod Reference to object that handles the callback
  213. */
  214. public void AddDataIn(Object eMethod) { AddCallback((IDataIn)eMethod, cbDataIn); }
  215. /**
  216. * Delete callback for DataIn (onDebug).
  217. *
  218. * @param eMethod Reference to object that handles the callback
  219. */
  220. public void DelDataIn(Object eMethod) { DelCallback((IDataIn)eMethod, cbDataIn); }
  221. protected boolean CallDataIn(String data) {
  222. boolean bResult = false;
  223. for (int i = 0; i < cbDataIn.size(); i++) {
  224. cbDataIn.get(i).onDataIn(this, data);
  225. bResult = true;
  226. }
  227. return bResult;
  228. }
  229. /**
  230. * Add callback for DataOut (onDataOut).
  231. *
  232. * @param eMethod Reference to object that handles the callback
  233. */
  234. public void AddDataOut(Object eMethod) { AddCallback((IDataOut)eMethod, cbDataOut); }
  235. /**
  236. * Delete callback for DataOut (onDataOut).
  237. *
  238. * @param eMethod Reference to object that handles the callback
  239. */
  240. public void DelDataOut(Object eMethod) { DelCallback((IDataOut)eMethod, cbDataOut); }
  241. protected boolean CallDataOut(String data, boolean FromParser) {
  242. boolean bResult = false;
  243. for (int i = 0; i < cbDataOut.size(); i++) {
  244. cbDataOut.get(i).onDataOut(this, data, FromParser);
  245. bResult = true;
  246. }
  247. return bResult;
  248. }
  249. /**
  250. * Add callback for NickInUse (onNickInUse).
  251. *
  252. * @param eMethod Reference to object that handles the callback
  253. */
  254. public void AddNickInUse(Object eMethod) { AddCallback(eMethod, cbNickInUse); }
  255. /**
  256. * Delete callback for NickInUse (onNickInUse).
  257. *
  258. * @param eMethod Reference to object that handles the callback
  259. */
  260. public void DelNickInUse(Object eMethod) { DelCallback(eMethod, cbNickInUse); }
  261. protected boolean CallNickInUse() {
  262. boolean bResult = false;
  263. for (int i = 0; i < cbNickInUse.size(); i++) {
  264. cbNickInUse.get(i).onNickInUse(this);
  265. bResult = true;
  266. }
  267. return bResult;
  268. }
  269. /**
  270. * Add callback for ErrorInfo (onError).
  271. *
  272. * @param eMethod Reference to object that handles the callback
  273. */
  274. public void AddErrorInfo(Object eMethod) { AddCallback(eMethod, cbErrorInfo); }
  275. /**
  276. * Delete callback for ErrorInfo (onError).
  277. *
  278. * @param eMethod Reference to object that handles the callback
  279. */
  280. public void DelErrorInfo(Object eMethod) { DelCallback(eMethod, cbErrorInfo); }
  281. protected boolean CallErrorInfo(int level, String data) {
  282. if (bDebug) { System.out.printf("[ERROR] {%d} %s\n", level, data); }
  283. boolean bResult = false;
  284. for (int i = 0; i < cbErrorInfo.size(); i++) {
  285. cbErrorInfo.get(i).onError(this, level, data);
  286. bResult = true;
  287. }
  288. return bResult;
  289. }
  290. /**
  291. * Add callback for ChannelJoin (onJoinChannel).
  292. *
  293. * @param eMethod Reference to object that handles the callback
  294. */
  295. public void AddChannelJoin(Object eMethod) { AddCallback(eMethod, cbChannelJoin); }
  296. /**
  297. * Delete callback for ChannelJoin (onJoinChannel).
  298. *
  299. * @param eMethod Reference to object that handles the callback
  300. */
  301. public void DelChannelJoin(Object eMethod) { DelCallback(eMethod, cbChannelJoin); }
  302. protected boolean CallChannelJoin(ChannelInfo cChannel, ChannelClientInfo cChannelClient) {
  303. boolean bResult = false;
  304. for (int i = 0; i < cbChannelJoin.size(); i++) {
  305. cbChannelJoin.get(i).onJoinChannel(this, cChannel, cChannelClient);
  306. bResult = true;
  307. }
  308. return bResult;
  309. }
  310. /**
  311. * Add callback for ChannelPart (onPartChannel).
  312. *
  313. * @param eMethod Reference to object that handles the callback
  314. */
  315. public void AddChannelPart(Object eMethod) { AddCallback(eMethod, cbChannelPart); }
  316. /**
  317. * Delete callback for ChannelPart (onPartChannel).
  318. *
  319. * @param eMethod Reference to object that handles the callback
  320. */
  321. public void DelChannelPart(Object eMethod) { DelCallback(eMethod, cbChannelPart); }
  322. protected boolean CallChannelPart(ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sReason) {
  323. boolean bResult = false;
  324. for (int i = 0; i < cbChannelPart.size(); i++) {
  325. cbChannelPart.get(i).onPartChannel(this, cChannel, cChannelClient, sReason);
  326. bResult = true;
  327. }
  328. return bResult;
  329. }
  330. /**
  331. * Add callback for ChannelQuit (onQuitChannel).
  332. *
  333. * @param eMethod Reference to object that handles the callback
  334. */
  335. public void AddChannelQuit(Object eMethod) { AddCallback(eMethod, cbChannelQuit); }
  336. /**
  337. * Delete callback for ChannelQuit (onQuitChannel).
  338. *
  339. * @param eMethod Reference to object that handles the callback
  340. */
  341. public void DelChannelQuit(Object eMethod) { DelCallback(eMethod, cbChannelQuit); }
  342. protected boolean CallChannelQuit(ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sReason) {
  343. boolean bResult = false;
  344. for (int i = 0; i < cbChannelQuit.size(); i++) {
  345. cbChannelQuit.get(i).onQuitChannel(this, cChannel, cChannelClient, sReason);
  346. bResult = true;
  347. }
  348. return bResult;
  349. }
  350. /**
  351. * Add callback for Quit (onQuit).
  352. *
  353. * @param eMethod Reference to object that handles the callback
  354. */
  355. public void AddQuit(Object eMethod) { AddCallback(eMethod, cbQuit); }
  356. /**
  357. * Delete callback for Quit (onQuit).
  358. *
  359. * @param eMethod Reference to object that handles the callback
  360. */
  361. public void DelQuit(Object eMethod) { DelCallback(eMethod, cbQuit); }
  362. protected boolean CallQuit(ClientInfo cClient, String sReason) {
  363. boolean bResult = false;
  364. for (int i = 0; i < cbQuit.size(); i++) {
  365. cbQuit.get(i).onQuit(this, cClient, sReason);
  366. bResult = true;
  367. }
  368. return bResult;
  369. }
  370. /**
  371. * Add callback for ChannelTopic (onTopic).
  372. *
  373. * @param eMethod Reference to object that handles the callback
  374. */
  375. public void AddTopic(Object eMethod) { AddCallback(eMethod, cbChannelTopic); }
  376. /**
  377. * Delete callback for ChannelTopic (onTopic).
  378. *
  379. * @param eMethod Reference to object that handles the callback
  380. */
  381. public void DelTopic(Object eMethod) { DelCallback(eMethod, cbChannelTopic); }
  382. protected boolean CallTopic(ChannelInfo cChannel, boolean bIsJoinTopic) {
  383. boolean bResult = false;
  384. for (int i = 0; i < cbChannelTopic.size(); i++) {
  385. cbChannelTopic.get(i).onTopic(this, cChannel, bIsJoinTopic);
  386. bResult = true;
  387. }
  388. return bResult;
  389. }
  390. /**
  391. * Add callback for ChannelModesChanged (onModeChange).
  392. *
  393. * @param eMethod Reference to object that handles the callback
  394. */
  395. public void AddModesChanged(Object eMethod) { AddCallback(eMethod, cbChannelModesChanged); }
  396. /**
  397. * Delete callback for ChannelModesChanged (onModeChange).
  398. *
  399. * @param eMethod Reference to object that handles the callback
  400. */
  401. public void DelModesChanged(Object eMethod) { DelCallback(eMethod, cbChannelModesChanged); }
  402. protected boolean CallModesChanged(ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sHost) {
  403. boolean bResult = false;
  404. for (int i = 0; i < cbChannelModesChanged.size(); i++) {
  405. cbChannelModesChanged.get(i).onModeChange(this, cChannel, cChannelClient, sHost);
  406. bResult = true;
  407. }
  408. return bResult;
  409. }
  410. /**
  411. * Add callback for UserModesChanged (onUserModeChange).
  412. *
  413. * @param eMethod Reference to object that handles the callback
  414. */
  415. public void AddUserModesChanged(Object eMethod) { AddCallback(eMethod, cbUserModesChanged); }
  416. /**
  417. * Delete callback for UserModesChanged (onUserModeChange).
  418. *
  419. * @param eMethod Reference to object that handles the callback
  420. */
  421. public void DelUserModesChanged(Object eMethod) { DelCallback(eMethod, cbUserModesChanged); }
  422. protected boolean CallUserModesChanged(ClientInfo cClient, String sSetby) {
  423. boolean bResult = false;
  424. for (int i = 0; i < cbUserModesChanged.size(); i++) {
  425. cbUserModesChanged.get(i).onUserModeChange(this, cClient, sSetby);
  426. bResult = true;
  427. }
  428. return bResult;
  429. }
  430. /**
  431. * Add callback for UserNickChanged (onNickChanged).
  432. *
  433. * @param eMethod Reference to object that handles the callback
  434. */
  435. public void AddNickChanged(Object eMethod) { AddCallback(eMethod, cbNickChanged); }
  436. /**
  437. * Delete callback for UserNickChanged (onNickChanged).
  438. *
  439. * @param eMethod Reference to object that handles the callback
  440. */
  441. public void DelNickChanged(Object eMethod) { DelCallback(eMethod, cbNickChanged); }
  442. protected boolean CallNickChanged(ClientInfo cClient, String sOldNick) {
  443. boolean bResult = false;
  444. for (int i = 0; i < cbNickChanged.size(); i++) {
  445. cbNickChanged.get(i).onNickChanged(this, cClient, sOldNick);
  446. bResult = true;
  447. }
  448. return bResult;
  449. }
  450. /**
  451. * Add callback for ChannelKick (onChannelKick).
  452. *
  453. * @param eMethod Reference to object that handles the callback
  454. */
  455. public void AddChannelKick(Object eMethod) { AddCallback(eMethod, cbChannelKick); }
  456. /**
  457. * Delete callback for ChannelKick (onChannelKick).
  458. *
  459. * @param eMethod Reference to object that handles the callback
  460. */
  461. public void DelChannelKick(Object eMethod) { DelCallback(eMethod, cbChannelKick); }
  462. protected boolean CallChannelKick(ChannelInfo cChannel, ChannelClientInfo cKickedClient, ChannelClientInfo cKickedByClient, String sReason, String sKickedByHost) {
  463. boolean bResult = false;
  464. for (int i = 0; i < cbChannelKick.size(); i++) {
  465. cbChannelKick.get(i).onChannelKick(this, cChannel, cKickedClient, cKickedByClient, sReason, sKickedByHost);
  466. bResult = true;
  467. }
  468. return bResult;
  469. }
  470. /**
  471. * Add callback for ChannelMessage (onChannelMessage).
  472. *
  473. * @param eMethod Reference to object that handles the callback
  474. */
  475. public void AddChannelMessage(Object eMethod) { AddCallback(eMethod, cbChannelMessage); }
  476. /**
  477. * Delete callback for ChannelMessage (onChannelMessage).
  478. *
  479. * @param eMethod Reference to object that handles the callback
  480. */
  481. public void DelChannelMessage(Object eMethod) { DelCallback(eMethod, cbChannelMessage); }
  482. protected boolean CallChannelMessage(ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sMessage, String sHost) {
  483. boolean bResult = false;
  484. for (int i = 0; i < cbChannelMessage.size(); i++) {
  485. cbChannelMessage.get(i).onChannelMessage(this, cChannel, cChannelClient, sMessage, sHost);
  486. bResult = true;
  487. }
  488. return bResult;
  489. }
  490. /**
  491. * Add callback for ChannelAction (onChannelAction).
  492. *
  493. * @param eMethod Reference to object that handles the callback
  494. */
  495. public void AddChannelAction(Object eMethod) { AddCallback(eMethod, cbChannelAction); }
  496. /**
  497. * Delete callback for ChannelAction (onChannelAction).
  498. *
  499. * @param eMethod Reference to object that handles the callback
  500. */
  501. public void DelChannelAction(Object eMethod) { DelCallback(eMethod, cbChannelAction); }
  502. protected boolean CallChannelAction(ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sMessage, String sHost) {
  503. boolean bResult = false;
  504. for (int i = 0; i < cbChannelAction.size(); i++) {
  505. cbChannelAction.get(i).onChannelAction(this, cChannel, cChannelClient, sMessage, sHost);
  506. bResult = true;
  507. }
  508. return bResult;
  509. }
  510. /**
  511. * Add callback for ChannelNotice (onChannelNotice).
  512. *
  513. * @param eMethod Reference to object that handles the callback
  514. */
  515. public void AddChannelNotice(Object eMethod) { AddCallback(eMethod, cbChannelNotice); }
  516. /**
  517. * Delete callback for ChannelNotice (onChannelNotice).
  518. *
  519. * @param eMethod Reference to object that handles the callback
  520. */
  521. public void DelChannelNotice(Object eMethod) { DelCallback(eMethod, cbChannelNotice); }
  522. protected boolean CallChannelNotice(ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sMessage, String sHost) {
  523. boolean bResult = false;
  524. for (int i = 0; i < cbChannelNotice.size(); i++) {
  525. cbChannelNotice.get(i).onChannelNotice(this, cChannel, cChannelClient, sMessage, sHost);
  526. bResult = true;
  527. }
  528. return bResult;
  529. }
  530. /**
  531. * Add callback for PrivateMessage (onPrivateMessage).
  532. *
  533. * @param eMethod Reference to object that handles the callback
  534. */
  535. public void AddPrivateMessage(Object eMethod) { AddCallback(eMethod, cbPrivateMessage); }
  536. /**
  537. * Delete callback for PrivateMessage (onPrivateMessage).
  538. *
  539. * @param eMethod Reference to object that handles the callback
  540. */
  541. public void DelPrivateMessage(Object eMethod) { DelCallback(eMethod, cbPrivateMessage); }
  542. protected boolean CallPrivateMessage(ClientInfo cClient, String sMessage, String sHost) {
  543. boolean bResult = false;
  544. for (int i = 0; i < cbPrivateMessage.size(); i++) {
  545. cbPrivateMessage.get(i).onPrivateMessage(this, cClient, sMessage, sHost);
  546. bResult = true;
  547. }
  548. return bResult;
  549. }
  550. /**
  551. * Add callback for PrivateAction (onPrivateAction).
  552. *
  553. * @param eMethod Reference to object that handles the callback
  554. */
  555. public void AddPrivateAction(Object eMethod) { AddCallback(eMethod, cbPrivateAction); }
  556. /**
  557. * Delete callback for PrivateAction (onPrivateAction).
  558. *
  559. * @param eMethod Reference to object that handles the callback
  560. */
  561. public void DelPrivateAction(Object eMethod) { DelCallback(eMethod, cbPrivateAction); }
  562. protected boolean CallPrivateAction(ClientInfo cClient, String sMessage, String sHost) {
  563. boolean bResult = false;
  564. for (int i = 0; i < cbPrivateAction.size(); i++) {
  565. cbPrivateAction.get(i).onPrivateAction(this, cClient, sMessage, sHost);
  566. bResult = true;
  567. }
  568. return bResult;
  569. }
  570. /**
  571. * Add callback for PrivateNotice (onPrivateNotice).
  572. *
  573. * @param eMethod Reference to object that handles the callback
  574. */
  575. public void AddPrivateNotice(Object eMethod) { AddCallback(eMethod, cbPrivateNotice); }
  576. /**
  577. * Delete callback for PrivateNotice (onPrivateNotice).
  578. *
  579. * @param eMethod Reference to object that handles the callback
  580. */
  581. public void DelPrivateNotice(Object eMethod) { DelCallback(eMethod, cbPrivateNotice); }
  582. protected boolean CallPrivateNotice(ClientInfo cClient, String sMessage, String sHost) {
  583. boolean bResult = false;
  584. for (int i = 0; i < cbPrivateNotice.size(); i++) {
  585. cbPrivateNotice.get(i).onPrivateNotice(this, cClient, sMessage, sHost);
  586. bResult = true;
  587. }
  588. return bResult;
  589. }
  590. /**
  591. * Add callback for UnknownMessage (onUnknownMessage).
  592. *
  593. * @param eMethod Reference to object that handles the callback
  594. */
  595. public void AddUnknownMessage(Object eMethod) { AddCallback(eMethod, cbUnknownMessage); }
  596. /**
  597. * Delete callback for UnknownMessage (onUnknownMessage).
  598. *
  599. * @param eMethod Reference to object that handles the callback
  600. */
  601. public void DelUnknownMessage(Object eMethod) { DelCallback(eMethod, cbUnknownMessage); }
  602. protected boolean CallUnknownMessage(ClientInfo cClient, String sMessage, String sHost) {
  603. boolean bResult = false;
  604. for (int i = 0; i < cbUnknownMessage.size(); i++) {
  605. cbUnknownMessage.get(i).onUnknownMessage(this, cClient, sMessage, sHost);
  606. bResult = true;
  607. }
  608. return bResult;
  609. }
  610. /**
  611. * Add callback for UnknownAction (onUnknownAction).
  612. *
  613. * @param eMethod Reference to object that handles the callback
  614. */
  615. public void AddUnknownAction(Object eMethod) { AddCallback(eMethod, cbUnknownAction); }
  616. /**
  617. * Delete callback for UnknownAction (onUnknownAction).
  618. *
  619. * @param eMethod Reference to object that handles the callback
  620. */
  621. public void DelUnknownAction(Object eMethod) { DelCallback(eMethod, cbUnknownAction); }
  622. protected boolean CallUnknownAction(ClientInfo cClient, String sMessage, String sHost) {
  623. boolean bResult = false;
  624. for (int i = 0; i < cbUnknownAction.size(); i++) {
  625. cbUnknownAction.get(i).onUnknownAction(this, cClient, sMessage, sHost);
  626. bResult = true;
  627. }
  628. return bResult;
  629. }
  630. /**
  631. * Add callback for UnknownNotice (onUnknownNotice).
  632. *
  633. * @param eMethod Reference to object that handles the callback
  634. */
  635. public void AddUnknownNotice(Object eMethod) { AddCallback(eMethod, cbUnknownNotice); }
  636. /**
  637. * Delete callback for UnknownNotice (onUnknownNotice).
  638. *
  639. * @param eMethod Reference to object that handles the callback
  640. */
  641. public void DelUnknownNotice(Object eMethod) { DelCallback(eMethod, cbUnknownNotice); }
  642. protected boolean CallUnknownNotice(ClientInfo cClient, String sMessage, String sHost) {
  643. boolean bResult = false;
  644. for (int i = 0; i < cbUnknownNotice.size(); i++) {
  645. cbUnknownNotice.get(i).onUnknownNotice(this, cClient, sMessage, sHost);
  646. bResult = true;
  647. }
  648. return bResult;
  649. }
  650. /**
  651. * Add callback for ChannelCTCP (onChannelCTCP).
  652. *
  653. * @param eMethod Reference to object that handles the callback
  654. */
  655. public void AddChannelCTCP(Object eMethod) { AddCallback(eMethod, cbChannelCTCP); }
  656. /**
  657. * Delete callback for ChannelCTCP (onChannelCTCP).
  658. *
  659. * @param eMethod Reference to object that handles the callback
  660. */
  661. public void DelChannelCTCP(Object eMethod) { DelCallback(eMethod, cbChannelCTCP); }
  662. protected boolean CallChannelCTCP(ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sType, String sMessage, String sHost) {
  663. boolean bResult = false;
  664. for (int i = 0; i < cbChannelCTCP.size(); i++) {
  665. cbChannelCTCP.get(i).onChannelCTCP(this, cChannel, cChannelClient, sType, sMessage, sHost);
  666. bResult = true;
  667. }
  668. return bResult;
  669. }
  670. /**
  671. * Add callback for PrivateCTCP (onPrivateCTCP).
  672. *
  673. * @param eMethod Reference to object that handles the callback
  674. */
  675. public void AddPrivateCTCP(Object eMethod) { AddCallback(eMethod, cbPrivateCTCP); }
  676. /**
  677. * Delete callback for PrivateCTCP (onPrivateCTCP).
  678. *
  679. * @param eMethod Reference to object that handles the callback
  680. */
  681. public void DelPrivateCTCP(Object eMethod) { DelCallback(eMethod, cbPrivateCTCP); }
  682. protected boolean CallPrivateCTCP(ClientInfo cClient, String sType, String sMessage, String sHost) {
  683. boolean bResult = false;
  684. for (int i = 0; i < cbPrivateCTCP.size(); i++) {
  685. cbPrivateCTCP.get(i).onPrivateCTCP(this, cClient, sType, sMessage, sHost);
  686. bResult = true;
  687. }
  688. return bResult;
  689. }
  690. /**
  691. * Add callback for UnknownCTCP (onUnknownCTCP).
  692. *
  693. * @param eMethod Reference to object that handles the callback
  694. */
  695. public void AddUnknownCTCP(Object eMethod) { AddCallback(eMethod, cbUnknownCTCP); }
  696. /**
  697. * Delete callback for UnknownCTCP (onUnknownCTCP).
  698. *
  699. * @param eMethod Reference to object that handles the callback
  700. */
  701. public void DelUnknownCTCP(Object eMethod) { DelCallback(eMethod, cbUnknownCTCP); }
  702. protected boolean CallUnknownCTCP(ClientInfo cClient, String sType, String sMessage, String sHost) {
  703. boolean bResult = false;
  704. for (int i = 0; i < cbUnknownCTCP.size(); i++) {
  705. cbUnknownCTCP.get(i).onUnknownCTCP(this, cClient, sType, sMessage, sHost);
  706. bResult = true;
  707. }
  708. return bResult;
  709. }
  710. /**
  711. * Add callback for ChannelCTCPReply (onChannelCTCPReply).
  712. *
  713. * @param eMethod Reference to object that handles the callback
  714. */
  715. public void AddChannelCTCPReply(Object eMethod) { AddCallback(eMethod, cbChannelCTCPReply); }
  716. /**
  717. * Delete callback for ChannelCTCPReply (onChannelCTCPReply).
  718. *
  719. * @param eMethod Reference to object that handles the callback
  720. */
  721. public void DelChannelCTCPReply(Object eMethod) { DelCallback(eMethod, cbChannelCTCPReply); }
  722. protected boolean CallChannelCTCPReply(ChannelInfo cChannel, ChannelClientInfo cChannelClient, String sType, String sMessage, String sHost) {
  723. boolean bResult = false;
  724. for (int i = 0; i < cbChannelCTCPReply.size(); i++) {
  725. cbChannelCTCPReply.get(i).onChannelCTCPReply(this, cChannel, cChannelClient, sType, sMessage, sHost);
  726. bResult = true;
  727. }
  728. return bResult;
  729. }
  730. /**
  731. * Add callback for PrivateCTCPReply (onPrivateCTCPReply).
  732. *
  733. * @param eMethod Reference to object that handles the callback
  734. */
  735. public void AddPrivateCTCPReply(Object eMethod) { AddCallback(eMethod, cbPrivateCTCPReply); }
  736. /**
  737. * Delete callback for PrivateCTCPReply (onPrivateCTCPReply).
  738. *
  739. * @param eMethod Reference to object that handles the callback
  740. */
  741. public void DelPrivateCTCPReply(Object eMethod) { DelCallback(eMethod, cbPrivateCTCPReply); }
  742. protected boolean CallPrivateCTCPReply(ClientInfo cClient, String sType, String sMessage, String sHost) {
  743. boolean bResult = false;
  744. for (int i = 0; i < cbPrivateCTCPReply.size(); i++) {
  745. cbPrivateCTCPReply.get(i).onPrivateCTCPReply(this, cClient, sType, sMessage, sHost);
  746. bResult = true;
  747. }
  748. return bResult;
  749. }
  750. /**
  751. * Add callback for UnknownCTCPReply (onUnknownCTCPReply).
  752. *
  753. * @param eMethod Reference to object that handles the callback
  754. */
  755. public void AddUnknownCTCPReply(Object eMethod) { AddCallback(eMethod, cbUnknownCTCPReply); }
  756. /**
  757. * Delete callback for UnknownCTCPReply (onUnknownCTCPReply).
  758. *
  759. * @param eMethod Reference to object that handles the callback
  760. */
  761. public void DelUnknownCTCPReply(Object eMethod) { DelCallback(eMethod, cbUnknownCTCPReply); }
  762. protected boolean CallUnknownCTCPReply(ClientInfo cClient, String sType, String sMessage, String sHost) {
  763. boolean bResult = false;
  764. for (int i = 0; i < cbUnknownCTCPReply.size(); i++) {
  765. cbUnknownCTCPReply.get(i).onUnknownCTCPReply(this, cClient, sType, sMessage, sHost);
  766. bResult = true;
  767. }
  768. return bResult;
  769. }
  770. /**
  771. * Add callback for GotNames (onGotNames).
  772. *
  773. * @param eMethod Reference to object that handles the callback
  774. */
  775. public void AddGotNames(Object eMethod) { AddCallback(eMethod, cbGotNames); }
  776. /**
  777. * Delete callback for GotNames (onGotNames).
  778. *
  779. * @param eMethod Reference to object that handles the callback
  780. */
  781. public void DelGotNames(Object eMethod) { DelCallback(eMethod, cbGotNames); }
  782. protected boolean CallGotNames(ChannelInfo cChannel) {
  783. boolean bResult = false;
  784. for (int i = 0; i < cbGotNames.size(); i++) {
  785. cbGotNames.get(i).onGotNames(this, cChannel);
  786. bResult = true;
  787. }
  788. return bResult;
  789. }
  790. /**
  791. * Perform a silent test on certain functions.
  792. *
  793. * @return Boolean result of test. (True only if ALL tests pass)
  794. */
  795. public boolean DoSelfTest() {
  796. return DoSelfTest(true);
  797. }
  798. /**
  799. * Perform a test on certain functions.
  800. *
  801. * @param bSilent Should output be given? (Sent to Console)
  802. * @return Boolean result of test. (True only if ALL tests pass)
  803. */
  804. public boolean DoSelfTest(boolean bSilent) {
  805. if (bDebug) {
  806. boolean bResult = false;
  807. ParserTestClass ptc = new ParserTestClass();
  808. if (bSilent) { bResult = ptc.SelfTest(); }
  809. else {
  810. System.out.printf(" --------------------\n");
  811. System.out.printf(" Beginning Tests\n");
  812. System.out.printf(" --------------------\n");
  813. ptc.RunTests();
  814. System.out.printf(" --------------------\n");
  815. System.out.printf(" End\n");
  816. System.out.printf(" --------------------\n");
  817. System.out.printf(" Total Tests: %d\n",ptc.GetTotalTests());
  818. System.out.printf(" Passed Tests: %d\n",ptc.GetPassedTests());
  819. System.out.printf(" Failed Tests: %d\n",ptc.GetFailedTests());
  820. System.out.printf(" --------------------\n");
  821. bResult = (ptc.GetTotalTests() == ptc.GetPassedTests());
  822. }
  823. ptc = null;
  824. return bResult;
  825. } else {
  826. return true;
  827. }
  828. }
  829. /**
  830. * Default constructor.
  831. */
  832. public IRCParser() { }
  833. /**
  834. * Constructor with ServerInfo.
  835. *
  836. * @param serverDetails Server information.
  837. */
  838. public IRCParser(ServerInfo serverDetails) { this(null,serverDetails); }
  839. /**
  840. * Constructor with MyInfo.
  841. *
  842. * @param myDetails Client information.|
  843. */
  844. public IRCParser(MyInfo myDetails) { this(myDetails,null); }
  845. /**
  846. * Constructor with ServerInfo and MyInfo.
  847. *
  848. * @param serverDetails Server information.
  849. * @param myDetails Client information.|
  850. */
  851. public IRCParser(MyInfo myDetails, ServerInfo serverDetails) {
  852. if (myDetails != null) { this.me = myDetails; }
  853. if (serverDetails != null) { this.server = serverDetails; }
  854. }
  855. private void ResetState() {
  856. // Reset General State info
  857. TriedAlt = false;
  858. Got001 = false;
  859. // Clear the hash tables
  860. hChannelList.clear();
  861. hClientList.clear();
  862. h005Info.clear();
  863. hPrefixModes.clear();
  864. hPrefixMap.clear();
  865. hChanModesOther.clear();
  866. hChanModesBool.clear();
  867. hUserModes.clear();
  868. hChanPrefix.clear();
  869. // Reset the mode indexes
  870. nNextKeyPrefix = 1;
  871. nNextKeyCMBool = 1;
  872. nNextKeyUser = 1;
  873. }
  874. private void connect() throws Exception {
  875. try {
  876. ResetState();
  877. CallDebugInfo(ndSocket,"Connecting to "+server.sHost+":"+server.nPort);
  878. socket = new Socket(server.sHost,server.nPort);
  879. if (bDebug) { System.out.printf("\t\t-> 1\n"); }
  880. out = new PrintWriter(socket.getOutputStream(), true);
  881. if (bDebug) { System.out.printf("\t\t-> 2\n"); }
  882. in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  883. if (bDebug) { System.out.printf("\t\t-> 3\n"); }
  884. } catch (Exception e) { throw e; }
  885. }
  886. /**
  887. * Begin execution. Connect to server, and start parsing incomming lines
  888. */
  889. public void run() {
  890. CallDebugInfo(ndInfo,"Begin Thread Execution");
  891. if (HasBegan) { return; } else { HasBegan = true; }
  892. try { connect(); } catch (Exception e) { CallDebugInfo(ndSocket,"Error Connecting, Aborted"); return; }
  893. // :HACK: While true loops really really suck.
  894. CallDebugInfo(ndSocket,"Socket Connected");
  895. String line = "";
  896. while(true) {
  897. try {
  898. line = in.readLine(); // Blocking :/
  899. if (line == null) {
  900. CallDebugInfo(ndSocket,"Socket Closed");
  901. break;
  902. } else {
  903. if (IsFirst) {
  904. if (!server.sPassword.equals("")) {
  905. SendString("PASS "+server.sPassword);
  906. }
  907. SetNickname(me.sNickname);
  908. SendString("USER "+me.sUsername.toLowerCase()+" * * :"+me.sRealname);
  909. IsFirst = false;
  910. }
  911. ProcessLine(line);
  912. }
  913. } catch (IOException e) {
  914. CallDebugInfo(ndSocket,"Socket Closed");
  915. break;
  916. }
  917. }
  918. CallDebugInfo(ndInfo,"End Thread Execution");
  919. }
  920. protected void finalize(){
  921. try {
  922. socket.close();
  923. } catch (IOException e) {
  924. CallDebugInfo(ndInfo,"Could not close socket");
  925. }
  926. }
  927. protected String GetParam(String line) {
  928. String[] params = null;
  929. params = line.split(" :",2);
  930. return params[params.length-1];
  931. }
  932. protected String[] IRCTokenise(String line) {
  933. if (line == null) {
  934. String[] tokens = new String[1];
  935. tokens[0] = "";
  936. return tokens; // Return empty string[]
  937. };
  938. String[] params = null;
  939. String[] tokens = null;
  940. params = line.split(" :",2);
  941. tokens = params[0].split(" ");
  942. if (params.length == 2) {
  943. String[] temp = new String[tokens.length+1];
  944. System.arraycopy(tokens, 0, temp, 0, tokens.length);
  945. tokens = temp;
  946. tokens[tokens.length-1] = params[1];
  947. }
  948. return tokens;
  949. }
  950. /**
  951. * Get the ClientInfo object for a person.
  952. *
  953. * @param sWho Who can be any valid identifier for a client as long as it contains a nickname (?:)nick(?!ident)(?@host)
  954. * @return ClientInfo Object for the client, or null
  955. */
  956. public ClientInfo GetClientInfo(String sWho) {
  957. if (bDebug) { System.out.printf("\t\tInput: %s | ",sWho); }
  958. sWho = ClientInfo.ParseHost(sWho);
  959. if (bDebug) { System.out.printf("Client Name: %s\n",sWho); }
  960. sWho = sWho.toLowerCase();
  961. if (hClientList.containsKey(sWho)) { return hClientList.get(sWho); } else { return null; }
  962. }
  963. /**
  964. * Get the ChannelInfo object for a channel.
  965. *
  966. * @param sWhat This is the name of the channel.
  967. * @return ChannelInfo Object for the channel, or null
  968. */
  969. public ChannelInfo GetChannelInfo(String sWhat) {
  970. sWhat = sWhat.toLowerCase();
  971. if (hChannelList.containsKey(sWhat)) { return hChannelList.get(sWhat); } else { return null; }
  972. }
  973. /**
  974. * Send a line to the server.
  975. *
  976. * @param line Line to send (\r\n termination is added automatically)
  977. */
  978. public void SendLine(String line) { CallDataOut(line,false); out.printf("%s\r\n",line);} // This should do some checks on stuff, public event!
  979. // Our Method
  980. protected void SendString(String line) {
  981. CallDataOut(line,true);
  982. out.printf("%s\r\n",line);
  983. }
  984. private void ProcessLine(String line) {
  985. String[] token = IRCTokenise(line);
  986. // String mainParam = token[token.length-1];
  987. int nParam;
  988. CallDataIn(line);
  989. String sParam = token[1];
  990. try {nParam = Integer.parseInt(token[1]);} catch (Exception e) { nParam = -1;}
  991. try {
  992. if (token[0].equals("PING") || token[1].equals("PING")) { SendString("PONG :"+sParam); }
  993. else {
  994. if (token[0].substring(0,1).equals(":")) {
  995. // Post Connect
  996. switch (nParam) {
  997. case -1:
  998. ProcessStringParam(sParam,token);
  999. break;
  1000. case 1: // 001 - Welcome to IRC
  1001. Got001 = true;
  1002. Process001(nParam,token);
  1003. break;
  1004. case 4: // 004 - ISUPPORT
  1005. case 5: // 005 - ISUPPORT
  1006. Process004_005(nParam,token);
  1007. break;
  1008. case 332: // Topic on Join
  1009. case 333: // Topic Setter On Join
  1010. ProcessTopic(sParam,token);
  1011. break;
  1012. case 375: // MOTD Start
  1013. break;
  1014. case 353: // Names
  1015. case 366: // End of Names
  1016. ProcessNames(nParam,token);
  1017. break;
  1018. case 324: // Modes
  1019. ProcessMode(sParam,token);
  1020. case 329: // Channel Time
  1021. case 368: // End of ban list
  1022. break;
  1023. case 376: // End of MOTD
  1024. case 422: // No MOTD
  1025. ProcessEndOfMOTD(nParam,token);
  1026. break;
  1027. case 433: // Nick In Use
  1028. ProcessNickInUse(nParam,token);
  1029. break;
  1030. default: // Unknown
  1031. break;
  1032. }
  1033. } else {
  1034. // Pre Connect
  1035. }
  1036. }
  1037. } catch (Exception e) { CallErrorInfo(errFatal,"Exception in Parser. {"+line+"} ["+e.getMessage()+"]"); e.getStackTrace(); }
  1038. }
  1039. private void ProcessStringParam(String sParam, String token[]) {
  1040. // Process a line where the parameter is a string (IE PRIVMSG, NOTICE etc - Not including PING!)
  1041. if (sParam.equalsIgnoreCase("PRIVMSG") || sParam.equalsIgnoreCase("NOTICE")) { ProcessIRCMessage(sParam,token); }
  1042. else if (sParam.equalsIgnoreCase("JOIN")) { ProcessJoinChannel(sParam,token); }
  1043. else if (sParam.equalsIgnoreCase("NICK")) { ProcessNickChange(sParam,token); }
  1044. else if (sParam.equalsIgnoreCase("KICK")) { ProcessKickChannel(sParam,token); }
  1045. else if (sParam.equalsIgnoreCase("PART")) { ProcessPartChannel(sParam,token); }
  1046. else if (sParam.equalsIgnoreCase("QUIT")) { ProcessQuit(sParam,token); }
  1047. else if (sParam.equalsIgnoreCase("TOPIC")) { ProcessTopic(sParam,token); }
  1048. else if (sParam.equalsIgnoreCase("MODE")) { ProcessMode(sParam,token); }
  1049. }
  1050. private void ProcessNickChange(String sParam, String token[]) {
  1051. ClientInfo iClient;
  1052. iClient = GetClientInfo(token[0]);
  1053. if (iClient != null) {
  1054. if (iClient.getHost().equals("")) { iClient.setUserBits(token[0],false); }
  1055. hClientList.remove(iClient.getNickname().toLowerCase());
  1056. iClient.setUserBits(token[2],true);
  1057. hClientList.put(iClient.getNickname().toLowerCase(),iClient);
  1058. CallNickChanged(iClient, ClientInfo.ParseHost(token[0]));
  1059. }
  1060. }
  1061. private void ProcessKickChannel(String sParam, String token[]) {
  1062. ChannelClientInfo iChannelClient;
  1063. ChannelClientInfo iChannelKicker;
  1064. ChannelInfo iChannel;
  1065. ClientInfo iClient;
  1066. ClientInfo iKicker;
  1067. String sReason = "";
  1068. iClient = GetClientInfo(token[3]);
  1069. iKicker = GetClientInfo(token[0]);
  1070. iChannel = GetChannelInfo(token[2]);
  1071. if (iClient == null) { return; }
  1072. if (iChannel == null) {
  1073. if (iClient != cMyself) {
  1074. CallErrorInfo(errWarning+errCanContinue, "Got kick for channel ("+token[2]+") that I am not on. [User: "+token[3]+"]");
  1075. }
  1076. return;
  1077. } else {
  1078. if (token.length > 4) { sReason = token[token.length-1]; }
  1079. iChannelClient = iChannel.getUser(iClient);
  1080. iChannelKicker = iChannel.getUser(iClient);
  1081. CallChannelKick(iChannel,iChannelClient,iChannelKicker,sReason,token[0]);
  1082. iChannel.delClient(iClient);
  1083. if (iClient == cMyself) {
  1084. iChannel.emptyChannel();
  1085. hChannelList.remove(iChannel.getName().toLowerCase());
  1086. } else {
  1087. if (!iClient.checkVisability()) {
  1088. hClientList.remove(iClient.getNickname().toLowerCase());
  1089. }
  1090. }
  1091. }
  1092. }
  1093. private void ProcessMode(String sParam, String token[]) {
  1094. String[] sModestr;
  1095. String sChannelName;
  1096. String sModeParam;
  1097. int nCurrent = 0, nParam = 1, nValue = 0;
  1098. boolean bPositive = true, bBooleanMode = true;
  1099. ChannelInfo iChannel;
  1100. ChannelClientInfo iChannelClientInfo;
  1101. ClientInfo iClient;
  1102. if (sParam.equals("324")) {
  1103. sChannelName = token[3];
  1104. // Java 6 Only
  1105. // sModestr = Arrays.copyOfRange(token,4,token.length);
  1106. sModestr = new String[token.length-4];
  1107. System.arraycopy(token, 4, sModestr, 0, token.length-4);
  1108. } else {
  1109. sChannelName = token[2];
  1110. // Java 6 Only
  1111. // sModestr = Arrays.copyOfRange(token,3,token.length);
  1112. sModestr = new String[token.length-3];
  1113. System.arraycopy(token, 3, sModestr, 0, token.length-3);
  1114. }
  1115. if (!ChannelInfo.isValidChannelName(this, sChannelName)) { ProcessUserMode(sParam, token, sModestr); return; }
  1116. iChannel = GetChannelInfo(sChannelName);
  1117. if (iChannel == null) {
  1118. CallErrorInfo(errWarning+errCanContinue, "Got modes for channel ("+sChannelName+") that I am not on.");
  1119. iChannel = new ChannelInfo(this, sChannelName);
  1120. hChannelList.put(iChannel.getName().toLowerCase(),iChannel);
  1121. }
  1122. if (!sParam.equals("324")) { nCurrent = iChannel.getMode(); }
  1123. for (int i = 0; i < sModestr[0].length(); ++i) {
  1124. Character cMode = sModestr[0].charAt(i);
  1125. if (cMode.equals("+".charAt(0))) { bPositive = true; }
  1126. else if (cMode.equals("-".charAt(0))) { bPositive = false; }
  1127. else if (cMode.equals(":".charAt(0))) { continue; }
  1128. else {
  1129. if (hChanModesBool.containsKey(cMode)) { nValue = hChanModesBool.get(cMode); bBooleanMode = true; }
  1130. else if (hChanModesOther.containsKey(cMode)) { nValue = hChanModesOther.get(cMode); bBooleanMode = false; }
  1131. else if (hPrefixModes.containsKey(cMode)) {
  1132. // (de) OP/Voice someone
  1133. sModeParam = sModestr[nParam++];
  1134. nValue = hPrefixModes.get(cMode);
  1135. if (bDebug) { System.out.printf("User Mode: %c [%s] {Positive: %b}\n",cMode, sModeParam, bPositive); }
  1136. iChannelClientInfo = iChannel.getUser(sModeParam);
  1137. if (iChannelClientInfo == null) {
  1138. // Client not known?
  1139. CallErrorInfo(errWarning+errCanContinue, "Got mode for client not known on channel - Added");
  1140. iClient = GetClientInfo(sModeParam);
  1141. if (iClient == null) {
  1142. CallErrorInfo(errWarning+errCanContinue, "Got mode for client not known at all - Added");
  1143. iClient = new ClientInfo(this, sModeParam);
  1144. hClientList.put(iClient.getNickname().toLowerCase(),iClient);
  1145. }
  1146. iChannelClientInfo = iChannel.addClient(iClient);
  1147. }
  1148. if (bPositive) { iChannelClientInfo.setChanMode(iChannelClientInfo.getChanMode() + nValue); }
  1149. else { iChannelClientInfo.setChanMode(iChannelClientInfo.getChanMode() - nValue); }
  1150. continue;
  1151. } else {
  1152. CallErrorInfo(errWarning+errCanContinue, "Got unknown mode "+cMode+" - Added as boolean mode");
  1153. hChanModesBool.put(cMode,nNextKeyCMBool);
  1154. nValue = nNextKeyCMBool;
  1155. bBooleanMode = true;
  1156. nNextKeyCMBool = nNextKeyCMBool*2;
  1157. }
  1158. if (bBooleanMode) {
  1159. if (bDebug) { System.out.printf("Boolean Mode: %c [%d] {Positive: %b}\n",cMode, nValue, bPositive); }
  1160. if (bPositive) { nCurrent = nCurrent + nValue; }
  1161. else { nCurrent = nCurrent - nValue; }
  1162. } else {
  1163. if (nValue == cmList) {
  1164. sModeParam = sModestr[nParam++];
  1165. iChannel.setListModeParam(cMode, sModeParam, bPositive);
  1166. if (bDebug) { System.out.printf("List Mode: %c [%s] {Positive: %b}\n",cMode, sModeParam, bPositive); }
  1167. } else {
  1168. if (bPositive) {
  1169. sModeParam = sModestr[nParam++];
  1170. if (bDebug) { System.out.printf("Set Mode: %c [%s] {Positive: %b}\n",cMode, sModeParam, bPositive); }
  1171. iChannel.setModeParam(cMode,sModeParam);
  1172. } else {
  1173. if ((nValue & cmUnset) == cmUnset) { sModeParam = sModestr[nParam++]; } else { sModeParam = ""; }
  1174. if (bDebug) { System.out.printf("Unset Mode: %c [%s] {Positive: %b}\n",cMode, sModeParam, bPositive); }
  1175. iChannel.setModeParam(cMode,"");
  1176. }
  1177. }
  1178. }
  1179. }
  1180. }
  1181. iChannel.setMode(nCurrent);
  1182. if (sParam.equals("324")) { CallModesChanged(iChannel, null, ""); }
  1183. else { CallModesChanged(iChannel, iChannel.getUser(token[0]), token[0]); }
  1184. }
  1185. // This isn't implemented yet.
  1186. private void ProcessUserMode(String sParam, String token[], String sModestr[]) {
  1187. int nCurrent = 0, nValue = 0;
  1188. boolean bPositive = true;
  1189. ClientInfo iClient;
  1190. iClient = GetClientInfo(token[2]);
  1191. if (iClient == null) { return; }
  1192. nCurrent = iClient.getUserMode();
  1193. for (int i = 0; i < sModestr[0].length(); ++i) {
  1194. Character cMode = sModestr[0].charAt(i);
  1195. if (cMode.equals("+".charAt(0))) { bPositive = true; }
  1196. else if (cMode.equals("-".charAt(0))) { bPositive = false; }
  1197. else if (cMode.equals(":".charAt(0))) { continue; }
  1198. else {
  1199. if (hUserModes.containsKey(cMode)) { nValue = hUserModes.get(cMode); }
  1200. else {
  1201. CallErrorInfo(errWarning+errCanContinue, "Got unknown user mode "+cMode+" - Added");
  1202. hUserModes.put(cMode,nNextKeyUser);
  1203. nValue = nNextKeyUser;
  1204. nNextKeyUser = nNextKeyUser*2;
  1205. }
  1206. if (bDebug) { System.out.printf("User Mode: %c [%d] {Positive: %b}\n",cMode, nValue, bPositive); }
  1207. if (bPositive) { nCurrent = nCurrent + nValue; }
  1208. else { nCurrent = nCurrent - nValue; }
  1209. }
  1210. }
  1211. iClient.setUserMode(nCurrent);
  1212. CallUserModesChanged(iClient, token[0]);
  1213. }
  1214. private void ProcessNames(int nParam, String token[]) {
  1215. ChannelInfo iChannel;
  1216. if (nParam == 366) {
  1217. // End of names
  1218. iChannel = GetChannelInfo(token[2]);
  1219. if (iChannel != null) {
  1220. iChannel.bAddingNames = false;
  1221. CallGotNames(iChannel);
  1222. }
  1223. } else {
  1224. // Names
  1225. ClientInfo iClient;
  1226. ChannelClientInfo iChannelClient;
  1227. iChannel = GetChannelInfo(token[4]);
  1228. if (iChannel == null) {
  1229. CallErrorInfo(errWarning+errCanContinue, "Got names for channel ("+token[4]+") that I am not on.");
  1230. iChannel = new ChannelInfo(this, token[4]);
  1231. hChannelList.put(iChannel.getName().toLowerCase(),iChannel);
  1232. }
  1233. // If we are not expecting names, clear the current known names - this is fresh stuff!
  1234. if (!iChannel.bAddingNames) { iChannel.emptyChannel(); }
  1235. iChannel.bAddingNames = true;
  1236. String[] sNames = token[token.length-1].split(" ");
  1237. String sNameBit = "", sModes = "", sName = "";
  1238. int nPrefix = 0;
  1239. for (int j = 0; j < sNames.length; ++j) {
  1240. sNameBit = sNames[j];
  1241. for (int i = 0; i < sNameBit.length(); ++i) {
  1242. Character cMode = sNameBit.charAt(i);
  1243. if (hPrefixMap.containsKey(cMode)) {
  1244. sModes = sModes+cMode;
  1245. nPrefix = nPrefix + hPrefixModes.get(hPrefixMap.get(cMode));
  1246. } else {
  1247. sName = sNameBit.substring(i);
  1248. break;
  1249. }
  1250. }
  1251. System.out.printf("Name: %s Modes: \"%s\" [%d]\n",sName,sModes,nPrefix);
  1252. iClient = GetClientInfo(sName);
  1253. if (iClient == null) { iClient = new ClientInfo(this, sName); hClientList.put(iClient.getNickname().toLowerCase(),iClient); }
  1254. iChannelClient = iChannel.addClient(iClient);
  1255. iChannelClient.setChanMode(nPrefix);
  1256. sName = "";
  1257. sModes = "";
  1258. nPrefix = 0;
  1259. }
  1260. }
  1261. }
  1262. // This horrible thing handles PRIVMSGs and NOTICES
  1263. // This inclues CTCPs and CTCPReplies
  1264. // It handles all 3 targets (Channel, Private, Unknown)
  1265. // Actions are handled here aswell separately from CTCPs.
  1266. // Each type has 5 Calls, making 15 callbacks handled here.
  1267. private void ProcessIRCMessage(String sParam, String token[]) {
  1268. ChannelClientInfo iChannelClient = null;
  1269. ChannelInfo iChannel = null;
  1270. ClientInfo iClient = null;
  1271. String sMessage = token[token.length-1];
  1272. String[] bits = sMessage.split(" ", 2);
  1273. Character Char1 = Character.valueOf((char)1);
  1274. String sCTCP = "";
  1275. boolean isAction = false;
  1276. boolean isCTCP = false;
  1277. iClient = GetClientInfo(token[0]);
  1278. if (sParam.equalsIgnoreCase("PRIVMSG")) {
  1279. if (bits[0].equalsIgnoreCase(Char1+"ACTION") && Character.valueOf(sMessage.charAt(sMessage.length()-1)).equals(Char1)) {
  1280. isAction = true;
  1281. } else if (Character.valueOf(sMessage.charAt(0)).equals(Char1) && Character.valueOf(sMessage.charAt(sMessage.length()-1)).equals(Char1)) {
  1282. isCTCP = true;
  1283. if (bits.length > 1) { sMessage = bits[1]; } else { sMessage = ""; }
  1284. bits = bits[0].split(Char1.toString());
  1285. sCTCP = bits[1];
  1286. if (bDebug) { System.out.printf("CTCP: \"%s\" \"%s\"\n",sCTCP,sMessage); }
  1287. }
  1288. }
  1289. if (ChannelInfo.isValidChannelName(this, token[2])) {
  1290. iChannel = GetChannelInfo(token[2]);
  1291. if (iClient != null && iChannel != null) { iChannelClient = iChannel.getUser(iClient); }
  1292. if (sParam.equalsIgnoreCase("PRIVMSG")) {
  1293. if (!isAction) {
  1294. if (isCTCP) {
  1295. CallChannelCTCP(iChannel, iChannelClient, sCTCP, sMessage, token[0]);
  1296. } else {
  1297. CallChannelMessage(iChannel, iChannelClient, sMessage, token[0]);
  1298. }
  1299. } else {
  1300. CallChannelAction(iChannel, iChannelClient, sMessage, token[0]);
  1301. }
  1302. } else if (sParam.equalsIgnoreCase("NOTICE")) {
  1303. if (isCTCP) {
  1304. CallChannelCTCPReply(iChannel, iChannelClient, sCTCP, sMessage, token[0]);
  1305. } else {
  1306. CallChannelNotice(iChannel, iChannelClient, sMessage, token[0]);
  1307. }
  1308. }
  1309. } else if (token[2].equalsIgnoreCase(cMyself.getNickname())) {
  1310. if (sParam.equalsIgnoreCase("PRIVMSG")) {
  1311. if (!isAction) {
  1312. if (isCTCP) {
  1313. CallPrivateCTCP(iClient, sCTCP, sMessage, token[0]);
  1314. } else {
  1315. CallPrivateMessage(iClient, sMessage, token[0]);
  1316. }
  1317. } else {
  1318. CallPrivateAction(iClient, sMessage, token[0]);
  1319. }
  1320. } else if (sParam.equalsIgnoreCase("NOTICE")) {
  1321. if (isCTCP) {
  1322. CallPrivateCTCPReply(iClient, sCTCP, sMessage, token[0]);
  1323. } else {
  1324. CallPrivateNotice(iClient, sMessage, token[0]);
  1325. }
  1326. }
  1327. } else {
  1328. if (bDebug) { System.out.printf("Message for Other ("+token[2]+")\n"); }
  1329. if (sParam.equalsIgnoreCase("PRIVMSG")) {
  1330. if (!isAction) {
  1331. if (isCTCP) {
  1332. CallUnknownCTCP(iClient, sCTCP, sMessage, token[0]);
  1333. } else {
  1334. CallUnknownMessage(iClient, sMessage, token[0]);
  1335. }
  1336. } else {
  1337. CallUnknownAction(iClient, sMessage, token[0]);
  1338. }
  1339. } else if (sParam.equalsIgnoreCase("NOTICE")) {
  1340. if (isCTCP) {
  1341. CallUnknownCTCPReply(iClient, sCTCP, sMessage, token[0]);
  1342. } else {
  1343. CallUnknownNotice(iClient, sMessage, token[0]);
  1344. }
  1345. }
  1346. }
  1347. }
  1348. private void ProcessTopic(String sParam, String token[]) {
  1349. ChannelInfo iChannel;
  1350. if (sParam.equals("332")) {
  1351. iChannel = GetChannelInfo(token[3]);
  1352. if (iChannel == null) { return; };
  1353. iChannel.setTopic(token[token.length-1]);
  1354. } else if (sParam.equals("333")) {
  1355. iChannel = GetChannelInfo(token[3]);
  1356. if (iChannel == null) { return; };
  1357. iChannel.setTopicTime(Long.parseLong(token[5]));
  1358. iChannel.setTopicUser(token[5]);
  1359. CallTopic(iChannel,false);
  1360. } else {
  1361. iChannel = GetChannelInfo(token[2]);
  1362. if (iChannel == null) { return; };
  1363. iChannel.setTopicTime(java.util.Calendar.getInstance().getTimeInMillis() / 1000);
  1364. String sTemp[] = token[0].split(":",2);
  1365. if (sTemp.length > 1) { token[0] = sTemp[1]; }
  1366. iChannel.setTopicUser(token[0]);
  1367. CallTopic(iChannel,true);
  1368. }
  1369. }
  1370. private void ProcessJoinChannel(String sParam, String token[]) {
  1371. // :nick!ident@host JOIN (:)#Channel
  1372. Character cTemp;
  1373. Byte nTemp;
  1374. if (token.length < 3) { return; }
  1375. ClientInfo iClient;
  1376. ChannelInfo iChannel;
  1377. ChannelClientInfo iChannelClient;
  1378. iClient = GetClientInfo(token[0]);
  1379. iChannel = GetChannelInfo(token[token.length-1]);
  1380. if (iClient == null) { iClient = new ClientInfo(this, token[0]); hClientList.put(iClient.getNickname().toLowerCase(),iClient); }
  1381. if (iChannel == null) {
  1382. if (iClient != cMyself) {
  1383. CallErrorInfo(errWarning+errCanContinue, "Got join for channel ("+token[token.length-1]+") that I am not on. [User: "+token[0]+"]");
  1384. }
  1385. iChannel = new ChannelInfo(this, token[token.length-1]);
  1386. hChannelList.put(iChannel.getName().toLowerCase(),iChannel);
  1387. SendString("MODE "+iChannel.getName());
  1388. for (Enumeration e = hChanModesOther.keys(); e.hasMoreElements();) {
  1389. cTemp = (Character)e.nextElement();
  1390. nTemp = hChanModesOther.get(cTemp);
  1391. if (nTemp == cmList) { SendString("MODE "+iChannel.getName()+" "+cTemp); }
  1392. }
  1393. } else {
  1394. // This is only done if we are on the channel. Else we wait for names.
  1395. iChannelClient = iChannel.addClient(iClient);
  1396. CallChannelJoin(iChannel, iChannelClient);
  1397. }
  1398. }
  1399. private void ProcessPartChannel(String sParam, String token[]) {
  1400. // :nick!ident@host PART #Channel
  1401. // :nick!ident@host PART #Channel :reason
  1402. if (token.length < 3) { return; }
  1403. ClientInfo iClient;
  1404. ChannelInfo iChannel;
  1405. ChannelClientInfo iChannelClient;
  1406. iClient = GetClientInfo(token[0]);
  1407. iChannel = GetChannelInfo(token[2]);
  1408. if (iClient == null) { return; }
  1409. if (iChannel == null) {
  1410. if (iClient != cMyself) {
  1411. CallErrorInfo(errWarning+errCanContinue, "Got part for channel ("+token[2]+") that I am not on. [User: "+token[0]+"]");
  1412. }
  1413. return;
  1414. } else {
  1415. String sReason = "";
  1416. if (token.length > 3) { sReason = token[token.length-1]; }
  1417. iChannelClient = iChannel.getUser(iClient);
  1418. CallChannelPart(iChannel,iChannelClient,sReason);
  1419. iChannel.delClient(iClient);
  1420. if (iClient == cMyself) {
  1421. iChannel.emptyChannel();
  1422. hChannelList.remove(iChannel.getName().toLowerCase());
  1423. } else { iClient.checkVisability(); }
  1424. }
  1425. }
  1426. private void ProcessQuit(String sParam, String token[]) {
  1427. // :nick!ident@host QUIT
  1428. // :nick!ident@host QUIT :reason
  1429. if (token.length < 2) { return; }
  1430. ClientInfo iClient;
  1431. ChannelInfo iChannel;
  1432. ChannelClientInfo iChannelClient;
  1433. iClient = GetClientInfo(token[0]);
  1434. if (iClient == null) { return; }
  1435. String sReason = "";
  1436. if (token.length > 2) { sReason = token[token.length-1]; }
  1437. for (Enumeration e = hChannelList.keys(); e.hasMoreElements();) {
  1438. iChannel = hChannelList.get(e.nextElement());
  1439. iChannelClient = iChannel.getUser(iClient);
  1440. if (iChannelClient != null) {
  1441. CallChannelQuit(iChannel,iChannelClient,sReason);
  1442. if (iClient == cMyself) {
  1443. iChannel.emptyChannel();
  1444. hChannelList.remove(iChannel.getName().toLowerCase());
  1445. } else {
  1446. iChannel.delClient(iClient);
  1447. }
  1448. }
  1449. }
  1450. CallQuit(iClient,sReason);
  1451. if (iClient == cMyself) {
  1452. hClientList.clear();
  1453. } else {
  1454. hClientList.remove(iClient.getNickname().toLowerCase());
  1455. }
  1456. }
  1457. private void Process004_005(int nParam, String token[]) {
  1458. if (nParam == 4) {
  1459. // 004
  1460. h005Info.put("USERMODES",token[5]);
  1461. } else {
  1462. // 005
  1463. String[] Bits = null;
  1464. String sKey = null, sValue = null;
  1465. for (int i = 3; i < token.length ; i++) {
  1466. Bits = token[i].split("=",2);
  1467. sKey = Bits[0].toUpperCase();
  1468. if (Bits.length == 2) { sValue = Bits[1]; } else { sValue = ""; }
  1469. if (bDebug) { System.out.printf("%s => %s \r\n",sKey,sValue); }
  1470. h005Info.put(sKey,sValue);
  1471. }
  1472. }
  1473. }
  1474. protected void ParseChanModes() {
  1475. final String sDefaultModes = "b,k,l,imnpstrc";
  1476. String[] Bits = null;
  1477. String ModeStr;
  1478. if (h005Info.containsKey("CHANMODES")) { ModeStr = h005Info.get("CHANMODES"); }
  1479. else { ModeStr = sDefaultModes; h005Info.put("CHANMODES",ModeStr); }
  1480. Bits = ModeStr.split(",",4);
  1481. if (Bits.length != 4) {
  1482. ModeStr = sDefaultModes;
  1483. CallErrorInfo(errError+errCanContinue, "CHANMODES String not valid. Using default string of \""+ModeStr+"\"");
  1484. h005Info.put("CHANMODES",ModeStr);
  1485. Bits = ModeStr.split(",",4);
  1486. }
  1487. // ResetState
  1488. hChanModesOther.clear();
  1489. hChanModesBool.clear();
  1490. nNextKeyCMBool = 1;
  1491. // List modes.
  1492. for (int i = 0; i < Bits[0].length(); ++i) {
  1493. Character cMode = Bits[0].charAt(i);
  1494. if (bDebug) { System.out.printf("List Mode: %c\n",cMode); }
  1495. if (!hChanModesOther.containsKey(cMode)) { hChanModesOther.put(cMode,cmList); }
  1496. }
  1497. // Param for Set and Unset.
  1498. Byte nBoth = (cmSet+cmUnset);
  1499. for (int i = 0; i < Bits[1].length(); ++i) {
  1500. Character cMode = Bits[1].charAt(i);
  1501. if (bDebug) { System.out.printf("Set/Unset Mode: %c\n",cMode); }
  1502. if (!hChanModesOther.containsKey(cMode)) { hChanModesOther.put(cMode,nBoth); }
  1503. }
  1504. // Param just for Set
  1505. for (int i = 0; i < Bits[2].length(); ++i) {
  1506. Character cMode = Bits[2].charAt(i);
  1507. if (bDebug) { System.out.printf("Set Only Mode: %c\n",cMode); }
  1508. if (!hChanModesOther.containsKey(cMode)) { hChanModesOther.put(cMode,cmSet); }
  1509. }
  1510. // Boolean Mode
  1511. for (int i = 0; i < Bits[3].length(); ++i) {
  1512. Character cMode = Bits[3].charAt(i);
  1513. if (bDebug) { System.out.printf("Boolean Mode: %c [%d]\n",cMode,nNextKeyCMBool); }
  1514. if (!hChanModesBool.containsKey(cMode)) {
  1515. hChanModesBool.put(cMode,nNextKeyCMBool);
  1516. nNextKeyCMBool = nNextKeyCMBool*2;
  1517. }
  1518. }
  1519. }
  1520. protected void ParseUserModes() {
  1521. final String sDefaultModes = "nwdoi";
  1522. String[] Bits = null;
  1523. String ModeStr;
  1524. if (h005Info.containsKey("USERMODES")) { ModeStr = h005Info.get("USERMODES"); }
  1525. else { ModeStr = sDefaultModes; h005Info.put("USERMODES", sDefaultModes); }
  1526. // ResetState
  1527. hUserModes.clear();
  1528. nNextKeyUser = 1;
  1529. // Boolean Mode
  1530. for (int i = 0; i < ModeStr.length(); ++i) {
  1531. Character cMode = ModeStr.charAt(i);
  1532. if (bDebug) { System.out.printf("User Mode: %c [%d]\n",cMode,nNextKeyUser); }
  1533. if (!hUserModes.containsKey(cMode)) {
  1534. hUserModes.put(cMode,nNextKeyUser);
  1535. nNextKeyUser = nNextKeyUser*2;
  1536. }
  1537. }
  1538. }
  1539. protected void ParseChanPrefix() {
  1540. final String sDefaultModes = "#&";
  1541. String[] Bits = null;
  1542. String ModeStr;
  1543. if (h005Info.containsKey("CHANTYPES")) { ModeStr = h005Info.get("CHANTYPES"); }
  1544. else { ModeStr = sDefaultModes; h005Info.put("CHANTYPES", sDefaultModes); }
  1545. // ResetState
  1546. hChanPrefix.clear();
  1547. // Boolean Mode
  1548. for (int i = 0; i < ModeStr.length(); ++i) {
  1549. Character cMode = ModeStr.charAt(i);
  1550. if (bDebug) { System.out.printf("Chan Prefix: %c\n",cMode); }
  1551. if (!hChanPrefix.containsKey(cMode)) { hChanPrefix.put(cMode,true); }
  1552. }
  1553. }
  1554. protected void ParsePrefixModes() {
  1555. final String sDefaultModes = "(ohv)@%+";
  1556. String[] Bits = null;
  1557. String ModeStr;
  1558. if (h005Info.containsKey("PREFIX")) { ModeStr = h005Info.get("PREFIX"); }
  1559. else { ModeStr = sDefaultModes; }
  1560. if (ModeStr.substring(0,1).equals("(")) { ModeStr = ModeStr.substring(1); }
  1561. else { ModeStr = sDefaultModes.substring(1); h005Info.put("PREFIX", sDefaultModes); }
  1562. Bits = ModeStr.split("\\)",2);
  1563. if (Bits.length != 2 || Bits[0].length() != Bits[1].length()) {
  1564. ModeStr = sDefaultModes;
  1565. CallErrorInfo(errError+errCanContinue, "PREFIX String not valid. Using default string of \""+ModeStr+"\"");
  1566. h005Info.put("PREFIX",ModeStr);
  1567. ModeStr = ModeStr.substring(1);
  1568. Bits = ModeStr.split("\\)",2);
  1569. }
  1570. // ResetState
  1571. hPrefixModes.clear();
  1572. hPrefixMap.clear();
  1573. nNextKeyPrefix = 1;
  1574. for (int i = 0; i < Bits[0].length(); ++i) {
  1575. Character cMode = Bits[0].charAt(i);
  1576. Character cPrefix = Bits[1].charAt(i);
  1577. if (bDebug) { System.out.printf("Prefix Mode: %c => %c [%d]\n",cMode,cPrefix,nNextKeyPrefix); }
  1578. if (!hPrefixModes.containsKey(cMode)) {
  1579. hPrefixModes.put(cMode,nNextKeyPrefix);
  1580. hPrefixMap.put(cMode,cPrefix);
  1581. hPrefixMap.put(cPrefix,cMode);
  1582. nNextKeyPrefix = nNextKeyPrefix*2;
  1583. }
  1584. }
  1585. }
  1586. private void ProcessEndOfMOTD(int nParam, String token[]) {
  1587. ParseChanModes();
  1588. ParseChanPrefix();
  1589. ParsePrefixModes();
  1590. ParseUserModes();
  1591. CallMOTDEnd();
  1592. }
  1593. private void Process001(int nParam, String token[]) {
  1594. // << :demon1.uk.quakenet.org 001 Java-Test :Welcome to the QuakeNet IRC Network, Java-Test
  1595. String sNick;
  1596. sServerName = token[0].substring(1,token[0].length());
  1597. sNick = token[2];
  1598. /* Code below is here incase relying on token[2] breaks somewhere
  1599. String[] temp = token[token.length-1].split(" ");
  1600. sConfirmedNickname = temp[temp.length-1];
  1601. // Some servers give a full host in 001
  1602. temp = sNick.split("!",2);
  1603. sNick = temp[0]; /* */
  1604. cMyself = GetClientInfo(sNick);
  1605. if (cMyself == null) { cMyself = new ClientInfo(this, sNick); }
  1606. }
  1607. private void ProcessNickInUse(int nParam, String token[]) {
  1608. if (!CallNickInUse()) {
  1609. // Manually handle nick in use.
  1610. CallDebugInfo(ndInfo,"No Nick in use Handler.");
  1611. if (!Got001) {
  1612. CallDebugInfo(ndInfo,"Using inbuilt handler");
  1613. // If this is before 001 we will try and get a nickname, else we will leave the nick as-is
  1614. if (!TriedAlt) { SetNickname(me.sAltNickname); TriedAlt = true; }
  1615. else {
  1616. if (sThinkNickname.equalsIgnoreCase(me.sAltNickname)) { sThinkNickname = me.sNickname; }
  1617. SetNickname('_'+sThinkNickname);
  1618. }
  1619. }
  1620. }
  1621. }
  1622. /**
  1623. * Join a Channel.
  1624. *
  1625. * @param sChannelName Name of channel to join
  1626. */
  1627. public void JoinChannel(String sChannelName) {
  1628. if (!ChannelInfo.isValidChannelName(this,sChannelName)) { return; }
  1629. SendString("JOIN "+sChannelName);
  1630. }
  1631. /**
  1632. * Leave a Channel.
  1633. *
  1634. * @param sChannelName Name of channel to join
  1635. */
  1636. public void PartChannel(String sChannelName, String sReason) {
  1637. if (!ChannelInfo.isValidChannelName(this,sChannelName)) { return; }
  1638. if (sReason.equals("")) { SendString("PART "+sChannelName); }
  1639. else { SendString("PART "+sChannelName+" :"+sReason); }
  1640. }
  1641. /**
  1642. * Set Nickname.
  1643. *
  1644. * @param sNewNickName New nickname wanted.
  1645. */
  1646. public void SetNickname(String sNewNickName) {
  1647. sThinkNickname = sNewNickName;
  1648. SendString("NICK "+sNewNickName);
  1649. }
  1650. /**
  1651. * Quit server. This method will wait for the server to close the socket.
  1652. *
  1653. * @param sReason Reason for quitting.
  1654. */
  1655. public void Quit(String sReason) {
  1656. if (sReason.equals("")) { SendString("QUIT"); }
  1657. else { SendString("QUIT :"+sReason); }
  1658. }
  1659. /**
  1660. * Disconnect from server. This method will quit and automatically close the
  1661. * socket without waiting for the server
  1662. *
  1663. * @param sReason Reason for quitting.
  1664. */
  1665. public void Disconnect(String sReason) {
  1666. Quit(sReason);
  1667. try { socket.close(); } catch (Exception e) { /* Meh */ };
  1668. }
  1669. /**
  1670. * Get SVN Version information
  1671. *
  1672. * @return SVN Version String
  1673. */
  1674. public static String getSvnInfo () { return "$Id$"; }
  1675. }
  1676. // eof