forked from Mirrors/openclonk
216 lines
6.6 KiB
C++
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
|