using mixed UnrealIRCd 5 and UnrealIRCd 6 networks.
This is a slightly complex rewrite of make_mode_str() and do_mode(),
as we nog go from single mode lines to potentially multiple mode lines.
In short: whenever we would be near buffer cut-off point (the famous
512 byte limit) then previously we would prevent the mode, though not
succesfully in all cases where a network consists of mixed 5.x and 6.x.
From this point onward we no longer do that. Instead we convert one
MODE command to two MODE lines if that is needed.
The benefit of this is that we no longer prevent it BEFORE processing
the MODE, which is a flawed method and could be wrong (causing desyncs).
And also, we no longer partially ignore MODE lines from clients when
they would cause the limit to be exceeded, as we replace them with
two MODE lines instead.
These are more changes than I wanted at such a late point but.. they seem
to be necessary to prevent U5-U6 compatibility issues.
side. This was due to channel->creationtime being set to TStime() but
then not adjusted/set later, (also) resulting in some adding/removing
action of modes as well.
It *seems* the other few cases were OK though: equal TS, lower TS,
higher TS, just not the "channel only exists on one side"-case.
Guess we need more test coverage!
This also removes the "TS for #channel changed" message that was sent
to channel members. I doubt regular users understand these messages.
I did add a message (unreal_log) to IRCOps, which may or may not be
useful or too noisy... unsure about this one :)
It means you can no longer modify eg parv[1] in-place with strtoken and such.
The main reason for this is that as a command handler you have no idea
where the arguments may come from. It could be from a do_cmd() with
read-only storage (eg a string literal) and so on.
It started with an experiment of how far I could get and how annoying the
side-effects would be, but they seem to be quite managable, so I'm
committing this stuff.
Hopefully this catches/solves some stupid bugs somewhere :)
- For HOOKTYPE_LOCAL_JOIN and HOOKTYPE_REMOTE_JOIN: drop parv[] argument
as it was useless anyway, it only contained the channel name in parv[1]
but never the key, sometimes was entirely NULL even.
- For HOOKTYPE_PRE_LOCAL_JOIN instead of char *parv[] we now pass
const char *key. As predicted more than a year ago when fixing
0902ed7a99
* channel->mode.extmode to channel->mode.mode
* channel->mode.extmodeparams to channel->mode.mode_params
This because all channel modes that are set there are extended channel
modes, only lists are still in core atm and they never get set here.
Eg no longer need to walk through the corechannelmodetable for
single param channel modes...
Also fix sjoin comments about "their" and "our" modes. In the merge
case this was not correct, it was "our old" and "merged modes".
We used to always send the long version:
SJOIN ts #channel +sntkl key 999 :xxx
From now on we only send that for the first SJOIN for a channel
when syncing. For any subsequent SJOINs (so for larger channels or
with lots of bans/exempts/invexes) we will use the short version:
SJOIN ts #channel :xxx
We now do it that way because the remote side already received
all the modes the first time, so they are redundant in the
subsequent SJOINs for the same channel.
Especially if you have a channel with a large mode string, such as
+lLfH 99 #redirectchan [30j#i10,40m#m10,7c#C15,10n#N15,30k#K10]:15 100:1d
it was previously 1) wasting bandwidth and 2) unnecessary CPU
trying to merge channel modes that were already the same.
Currently only supported option is:
BCTX_CONV_OPTION_WRITE_LETTER_BANS: always write letter bans
This removes the NULL pointer magic that i was not happy about.
The only stuff we still have is if a bounce servermode is detected
(incoming) then we just ignore it.
All this bounce stuff wasn't used much, and didn't even work
(was always sending empty bounce string). It was only complicating
the code everywhere with stupid stuff like:
*x++ = bounce ? '+' : '-';
what = MODE_DEL;
* New macro IsInvalidChannelTS() which evaluates to ts < 750000
* Check for faulty creation time ("fishy timestamp") at ALL places
where channel->creationtime is set.
* Also, important, changed behavior:
if !IsInvalidChannelTS then:
1) We print our warning
2) We pretend ts is our channel creationtime (which may be
TStime() if the channel did not previously exist)
3) We allow the command through and allow it to merge (in case of SJOIN)
This makes it so we still log the error (noisy) but on the other hand
we won't get "infected" by fishy timestamps since we will never set
them, no matter what happens.
just like client->user is set if the client is a user.
Rename client->srvptr to client->uplink: this is the uplink that the client
is connected to. If the client is a user then it is set to the server that
the client is connected to, if the client is a server then it is set to the
server that the server is connected to (the.. tadah.. uplink).
For local clients it is always set to &me.
change some more calls to make_channel() to use find_channel().
Also make it take 1 argument instead of 3.
Needed to be careful in sjoin code since the previous code set
channel->creationtime to 0 if client was a remote. Now merged
a few if's into one. Should be correct :D.
They were already ignored in MODE by remote UnrealIRCd servers,
but this makes it so local modes (+Z and +d at the moment)
are not sent across the wire.
This also changes the channel_modes() function to have an additional
'hide_local_modes' argument. Set this to 1 if you are building a
buffer that will be sent to remote servers, otherwise use 0,
which is far more common.
Also, this will skip saving of local channel modes to channeldb
since all of these are temporary, or at the moment anyway.
Thanks to alice for reporting this bug and providing a good test
case to help fix this issue and the previous ones.
and HOOKTYPE_REMOTE_CHANMODE are called from the SJOIN code.
We now set the samode argument to -1 if it is an SJOIN server sync,
so chanmodes/permanent won't destroy the channel while processing
the SJOIN. The SJOIN code already takes care of destroying at the end.
so they can fetch more history than the standard on-join history.
In the future we are also likely to implement IRCv3 CHATHISTORY
once that becomes an official specification. However, until it is
specified and until most major clients support it, several years
are likely to pass. It would be a shame to withhold channel
history to many end-users in the meantime when it takes so little
effort from us to provide an easy command.
See also
https://www.unrealircd.org/docs/Channel_history
And in particular the new section:
https://www.unrealircd.org/docs/Channel_history#Playback_frontends
which explains the relationship between on-join playback,
HISTORY and CHATHISTORY.