Creating an OPChat in a hubsoft

Discussion and questions about hub software
Locked
Toast

Creating an OPChat in a hubsoft

Post by Toast » 02 Apr 2009, 09:09

We had some questions on how to create an opchat in a hubsoft on DCDev i was wondering if someone of those that already has implemented these functions mind explaining how they did

adrian_007
Senior Member
Posts: 126
Joined: 06 Jan 2008, 13:00

Re: Creating an OPChat in a hubsoft

Post by adrian_007 » 02 Apr 2009, 14:47

Code: Select all

/* 
 * Copyright (C) 2007-2008 adrian_007, adrian-007 on o2 point pl
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; 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 "stdinc.h"
#include "BotManager.h"
#include "AdminSettings.h"

#include <adchpp/SettingsManager.h>
#include <adchpp/Encoder.h>
#include <adchpp/TigerHash.h>

namespace adcadmin {
using namespace std::tr1;
using namespace std::tr1::placeholders;

BotManager* BotManager::instance = 0;
const string BotManager::className = "BotManager";
size_t BotManager::AdminsFlag = Client::FLAG_OWNER | Client::FLAG_SU | Client::FLAG_OP;

BotManager::BotManager() {
	// get sid and cid for bot, then cache inf message

	opchat.sid = ClientManager::getInstance()->makeSID();
	opchat.cid = ClientManager::getInstance()->addVirtualClient(opchat.sid, ADMIN_SETTING(OPCHAT_NICK));
	opchat.inf = AdcCommand(AdcCommand::CMD_INF, AdcCommand::TYPE_BROADCAST, opchat.sid)
	.addParam("NI", ADMIN_SETTING(OPCHAT_NICK))
	.addParam("DE", ADMIN_SETTING(OPCHAT_DESCRIPTION))
	.addParam("ID", opchat.cid.toBase32())
	.addParam("CT5")
	.getBuffer();

	security.sid = ClientManager::getInstance()->makeSID();
	security.cid = ClientManager::getInstance()->addVirtualClient(security.sid, ADMIN_SETTING(SECURITY_BOT_NICK));
	security.inf = AdcCommand(AdcCommand::CMD_INF, AdcCommand::TYPE_BROADCAST, security.sid)
	.addParam("NI", ADMIN_SETTING(SECURITY_BOT_NICK))
	.addParam("DE", ADMIN_SETTING(SECURITY_BOT_DESCRIPTION))
	.addParam("ID", security.cid.toBase32())
	.addParam("CT5")
	.getBuffer();

	receiveConn = manage(&ClientManager::getInstance()->signalReceive(), std::tr1::bind(&BotManager::onReceive, this, _1, _2, _3));
}

BotManager::~BotManager() {

}

void BotManager::broadcast(uint32_t speakerSid, const std::string& aMsg, bool pm /*= true*/, size_t clientClass /*= 0*/, bool isOpchat /*= false*/) {
	AdcCommand snd(AdcCommand::CMD_MSG, AdcCommand::TYPE_DIRECT, speakerSid);
	snd.addParam(aMsg);
	if(pm)
		snd.addParam("PM", AdcCommand::fromSID(isOpchat ? opchat.sid : security.sid));

	FastMutex::Lock l(ManagedSocket::getWriteMutex());
	const ClientManager::ClientMap& clients = ClientManager::getInstance()->getClients();
	for(ClientManager::ClientMap::const_iterator i = clients.begin(); i != clients.end(); ++i) {
		if(clientClass == 0 || i->second->isAnySet(clientClass)) {
			snd.setTo(i->second->getSID());
			i->second->fastSend(snd.getBuffer());
		}
	}
}

AdcCommand BotManager::botMessage(const std::string& aMsg) {
	AdcCommand cmd(AdcCommand::CMD_MSG, AdcCommand::TYPE_BROADCAST, getBotSID());
	cmd.addParam(aMsg);
	return cmd;
}

void BotManager::securityBotMessage(Client& c, const std::string& aMsg, bool pm /*= false*/) {
	AdcCommand cmd(AdcCommand::CMD_MSG, AdcCommand::TYPE_DIRECT, security.sid);
	cmd.addParam(aMsg);
	if(pm)
		cmd.addParam("PM", AdcCommand::fromSID(security.sid));
	cmd.setTo(c.getSID());
	c.fastSend(cmd.getBuffer());
}

void BotManager::securityBotMessage(uint32_t aSid, const std::string& aMsg, bool pm /*= false*/) {
	AdcCommand cmd(AdcCommand::CMD_MSG, AdcCommand::TYPE_DIRECT, security.sid);
	cmd.addParam(aMsg);
	if(pm)
		cmd.addParam("PM", AdcCommand::fromSID(security.sid));
	ClientManager::getInstance()->sendTo(cmd, aSid);
}

void BotManager::onReceive(Client& c, AdcCommand& cmd, int& handled) {
	if(c.getState() == Client::STATE_IDENTIFY) {
		c.send(opchat.inf);
		c.send(security.inf);
	} else if(cmd.getCommand() == AdcCommand::CMD_MSG) {
		if(cmd.getType() == AdcCommand::TYPE_ECHO) {
			if(cmd.getTo() == getOpChatSID()) {
				broadcast(c.getSID(), cmd.getParam(0), true, AdminsFlag, true);
				handled |= ClientManager::DONT_SEND | ClientManager::DONT_DISPATCH;
			} else if(cmd.getTo() == getBotSID()) {
				AdcCommand snd = AdcCommand(AdcCommand::CMD_MSG, AdcCommand::TYPE_ECHO, getBotSID());
				snd.setTo(c.getSID());
				snd.addParam("Hub-Security doesn't accept private messages [todo some better string]");
				snd.addParam("PM", AdcCommand::fromSID(security.sid));
				c.send(snd);
				handled |= ClientManager::DONT_SEND | ClientManager::DONT_DISPATCH;
			}
		} else {

			const string& command = cmd.getParam(0);
			if(command[0] == '!') {
				string::size_type i = command.find(" ");
				if(i != string::npos) {
					string _cmd = command.substr(1, i-1);
					string param = command.substr(i+1);
					if(_cmd == "bc") {
						if(!param.empty()) {
							broadcast(c.getSID(), param);
						}
						handled |= ClientManager::DONT_SEND | ClientManager::DONT_DISPATCH;
					}
				}
			} else if(command[0] == '+') {
				string::size_type i = command.find(" ");
				if(i != string::npos) {
					string cmd = command.substr(1, i-1);
					string param = command.substr(i+1);
					if(cmd == "report") {
						if(!param.empty()) {
							string report = boost::str(boost::format("Report (From: %s, IPv4: %s): %s") % c.getField("NI") % c.getField("I4") % param);
							broadcast(c.getSID(), report, true, AdminsFlag, true);
							c.send(botMessage("Thank you, your report has been sent!"));
						} else {
							c.send(botMessage("No report content!"));
						}
						handled |= ClientManager::DONT_SEND | ClientManager::DONT_DISPATCH;
					}
				}
			}
		}
	}
}
} // namespace adcadmin

Code: Select all

/* 
 * Copyright (C) 2007-2008 adrian_007, adrian-007 on o2 point pl
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; 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 BOT_MANAGER
#define BOT_MANAGER

#include <adchpp/Singleton.h>
#include <adchpp/ClientManager.h>
#include <adchpp/Signal.h>

namespace adcadmin {
class BotManager : public Singleton<BotManager> {
public:
	BotManager();
	virtual ~BotManager();

	// client flag that represents op or su or owner
	static size_t AdminsFlag;

	uint32_t getBotSID() const { return security.sid; }
	uint32_t getOpChatSID() const { return opchat.sid; }

	AdcCommand botMessage(const std::string& aMsg);
	void securityBotMessage(Client& c, const std::string& aMsg, bool pm = false);
	void securityBotMessage(uint32_t aSid, const std::string& aMsg, bool pm = false);

	void broadcast(uint32_t speakerSID, const std::string& aMsg, bool pm = true, size_t clientClass = 0, bool isOpchat = false);

private:
	struct BotData {
		uint32_t sid;
		CID cid;
		BufferPtr inf;
	};

	BotData security;
	BotData opchat;

	ClientManager::SignalReceive::ManagedConnection receiveConn;
	void onReceive(Client& c, AdcCommand& cmd, int& handled);

	friend class Singleton<BotManager>;
	static BotManager* instance;
	static const std::string className;
};
} // namespace adcadmin
#endif
since it's ugly and alpha (project suspended) you can consider it as a pseudo-code :P

Toast

Re: Creating an OPChat in a hubsoft

Post by Toast » 02 Apr 2009, 19:47

Change the license then so everyone can use it and tnx :)

Sulan
Junior Member
Posts: 16
Joined: 19 Jan 2009, 20:33

Re: Creating an OPChat in a hubsoft

Post by Sulan » 02 Apr 2009, 20:35

Arne commited some new code today in rev 151 for adch, its supposed to be a start for bots or something, have not looked in to it yet.

Anyway, the basics for creating an opchat is quite simple.
Step1: Create a fake user (opchat).
Step2: broadcast any message to the fake user to all OPs (or users above certain rank).

This should be fairly easy to do with a 3d party software or in most hub with a decent script api, even to hardcode it should be easy.

adrian_007
Senior Member
Posts: 126
Joined: 06 Jan 2008, 13:00

Re: Creating an OPChat in a hubsoft

Post by adrian_007 » 02 Apr 2009, 20:58

1. why would i change from gpl?
2. i've checked those changes and it seems to be even easier to do with adchpp now. but still i can't compile adchpp under windows....

Locked