353 lines
8.1 KiB
C#
353 lines
8.1 KiB
C#
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;
|
|
private int c_Attempts;
|
|
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" ) ); } }
|
|
|
|
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));
|
|
}
|
|
|
|
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 );
|
|
|
|
Broadcast( parOne, str );
|
|
}
|
|
|
|
}
|
|
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")); }
|
|
}
|
|
}
|
|
} |