Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Development

Development::Development Forum for development topics and for those interested in EQEMu development. (Not a support forum)

Reply
 
Thread Tools Display Modes
  #1  
Old 07-29-2009, 09:48 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default EQEmu ChatServer w/ IRC (Win32)

Here's the source for what i've been working on the last few days. You will need to add some entries to the chatserver section of eqemu_config.xml or it will *not* work.

The IRC.cpp and IRC.h are modified versions of iainsheppard's IRC class.
You can download the original copy at: http://www.nongnu.org/cpirc/

Also, if it never joins your channel, just PM the bot saying !rejoin and it will rejoin the channel from the XML file.

It does NOT do automatic reconnection. The support for auto-reconnect is in the class, though.

Nickserv stuff can also be added in the triggers function, if needed.

Here's the bot:

http://www.sendspace.com/file/w3an9e

The needed XML stuff examples:

Code:
		<channeltooutput>#EQEmu</channeltooutput>
		<eqchanneltooutput>General</eqchanneltooutput>
		<chatirchost>eqnet.eqemulator.net</chatirchost>
		<chatircport>6667</chatircport>
		<chatircnick>SecretsBot</chatircnick>
First, channeltooutput. This puts all chat from the application to this IRC channel.

Next, EQChannelToOutput. This channel must already exist, otherwise it will crash on the iterator. It outputs all IRC talk to this channel in-game.

Next, ChatIRCHost. This field specifies which IRC server to connect to. I suggest using eqnet.eqemulator.net.

Next, ChatIRCPort. This tells which port to connect to on ChatIRCHost.

Finally, ChatIRCNick. This is your bot's nickname. Currently, there is no nickserv support, however that can be added at a later date.



Note: Win32 is only supported because it uses Winsock & windows threading. I am willing to bet if you use the source from http://www.nongnu.org/cpirc/ it will compile with the files replaced. (the reason i'm doing this is because Winsock does not support fdopen) I do not have a linux box otherwise i'd make a linux version.

Enjoy!

(ps: thanks for the help on this KLS and AndMetal!)

(ps: it's my first hack, so be easy on me :P)

Last edited by Secrets; 07-30-2009 at 05:53 AM..
Reply With Quote
  #2  
Old 07-29-2009, 09:52 PM
Scorpious2k's Avatar
Scorpious2k
Demi-God
 
Join Date: Mar 2003
Location: USA
Posts: 1,067
Default

Nice work Secrets.
__________________
Maybe I should try making one of these servers...
Reply With Quote
  #3  
Old 07-29-2009, 10:24 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default Diff

Code:
Index: chatchannel.cpp
===================================================================
--- chatchannel.cpp	(revision 846)
+++ chatchannel.cpp	(working copy)
@@ -1,699 +1,725 @@
-/*
-	EQEMu:  Everquest Server Emulator
-
-	Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net)
-
-	This program is free software; you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation; version 2 of the License.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY except by those people which sell it, which
-	are required to give you total support for your newly bought product;
-	without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-	A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program; if not, write to the Free Software
-	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-#include "chatchannel.h"
-#include "clientlist.h"
-#include "database.h"
-#include "../common/MiscFunctions.h"
-#include <cstdlib>
-
-extern Database database;
-
-ChatChannel::ChatChannel(string inName, string inOwner, string inPassword, bool inPermanent, int inMinimumStatus) : 
-	DeleteTimer(0) {
-
-	Name = inName;
-
-	Owner = inOwner;
-
-	Password = inPassword;
-
-	Permanent = inPermanent;
-
-	MinimumStatus = inMinimumStatus;
-
-	Moderated = false;
-
-	_log(CHANNELS__TRACE, "New ChatChannel created: Name: [%s], Owner: [%s], Password: [%s], MinStatus: %i", 
-			      Name.c_str(), Owner.c_str(), Password.c_str(), MinimumStatus);
-
-}
-
-ChatChannel::~ChatChannel() {
-
-	LinkedListIterator<Client*> iterator(ClientsInChannel);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements())
-		iterator.RemoveCurrent(false);
-}
-
-ChatChannel* ChatChannelList::CreateChannel(string Name, string Owner, string Password, bool Permanent, int MinimumStatus) {
-
-	ChatChannel *NewChannel = new ChatChannel(CapitaliseName(Name), Owner, Password, Permanent, MinimumStatus);
-
-	ChatChannels.Insert(NewChannel);
-
-	return NewChannel;
-}
-
-ChatChannel* ChatChannelList::FindChannel(string Name) {
-
-	string NormalisedName = CapitaliseName(Name);
-
-	LinkedListIterator<ChatChannel*> iterator(ChatChannels);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements()) {
-
-		ChatChannel *CurrentChannel = iterator.GetData();
-
-		if(CurrentChannel && (CurrentChannel->Name == NormalisedName))
-			return iterator.GetData();
-
-		iterator.Advance();
-	}
-
-	return NULL;
-}
-
-void ChatChannelList::SendAllChannels(Client *c) {
-
-	if(!c) return;
-
-	if(!c->CanListAllChannels()) {
-		c->GeneralChannelMessage("You do not have permission to list all the channels.");
-		return;
-	}
-
-	c->GeneralChannelMessage("All current channels:");
-
-	int ChannelsInLine = 0;
-
-	LinkedListIterator<ChatChannel*> iterator(ChatChannels);
-
-	iterator.Reset();
-
-	string Message;
-
-	char CountString[10];
-
-	while(iterator.MoreElements()) {
-
-		ChatChannel *CurrentChannel = iterator.GetData();
-
-		if(!CurrentChannel || (CurrentChannel->GetMinStatus() > c->GetAccountStatus())) {
-
-			iterator.Advance();
-
-			continue;
-		}
-
-		if(ChannelsInLine > 0)
-			Message += ", ";
-
-		sprintf(CountString, "(%i)", CurrentChannel->MemberCount(c->GetAccountStatus()));
-
-		Message += CurrentChannel->GetName();
-
-		Message += CountString;
-
-		ChannelsInLine++;
-
-		if(ChannelsInLine == 6) {
-
-			c->GeneralChannelMessage(Message);
-
-			ChannelsInLine = 0;
-
-			Message.clear();
-		}
-
-		iterator.Advance();
-	}
-
-	if(ChannelsInLine > 0)
-		c->GeneralChannelMessage(Message);
-
-}
-
-void ChatChannelList::RemoveChannel(ChatChannel *Channel) {
-
-	_log(CHANNELS__TRACE, "RemoveChannel(%s)", Channel->GetName().c_str());
-
-	LinkedListIterator<ChatChannel*> iterator(ChatChannels);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements()) {
-
-		if(iterator.GetData() == Channel) {
-
-			iterator.RemoveCurrent();
-
-			return;
-		}
-
-		iterator.Advance();
-	}
-}
-
-void ChatChannelList::RemoveAllChannels() {
-
-	_log(CHANNELS__TRACE, "RemoveAllChannels");
-
-	LinkedListIterator<ChatChannel*> iterator(ChatChannels);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements())
-		iterator.RemoveCurrent();
-}
-
-int ChatChannel::MemberCount(int Status) {
-
-	int Count = 0;
-
-	LinkedListIterator<Client*> iterator(ClientsInChannel);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements()) {
-
-		Client *ChannelClient = iterator.GetData();
-
-		if(ChannelClient && (!ChannelClient->GetHideMe() || (ChannelClient->GetAccountStatus() < Status)))
-			Count++;
-
-		iterator.Advance();
-	}
-
-	return Count;
-}
-
-void ChatChannel::SetPassword(string inPassword) {
-
-	Password = inPassword;
-
-	if(Permanent)
-	{
-		RemoveApostrophes(Password);
-		database.SetChannelPassword(Name, Password);
-	}
-}
-
-void ChatChannel::SetOwner(string inOwner) {
-
-	Owner = inOwner;
-
-	if(Permanent)
-		database.SetChannelOwner(Name, Owner);
-}
-
-void ChatChannel::AddClient(Client *c) {
-
-	if(!c) return;
-
-	DeleteTimer.Disable();
-
-	if(IsClientInChannel(c)) {
-
-		_log(CHANNELS__ERROR, "Client %s already in channel %s", c->GetName().c_str(), GetName().c_str());
-
-		return;
-	}
-
-	bool HideMe = c->GetHideMe();
-
-	int AccountStatus = c->GetAccountStatus();
-
-	_log(CHANNELS__TRACE, "Adding %s to channel %s", c->GetName().c_str(), Name.c_str());
-
-	LinkedListIterator<Client*> iterator(ClientsInChannel);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements()) {
-
-		Client *CurrentClient = iterator.GetData();
-
-		if(CurrentClient && CurrentClient->IsAnnounceOn())
-			if(!HideMe || (CurrentClient->GetAccountStatus() > AccountStatus))
-				CurrentClient->AnnounceJoin(this, c);
-
-		iterator.Advance();
-	}
-
-	ClientsInChannel.Insert(c);
-
-}
-
-bool ChatChannel::RemoveClient(Client *c) {
-
-	if(!c) return false;
-
-	_log(CHANNELS__TRACE, "RemoveClient %s from channel %s", c->GetName().c_str(), GetName().c_str());
-
-	bool HideMe = c->GetHideMe();
-
-	int AccountStatus = c->GetAccountStatus();
-
-	int PlayersInChannel = 0;
-
-	LinkedListIterator<Client*> iterator(ClientsInChannel);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements()) {
-
-		Client *CurrentClient = iterator.GetData();
-
-		if(CurrentClient == c) {
-			iterator.RemoveCurrent(false);
-		}
-		else if(CurrentClient) {
-
-			PlayersInChannel++;
-
-			if(CurrentClient->IsAnnounceOn())
-				if(!HideMe || (CurrentClient->GetAccountStatus() > AccountStatus))
-					CurrentClient->AnnounceLeave(this, c);
-
-			iterator.Advance();
-		}
-
-	}
-
-	if((PlayersInChannel == 0) && !Permanent) {
-
-		if((Password.length() == 0) || (RuleI(Channels, DeleteTimer) == 0))
-			return false;
-
-		_log(CHANNELS__TRACE, "Starting delete timer for empty password protected channel %s", Name.c_str());
-			
-		DeleteTimer.Start(RuleI(Channels, DeleteTimer) * 60000);
-	}
-
-	return true;
-}
-
-void ChatChannel::SendOPList(Client *c) {
-
-	if(!c) return;
-
-	c->GeneralChannelMessage("Channel " + Name + " op-list: (Owner=" + Owner + ")");
-
-	list<string>::iterator Iterator;
-
-	for(Iterator = Moderators.begin(); Iterator != Moderators.end(); Iterator++)
-		c->GeneralChannelMessage((*Iterator));
-
-}
-
-void ChatChannel::SendChannelMembers(Client *c) {
-
-	if(!c) return;
-
-	char CountString[10];
-
-	sprintf(CountString, "(%i)", MemberCount(c->GetAccountStatus()));
-
-	string Message = "Channel " + GetName();
-
-	Message += CountString;
-
-	Message += " members:";
-
-	c->GeneralChannelMessage(Message);
-
-	int AccountStatus = c->GetAccountStatus();
-
-	Message.clear();
-
-	int MembersInLine = 0;
-
-	LinkedListIterator<Client*> iterator(ClientsInChannel);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements()) {
-
-		Client *ChannelClient = iterator.GetData();
-
-		// Don't list hidden characters with status higher or equal than the character requesting the list.
-		//
-		if(!ChannelClient || (ChannelClient->GetHideMe() && (ChannelClient->GetAccountStatus() >= AccountStatus))) {
-			iterator.Advance();
-			continue;
-		}
-
-		if(MembersInLine > 0)
-			Message += ", ";
-
-		Message += ChannelClient->GetName();
-
-		MembersInLine++;
-
-		if(MembersInLine == 6) {
-
-			c->GeneralChannelMessage(Message);
-
-			MembersInLine = 0;
-
-			Message.clear();
-		}
-
-		iterator.Advance();
-	}
-
-	if(MembersInLine > 0)
-		c->GeneralChannelMessage(Message);
-
-}
-
-void ChatChannel::SendMessageToChannel(string Message, Client* Sender) {
-
-	if(!Sender) return;
-
-	LinkedListIterator<Client*> iterator(ClientsInChannel);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements()) {
-
-		Client *ChannelClient = iterator.GetData();
-
-		if(ChannelClient)
-			ChannelClient->SendChannelMessage(Name, Message, Sender);
-
-		iterator.Advance();
-	}
-}
-
-void ChatChannel::SetModerated(bool inModerated) {
-
-	Moderated = inModerated;
-
-	LinkedListIterator<Client*> iterator(ClientsInChannel);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements()) {
-
-		Client *ChannelClient = iterator.GetData();
-
-		if(ChannelClient) {
-
-			if(Moderated)
-				ChannelClient->GeneralChannelMessage("Channel " + Name + " is now moderated.");
-			else
-				ChannelClient->GeneralChannelMessage("Channel " + Name + " is no longer moderated.");
-		}
-
-		iterator.Advance();
-	}
-
-}
-bool ChatChannel::IsClientInChannel(Client *c) {
-
-	if(!c) return false;
-
-	LinkedListIterator<Client*> iterator(ClientsInChannel);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements()) {
-
-		if(iterator.GetData() == c)
-			return true;
-
-		iterator.Advance();
-	}
-
-	return false;
-}
-
-ChatChannel *ChatChannelList::AddClientToChannel(string ChannelName, Client *c) {
-
-	if(!c) return NULL;
-
-	if((ChannelName.length() > 0) && (isdigit(ChannelName[0]))) {
-		
-		c->GeneralChannelMessage("The channel name can not begin with a number.");
-
-		return NULL;
-	}
-
-	string NormalisedName, Password;
-
-	string::size_type Colon = ChannelName.find_first_of(":");
-
-	if(Colon == string::npos) 
-		NormalisedName = CapitaliseName(ChannelName);
-	else {
-		NormalisedName = CapitaliseName(ChannelName.substr(0, Colon));
-
-		Password = ChannelName.substr(Colon + 1);
-	}
-
-	if((NormalisedName.length() > 64) || (Password.length() > 64)) {
-
-		c->GeneralChannelMessage("The channel name or password cannot exceed 64 characters.");
-
-		return NULL;
-	}
-
-	_log(CHANNELS__TRACE, "AddClient to channel [%s] with password [%s]", NormalisedName.c_str(), Password.c_str());
-
-	ChatChannel *RequiredChannel = FindChannel(NormalisedName);
-
-	if(!RequiredChannel)
-		RequiredChannel = CreateChannel(NormalisedName, c->GetName(), Password, false, 0);
-
-	if(RequiredChannel->GetMinStatus() > c->GetAccountStatus()) {
-
-		string Message = "You do not have the required account status to join channel " + NormalisedName;
-
-		c->GeneralChannelMessage(Message);
-
-		return NULL;
-	}
-
-	if(RequiredChannel->IsClientInChannel(c))
-		return NULL;
-
-	if(RequiredChannel->IsInvitee(c->GetName())) {
-
-		RequiredChannel->AddClient(c);
-
-		RequiredChannel->RemoveInvitee(c->GetName());
-
-		return RequiredChannel;
-	}
-
-	if(RequiredChannel->CheckPassword(Password) || RequiredChannel->IsOwner(c->GetName()) || RequiredChannel->IsModerator(c->GetName()) ||
-	   c->IsChannelAdmin()) {
-
-		RequiredChannel->AddClient(c);
-
-		return RequiredChannel;
-	}
-
-	c->GeneralChannelMessage("Incorrect password for channel " + (NormalisedName));
-
-	return NULL;
-}
-
-ChatChannel *ChatChannelList::RemoveClientFromChannel(string inChannelName, Client *c) {
-
-	if(!c) return NULL;
-
-	string ChannelName = inChannelName;
-
-	if((inChannelName.length() > 0) && isdigit(ChannelName[0]))
-		ChannelName = c->ChannelSlotName(atoi(inChannelName.c_str()));
-
-	ChatChannel *RequiredChannel = FindChannel(ChannelName);
-
-	if(!RequiredChannel)
-		return NULL;
-
-	// RemoveClient will return false if there is no-one left in the channel, and the channel is not permanent and has
-	// no password.
-	//
-	if(!RequiredChannel->RemoveClient(c))
-		RemoveChannel(RequiredChannel);
-
-	return RequiredChannel;
-}
-
-void ChatChannelList::Process() {
-
-	LinkedListIterator<ChatChannel*> iterator(ChatChannels);
-
-	iterator.Reset();
-
-	while(iterator.MoreElements()) {
-
-		ChatChannel *CurrentChannel = iterator.GetData();
-
-		if(CurrentChannel && CurrentChannel->ReadyToDelete()) {
-
-			_log(CHANNELS__TRACE, "Empty temporary password protected channel %s being destroyed.",
-				CurrentChannel->GetName().c_str());
-
-			RemoveChannel(CurrentChannel);
-		}
-
-		iterator.Advance();
-
-	}
-}
-
-void ChatChannel::AddInvitee(string Invitee) {
-
-	if(!IsInvitee(Invitee)) {
-
-		Invitees.push_back(Invitee);
-
-		_log(CHANNELS__TRACE, "Added %s as invitee to channel %s", Invitee.c_str(), Name.c_str());
-	}
-
-}
-
-void ChatChannel::RemoveInvitee(string Invitee) {
-
-	list<string>::iterator Iterator;
-
-	for(Iterator = Invitees.begin(); Iterator != Invitees.end(); Iterator++) {
-
-		if((*Iterator) == Invitee) {
-
-			Invitees.erase(Iterator);
-
-			_log(CHANNELS__TRACE, "Removed %s as invitee to channel %s", Invitee.c_str(), Name.c_str());
-
-			return;
-		}
-	}
-}
-
-bool ChatChannel::IsInvitee(string Invitee) {
-
-	list<string>::iterator Iterator;
-
-	for(Iterator = Invitees.begin(); Iterator != Invitees.end(); Iterator++) {
-
-		if((*Iterator) == Invitee)
-			return true;
-	}
-
-	return false;
-}
-
-void ChatChannel::AddModerator(string Moderator) {
-
-	if(!IsModerator(Moderator)) {
-
-		Moderators.push_back(Moderator);
-
-		_log(CHANNELS__TRACE, "Added %s as moderator to channel %s", Moderator.c_str(), Name.c_str());
-	}
-
-}
-
-void ChatChannel::RemoveModerator(string Moderator) {
-
-	list<string>::iterator Iterator;
-
-	for(Iterator = Moderators.begin(); Iterator != Moderators.end(); Iterator++) {
-
-		if((*Iterator) == Moderator) {
-
-			Moderators.erase(Iterator);
-
-			_log(CHANNELS__TRACE, "Removed %s as moderator to channel %s", Moderator.c_str(), Name.c_str());
-
-			return;
-		}
-	}
-}
-
-bool ChatChannel::IsModerator(string Moderator) {
-
-	list<string>::iterator Iterator;
-
-	for(Iterator = Moderators.begin(); Iterator != Moderators.end(); Iterator++) {
-
-		if((*Iterator) == Moderator)
-			return true;
-	}
-
-	return false;
-}
-
-void ChatChannel::AddVoice(string inVoiced) {
-
-	if(!HasVoice(inVoiced)) {
-
-		Voiced.push_back(inVoiced);
-
-		_log(CHANNELS__TRACE, "Added %s as voiced to channel %s", inVoiced.c_str(), Name.c_str());
-	}
-
-}
-
-void ChatChannel::RemoveVoice(string inVoiced) {
-
-	list<string>::iterator Iterator;
-
-	for(Iterator = Voiced.begin(); Iterator != Voiced.end(); Iterator++) {
-
-		if((*Iterator) == inVoiced) {
-
-			Voiced.erase(Iterator);
-
-			_log(CHANNELS__TRACE, "Removed %s as voiced to channel %s", inVoiced.c_str(), Name.c_str());
-
-			return;
-		}
-	}
-}
-
-bool ChatChannel::HasVoice(string inVoiced) {
-
-	list<string>::iterator Iterator;
-
-	for(Iterator = Voiced.begin(); Iterator != Voiced.end(); Iterator++) {
-
-		if((*Iterator) == inVoiced)
-			return true;
-	}
-
-	return false;
-}
-
-string CapitaliseName(string inString) {
-
-	string NormalisedName = inString;
-
-	for(unsigned int i = 0; i < NormalisedName.length(); i++) {
-
-		if(i == 0)
-			NormalisedName[i] = toupper(NormalisedName[i]);
-		else
-			NormalisedName[i] = tolower(NormalisedName[i]);
-	}
-
-	return NormalisedName;
-}
+/*
+	EQEMu:  Everquest Server Emulator
+
+	Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net)
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; version 2 of the License.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY except by those people which sell it, which
+	are required to give you total support for your newly bought product;
+	without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+	A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the Free Software
+	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+#include "chatchannel.h"
+#include "ChatConfig.h"
+#include "clientlist.h"
+#include "database.h"
+#include "../common/MiscFunctions.h"
+#include <cstdlib>
+#include "IRC.h"
+
+extern Database database;
+
+extern IRC conn;
+
+ChatChannel::ChatChannel(string inName, string inOwner, string inPassword, bool inPermanent, int inMinimumStatus) : 
+	DeleteTimer(0) {
+
+	Name = inName;
+
+	Owner = inOwner;
+
+	Password = inPassword;
+
+	Permanent = inPermanent;
+
+	MinimumStatus = inMinimumStatus;
+
+	Moderated = false;
+
+	_log(CHANNELS__TRACE, "New ChatChannel created: Name: [%s], Owner: [%s], Password: [%s], MinStatus: %i", 
+			      Name.c_str(), Owner.c_str(), Password.c_str(), MinimumStatus);
+
+}
+
+ChatChannel::~ChatChannel() {
+
+	LinkedListIterator<Client*> iterator(ClientsInChannel);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements())
+		iterator.RemoveCurrent(false);
+}
+
+ChatChannel* ChatChannelList::CreateChannel(string Name, string Owner, string Password, bool Permanent, int MinimumStatus) {
+
+	ChatChannel *NewChannel = new ChatChannel(CapitaliseName(Name), Owner, Password, Permanent, MinimumStatus);
+
+	ChatChannels.Insert(NewChannel);
+
+	return NewChannel;
+}
+
+ChatChannel* ChatChannelList::FindChannel(string Name) {
+
+	string NormalisedName = CapitaliseName(Name);
+
+	LinkedListIterator<ChatChannel*> iterator(ChatChannels);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements()) {
+
+		ChatChannel *CurrentChannel = iterator.GetData();
+
+		if(CurrentChannel && (CurrentChannel->Name == NormalisedName))
+			return iterator.GetData();
+
+		iterator.Advance();
+	}
+
+	return NULL;
+}
+
+void ChatChannelList::SendAllChannels(Client *c) {
+
+	if(!c) return;
+
+	if(!c->CanListAllChannels()) {
+		c->GeneralChannelMessage("You do not have permission to list all the channels.");
+		return;
+	}
+
+	c->GeneralChannelMessage("All current channels:");
+
+	int ChannelsInLine = 0;
+
+	LinkedListIterator<ChatChannel*> iterator(ChatChannels);
+
+	iterator.Reset();
+
+	string Message;
+
+	char CountString[10];
+
+	while(iterator.MoreElements()) {
+
+		ChatChannel *CurrentChannel = iterator.GetData();
+
+		if(!CurrentChannel || (CurrentChannel->GetMinStatus() > c->GetAccountStatus())) {
+
+			iterator.Advance();
+
+			continue;
+		}
+
+		if(ChannelsInLine > 0)
+			Message += ", ";
+
+		sprintf(CountString, "(%i)", CurrentChannel->MemberCount(c->GetAccountStatus()));
+
+		Message += CurrentChannel->GetName();
+
+		Message += CountString;
+
+		ChannelsInLine++;
+
+		if(ChannelsInLine == 6) {
+
+			c->GeneralChannelMessage(Message);
+
+			ChannelsInLine = 0;
+
+			Message.clear();
+		}
+
+		iterator.Advance();
+	}
+
+	if(ChannelsInLine > 0)
+		c->GeneralChannelMessage(Message);
+
+}
+
+void ChatChannelList::RemoveChannel(ChatChannel *Channel) {
+
+	_log(CHANNELS__TRACE, "RemoveChannel(%s)", Channel->GetName().c_str());
+
+	LinkedListIterator<ChatChannel*> iterator(ChatChannels);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements()) {
+
+		if(iterator.GetData() == Channel) {
+
+			iterator.RemoveCurrent();
+
+			return;
+		}
+
+		iterator.Advance();
+	}
+}
+
+void ChatChannelList::RemoveAllChannels() {
+
+	_log(CHANNELS__TRACE, "RemoveAllChannels");
+
+	LinkedListIterator<ChatChannel*> iterator(ChatChannels);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements())
+		iterator.RemoveCurrent();
+}
+
+int ChatChannel::MemberCount(int Status) {
+
+	int Count = 0;
+
+	LinkedListIterator<Client*> iterator(ClientsInChannel);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements()) {
+
+		Client *ChannelClient = iterator.GetData();
+
+		if(ChannelClient && (!ChannelClient->GetHideMe() || (ChannelClient->GetAccountStatus() < Status)))
+			Count++;
+
+		iterator.Advance();
+	}
+
+	return Count;
+}
+
+void ChatChannel::SetPassword(string inPassword) {
+
+	Password = inPassword;
+
+	if(Permanent)
+	{
+		RemoveApostrophes(Password);
+		database.SetChannelPassword(Name, Password);
+	}
+}
+
+void ChatChannel::SetOwner(string inOwner) {
+
+	Owner = inOwner;
+
+	if(Permanent)
+		database.SetChannelOwner(Name, Owner);
+}
+
+void ChatChannel::AddClient(Client *c) {
+
+	if(!c) return;
+
+	DeleteTimer.Disable();
+
+	if(IsClientInChannel(c)) {
+
+		_log(CHANNELS__ERROR, "Client %s already in channel %s", c->GetName().c_str(), GetName().c_str());
+
+		return;
+	}
+
+	bool HideMe = c->GetHideMe();
+
+	int AccountStatus = c->GetAccountStatus();
+
+	_log(CHANNELS__TRACE, "Adding %s to channel %s", c->GetName().c_str(), Name.c_str());
+
+	LinkedListIterator<Client*> iterator(ClientsInChannel);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements()) {
+
+		Client *CurrentClient = iterator.GetData();
+
+		if(CurrentClient && CurrentClient->IsAnnounceOn())
+			if(!HideMe || (CurrentClient->GetAccountStatus() > AccountStatus))
+				CurrentClient->AnnounceJoin(this, c);
+
+		iterator.Advance();
+	}
+
+	ClientsInChannel.Insert(c);
+
+}
+
+bool ChatChannel::RemoveClient(Client *c) {
+
+	if(!c) return false;
+
+	_log(CHANNELS__TRACE, "RemoveClient %s from channel %s", c->GetName().c_str(), GetName().c_str());
+
+	bool HideMe = c->GetHideMe();
+
+	int AccountStatus = c->GetAccountStatus();
+
+	int PlayersInChannel = 0;
+
+	LinkedListIterator<Client*> iterator(ClientsInChannel);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements()) {
+
+		Client *CurrentClient = iterator.GetData();
+
+		if(CurrentClient == c) {
+			iterator.RemoveCurrent(false);
+		}
+		else if(CurrentClient) {
+
+			PlayersInChannel++;
+
+			if(CurrentClient->IsAnnounceOn())
+				if(!HideMe || (CurrentClient->GetAccountStatus() > AccountStatus))
+					CurrentClient->AnnounceLeave(this, c);
+
+			iterator.Advance();
+		}
+
+	}
+
+	if((PlayersInChannel == 0) && !Permanent) {
+
+		if((Password.length() == 0) || (RuleI(Channels, DeleteTimer) == 0))
+			return false;
+
+		_log(CHANNELS__TRACE, "Starting delete timer for empty password protected channel %s", Name.c_str());
+			
+		DeleteTimer.Start(RuleI(Channels, DeleteTimer) * 60000);
+	}
+
+	return true;
+}
+
+void ChatChannel::SendOPList(Client *c) {
+
+	if(!c) return;
+
+	c->GeneralChannelMessage("Channel " + Name + " op-list: (Owner=" + Owner + ")");
+
+	list<string>::iterator Iterator;
+
+	for(Iterator = Moderators.begin(); Iterator != Moderators.end(); Iterator++)
+		c->GeneralChannelMessage((*Iterator));
+
+}
+
+void ChatChannel::SendChannelMembers(Client *c) {
+
+	if(!c) return;
+
+	char CountString[10];
+
+	sprintf(CountString, "(%i)", MemberCount(c->GetAccountStatus()));
+
+	string Message = "Channel " + GetName();
+
+	Message += CountString;
+
+	Message += " members:";
+
+	c->GeneralChannelMessage(Message);
+
+	int AccountStatus = c->GetAccountStatus();
+
+	Message.clear();
+
+	int MembersInLine = 0;
+
+	LinkedListIterator<Client*> iterator(ClientsInChannel);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements()) {
+
+		Client *ChannelClient = iterator.GetData();
+
+		// Don't list hidden characters with status higher or equal than the character requesting the list.
+		//
+		if(!ChannelClient || (ChannelClient->GetHideMe() && (ChannelClient->GetAccountStatus() >= AccountStatus))) {
+			iterator.Advance();
+			continue;
+		}
+
+		if(MembersInLine > 0)
+			Message += ", ";
+
+		Message += ChannelClient->GetName();
+
+		MembersInLine++;
+
+		if(MembersInLine == 6) {
+
+			c->GeneralChannelMessage(Message);
+
+			MembersInLine = 0;
+
+			Message.clear();
+		}
+
+		iterator.Advance();
+	}
+
+	if(MembersInLine > 0)
+		c->GeneralChannelMessage(Message);
+
+}
+
+void ChatChannel::SendMessageToChannel(string Message, Client* Sender) { /* edited for IRC -- Secrets*/
+
+	if(!Sender) return;
+
+	const ChatConfig *Config=ChatConfig::get();
+	
+	LinkedListIterator<Client*> iterator(ClientsInChannel);
+
+	string ChannelToOutput = Config->ChannelToOutput.c_str();
+
+	char target[64];
+	strcpy(target,Config->ChannelToOutput.c_str());
+	iterator.Reset();
+
+	while(iterator.MoreElements()) {
+
+		Client *ChannelClient = iterator.GetData();
+
+		if(ChannelClient)
+			ChannelClient->SendChannelMessage(Name, Message, Sender);
+		conn.privmsg(target,"%s tells channel '%s', '%s'", Sender->GetName().c_str(), Name.c_str()  , Message.c_str()); // Secrets -- IRC : Send message to IRC also
+		iterator.Advance();
+	}
+}
+
+void ChatChannel::SendMessageToChannelFromIRC(string Message, string IRCName) { /* Sends IRC Messages to Game */
+
+	LinkedListIterator<Client*> iterator(ClientsInChannel);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements()) {
+
+		Client *ChannelClient = iterator.GetData();
+
+		if(ChannelClient)
+			ChannelClient->SendChannelMessageFromIRC(Message, IRCName);
+		iterator.Advance();
+	}
+}
+
+void ChatChannel::SetModerated(bool inModerated) {
+
+	Moderated = inModerated;
+
+	LinkedListIterator<Client*> iterator(ClientsInChannel);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements()) {
+
+		Client *ChannelClient = iterator.GetData();
+
+		if(ChannelClient) {
+
+			if(Moderated)
+				ChannelClient->GeneralChannelMessage("Channel " + Name + " is now moderated.");
+			else
+				ChannelClient->GeneralChannelMessage("Channel " + Name + " is no longer moderated.");
+		}
+
+		iterator.Advance();
+	}
+
+}
+bool ChatChannel::IsClientInChannel(Client *c) {
+
+	if(!c) return false;
+
+	LinkedListIterator<Client*> iterator(ClientsInChannel);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements()) {
+
+		if(iterator.GetData() == c)
+			return true;
+
+		iterator.Advance();
+	}
+
+	return false;
+}
+
+ChatChannel *ChatChannelList::AddClientToChannel(string ChannelName, Client *c) {
+
+	if(!c) return NULL;
+
+	if((ChannelName.length() > 0) && (isdigit(ChannelName[0]))) {
+		
+		c->GeneralChannelMessage("The channel name can not begin with a number.");
+
+		return NULL;
+	}
+
+	string NormalisedName, Password;
+
+	string::size_type Colon = ChannelName.find_first_of(":");
+
+	if(Colon == string::npos) 
+		NormalisedName = CapitaliseName(ChannelName);
+	else {
+		NormalisedName = CapitaliseName(ChannelName.substr(0, Colon));
+
+		Password = ChannelName.substr(Colon + 1);
+	}
+
+	if((NormalisedName.length() > 64) || (Password.length() > 64)) {
+
+		c->GeneralChannelMessage("The channel name or password cannot exceed 64 characters.");
+
+		return NULL;
+	}
+
+	_log(CHANNELS__TRACE, "AddClient to channel [%s] with password [%s]", NormalisedName.c_str(), Password.c_str());
+
+	ChatChannel *RequiredChannel = FindChannel(NormalisedName);
+
+	if(!RequiredChannel)
+		RequiredChannel = CreateChannel(NormalisedName, c->GetName(), Password, false, 0);
+
+	if(RequiredChannel->GetMinStatus() > c->GetAccountStatus()) {
+
+		string Message = "You do not have the required account status to join channel " + NormalisedName;
+
+		c->GeneralChannelMessage(Message);
+
+		return NULL;
+	}
+
+	if(RequiredChannel->IsClientInChannel(c))
+		return NULL;
+
+	if(RequiredChannel->IsInvitee(c->GetName())) {
+
+		RequiredChannel->AddClient(c);
+
+		RequiredChannel->RemoveInvitee(c->GetName());
+
+		return RequiredChannel;
+	}
+
+	if(RequiredChannel->CheckPassword(Password) || RequiredChannel->IsOwner(c->GetName()) || RequiredChannel->IsModerator(c->GetName()) ||
+	   c->IsChannelAdmin()) {
+
+		RequiredChannel->AddClient(c);
+
+		return RequiredChannel;
+	}
+
+	c->GeneralChannelMessage("Incorrect password for channel " + (NormalisedName));
+
+	return NULL;
+}
+
+ChatChannel *ChatChannelList::RemoveClientFromChannel(string inChannelName, Client *c) {
+
+	if(!c) return NULL;
+
+	string ChannelName = inChannelName;
+
+	if((inChannelName.length() > 0) && isdigit(ChannelName[0]))
+		ChannelName = c->ChannelSlotName(atoi(inChannelName.c_str()));
+
+	ChatChannel *RequiredChannel = FindChannel(ChannelName);
+
+	if(!RequiredChannel)
+		return NULL;
+
+	// RemoveClient will return false if there is no-one left in the channel, and the channel is not permanent and has
+	// no password.
+	//
+	if(!RequiredChannel->RemoveClient(c))
+		RemoveChannel(RequiredChannel);
+
+	return RequiredChannel;
+}
+
+void ChatChannelList::Process() {
+
+	LinkedListIterator<ChatChannel*> iterator(ChatChannels);
+
+	iterator.Reset();
+
+	while(iterator.MoreElements()) {
+
+		ChatChannel *CurrentChannel = iterator.GetData();
+
+		if(CurrentChannel && CurrentChannel->ReadyToDelete()) {
+
+			_log(CHANNELS__TRACE, "Empty temporary password protected channel %s being destroyed.",
+				CurrentChannel->GetName().c_str());
+
+			RemoveChannel(CurrentChannel);
+		}
+
+		iterator.Advance();
+
+	}
+}
+
+void ChatChannel::AddInvitee(string Invitee) {
+
+	if(!IsInvitee(Invitee)) {
+
+		Invitees.push_back(Invitee);
+
+		_log(CHANNELS__TRACE, "Added %s as invitee to channel %s", Invitee.c_str(), Name.c_str());
+	}
+
+}
+
+void ChatChannel::RemoveInvitee(string Invitee) {
+
+	list<string>::iterator Iterator;
+
+	for(Iterator = Invitees.begin(); Iterator != Invitees.end(); Iterator++) {
+
+		if((*Iterator) == Invitee) {
+
+			Invitees.erase(Iterator);
+
+			_log(CHANNELS__TRACE, "Removed %s as invitee to channel %s", Invitee.c_str(), Name.c_str());
+
+			return;
+		}
+	}
+}
+
+bool ChatChannel::IsInvitee(string Invitee) {
+
+	list<string>::iterator Iterator;
+
+	for(Iterator = Invitees.begin(); Iterator != Invitees.end(); Iterator++) {
+
+		if((*Iterator) == Invitee)
+			return true;
+	}
+
+	return false;
+}
+
+void ChatChannel::AddModerator(string Moderator) {
+
+	if(!IsModerator(Moderator)) {
+
+		Moderators.push_back(Moderator);
+
+		_log(CHANNELS__TRACE, "Added %s as moderator to channel %s", Moderator.c_str(), Name.c_str());
+	}
+
+}
+
+void ChatChannel::RemoveModerator(string Moderator) {
+
+	list<string>::iterator Iterator;
+
+	for(Iterator = Moderators.begin(); Iterator != Moderators.end(); Iterator++) {
+
+		if((*Iterator) == Moderator) {
+
+			Moderators.erase(Iterator);
+
+			_log(CHANNELS__TRACE, "Removed %s as moderator to channel %s", Moderator.c_str(), Name.c_str());
+
+			return;
+		}
+	}
+}
+
+bool ChatChannel::IsModerator(string Moderator) {
+
+	list<string>::iterator Iterator;
+
+	for(Iterator = Moderators.begin(); Iterator != Moderators.end(); Iterator++) {
+
+		if((*Iterator) == Moderator)
+			return true;
+	}
+
+	return false;
+}
+
+void ChatChannel::AddVoice(string inVoiced) {
+
+	if(!HasVoice(inVoiced)) {
+
+		Voiced.push_back(inVoiced);
+
+		_log(CHANNELS__TRACE, "Added %s as voiced to channel %s", inVoiced.c_str(), Name.c_str());
+	}
+
+}
+
+void ChatChannel::RemoveVoice(string inVoiced) {
+
+	list<string>::iterator Iterator;
+
+	for(Iterator = Voiced.begin(); Iterator != Voiced.end(); Iterator++) {
+
+		if((*Iterator) == inVoiced) {
+
+			Voiced.erase(Iterator);
+
+			_log(CHANNELS__TRACE, "Removed %s as voiced to channel %s", inVoiced.c_str(), Name.c_str());
+
+			return;
+		}
+	}
+}
+
+bool ChatChannel::HasVoice(string inVoiced) {
+
+	list<string>::iterator Iterator;
+
+	for(Iterator = Voiced.begin(); Iterator != Voiced.end(); Iterator++) {
+
+		if((*Iterator) == inVoiced)
+			return true;
+	}
+
+	return false;
+}
+
+string CapitaliseName(string inString) {
+
+	string NormalisedName = inString;
+
+	for(unsigned int i = 0; i < NormalisedName.length(); i++) {
+
+		if(i == 0)
+			NormalisedName[i] = toupper(NormalisedName[i]);
+		else
+			NormalisedName[i] = tolower(NormalisedName[i]);
+	}
+
+	return NormalisedName;
+}
Index: chatchannel.h
===================================================================
--- chatchannel.h	(revision 846)
+++ chatchannel.h	(working copy)
@@ -25,6 +25,7 @@
 	int MemberCount(int Status);
 	string GetName() { return Name; }
 	void SendMessageToChannel(string Message, Client* Sender);
+	void SendMessageToChannelFromIRC(string Message, string IRCName);
 	bool CheckPassword(string inPassword) { return ((Password.length() == 0) || (Password == inPassword)); }
 	void SetPassword(string inPassword);
 	bool IsOwner(string Name) { return (Owner == Name); }
@@ -44,7 +45,6 @@
 	bool HasVoice(string Voiced);
 	inline bool IsModerated() { return Moderated; }
 	void SetModerated(bool inModerated);
-
 	friend class ChatChannelList;
 
 private:
Index: chatserver.cpp
===================================================================
--- chatserver.cpp	(revision 846)
+++ chatserver.cpp	(working copy)
@@ -1,155 +1,237 @@
-/*
-	EQEMu:  Everquest Server Emulator
-
-	Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net)
-
-	This program is free software; you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation; version 2 of the License.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY except by those people which sell it, which
-	are required to give you total support for your newly bought product;
-	without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-	A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program; if not, write to the Free Software
-	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-#include "../common/debug.h"
-#include "clientlist.h"
-#include "../common/opcodemgr.h"
-#include "../common/EQStreamFactory.h"
-#include "../common/rulesys.h"
-#include "database.h"
-#include "ChatConfig.h"
-#include "chatchannel.h"
-#include <list>
-#include <signal.h>
-
-volatile bool RunLoops = true;
-
-TimeoutManager          timeout_manager;
-
-Clientlist *CL;
-
-ChatChannelList *ChannelList;
-
-Database database;
-
-string WorldShortName;
-
-RuleManager *rules = new RuleManager();
-
-void CatchSignal(int sig_num) {
-
-	RunLoops = false;
-}
-
-string GetMailPrefix() {
-
-	return "SOE.EQ." + WorldShortName + ".";
-
-}
-
-int main() {
-
-	// Check every minute for unused channels we can delete
-	//
-	Timer ChannelListProcessTimer(60000);
-
-	_log(CHANNELS__INIT, "Starting EQEmu Chat Channel Server");
-
-	if (!ChatConfig::LoadConfig()) {
-
-		_log(CHANNELS__INIT, "Loading server configuration failed.");
-
-		return(1);
-	}
-
-	const ChatConfig *Config=ChatConfig::get();
-
-	if(!load_log_settings(Config->LogSettingsFile.c_str()))
-		_log(CHANNELS__INIT, "Warning: Unable to read %s", Config->LogSettingsFile.c_str());
-	else
-		_log(CHANNELS__INIT, "Log settings loaded from %s", Config->LogSettingsFile.c_str());
-
-	WorldShortName = Config->ShortName;
-
-	_log(CHANNELS__INIT, "Connecting to MySQL...");
-
-	if (!database.Connect(
-		Config->DatabaseHost.c_str(),
-		Config->DatabaseUsername.c_str(),
-		Config->DatabasePassword.c_str(),
-		Config->DatabaseDB.c_str(),
-		Config->DatabasePort)) {
-		_log(WORLD__INIT_ERR, "Cannot continue without a database connection.");
-		return(1);
-	}
-
-	char tmp[64];
-
-	if (database.GetVariable("RuleSet", tmp, sizeof(tmp)-1)) {
-		_log(WORLD__INIT, "Loading rule set '%s'", tmp);
-		if(!rules->LoadRules(&database, tmp)) {
-			_log(CHANNELS__ERROR, "Failed to load ruleset '%s', falling back to defaults.", tmp);
-		}
-	} else {
-		if(!rules->LoadRules(&database, "default")) {
-			_log(CHANNELS__INIT, "No rule set configured, using default rules");
-		} else {
-			_log(CHANNELS__INIT, "Loaded default rule set 'default'", tmp);
-		}
-	}
-
-	CL = new Clientlist(Config->ChatPort);
-
-	ChannelList = new ChatChannelList();
-	
-	database.LoadChatChannels();
-
-	if (signal(SIGINT, CatchSignal) == SIG_ERR)	{
-		_log(CHANNELS__ERROR, "Could not set signal handler");
-		return 0;
-	}
-	if (signal(SIGTERM, CatchSignal) == SIG_ERR)	{
-		_log(CHANNELS__ERROR, "Could not set signal handler");
-		return 0;
-	}
-
-	while(RunLoops) {
-
-		Timer::SetCurrentTime();
-
-		CL->Process();
-
-		if(ChannelListProcessTimer.Check())
-			ChannelList->Process();
-
-		timeout_manager.CheckTimeouts();
-
-		Sleep(100);
-	}
-
-	ChannelList->RemoveAllChannels();
-
-	CL->CloseAllConnections();
-
-}
-
-void UpdateWindowTitle(char* iNewTitle) {
-#ifdef WIN32
-        char tmp[500];
-        if (iNewTitle) {
-                snprintf(tmp, sizeof(tmp), "World: %s", iNewTitle);
-        }
-        else {
-                snprintf(tmp, sizeof(tmp), "World");
-        }
-        SetConsoleTitle(tmp);
-#endif
-}
+/*
+	EQEMu:  Everquest Server Emulator
+
+	Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net)
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; version 2 of the License.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY except by those people which sell it, which
+	are required to give you total support for your newly bought product;
+	without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+	A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the Free Software
+	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+
+#include "../common/debug.h"
+#include "clientlist.h"
+#include "../common/opcodemgr.h"
+#include "../common/EQStreamFactory.h"
+#include "../common/rulesys.h"
+#include "database.h"
+#include "ChatConfig.h"
+#include "chatchannel.h"
+#include "IRC.h"
+#include <list>
+#include <signal.h>
+#ifdef WIN32
+#include <process.h>
+#else
+#include <pthread.h>
+#endif
+
+volatile bool RunLoops = true;
+
+TimeoutManager          timeout_manager;
+
+Clientlist *CL;
+
+ChatChannelList *ChannelList;
+
+Database database;
+
+string WorldShortName;
+
+RuleManager *rules = new RuleManager();
+
+IRC conn; // Secrets edit
+
+
+void CatchSignal(int sig_num) {
+
+	RunLoops = false;
+}
+
+string GetMailPrefix() {
+
+	return "SOE.EQ." + WorldShortName + ".";
+}
+
+void IRCConnect(void* irc_conn) { /* maintains the loop for processing the other two IRC commands */
+		conn.message_loop();
+}
+
+
+int end_of_motd(char* params, irc_reply_data* hostd, void* conn) /* hooks END OF MOTD message from IRC */
+	{
+		IRC* irc_conn=(IRC*)conn;
+	
+		const ChatConfig *Config=ChatConfig::get();
+
+		char name[128];
+
+		strcpy(name,Config->ChatIRCHost.c_str());
+			
+
+		irc_conn->join(name);
+
+		return 0;
+	}
+
+int triggers(char*params,irc_reply_data*hostd,void*conn) /* hooks privmsg to your specified channel */
+{
+
+	IRC* irc_conn=(IRC*)conn;
+	
+
+	const ChatConfig *Config=ChatConfig::get();
+
+	string ChannelName = Config->EQChannelToOutput;
+
+	ChatChannel *RequiredChannel = ChannelList->FindChannel(ChannelName);
+
+	char name[128];
+	strcpy(name,Config->ChannelToOutput.c_str());
+
+	if(!strcmp(params,":!rejoin"))
+	{
+		irc_conn->join(name);
+	}		
+
+	string parame = params;
+	string IRCName = hostd->nick;
+
+	if(!strcmp(hostd->target,name))
+        
+	{
+		RequiredChannel->SendMessageToChannelFromIRC(parame, IRCName); // I got an IRC command, now let's send it
+	}
+	return 0;
+	
+}
+		
+int main() {
+
+	// Check every minute for unused channels we can delete
+	//
+	Timer ChannelListProcessTimer(60000);
+
+	_log(CHANNELS__INIT, "Starting EQEmu Chat Channel Server");
+	
+    
+	if (!ChatConfig::LoadConfig()) {
+
+		_log(CHANNELS__INIT, "Loading server configuration failed.");
+
+		return(1);
+	}
+
+	const ChatConfig *Config=ChatConfig::get();
+
+	/* begin IRC crap */
+
+
+	
+	#ifndef WIN32
+	pthread_t th1;
+	#endif
+
+	char array1[64];
+	char array2[64];
+	strcpy(array1, Config->ChatIRCHost.c_str());
+	strcpy(array2, Config->ChatIRCNick.c_str());
+	conn.hook_irc_command("PRIVMSG",&triggers);
+	conn.hook_irc_command("376", &end_of_motd); /* hook the end of MOTD message */
+	conn.start(array1,Config->ChatIRCPort,array2,"EQEMu IRC Bot","EQEMu IRC Bot",0);
+
+	#ifdef WIN32
+	_beginthread(IRCConnect,0,(void*)&conn);
+	#else
+	pthread_create(&th1,NULL,IRCConnect,(void*)&conn);
+	#endif
+
+	/* end irc crap */
+
+	if(!load_log_settings(Config->LogSettingsFile.c_str()))
+		_log(CHANNELS__INIT, "Warning: Unable to read %s", Config->LogSettingsFile.c_str());
+	else
+		_log(CHANNELS__INIT, "Log settings loaded from %s", Config->LogSettingsFile.c_str());
+
+	WorldShortName = Config->ShortName;
+
+	_log(CHANNELS__INIT, "Connecting to MySQL...");
+
+	if (!database.Connect(
+		Config->DatabaseHost.c_str(),
+		Config->DatabaseUsername.c_str(),
+		Config->DatabasePassword.c_str(),
+		Config->DatabaseDB.c_str(),
+		Config->DatabasePort)) {
+		_log(WORLD__INIT_ERR, "Cannot continue without a database connection.");
+		return(1);
+	}
+
+	char tmp[64];
+
+	if (database.GetVariable("RuleSet", tmp, sizeof(tmp)-1)) {
+		_log(WORLD__INIT, "Loading rule set '%s'", tmp);
+		if(!rules->LoadRules(&database, tmp)) {
+			_log(CHANNELS__ERROR, "Failed to load ruleset '%s', falling back to defaults.", tmp);
+		}
+	} else {
+		if(!rules->LoadRules(&database, "default")) {
+			_log(CHANNELS__INIT, "No rule set configured, using default rules");
+		} else {
+			_log(CHANNELS__INIT, "Loaded default rule set 'default'", tmp);
+		}
+	}
+
+	CL = new Clientlist(Config->ChatPort);
+
+	ChannelList = new ChatChannelList();
+	
+	database.LoadChatChannels();
+
+	if (signal(SIGINT, CatchSignal) == SIG_ERR)	{
+		_log(CHANNELS__ERROR, "Could not set signal handler");
+		return 0;
+	}
+	if (signal(SIGTERM, CatchSignal) == SIG_ERR)	{
+		_log(CHANNELS__ERROR, "Could not set signal handler");
+		return 0;
+	}
+
+	while(RunLoops) {
+		Timer::SetCurrentTime();
+		CL->Process();
+		if(ChannelListProcessTimer.Check())
+		ChannelList->Process();
+		timeout_manager.CheckTimeouts();
+		Sleep(100);
+	}
+
+	ChannelList->RemoveAllChannels();
+
+	CL->CloseAllConnections();
+
+}
+
+void UpdateWindowTitle(char* iNewTitle) {
+#ifdef WIN32
+        char tmp[500];
+        if (iNewTitle) {
+                snprintf(tmp, sizeof(tmp), "World: %s", iNewTitle);
+        }
+        else {
+                snprintf(tmp, sizeof(tmp), "World");
+        }
+        SetConsoleTitle(tmp);
+#endif
+}
\ No newline at end of file
Index: chatserver.vcproj
===================================================================
--- chatserver.vcproj	(revision 846)
+++ chatserver.vcproj	(working copy)
@@ -193,6 +193,10 @@
 				RelativePath=".\database.cpp"
 				>
 			</File>
+			<File
+				RelativePath=".\IRC.cpp"
+				>
+			</File>
 		</Filter>
 		<Filter
 			Name="Header Files"
@@ -215,6 +219,10 @@
 				RelativePath=".\database.h"
 				>
 			</File>
+			<File
+				RelativePath=".\IRC.h"
+				>
+			</File>
 		</Filter>
 		<Filter
 			Name="Common Header Files"
Index: clientlist.cpp
===================================================================
--- clientlist.cpp	(revision 846)
+++ clientlist.cpp	(working copy)
@@ -25,6 +25,7 @@
 #include "clientlist.h"
 #include "database.h"
 #include "chatchannel.h"
+#include "ChatConfig.h" // Secrets -- IRC
 
 #include "../common/EQStreamFactory.h"
 #include "../common/EmuTCPConnection.h"
@@ -436,6 +437,7 @@
 
 }
 
+
 void Clientlist::CloseAllConnections() {
 
 
@@ -1003,6 +1005,31 @@
 	safe_delete(outapp);
 }
 
+void Client::SendChannelMessageFromIRC(string Message, string IRCName) { /* Packet handler for IRC Messages */
+
+	const ChatConfig *Config=ChatConfig::get();
+
+	string FQSenderName = "IRC." + IRCName;
+
+	string ChannelName = Config->EQChannelToOutput.c_str();
+
+	int PacketLength = ChannelName.length() + Message.length() + FQSenderName.length() + 3;
+
+	EQApplicationPacket *outapp = new EQApplicationPacket(OP_ChannelMessage, PacketLength);
+
+	char *PacketBuffer = (char *)outapp->pBuffer;
+
+	VARSTRUCT_ENCODE_STRING(PacketBuffer, ChannelName.c_str());
+	VARSTRUCT_ENCODE_STRING(PacketBuffer, FQSenderName.c_str());
+	VARSTRUCT_ENCODE_STRING(PacketBuffer, Message.c_str());
+
+	_pkt(CHANNELS__PACKETS, outapp);
+	QueuePacket(outapp);
+
+	safe_delete(outapp);
+}
+
+
 void Client::ToggleAnnounce() {
 
 	string Message = "Announcing now ";
Index: clientlist.h
===================================================================
--- clientlist.h	(revision 846)
+++ clientlist.h	(working copy)
@@ -1,156 +1,157 @@
-/*
-	EQEMu:  Everquest Server Emulator
-
-	Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net)
-
-	This program is free software; you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation; version 2 of the License.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY except by those people which sell it, which
-	are required to give you total support for your newly bought product;
-	without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-	A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program; if not, write to the Free Software
-	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-#ifndef CHATSERVER_CLIENTLIST_H
-#define CHATSERVER_CLIENTLIST_H
-
-#include "../common/opcodemgr.h"
-#include "../common/EQStreamType.h"
-#include "../common/EQStreamFactory.h"
-#include "../common/rulesys.h"
-#include "chatchannel.h"
-#include <list>
-#include <vector>
-
-#define MAX_JOINED_CHANNELS 10
-
-enum { CommandJoin = 0, CommandLeaveAll, CommandLeave, CommandListAll, CommandList, CommandSet, CommandAnnounce, CommandSetOwner,
-       CommandOPList, CommandInvite, CommandGrant, CommandModerate, CommandVoice, CommandKick, 
-       CommandPassword, CommandToggleInvites, CommandAFK, CommandUptime, CommandEndOfList };
-
-struct CommandEntry {
-	const char *CommandString;
-	int    CommandCode;
-};
-
-static const CommandEntry Commands[] = { 
-					 { "join", CommandJoin },
-					 { "leaveall", CommandLeaveAll },
-					 { "leave", CommandLeave },
-					 { "listall", CommandListAll },
-					 { "list", CommandList },
-					 { "set", CommandSet },
-					 { "announce", CommandAnnounce },
-					 { "setowner", CommandSetOwner },
-					 { "oplist", CommandOPList },
-					 { "invite", CommandInvite },
-					 { "grant", CommandGrant },
-					 { "moderate", CommandModerate },
-					 { "voice", CommandVoice },
-					 { "kick", CommandKick },
-					 { "password", CommandPassword },
-					 { "toggleinvites", CommandToggleInvites },
-					 { "afk", CommandAFK },
-					 { "uptime", CommandUptime },
-					 { "", CommandEndOfList } };
-
-class Client {
-
-public:
-	Client(EQStream* eqs);
-	~Client();
-
-	EQStream *ClientStream;
-	void AddCharacter(const char *CharacterName);
-	void ClearCharacters() { Characters.clear(); }
-	void SendMailBoxes();
-	inline void QueuePacket(const EQApplicationPacket *p, bool ack_req=true) { ClientStream->QueuePacket(p, ack_req); }
-	string GetName() { if(Characters.size()) return Characters[0]; else return ""; }
-	void JoinChannels(string ChannelList);
-	void LeaveChannels(string ChannelList);
-	void LeaveAllChannels(bool SendUpdatedChannelList = true);
-	void AddToChannelList(ChatChannel *JoinedChannel);
-	void RemoveFromChannelList(ChatChannel *JoinedChannel);
-	void SendChannelMessage(string Message);
-	void SendChannelMessage(string ChannelName, string Message, Client *Sender);
-	void SendChannelMessageByNumber(string Message);
-	void SendChannelList();
-	void CloseConnection();
-	void ToggleAnnounce();
-	bool IsAnnounceOn() { return (Announce == true); }
-	void AnnounceJoin(ChatChannel *Channel, Client *c);
-	void AnnounceLeave(ChatChannel *Channel, Client *c);
-	void GeneralChannelMessage(string Message);
-	void GeneralChannelMessage(const char *Characters);
-	void SetChannelPassword(string ChannelPassword);
-	void ProcessChannelList(string CommandString);
-	void ProcessKarma();
-	int ChannelCount();
-	inline void SetAccountID(int inAccountID) { AccountID = inAccountID; }
-	inline int GetAccountID() { return AccountID; }
-	inline void SetAccountStatus(int inStatus) { Status = inStatus; }
-	inline void SetHideMe(bool inHideMe) { HideMe = inHideMe; }
-	inline void SetKarma(uint32 inKarma) { TotalKarma = inKarma; }
-	inline int GetAccountStatus() { return Status; }
-	inline bool GetHideMe() { return HideMe; }
-	inline uint32 GetKarma() { return TotalKarma; }
-	void SetChannelOwner(string CommandString);
-	void OPList(string CommandString);
-	void ChannelInvite(string CommandString);
-	void ChannelGrantModerator(string CommandString);
-	void ChannelGrantVoice(string CommandString);
-	void ChannelKick(string CommandString);
-	void ChannelModerate(string CommandString);
-	string ChannelSlotName(int ChannelNumber);
-	void ToggleInvites();
-	bool InvitesAllowed() { return AllowInvites; }
-	inline bool IsChannelAdmin() { return (Status >= RuleI(Channels, RequiredStatusAdmin)); }
-	inline bool CanListAllChannels() { return (Status >= RuleI(Channels, RequiredStatusListAll)); }
-	void SendHelp();
-	inline bool GetForceDisconnect() { return ForceDisconnect; }
-
-private:
-	int CurrentMailBox;
-	vector<string> Characters;
-	ChatChannel *JoinedChannels[MAX_JOINED_CHANNELS];
-	bool Announce;
-	int AccountID;
-	int Status;
-	bool HideMe;
-	bool AllowInvites;
-
+/*
+	EQEMu:  Everquest Server Emulator
+
+	Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net)
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; version 2 of the License.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY except by those people which sell it, which
+	are required to give you total support for your newly bought product;
+	without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+	A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the Free Software
+	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+#ifndef CHATSERVER_CLIENTLIST_H
+#define CHATSERVER_CLIENTLIST_H
+
+#include "../common/opcodemgr.h"
+#include "../common/EQStreamType.h"
+#include "../common/EQStreamFactory.h"
+#include "../common/rulesys.h"
+#include "chatchannel.h"
+#include <list>
+#include <vector>
+
+#define MAX_JOINED_CHANNELS 10
+
+enum { CommandJoin = 0, CommandLeaveAll, CommandLeave, CommandListAll, CommandList, CommandSet, CommandAnnounce, CommandSetOwner,
+       CommandOPList, CommandInvite, CommandGrant, CommandModerate, CommandVoice, CommandKick, 
+       CommandPassword, CommandToggleInvites, CommandAFK, CommandUptime, CommandEndOfList };
+
+struct CommandEntry {
+	const char *CommandString;
+	int    CommandCode;
+};
+
+static const CommandEntry Commands[] = { 
+					 { "join", CommandJoin },
+					 { "leaveall", CommandLeaveAll },
+					 { "leave", CommandLeave },
+					 { "listall", CommandListAll },
+					 { "list", CommandList },
+					 { "set", CommandSet },
+					 { "announce", CommandAnnounce },
+					 { "setowner", CommandSetOwner },
+					 { "oplist", CommandOPList },
+					 { "invite", CommandInvite },
+					 { "grant", CommandGrant },
+					 { "moderate", CommandModerate },
+					 { "voice", CommandVoice },
+					 { "kick", CommandKick },
+					 { "password", CommandPassword },
+					 { "toggleinvites", CommandToggleInvites },
+					 { "afk", CommandAFK },
+					 { "uptime", CommandUptime },
+					 { "", CommandEndOfList } };
+
+class Client {
+
+public:
+	Client(EQStream* eqs);
+	~Client();
+
+	EQStream *ClientStream;
+	void AddCharacter(const char *CharacterName);
+	void ClearCharacters() { Characters.clear(); }
+	void SendMailBoxes();
+	inline void QueuePacket(const EQApplicationPacket *p, bool ack_req=true) { ClientStream->QueuePacket(p, ack_req); }
+	string GetName() { if(Characters.size()) return Characters[0]; else return ""; }
+	void JoinChannels(string ChannelList);
+	void LeaveChannels(string ChannelList);
+	void LeaveAllChannels(bool SendUpdatedChannelList = true);
+	void AddToChannelList(ChatChannel *JoinedChannel);
+	void RemoveFromChannelList(ChatChannel *JoinedChannel);
+	void SendChannelMessage(string Message);
+	void SendChannelMessage(string ChannelName, string Message, Client *Sender);
+	void SendChannelMessageFromIRC(string Message, string IRCName);
+	void SendChannelMessageByNumber(string Message);
+	void SendChannelList();
+	void CloseConnection();
+	void ToggleAnnounce();
+	bool IsAnnounceOn() { return (Announce == true); }
+	void AnnounceJoin(ChatChannel *Channel, Client *c);
+	void AnnounceLeave(ChatChannel *Channel, Client *c);
+	void GeneralChannelMessage(string Message);
+	void GeneralChannelMessage(const char *Characters);
+	void SetChannelPassword(string ChannelPassword);
+	void ProcessChannelList(string CommandString);
+	void ProcessKarma();
+	int ChannelCount();
+	inline void SetAccountID(int inAccountID) { AccountID = inAccountID; }
+	inline int GetAccountID() { return AccountID; }
+	inline void SetAccountStatus(int inStatus) { Status = inStatus; }
+	inline void SetHideMe(bool inHideMe) { HideMe = inHideMe; }
+	inline void SetKarma(uint32 inKarma) { TotalKarma = inKarma; }
+	inline int GetAccountStatus() { return Status; }
+	inline bool GetHideMe() { return HideMe; }
+	inline uint32 GetKarma() { return TotalKarma; }
+	void SetChannelOwner(string CommandString);
+	void OPList(string CommandString);
+	void ChannelInvite(string CommandString);
+	void ChannelGrantModerator(string CommandString);
+	void ChannelGrantVoice(string CommandString);
+	void ChannelKick(string CommandString);
+	void ChannelModerate(string CommandString);
+	string ChannelSlotName(int ChannelNumber);
+	void ToggleInvites();
+	bool InvitesAllowed() { return AllowInvites; }
+	inline bool IsChannelAdmin() { return (Status >= RuleI(Channels, RequiredStatusAdmin)); }
+	inline bool CanListAllChannels() { return (Status >= RuleI(Channels, RequiredStatusListAll)); }
+	void SendHelp();
+	inline bool GetForceDisconnect() { return ForceDisconnect; }
+
+private:
+	int CurrentMailBox;
+	vector<string> Characters;
+	ChatChannel *JoinedChannels[MAX_JOINED_CHANNELS];
+	bool Announce;
+	int AccountID;
+	int Status;
+	bool HideMe;
+	bool AllowInvites;
+
 	//Anti Spam Stuff
 	Timer *KarmaGrabUpdateTimer;
 	uint32 TotalKarma;
 
 	Timer *GlobalChatLimiterTimer; //60 seconds
-	int AttemptedMessages;
-	bool ForceDisconnect;
-};
-
-class Clientlist {
-
-public:
-	Clientlist(int MailPort);
-	void	Process();
-	void	CloseAllConnections();
-	Client *FindCharacter(string CharacterName);
-	void	CheckForStaleConnections(Client *c);
-
-private:
-	EQStreamFactory *chatsf;
-
-	list<Client*> ClientChatConnections;
-
-	OpcodeManager *ChatOpMgr;
-};
-
-#endif
+	int AttemptedMessages;
+	bool ForceDisconnect;
+};
+
+class Clientlist {
+
+public:
+	Clientlist(int MailPort);
+	void	Process();
+	void	CloseAllConnections();
+	Client *FindCharacter(string CharacterName);
+	void	CheckForStaleConnections(Client *c);
+
+private:
+	EQStreamFactory *chatsf;
+
+	list<Client*> ClientChatConnections;
+
+	OpcodeManager *ChatOpMgr;
+};
+
+#endif
Diff for those who are interested

Last edited by Secrets; 07-30-2009 at 06:28 AM.. Reason: code, not quote
Reply With Quote
  #4  
Old 07-29-2009, 10:29 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

And the rest of it~

Code:
Index: EQEmuConfig.cpp
===================================================================
--- EQEmuConfig.cpp	(revision 832)
+++ EQEmuConfig.cpp	(working copy)
@@ -128,6 +128,26 @@
 	text=ParseTextBlock(ele,"port",true);
 	if (text)
 		ChatPort=atoi(text);
+	
+	text=ParseTextBlock(ele,"channeltooutput",true);
+	if (text)
+		ChannelToOutput=text;
+
+	text=ParseTextBlock(ele,"eqchanneltooutput",true);
+	if (text)
+		EQChannelToOutput=text;
+
+	text=ParseTextBlock(ele,"chatirchost",true);
+	if (text)
+		ChatIRCHost=text;
+
+	text=ParseTextBlock(ele,"chatircport",true);
+	if (text)
+		ChatIRCPort=atoi(text);
+
+	text=ParseTextBlock(ele,"chatircnick",true);
+	if (text)
+		ChatIRCNick=text;
 }
 		
 void EQEmuConfig::do_mailserver(TiXmlElement *ele) {
@@ -323,6 +343,16 @@
 		return(ChatHost);
 	if(var_name == "ChatPort")
 		return(itoa(ChatPort));
+	if(var_name == "ChannelToOutput")
+		return (ChannelToOutput);
+	if(var_name == "EQChannelToOutput")
+		return (EQChannelToOutput);
+	if(var_name == "ChatIRCHost")
+		return(ChatIRCHost);
+	if(var_name == "ChatIRCPort")
+		return(itoa(ChatIRCPort));
+	if(var_name == "ChatIRCNick")
+		return(ChatIRCNick);
 	if(var_name == "MailHost")
 		return(MailHost);
 	if(var_name == "MailPort")
@@ -386,6 +416,11 @@
 	cout << "WorldHTTPEnabled = " << WorldHTTPEnabled << endl;
 	cout << "ChatHost = " << ChatHost << endl;
 	cout << "ChatPort = " << ChatPort << endl;
+	cout << "ChannelToOutput = " << ChannelToOutput << endl;
+	cout << "EQChannelToOutput = " << EQChannelToOutput << endl;
+	cout << "ChatIRCHost = " << ChatIRCHost << endl;
+	cout << "ChatIRCPort = " << ChatIRCPort << endl;
+	cout << "ChatIRCNick = " << ChatIRCNick << endl;
 	cout << "MailHost = " << MailHost << endl;
 	cout << "MailPort = " << MailPort << endl;
 	cout << "DatabaseHost = " << DatabaseHost << endl;
Index: EQEmuConfig.h
===================================================================
--- EQEmuConfig.h	(revision 832)
+++ EQEmuConfig.h	(working copy)
@@ -46,7 +46,12 @@
 	// From <chatserver/>
 	string ChatHost;
 	uint16 ChatPort;
-	
+	string ChannelToOutput;
+	string EQChannelToOutput;
+	string ChatIRCHost;
+	uint16 ChatIRCPort;
+	string ChatIRCNick;
+
 	// From <mailserver/>
 	string MailHost;
 	uint16 MailPort;
@@ -110,7 +115,7 @@
 		LoginHost="eqemulator.net";
 		LoginPort=5998;
 
-		// World
+		// Worldstrcpy(lsi->name, Config->LongName.c_str());
 		Locked=false;
 		WorldTCPPort=9000;
 		TelnetEnabled=false;
@@ -122,7 +127,13 @@
 		// Mail
 		ChatHost="eqchat.eqemulator.net";
 		ChatPort=7778;
+		ChannelToOutput="#eqemuchattest";
+		EQChannelToOutput="General";
+		ChatIRCHost="eqnet.eqemulator.net";
+		ChatIRCPort=6667;
+		ChatIRCNick="Secretsbot";
 
+
 		// Mail
 		MailHost="eqmail.eqemulator.net";
 		MailPort=7779;
Reply With Quote
  #5  
Old 07-29-2009, 11:20 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

Replace this for a crash fix with packet length and sending packets to the client, it's hackish but it fixes it

Code:
		if(Message.length() > 100)
			return;
in

Code:
ChatChannel::SendMessageToChannelFromIRC
below

Code:
					Client *ChannelClient = iterator.GetData();
Reply With Quote
  #6  
Old 07-30-2009, 02:56 AM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

After further looking, that's not the case. Also, I realized that UCS is a better place to do my coding in as it has SoF support. I tested this to work on both SoF and Titanium.

http://www.sendspace.com/file/ea36cb

Also, linux support is still not in. I do not have a linux box so I would appreciate if someone took the the time to look into that. Thanks!

Can a mod update the first link with this file as well?

If you are interested in the fix for the actual crash, it's

Code:
	if(strstr(params,"%s"))
	{
		return 0;
	}
in

Code:
int triggers(char*params,irc_reply_data*hostd,void*conn) /* hooks privmsg to your specified channel */
above

Code:
	if(!strcmp(params,":!rejoin"))
	{
		irc_conn->join(name);
	}

Last edited by Secrets; 07-30-2009 at 11:00 AM..
Reply With Quote
  #7  
Old 07-30-2009, 06:59 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

Gonna try and get a linux version of this today and then it will be SVN-ready. Also, I figured out the crash issue (for reals this time!) and it's related to sprintf in MiscFunctions.h -- If "%whatever" is provided, it crashes the app, so I just did sprintf("%s"), string instead in MiscFunctions.h to fix it. When I finish Linux support, this will be added in.
Reply With Quote
  #8  
Old 07-30-2009, 10:42 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

Quote:
Originally Posted by Secrets View Post
Gonna try and get a linux version of this today and then it will be SVN-ready. Also, I figured out the crash issue (for reals this time!) and it's related to sprintf in MiscFunctions.h -- If "%whatever" is provided, it crashes the app, so I just did sprintf("%s"), string instead in MiscFunctions.h to fix it. When I finish Linux support, this will be added in.
I can't figure out what's wrong my linux port, so someone else is going to have to port it.
Reply With Quote
  #9  
Old 08-02-2009, 06:42 AM
AndMetal
Developer
 
Join Date: Mar 2007
Location: Ohio
Posts: 648
Default

I've got a working port (see the attachment for a diff), but I think we may want to take a moment to figure out the scope for this.

On Live, chat channels could be for the local server (General), another server (tgc.General), or serverwide (serverwide.General). In addition, we could also send tells the same way (;tell tcg.Cavedude). I think we should consider what we could do to accomplish all 3 scenarios.

I think we may need 2 things: a local list of servers / IRC servers (including shortnames, like tgc) to connect to (primarily to choose what IRC server you would want to connect to), plus a master list of Emu servers via the login server (both public & private). That way, we can communicate to virtually anyone anywhere at any time.
Attached Files
File Type: zip ucs_with_IRC.zip (29.3 KB, 5 views)
__________________
GM-Impossible of 'A work in progress'
A non-legit PEQ DB server
How to create your own non-legit server

My Contributions to the Wiki
Reply With Quote
  #10  
Old 08-03-2009, 07:36 PM
Yeormom
Discordant
 
Join Date: Apr 2004
Location: 127.0.0.1
Posts: 402
Default

Should be cautioned when integrated IRC services, depending on your network. If you're using a real server, most datacenter resellers prohibit the use of IRC on their networks.
__________________
Yeorwned
Bane of Life [Custom Classic/PvP]
Reply With Quote
  #11  
Old 08-06-2009, 05:02 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

Quote:
Originally Posted by Yeormom View Post
Should be cautioned when integrated IRC services, depending on your network. If you're using a real server, most datacenter resellers prohibit the use of IRC on their networks.
Yeah, my VPS service doesn't allow it on their network.

Some do though, some don't.
Reply With Quote
  #12  
Old 04-30-2010, 08:35 PM
mixxit
Hill Giant
 
Join Date: Sep 2006
Posts: 155
Default

all links broken including attachment? :(
Reply With Quote
  #13  
Old 04-30-2010, 09:20 PM
Secrets's Avatar
Secrets
Demi-God
 
Join Date: May 2007
Location: b
Posts: 1,450
Default

Quote:
Originally Posted by mixxit View Post
all links broken including attachment? :(
I'll see if I can dig this up, I had a version that worked on windows only, but crashed a lot.
Reply With Quote
  #14  
Old 07-26-2010, 12:12 PM
AndMetal
Developer
 
Join Date: Mar 2007
Location: Ohio
Posts: 648
Default

Check out the UCS_IRC-Bot and UCS_IRC-Instanced branches in SVN.

As far as I know, Instanced is basically unusable in its current form because of how the threads are being handled causing a seg fault. Bot seemed to work fine on Windows & Linux if memory serves me correctly.
__________________
GM-Impossible of 'A work in progress'
A non-legit PEQ DB server
How to create your own non-legit server

My Contributions to the Wiki
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 05:38 AM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3