ft_irc 1.0
読み取り中…
検索中…
一致する文字列を見つけられません
JoinCommand.cpp
[詳解]
1
8#include "JoinCommand.hpp"
9#include "Channel.hpp"
10#include "Client.hpp"
11#include "CommandUtils.hpp" // For split
12#include "Replies.hpp"
13#include "Server.hpp"
14
16
18 if (args.empty()) {
20 params.push_back("JOIN");
22 return;
23 }
24
25 const std::string &channelStr = args[0];
26
27 // Handle JOIN 0
28 if (channelStr == "0") {
29 const std::vector<Channel *> &joinedChannels = client->getChannels();
30 for (size_t i = 0; i < joinedChannels.size(); ++i) {
31 Channel *channel = joinedChannels[i];
32 std::string partMessage = client->getPrefix() + " PART " + channel->getName() + "\r\n";
33 channel->broadcast(partMessage, NULL); // Broadcast to all including the client
34 channel->removeMember(client);
35 }
36 // The client's channel list will be cleared by the subsequent removeMember calls
37 // via the client's removeChannel method, which should be called from Channel::removeMember.
38 // Let's assume Channel::removeMember calls client->removeChannel.
39 // A more robust implementation would clear it here.
40 const_cast<std::vector<Channel *> &>(client->getChannels()).clear(); // Simplified for now
41 return;
42 }
43
44 std::vector<std::string> channels = split(channelStr, ',');
45
46 for (size_t i = 0; i < channels.size(); ++i) {
47 const std::string &channelName = channels[i];
48
49 if (channelName.empty() || channelName[0] != '#') {
51 params.push_back(channelName);
52 client->sendMessage(
54 continue;
55 }
56
57 Channel *channel = _server->getChannel(channelName);
58 if (channel == NULL) {
59 channel = new Channel(channelName);
60 _server->addChannel(channel);
61 // The first user to join a channel becomes an operator
62 channel->addOperator(client);
63 }
64
65 if (channel->isMember(client)) {
66 continue; // Already in channel
67 }
68
69 // Check channel modes for joining
70 if (channel->hasMode('i') && !channel->isInvitedUser(client)) {
72 params.push_back(channelName);
73 client->sendMessage(
75 continue;
76 }
77
78 if (channel->hasMode('k')) {
79 // If a key is provided, check it. If not, or if incorrect, deny access.
80 if (args.size() < 2 || !channel->checkKey(args[1])) {
82 params.push_back(channelName);
83 client->sendMessage(
85 continue;
86 }
87 }
88
89 if (channel->hasMode('l') && channel->getMembers().size() >= channel->getLimit()) {
91 params.push_back(channelName);
92 client->sendMessage(
94 continue;
95 }
96
97 channel->addMember(client);
98 client->addChannel(channel);
99
100 // If client was invited, remove them from the invited list
101 if (channel->isInvitedUser(client)) {
102 channel->removeInvitedUser(client);
103 }
104
105 std::string joinMessage = client->getPrefix() + " JOIN " + channelName + "\r\n";
106 channel->broadcast(joinMessage, NULL); // Broadcast to all including the new member
107
108 // Send topic
109 if (channel->getTopic().empty()) {
111 params.push_back(channelName);
112 client->sendMessage(formatReply(_server->getServerName(), client->getNickname(), RPL_NOTOPIC, params));
113 } else {
115 params.push_back(channelName);
116 params.push_back(channel->getTopic());
117 client->sendMessage(formatReply(_server->getServerName(), client->getNickname(), RPL_TOPIC, params));
118 }
119
120 // Send names list
121 std::string names;
122 const std::map<int, Client *> &members = channel->getMembers();
123 for (std::map<int, Client *>::const_iterator it = members.begin(); it != members.end(); ++it) {
124 if (channel->isOperator(it->second)) {
125 names += "@";
126 }
127 names += it->second->getNickname() + " ";
128 }
129 // Trim trailing space
130 if (!names.empty()) {
131 names.erase(names.length() - 1);
132 }
133
134 std::vector<std::string> names_params;
135 names_params.push_back(channelName);
136 names_params.push_back(names);
137 client->sendMessage(formatReply(_server->getServerName(), client->getNickname(), RPL_NAMREPLY, names_params));
138
139 std::vector<std::string> end_params;
140 end_params.push_back(channelName);
141 client->sendMessage(formatReply(_server->getServerName(), client->getNickname(), RPL_ENDOFNAMES, end_params));
142 }
143}
Manages channel members and states.
Manages client connection and state.
std::vector< std::string > split(const std::string &s, char delimiter)
Splits a string into a vector of strings based on a delimiter.
Utility functions for command handling.
Handles the JOIN command.
std::string formatReply(const std::string &serverName, const std::string &clientNickname, const std::string &replyCodeAndText)
Formats an IRC reply message without extra parameters.
Definition Replies.cpp:14
Defines IRC numeric replies and error messages.
#define ERR_INVITEONLYCHAN
Definition Replies.hpp:83
#define RPL_NOTOPIC
Definition Replies.hpp:49
#define RPL_TOPIC
Definition Replies.hpp:48
#define ERR_BADCHANNELKEY
Definition Replies.hpp:81
#define RPL_ENDOFNAMES
Definition Replies.hpp:56
#define RPL_NAMREPLY
Definition Replies.hpp:55
#define ERR_CHANNELISFULL
Definition Replies.hpp:82
#define ERR_NOSUCHCHANNEL
Definition Replies.hpp:65
#define ERR_NEEDMOREPARAMS
Definition Replies.hpp:76
Core IRC server implementation.
T begin(T... args)
チャンネルのメンバーと状態を管理するクラス。
Definition Channel.hpp:25
void addMember(Client *client)
Definition Channel.cpp:30
const std::map< int, Client * > & getMembers() const
Definition Channel.cpp:24
unsigned int getLimit() const
Definition Channel.cpp:85
const std::string & getName() const
Definition Channel.cpp:22
bool hasMode(char mode) const
Definition Channel.cpp:59
bool isMember(Client *client) const
Definition Channel.cpp:37
void addOperator(Client *client)
Definition Channel.cpp:47
bool isInvitedUser(Client *client) const
Definition Channel.cpp:91
void broadcast(const std::string &message, Client *excludeClient)
Definition Channel.cpp:39
bool isOperator(Client *client) const
Definition Channel.cpp:51
void removeMember(Client *client)
Definition Channel.cpp:32
bool checkKey(const std::string &key) const
Definition Channel.cpp:79
void removeInvitedUser(Client *client)
Definition Channel.cpp:89
const std::string & getTopic() const
Definition Channel.cpp:26
Represents an IRC client connected to the server.
Definition Client.hpp:25
const std::vector< Channel * > & getChannels() const
Gets the list of channels the client is in.
Definition Client.cpp:43
std::string getPrefix() const
Generates the client's IRC prefix (e.g., :nick!user@host).
Definition Client.cpp:50
virtual void sendMessage(const std::string &message) const
Sends a message to the client by appending it to the send buffer.
Definition Client.cpp:135
const std::string & getNickname() const
Gets the client's nickname.
Definition Client.cpp:25
void addChannel(Channel *channel)
Adds a channel to the client's list of joined channels.
Definition Client.cpp:73
Abstract base class (interface) for all IRC commands.
Definition ICommand.hpp:26
Server * _server
Pointer to the IRC server instance.
Definition ICommand.hpp:28
void execute(Client *client, const std::vector< std::string > &args)
Executes the JOIN command.
JoinCommand(Server *server)
Constructs a JoinCommand object.
Implements the core IRC server functionality as a Singleton.
Definition Server.hpp:49
Channel * getChannel(const std::string &name)
Retrieves a Channel object by its name.
Definition Server.cpp:406
const std::string & getServerName() const
Gets the server's name.
Definition Server.cpp:381
void addChannel(Channel *channel)
Adds a new channel to the server.
Definition Server.cpp:400
T empty(T... args)
T end(T... args)
T erase(T... args)
T push_back(T... args)
T size(T... args)