openclonk/src/network/C4Network2IRC.h

216 lines
6.6 KiB
C++

/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2010-2016, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
#ifndef C4NETWORK2IRC_H
#define C4NETWORK2IRC_H
#include "network/C4NetIO.h"
enum C4Network2IRCMessageType
{
MSG_Server,
MSG_Status,
MSG_Message,
MSG_Notice,
MSG_Action
};
const int C4NetIRCMaxLogLength = 300000; // Maximum total length of log - if log gets longer, it will be cleared even if messages have never been read
const int C4NetIRCMaxReadLogLength = 1000; // Maximum log messages kept even after they've been read
class C4Network2IRCMessage
{
friend class C4Network2IRCClient;
public:
C4Network2IRCMessage(C4Network2IRCMessageType enType, const char *szSource, const char *szTarget, const char *szData)
: iTimestamp(time(nullptr)), eType(enType), Source(szSource), Target(szTarget), Data(szData), Next(nullptr)
{ }
private:
time_t iTimestamp;
C4Network2IRCMessageType eType;
StdCopyStrBuf Source, Target, Data;
// used by C4Network2IRCClient
C4Network2IRCMessage *Next;
public:
time_t getTimestamp() const { return iTimestamp; }
C4Network2IRCMessageType getType() const { return eType; }
const char *getSource() const { return Source.getData(); }
const char *getTarget() const { return Target.getData(); }
const char *getData() const { return Data.getData(); }
bool isChannel() const { return Target.getLength() && (*Target.getData() == '#' || *Target.getData() == '+'); }
C4Network2IRCMessage *getNext() const { return Next; }
};
class C4Network2IRCUser
{
friend class C4Network2IRCChannel;
public:
C4Network2IRCUser(const char *szName);
private:
StdCopyStrBuf Prefix;
StdCopyStrBuf Name;
// used by C4Network2IRCChannel
C4Network2IRCUser *Next;
public:
const char *getPrefix() const { return Prefix.getData(); }
const char *getName() const { return Name.getData(); }
C4Network2IRCUser *getNext() const { return Next; }
private:
// called by C4Network2IRCChannel
void SetPrefix(const char *szPrefix) { Prefix = szPrefix; }
};
class C4Network2IRCChannel
{
friend class C4Network2IRCClient;
public:
C4Network2IRCChannel(const char *szName);
~C4Network2IRCChannel();
private:
StdCopyStrBuf Name;
StdCopyStrBuf Topic;
C4Network2IRCUser *pUsers;
bool fReceivingUsers;
// used by C4Network2IRCClient
C4Network2IRCChannel *Next;
public:
const char *getName() const { return Name.getData(); }
const char *getTopic() const { return Topic.getData(); }
C4Network2IRCUser *getUsers() const { return pUsers; }
C4Network2IRCUser *getUser(const char *szName) const;
bool isUsersLocked() const { return fReceivingUsers; }
private:
// called by C4Network2IRCClient
void OnUsers(const char *szUsers, const char *szPrefixes);
void OnUsersEnd();
void OnJoin(const char *szUser);
void OnPart(const char *szUser, const char *szComment);
void OnKick(const char *szUser, const char *szComment);
void OnTopic(const char *szTopic);
C4Network2IRCUser *AddUser(const char *szName);
void DeleteUser(C4Network2IRCUser *pUser);
void ClearUsers();
};
class C4Network2IRCClient : public C4NetIOTCP, private C4NetIO::CBClass
{
public:
C4Network2IRCClient();
~C4Network2IRCClient() override;
private:
// Connection information
C4NetIO::addr_t ServerAddr, PeerAddr;
bool fConnecting{false}, fConnected{false};
// Status information
StdCopyStrBuf Nick, RealName, Password;
StdCopyStrBuf AutoJoin;
C4Network2IRCChannel *pChannels{nullptr};
// User mode/prefix map
StdCopyStrBuf Prefixes;
// Message log
C4Network2IRCMessage *pLog{nullptr}, *pLogLastRead, *pLogEnd{nullptr};
int32_t iLogLength{0}, iUnreadLogLength{0};
// Event queue for notify
class C4InteractiveThread *pNotify{nullptr};
// Critical section for data
CStdCSec CSec;
private:
// Overridden
void PackPacket(const C4NetIOPacket &rPacket, StdBuf &rOutBuf) override;
size_t UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &addr) override;
// Callbacks
bool OnConn(const C4NetIO::addr_t &AddrPeer, const C4NetIO::addr_t &AddrConnect, const addr_t *pOwnAddr, C4NetIO *pNetIO) override;
void OnDisconn(const C4NetIO::addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason) override;
void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO) override;
public:
CStdCSec *getCSec() { return &CSec; }
// only call these while holding a lock on the above critical section!
C4Network2IRCChannel *getFirstChannel() const;
C4Network2IRCChannel *getNextChannel(C4Network2IRCChannel *pPrevChan) const;
C4Network2IRCChannel *getChannel(const char *szName) const;
C4Network2IRCMessage *getMessageLog() const { return pLog; }
C4Network2IRCMessage *getUnreadMessageLog() const { return pLogLastRead ? pLogLastRead->getNext() : pLog; }
void ClearMessageLog();
void MarkMessageLogRead();
const char *getUserName() const { return Nick.getData(); }
using C4NetIOTCP::Connect;
// Simple network communication
bool Connect(const char *szServer, const char *szNick, const char *szRealName, const char *szPassword = nullptr, const char *szChannel = nullptr);
using C4NetIOTCP::Close;
bool Close() override;
using C4NetIOTCP::Send;
bool Send(const char *szCommand, const char *szParameters = nullptr);
// Notfiy interface
void SetNotify(class C4InteractiveThread *pnNotify) { pNotify = pnNotify; }
// Special IRC commands
bool Quit(const char *szReason);
bool Join(const char *szChannel);
bool Part(const char *szChannel);
bool Message(const char *szTarget, const char *szText);
bool Notice(const char *szTarget, const char *szText);
bool Action(const char *szTarget, const char *szText);
bool ChangeNick(const char *szNewNick);
bool RegisterNick(const char *szPassword, const char *szMail);
// Status
bool IsActive() const { return fConnecting || fConnected; }
bool IsConnected() const { return fConnected; }
private:
void OnCommand(const char *szSender, const char *szCommand, const char *szParameters);
void OnNumericCommand(const char *szSender, int iCommand, const char *szParameters);
void OnConnected();
void OnMessage(bool fNotice, const char *szSource, const char *szTarget, const char *szText);
void PopMessage();
void PushMessage(C4Network2IRCMessageType eType, const char *szSource, const char *szTarget, const char *szText);
C4Network2IRCChannel *AddChannel(const char *szName);
void DeleteChannel(C4Network2IRCChannel *pChannel);
};
#endif // C4NETWORK2IRC_H