[svn] Port over ratbox 2.2 r23507, r23624, r23626 (jilles/anfl):
Change TS6 JOIN processing - don't send out simple modes in TS6 JOIN and TS5 SJOIN when a local user joins an existing channel - don't send out simple modes in TS6 JOIN and TS5 SJOIN when propagating a TS6 JOIN - don't interpret simple modes in an incoming TS6 JOIN This is to avoid desyncs when certain mode changes (e.g. -im) cross with joins. A downside is that simple modes will be more desynched when a JOIN creates a channel or lowers TS, but that's less important. Update the TS6 specification to include this, and clarify that TMODE can come from a server and that MODE must be translated into TMODE from other servers too.
This commit is contained in:
parent
9b6ff0c8f9
commit
bee3b6716c
4 changed files with 102 additions and 171 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
jilles 2007/02/11 16:54:43 UTC (20070211-3209)
|
||||||
|
Log:
|
||||||
|
Make -logfile work again.
|
||||||
|
|
||||||
|
|
||||||
|
Changes: Modified:
|
||||||
|
+2 -2 trunk/src/s_log.c (File Modified)
|
||||||
|
|
||||||
|
|
||||||
nenolod 2007/02/09 22:18:23 UTC (20070209-3205)
|
nenolod 2007/02/09 22:18:23 UTC (20070209-3205)
|
||||||
Log:
|
Log:
|
||||||
- fix off-by-one memory overflow error.
|
- fix off-by-one memory overflow error.
|
||||||
|
|
|
@ -1,11 +1,35 @@
|
||||||
$Id: ts6.txt 6 2005-09-10 01:02:21Z nenolod $
|
$Id: ts6.txt 3211 2007-02-20 00:34:28Z jilles $
|
||||||
|
|
||||||
TS6 Proposal (v7)
|
TS6 Proposal (v8)
|
||||||
Written by Lee H <lee@leeh.co.uk>
|
Written by Lee H <lee@leeh.co.uk>
|
||||||
Ideas borrowed heavily from ircnet (Beeth, jv, Q)
|
Ideas borrowed heavily from ircnet (Beeth, jv, Q)
|
||||||
|
|
||||||
Introduction
|
- Changes between v7 and v8 -
|
||||||
------------
|
-----------------------------
|
||||||
|
|
||||||
|
In the v7 specification, the JOIN command included the channel modes of a
|
||||||
|
channel, and acted on them following TS rules. In the v8 specification,
|
||||||
|
JOIN will never send modes.
|
||||||
|
|
||||||
|
Desyncs can occur both when they are sent and when they are not. If they
|
||||||
|
are sent, then you can have a situation where a user on one side of the
|
||||||
|
network issues "MODE #channel -l", and a user on another side of the network
|
||||||
|
issues "JOIN #channel" whilst the +l still exists. As the JOIN string sent
|
||||||
|
server<->server includes the full modes at the time of the user joining,
|
||||||
|
this will propagate the +l, but there is a -l crossing in the other
|
||||||
|
direction. Desync will occur beyond where they intersect.
|
||||||
|
|
||||||
|
If the modes are not sent, then a lower TS JOIN command, or a JOIN command
|
||||||
|
that creates a channel will cause a desync.
|
||||||
|
|
||||||
|
It is judged that the desync with sending the modes is worse than the desync
|
||||||
|
by not sending them, as such the v8 specification dictates modes are not
|
||||||
|
sent with a JOIN command server<->server.
|
||||||
|
|
||||||
|
The v8 specification also clarifies that servers may issue TMODE.
|
||||||
|
|
||||||
|
- Introduction -
|
||||||
|
----------------
|
||||||
|
|
||||||
This document aims to fix some of the flaws that are still present in the
|
This document aims to fix some of the flaws that are still present in the
|
||||||
current TS system.
|
current TS system.
|
||||||
|
@ -28,8 +52,8 @@ issue a mode during a netburst and the mode will be set on the server
|
||||||
we are bursting to.
|
we are bursting to.
|
||||||
|
|
||||||
|
|
||||||
Definitions
|
- Definitions -
|
||||||
-----------
|
---------------
|
||||||
|
|
||||||
Throughout this document, the following terms are used:
|
Throughout this document, the following terms are used:
|
||||||
|
|
||||||
|
@ -43,8 +67,8 @@ UID - An ID concateneted to a SID. This forms the clients UID.
|
||||||
TS6 - The TS version 6.
|
TS6 - The TS version 6.
|
||||||
|
|
||||||
|
|
||||||
Support
|
- Support -
|
||||||
-------
|
-----------
|
||||||
|
|
||||||
Support for this document is given by the TS version 6.
|
Support for this document is given by the TS version 6.
|
||||||
|
|
||||||
|
@ -60,8 +84,8 @@ http://www.leeh.co.uk/ircd/encap.txt
|
||||||
The TS6 protocol does not supports masked entities.
|
The TS6 protocol does not supports masked entities.
|
||||||
|
|
||||||
|
|
||||||
Nick TS rules
|
- Nick TS rules -
|
||||||
-------------
|
-----------------
|
||||||
|
|
||||||
A server receiving a command that requires nick TS rules must check for a
|
A server receiving a command that requires nick TS rules must check for a
|
||||||
collision between an existing user, and the nick in the received message.
|
collision between an existing user, and the nick in the received message.
|
||||||
|
@ -81,8 +105,8 @@ clients user@host are different it will collide the new user and drop the
|
||||||
message.
|
message.
|
||||||
|
|
||||||
|
|
||||||
Nick TS collisions
|
- Nick TS collisions -
|
||||||
------------------
|
----------------------
|
||||||
|
|
||||||
If both users are to be collided, we must issue a KILL for the existing
|
If both users are to be collided, we must issue a KILL for the existing
|
||||||
user to all servers. If the new user has a UID then we must also issue a
|
user to all servers. If the new user has a UID then we must also issue a
|
||||||
|
@ -98,8 +122,8 @@ If only the new user is being collided, we must issue a KILL for the new user
|
||||||
back to the server sending us data if the new user has a UID.
|
back to the server sending us data if the new user has a UID.
|
||||||
|
|
||||||
|
|
||||||
Channel TS rules
|
- Channel TS rules -
|
||||||
----------------
|
--------------------
|
||||||
|
|
||||||
A server receiving a command that requires normal channel TS rules must
|
A server receiving a command that requires normal channel TS rules must
|
||||||
apply the following rules to the command.
|
apply the following rules to the command.
|
||||||
|
@ -125,8 +149,8 @@ losing their op (+o) status who do not have a UID as 'deopped'. A server must
|
||||||
ignore any "MODE" commands from a user marked as 'deopped'.
|
ignore any "MODE" commands from a user marked as 'deopped'.
|
||||||
|
|
||||||
|
|
||||||
Simple channel TS rules
|
- Simple channel TS rules -
|
||||||
-----------------------
|
---------------------------
|
||||||
|
|
||||||
A server receiving a command that requires simple channel TS rules must
|
A server receiving a command that requires simple channel TS rules must
|
||||||
apply the following rules to the command.
|
apply the following rules to the command.
|
||||||
|
@ -139,11 +163,11 @@ Simple channel TS rules do not affect current modes in the channel except
|
||||||
for the modes we are accepting.
|
for the modes we are accepting.
|
||||||
|
|
||||||
|
|
||||||
The following commands are defined here as the TS6 protocol
|
- The following commands are defined here as the TS6 protocol -
|
||||||
-----------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
|
|
||||||
PASS:
|
- PASS -
|
||||||
PASS <PASSWORD> TS <TS_CURRENT> :<SID>
|
PASS <PASSWORD> TS <TS_CURRENT> :<SID>
|
||||||
|
|
||||||
This command is used for password verification with the server we are
|
This command is used for password verification with the server we are
|
||||||
connecting to.
|
connecting to.
|
||||||
|
@ -156,8 +180,8 @@ The <PASSWORD> field is the password we have stored for this server,
|
||||||
<TS_CURRENT> is our current TS version. If this field is not present then
|
<TS_CURRENT> is our current TS version. If this field is not present then
|
||||||
the server does not support TS6. <SID> is the SID of the server.
|
the server does not support TS6. <SID> is the SID of the server.
|
||||||
|
|
||||||
UID:
|
- UID -
|
||||||
:<SID> UID <NICK> <HOPS> <TS> +<UMODE> <USERNAME> <HOSTNAME> <IP> <UID> :<GECOS>
|
:<SID> UID <NICK> <HOPS> <TS> +<UMODE> <USERNAME> <HOSTNAME> <IP> <UID> :<GECOS>
|
||||||
|
|
||||||
This command is used for introducing clients to the network.
|
This command is used for introducing clients to the network.
|
||||||
|
|
||||||
|
@ -176,8 +200,8 @@ clients UID. The <GECOS> field is the clients gecos.
|
||||||
|
|
||||||
A server receiving a UID command must apply nick TS rules to the nick.
|
A server receiving a UID command must apply nick TS rules to the nick.
|
||||||
|
|
||||||
SID:
|
- SID -
|
||||||
:<SID> SID <SERVERNAME> <HOPS> <SID> :<GECOS>
|
:<SID> SID <SERVERNAME> <HOPS> <SID> :<GECOS>
|
||||||
|
|
||||||
This command is used for introducing servers to the network.
|
This command is used for introducing servers to the network.
|
||||||
|
|
||||||
|
@ -196,8 +220,8 @@ connected server through which the command was received.
|
||||||
Client and servers which do not have a UID/SID must be introduced by old
|
Client and servers which do not have a UID/SID must be introduced by old
|
||||||
methods.
|
methods.
|
||||||
|
|
||||||
SJOIN:
|
- SJOIN -
|
||||||
:<SID> SJOIN <TS> <CHANNAME> +<CHANMODES> :<UIDS>
|
:<SID> SJOIN <TS> <CHANNAME> +<CHANMODES> :<UIDS>
|
||||||
|
|
||||||
This command is used for introducing users to channels.
|
This command is used for introducing users to channels.
|
||||||
|
|
||||||
|
@ -216,23 +240,28 @@ to introduce a single user to an existing channel. It must instead
|
||||||
use the "JOIN" command defined in this specification. A TS6 server must
|
use the "JOIN" command defined in this specification. A TS6 server must
|
||||||
still use SJOIN for creating channels.
|
still use SJOIN for creating channels.
|
||||||
|
|
||||||
JOIN:
|
- JOIN -
|
||||||
:<UID> JOIN <TS> <CHANNAME> +<CHANMODES>
|
:<UID> JOIN <TS> <CHANNAME> +
|
||||||
|
|
||||||
This command is used for introducing one user unopped to an existing channel.
|
This command is used for introducing one user unopped to an existing channel.
|
||||||
|
|
||||||
The <UID> field is the UID of the client joining the channel. The
|
The <UID> field is the UID of the client joining the channel. The
|
||||||
<TS> field is the channels current TS, <CHANNAME> is the channels
|
<TS> field is the channels current TS, <CHANNAME> is the channels
|
||||||
current name, <CHANMODES> are the channels current modes.
|
current name.
|
||||||
|
|
||||||
A server receiving a JOIN must apply normal channel TS rules to the JOIN.
|
A server receiving a JOIN must apply normal channel TS rules to the JOIN.
|
||||||
|
|
||||||
It should be noted that whilst JOIN would not normally create a
|
No channel modes are sent with the JOIN command. In previous versions of
|
||||||
channel, during specific race conditions it can. This can create
|
this specification, the "+" parameter contained the channels current modes.
|
||||||
a ban desync that this specification does not rectify.
|
A server following this version of the specification must not interpret this
|
||||||
|
argument and must not propagate any value other than "+" for this parameter.
|
||||||
|
|
||||||
BMASK:
|
It should be noted that whilst JOIN would not normally create a
|
||||||
:<SID> BMASK <TS> <CHANNAME> <TYPE> :<MASKS>
|
channel or lower the timestamp, during specific conditions it can. This
|
||||||
|
can create a desync that this specification does not rectify.
|
||||||
|
|
||||||
|
- BMASK -
|
||||||
|
:<SID> BMASK <TS> <CHANNAME> <TYPE> :<MASKS>
|
||||||
|
|
||||||
This command is used for bursting channel bans to a network.
|
This command is used for bursting channel bans to a network.
|
||||||
|
|
||||||
|
@ -253,17 +282,18 @@ It should be noted however, that a BMASK with a lower TS should
|
||||||
not be possible without a desync, due to it being sent after
|
not be possible without a desync, due to it being sent after
|
||||||
SJOIN.
|
SJOIN.
|
||||||
|
|
||||||
TMODE:
|
- TMODE -
|
||||||
:<UID> TMODE <TS> <CHANNAME> <MODESTRING>
|
:<SID|UID> TMODE <TS> <CHANNAME> <MODESTRING>
|
||||||
|
|
||||||
This command is used for clients issuing modes on a channel.
|
This command is used for clients issuing modes on a channel.
|
||||||
|
|
||||||
<UID> is the UID of the client setting the mode. <TS> is the
|
<SID|UID> is either the UID of the client setting the mode, or the SID of
|
||||||
current TS of the channel, <CHANNAME> is the channels name.
|
the server setting the mode. <TS> is the current TS of the channel,
|
||||||
<MODESTRING> is the raw mode the client is setting.
|
<CHANNAME> is the channels name. <MODESTRING> is the raw mode the client is
|
||||||
|
setting.
|
||||||
|
|
||||||
A server receiving a TMODE must apply simple channel TS rules to the TMODE.
|
A server receiving a TMODE must apply simple channel TS rules to the TMODE.
|
||||||
|
|
||||||
A TS6 server must translate MODEs issued by a local client into TMODE
|
A TS6 server must translate MODEs issued by a local client, or received from
|
||||||
to send to other TS6 capable servers.
|
a server into TMODE to send to other TS6 capable servers.
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
#define SERNO "20070209-3205"
|
#define SERNO "20070211-3209"
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
* USA
|
* USA
|
||||||
*
|
*
|
||||||
* $Id: m_join.c 3173 2007-01-31 23:57:18Z jilles $
|
* $Id: m_join.c 3211 2007-02-20 00:34:28Z jilles $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "stdinc.h"
|
#include "stdinc.h"
|
||||||
|
@ -62,7 +62,7 @@ mapi_hlist_av1 join_hlist[] = {
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_MODULE_AV1(join, NULL, NULL, join_clist, join_hlist, NULL, "$Revision: 3173 $");
|
DECLARE_MODULE_AV1(join, NULL, NULL, join_clist, join_hlist, NULL, "$Revision: 3211 $");
|
||||||
|
|
||||||
static void do_join_0(struct Client *client_p, struct Client *source_p);
|
static void do_join_0(struct Client *client_p, struct Client *source_p);
|
||||||
static int check_channel_name_loc(struct Client *source_p, const char *name);
|
static int check_channel_name_loc(struct Client *source_p, const char *name);
|
||||||
|
@ -342,17 +342,15 @@ m_join(struct Client *client_p, struct Client *source_p, int parc, const char *p
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char *modes = channel_modes(chptr, &me);
|
|
||||||
|
|
||||||
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
||||||
":%s JOIN %ld %s %s",
|
":%s JOIN %ld %s +",
|
||||||
use_id(source_p), (long) chptr->channelts,
|
use_id(source_p), (long) chptr->channelts,
|
||||||
chptr->chname, modes);
|
chptr->chname);
|
||||||
|
|
||||||
sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
|
sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
|
||||||
":%s SJOIN %ld %s %s :%s",
|
":%s SJOIN %ld %s + :%s",
|
||||||
me.name, (long) chptr->channelts,
|
me.name, (long) chptr->channelts,
|
||||||
chptr->chname, modes, source_p->name);
|
chptr->chname, source_p->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
del_invite(chptr, source_p);
|
del_invite(chptr, source_p);
|
||||||
|
@ -396,13 +394,10 @@ static int
|
||||||
ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
|
||||||
{
|
{
|
||||||
struct Channel *chptr;
|
struct Channel *chptr;
|
||||||
static struct Mode mode, *oldmode;
|
static struct Mode mode;
|
||||||
const char *s;
|
|
||||||
const char *modes;
|
|
||||||
time_t oldts;
|
time_t oldts;
|
||||||
time_t newts;
|
time_t newts;
|
||||||
int isnew;
|
int isnew;
|
||||||
int args = 0;
|
|
||||||
int keep_our_modes = YES;
|
int keep_our_modes = YES;
|
||||||
int keep_new_modes = YES;
|
int keep_new_modes = YES;
|
||||||
dlink_node *ptr, *next_ptr;
|
dlink_node *ptr, *next_ptr;
|
||||||
|
@ -428,89 +423,11 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *
|
||||||
mode.key[0] = mode.forward[0] = '\0';
|
mode.key[0] = mode.forward[0] = '\0';
|
||||||
mode.mode = mode.limit = mode.join_num = mode.join_time = 0;
|
mode.mode = mode.limit = mode.join_num = mode.join_time = 0;
|
||||||
|
|
||||||
s = parv[3];
|
|
||||||
while(*s)
|
|
||||||
{
|
|
||||||
switch (*(s++))
|
|
||||||
{
|
|
||||||
case 'i':
|
|
||||||
mode.mode |= MODE_INVITEONLY;
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
mode.mode |= MODE_NOPRIVMSGS;
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
mode.mode |= MODE_PRIVATE;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
mode.mode |= MODE_SECRET;
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
mode.mode |= MODE_MODERATED;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
mode.mode |= MODE_TOPICLIMIT;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
mode.mode |= MODE_REGONLY;
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
mode.mode |= MODE_EXLIMIT;
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
mode.mode |= MODE_PERMANENT;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
mode.mode |= MODE_NOCOLOR;
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
mode.mode |= MODE_FREEINVITE;
|
|
||||||
break;
|
|
||||||
case 'z':
|
|
||||||
mode.mode |= MODE_OPMODERATE;
|
|
||||||
break;
|
|
||||||
case 'F':
|
|
||||||
mode.mode |= MODE_FREETARGET;
|
|
||||||
break;
|
|
||||||
case 'Q':
|
|
||||||
mode.mode |= MODE_DISFORWARD;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
if(parc < 5 + args)
|
|
||||||
return 0;
|
|
||||||
strlcpy(mode.forward, parv[4 + args], sizeof(mode.forward));
|
|
||||||
args++;
|
|
||||||
break;
|
|
||||||
case 'j':
|
|
||||||
/* sent a +j without an arg. */
|
|
||||||
if(parc < 5 + args)
|
|
||||||
return 0;
|
|
||||||
sscanf(parv[4 + args], "%d:%d", &mode.join_num, &mode.join_time);
|
|
||||||
args++;
|
|
||||||
break;
|
|
||||||
case 'k':
|
|
||||||
/* sent a +k without a key, eek. */
|
|
||||||
if(parc < 5 + args)
|
|
||||||
return 0;
|
|
||||||
strlcpy(mode.key, parv[4 + args], sizeof(mode.key));
|
|
||||||
args++;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
/* sent a +l without a limit. */
|
|
||||||
if(parc < 5 + args)
|
|
||||||
return 0;
|
|
||||||
mode.limit = atoi(parv[4 + args]);
|
|
||||||
args++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL)
|
if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
newts = atol(parv[1]);
|
newts = atol(parv[1]);
|
||||||
oldts = chptr->channelts;
|
oldts = chptr->channelts;
|
||||||
oldmode = &chptr->mode;
|
|
||||||
|
|
||||||
#ifdef IGNORE_BOGUS_TS
|
#ifdef IGNORE_BOGUS_TS
|
||||||
if(newts < 800000000)
|
if(newts < 800000000)
|
||||||
|
@ -547,55 +464,30 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *
|
||||||
else
|
else
|
||||||
keep_new_modes = NO;
|
keep_new_modes = NO;
|
||||||
|
|
||||||
if(!keep_new_modes)
|
|
||||||
mode = *oldmode;
|
|
||||||
else if(keep_our_modes)
|
|
||||||
{
|
|
||||||
mode.mode |= oldmode->mode;
|
|
||||||
if(oldmode->limit > mode.limit)
|
|
||||||
mode.limit = oldmode->limit;
|
|
||||||
if(strcmp(mode.key, oldmode->key) < 0)
|
|
||||||
strcpy(mode.key, oldmode->key);
|
|
||||||
if(oldmode->join_num > mode.join_num ||
|
|
||||||
(oldmode->join_num == mode.join_num &&
|
|
||||||
oldmode->join_time > mode.join_time))
|
|
||||||
{
|
|
||||||
mode.join_num = oldmode->join_num;
|
|
||||||
mode.join_time = oldmode->join_time;
|
|
||||||
}
|
|
||||||
if(irccmp(mode.forward, oldmode->forward) < 0)
|
|
||||||
strcpy(mode.forward, oldmode->forward);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* If setting -j, clear join throttle state -- jilles */
|
|
||||||
if (!mode.join_num)
|
|
||||||
chptr->join_count = chptr->join_delta = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_final_mode(&mode, oldmode);
|
|
||||||
chptr->mode = mode;
|
|
||||||
|
|
||||||
/* Lost the TS, other side wins, so remove modes on this side */
|
/* Lost the TS, other side wins, so remove modes on this side */
|
||||||
if(!keep_our_modes)
|
if(!keep_our_modes)
|
||||||
{
|
{
|
||||||
|
set_final_mode(&mode, &chptr->mode);
|
||||||
|
chptr->mode = mode;
|
||||||
remove_our_modes(chptr, source_p);
|
remove_our_modes(chptr, source_p);
|
||||||
DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
|
DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
|
||||||
{
|
{
|
||||||
del_invite(chptr, ptr->data);
|
del_invite(chptr, ptr->data);
|
||||||
}
|
}
|
||||||
|
/* If setting -j, clear join throttle state -- jilles */
|
||||||
|
chptr->join_count = chptr->join_delta = 0;
|
||||||
sendto_channel_local(ALL_MEMBERS, chptr,
|
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||||
":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
|
":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
|
||||||
me.name, chptr->chname, chptr->chname,
|
me.name, chptr->chname, chptr->chname,
|
||||||
(long) oldts, (long) newts);
|
(long) oldts, (long) newts);
|
||||||
|
if(*modebuf != '\0')
|
||||||
|
sendto_channel_local(ALL_MEMBERS, chptr,
|
||||||
|
":%s MODE %s %s %s",
|
||||||
|
source_p->servptr->name,
|
||||||
|
chptr->chname, modebuf, parabuf);
|
||||||
|
*modebuf = *parabuf = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*modebuf != '\0')
|
|
||||||
sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s %s %s",
|
|
||||||
source_p->user->server, chptr->chname, modebuf, parabuf);
|
|
||||||
|
|
||||||
*modebuf = *parabuf = '\0';
|
|
||||||
|
|
||||||
if(!IsMember(source_p, chptr))
|
if(!IsMember(source_p, chptr))
|
||||||
{
|
{
|
||||||
add_user_to_channel(chptr, source_p, CHFL_PEON);
|
add_user_to_channel(chptr, source_p, CHFL_PEON);
|
||||||
|
@ -611,14 +503,14 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *
|
||||||
source_p->host, chptr->chname);
|
source_p->host, chptr->chname);
|
||||||
}
|
}
|
||||||
|
|
||||||
modes = channel_modes(chptr, client_p);
|
|
||||||
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
|
||||||
":%s JOIN %ld %s %s",
|
":%s JOIN %ld %s +",
|
||||||
source_p->id, (long) chptr->channelts, chptr->chname, modes);
|
source_p->id, (long) chptr->channelts, chptr->chname);
|
||||||
sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
|
sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
|
||||||
":%s SJOIN %ld %s %s :%s",
|
":%s SJOIN %ld %s %s :%s",
|
||||||
source_p->user->server, (long) chptr->channelts,
|
source_p->user->server, (long) chptr->channelts,
|
||||||
chptr->chname, modes, source_p->name);
|
chptr->chname, keep_new_modes ? "+" : "0",
|
||||||
|
source_p->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue