using System;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Collections;
using Server;
using Knives.Utils;
namespace Knives.Chat3
{
public enum IrcColor
{
White = 0,
Black = 1,
Blue = 2,
Green = 3,
LightRed = 4,
Brown = 5,
Purple = 6,
Orange = 7,
Yellow = 8,
LightGreen = 9,
Cyan = 10,
LightCyan = 11,
LightBlue = 12,
Pink = 13,
Grey = 14,
LightGrey = 15,
};
public class IrcConnection
{
private static IrcConnection s_Connection = new IrcConnection();
public static IrcConnection Connection{ get{ return s_Connection; } }
private TcpClient c_Tcp;
private Thread c_Thread;
private StreamReader c_Reader;
private StreamWriter c_Writer;
private bool c_Connecting, c_Connected, [COLOR=red]m_Authenticated[/COLOR];
private int c_Attempts, [COLOR=red]m_AuthAttempts[/COLOR];
private DateTime c_LastPong;
public bool Connecting{ get{ return c_Connecting; } }
public bool Connected{ get{ return c_Connected; } }
public bool HasMoreAttempts{ get{ return c_Attempts <= Data.IrcMaxAttempts; } }
public IrcConnection()
{
}
public void Connect( Mobile m )
{
Data data = Data.GetData( m );
if ( c_Connecting )
{
m.SendMessage( data.SystemC, General.Local(102) );
return;
}
if ( c_Connected )
{
m.SendMessage( data.SystemC, General.Local(103) );
return;
}
Connect();
}
public void Connect()
{
new Thread( new ThreadStart( ConnectTcp ) ).Start();
}
public void CancelConnect()
{
c_Attempts = Data.IrcMaxAttempts;
}
private void Reconnect()
{
c_Attempts++;
if ( !HasMoreAttempts )
{
c_Attempts = 1;
BroadcastSystem( General.Local(104) );
return;
}
BroadcastSystem( General.Local(105) + c_Attempts );
Connect();
}
private void ConnectTcp()
{
try{ c_Tcp = new TcpClient( Data.IrcServer, Data.IrcPort ); }
catch
{
BroadcastSystem( General.Local(106) );
Reconnect();
return;
}
ConnectStream();
}
private void ConnectStream()
{try{
c_Connecting = true;
c_LastPong = DateTime.Now;
c_Reader = new StreamReader(c_Tcp.GetStream(), System.Text.Encoding.Default);
c_Writer = new StreamWriter(c_Tcp.GetStream(), System.Text.Encoding.Default);
BroadcastSystem( General.Local(107) );
SendMessage(String.Format("USER {0} 1 * :Hello!", Data.IrcNick));
SendMessage(String.Format("NICK {0}", Data.IrcNick));
c_Thread = new Thread(new ThreadStart(ReadStream));
c_Thread.Start();
Server.Timer.DelayCall( TimeSpan.FromSeconds( 15.0 ), new Server.TimerCallback( Names ) );
foreach (Data data in Data.Datas.Values)
if (data.Mobile.HasGump(typeof(SetupGump)))
General.RefreshGump(data.Mobile, typeof(SetupGump));
}catch{ Errors.Report( String.Format( "IrcConnection-> ConnectStream" ) ); } }
[COLOR=red] private void Auth()
{
if (!m_Authenticated)
{
SendMessage("PRIVMSG [/COLOR][EMAIL="[email protected]"][COLOR=red][email protected][/COLOR][/EMAIL][COLOR=red] AUTH XXXX XXXX");
m_AuthAttempts++;[/COLOR]
[COLOR=red] if (m_AuthAttempts < 10)
{
Server.Timer.DelayCall(TimeSpan.FromSeconds(15.0), new Server.TimerCallback(Auth));
}
}
}[/COLOR]
private void Names()
{
if (c_Connected)
SendMessage("NAMES " + Data.IrcRoom);
else
return;
Server.Timer.DelayCall( TimeSpan.FromSeconds( 15.0 ), new Server.TimerCallback( Names ) );
}
private void PingPong(string str)
{
if (!c_Connecting && !c_Connected)
return;
if (str.IndexOf("PING") != -1)
str = str.Replace("PING", "PONG");
else
str = str.Replace("PONG", "PING");
SendMessage( str );
}
public void SendMessage( string msg )
{
try{
BroadcastRaw( msg );
c_Writer.WriteLine( msg );
c_Writer.Flush();
}catch{ Disconnect(); }
}
public void SendUserMessage( Mobile m, string msg )
{
if ( !Connected )
return;
msg = OutParse( m, m.Name + ": " + msg );
s_Connection.SendMessage( String.Format( "PRIVMSG {0} : {1}", Data.IrcRoom, msg ));
BroadcastRaw( String.Format( "PRIVMSG {0} : {1}", Data.IrcRoom, msg ) );
}
private string OutParse( Mobile m, string str )
{
if ( m.AccessLevel != AccessLevel.Player )
return str = '\x0003' + ((int)Data.IrcStaffColor).ToString() + str;
return str;
}
private void BroadcastSystem( string msg )
{
foreach( Data data in Data.Datas.Values )
if ( data.Channels.Contains("IRC") && !data.Banned )
data.Mobile.SendMessage( data.SystemC, msg );
}
private void Broadcast( string name, string msg )
{
if (!(Channel.GetByName("IRC") is IRC))
return;
((IRC)Channel.GetByName("IRC")).Broadcast(name, msg);
}
private void Broadcast( Mobile m, string msg )
{
}
private void BroadcastRaw( string msg )
{
foreach( Data data in Data.Datas.Values )
if ( data.IrcRaw )
data.Mobile.SendMessage( data.SystemC, "RAW: " + msg );
}
private void ReadStream()
{try{
string input = "";
while( c_Thread.IsAlive )
{
input = c_Reader.ReadLine();
if ( input == null )
break;
HandleInput( input );
}
Disconnect();
}catch{ Disconnect(); } }
private void HandleInput( string str )
{try{
if (str == null)
return;
BroadcastRaw( str );
if ( str.IndexOf( "PONG" ) != -1 || str.IndexOf("PING") != -1 )
{
PingPong( str );
return;
}
if ( str.IndexOf( "353" ) != -1 )
{
BroadcastRaw( General.Local(109) );
int index = str.ToLower().IndexOf( Data.IrcRoom.ToLower() ) + Data.IrcRoom.Length + 2;
if ( index == 1 )
return;
string strList = str.Substring( index, str.Length-index );
string[] strs = strList.Trim().Split( ' ' );
Data.IrcList.Clear();
Data.IrcList.AddRange( strs );
Data.IrcList.Remove( Data.IrcNick );
}
if (str.IndexOf("001") != -1 && c_Connecting)
{
c_Connected = true;
c_Connecting = false;
BroadcastSystem(General.Local(108));
c_Attempts = 1;
SendMessage(String.Format("JOIN {0}", Data.IrcRoom));
foreach (Data data in Data.Datas.Values)
if (data.Mobile.HasGump(typeof(SetupGump)))
General.RefreshGump(data.Mobile, typeof(SetupGump));
[COLOR=red]m_Authenticated = false;
m_AuthAttempts = 0;
Server.Timer.DelayCall(TimeSpan.FromSeconds(15.0), new Server.TimerCallback(Auth));
[/COLOR] }
[COLOR=red]if (str.IndexOf("Notice from Q(QuakeNet):") != -1 && !m_Authenticated)
{
string message = str.Substring( 25, str.Length - 25 );[/COLOR]
[COLOR=red] if (message == "AUTH'd successfully.")
{
m_Authenticated = true;
}
}[/COLOR]
if (str.Length > 300)
return;
if (str.IndexOf("PRIVMSG") != -1)
{
string parOne = str.Substring( 1, str.IndexOf( "!" )-1 );
string parThree = str.Substring( str.IndexOf( "!" )+1, str.Length-str.IndexOf("!")-(str.Length-str.IndexOf("PRIVMSG"))-1);
int index = 0;
index = str.ToLower().IndexOf( Data.IrcRoom.ToLower() ) + Data.IrcRoom.Length + 2;
if ( index == 1 )
return;
string parTwo = str.Substring( index, str.Length-index );
if (parTwo.IndexOf("ACTION") != -1)
{
index = parTwo.IndexOf("ACTION") + 7;
parTwo = parTwo.Substring(index, parTwo.Length - index);
str = String.Format("<{0}> {1} {2}", Data.IrcRoom, parOne, parTwo);
}
else
{
str = String.Format("<{0}> {1}: {2}", Data.IrcRoom, parOne, parTwo);
}
[COLOR=seagreen]switch (ChatHelper.Check(parOne, parTwo))
{
case ProfanityCheckResult.Nothing:
Broadcast(parOne, str);
break;
case ProfanityCheckResult.Warning:
ChatHelper.Warn(this, parOne);
break;
case ProfanityCheckResult.Profanation:
ChatHelper.Kick(this, parOne);
break;
}[/COLOR]
}
}
catch (Exception e) { Errors.Report(String.Format("IrcConnection-> HandleInput")); Console.WriteLine(e.Message); }}
public void Disconnect()
{
Disconnect( true );
}
public void Disconnect(bool reconn)
{
try
{
if (c_Connected)
BroadcastSystem(General.Local(110));
c_Connected = false;
c_Connecting = false;
if (c_Thread != null)
{
c_Thread.Abort();
c_Thread = null;
}
if (c_Reader != null)
c_Reader.Close();
if (c_Writer != null)
c_Writer.Close();
if (c_Tcp != null)
c_Tcp.Close();
if (reconn)
Reconnect();
foreach (Data data in Data.Datas.Values)
if (data.Mobile.HasGump(typeof(SetupGump)))
General.RefreshGump(data.Mobile, typeof(SetupGump));
}
catch { Errors.Report(String.Format("IrcConnection-> Disconnect")); }
}
}
}