www.pudn.com > AjaxChatUchat.rar > ChatEngine.cs


using System; 
using System.Text; 
using System.Threading; 
using System.Collections; 
using System.Collections.Specialized; 
 
namespace UChat.ChatEngine 
{ 
	public class ChatEngine : IChatEngine 
	{ 
		const string msg = "
  • {1}
  • \r\n"; const string userlistfmt = "
  • {0}
  • \r\n"; const string serverstyle = "servermsg"; const string userstyle = "usermsg"; const string actionstyle = "actionmsg"; const string timeoutfmt = "User {0} timed out"; const string textlimitfmt = "{0}, your message was {1} characters long. The limit is {2} characters."; const string nickinusefmt = "{0} a user with this nick already exists"; const string joinedfmt = "User {0} has joined"; const string nickfmt = "{0} is now known as {1}"; const string killfmt = "User {0} has been terminated!"; const string clearfmt = "User {0} has cleared all chat log!"; const string unknowcmdfmt = "User {0} : Unknow command"; const string mefmt = "{0} {1}"; const string txtfmt = "{0}: {1}"; const long timerdelay = 300000; const int maxbuffer = 20; const int textlimit = 100; Timer timer; Hashtable users; StringCollection chat; StringCollection pings; object syncRoot = new object(); /// /// Default constructor /// public ChatEngine() { users = new Hashtable(); chat = new StringCollection(); pings = new StringCollection(); TimerCallback OnTimerTick = new TimerCallback( TimerTick ); timer = new Timer( OnTimerTick, null, timerdelay, timerdelay ); } /// /// Check for pinged out users /// private void TimerTick( object state ) { lock( syncRoot ) { string[] current = new string[ users.Keys.Count ]; users.Keys.CopyTo( current, 0 ); foreach( string guid in current ) { if( !pings.Contains( guid ) ) { chat.Add( this.MakeServerMessage( string.Format( timeoutfmt, users[ guid ].ToString() ) ) ); users.Remove( guid ); } } pings.Clear(); } } /// /// Gets the current list of /// users /// public string[] Users { get { string[] nicks = new string[ users.Count ]; users.Values.CopyTo( nicks, 0 ); return nicks; } } /// /// HTML Formatted user list /// public string UserList { get { StringBuilder sb = new StringBuilder(); string[] nicks = new string[ users.Count ]; users.Values.CopyTo( nicks, 0 ); foreach( string user in nicks ) { sb.Append( string.Format( userlistfmt, user ) ); } return sb.ToString(); } } /// /// Gets the current buffer of chat text /// public string BufferText { get { StringBuilder sb = new StringBuilder(); foreach( string line in chat ) { sb.Append( line ); } return sb.ToString(); } } /// /// Does a user exist based on a guid /// public bool GuidExists( string guid ) { return users.ContainsKey( guid ); } /// /// Checks to see if the current user /// exists in the list /// public bool UserExists(string user) { return users.ContainsValue( user ); } /// /// Adds a user to the list /// public void AddUser(string id, string user) { lock( syncRoot ) if( !UserExists( user ) ) { users.Add( id, user ); pings.Add( id ); chat.Add( this.MakeServerMessage( string.Format( joinedfmt, user ) ) ); } } /// /// Pings this chat server and keeps /// a user alive /// public void Ping(string guid) { lock( syncRoot ) pings.Add( guid ); } /// /// Adds text to the buffer /// public void AddText(string guid, string text) { if( text.Trim().Length == 0 ) return; if( text.Length > textlimit ) { chat.Add( MakeServerMessage( string.Format( textlimitfmt, users[ guid ].ToString(), text.Length, textlimit ) ) ); return; } while( chat.Count > maxbuffer ) { chat.RemoveAt( 0 ); } if( !pings.Contains( guid ) ) { pings.Add( guid ); } chat.Add( ParseText( users[ guid ].ToString(), text ) ); } /// /// Format the users chat depending on whether /// a control command was supplied. /// private string ParseText( string user, string text ) { if( text.StartsWith( "/me " ) ) { return MakeActionMessage( string.Format( mefmt, user, text.Replace( "/me", string.Empty ) ) ); } if( text.StartsWith( "/admin " ) ) { string command = text.Replace("/admin", string.Empty).Trim(); string result = string.Empty; switch(command) { case "clear": chat.Clear(); result = MakeServerMessage( string.Format(clearfmt, user) ); break; default: result = MakeServerMessage( string.Format(unknowcmdfmt, user) ); break; } return result; } if( text.StartsWith( "/nick " ) ) { string newnick = text.Replace( "/nick", string.Empty ).Trim(); if( UserExists( newnick ) ) { return MakeServerMessage( string.Format( nickinusefmt, user ) ); } string[] keys = new string[ users.Count ]; users.Keys.CopyTo( keys, 0 ); foreach( string key in keys ) { if( users[ key ].ToString() == user ) { users[ key ] = newnick; return MakeServerMessage( string.Format(nickfmt, user, newnick ) ); } } } return MakeUserMessage( string.Format( txtfmt, user, text ) ); } /// /// Remove the user /// public void Remove( string user, string password ) { // // TODO: Add your password here if( password != "Add password here!" ) return; if( this.UserExists( user ) ) { string[] keys = new string[ users.Count ]; foreach( DictionaryEntry e in users ) { if( e.Value.ToString() == user ) { chat.Add( this.MakeServerMessage( string.Format( killfmt, user ) ) ); users.Remove( e.Key ); return; } } } if( pings.Contains( user ) ) pings.Remove( user ); } /// /// Format a server message by wrapping /// text in a list item with the server /// css class selector /// private string MakeServerMessage( string text ) { return string.Format( msg, serverstyle, text ); } /// /// Format a user message by wrapping text /// in a list item with the user css class /// selector /// private string MakeUserMessage( string text ) { return string.Format( msg, userstyle, text ); } /// /// Format a user action message by wrapping text /// in a list item with the action css class /// selector /// private string MakeActionMessage( string text ) { return string.Format( msg, actionstyle, text ); } } }