示例#1
0
 public void HandleCommand(ClientCommandContext ctx)
 {
     ctx.Connection.SendReply(new AdminMeReply());
     ctx.Connection.SendReply(new AdminLocation1Reply());
     ctx.Connection.SendReply(new AdminLocation2Reply());
     ctx.Connection.SendReply(new AdminEMailReply());
 }
示例#2
0
        public void HandleCommand(ClientCommandContext ctx)
        {
            IEnumerable <string> channelNames = (ctx.Arguments.FirstOrDefault() ?? string.Empty).Split(',').Select(n => n.ToLowerInvariant());

            if (!channelNames.Any())
            {
                ctx.Connection.SendReply(new NeedMoreParamsReply(NAME));
                return;
            }

            foreach (string channelName in channelNames)
            {
                Channels.GetChannel(c => channelName.Equals(c.GetIRCName()), channel => {
                    if (channel == null)
                    {
                        ctx.Connection.SendReply(new NoSuchChannelReply(channelName));
                        return;
                    }

                    ChannelUsers.HasSession(channel, ctx.Session, hasUser => {
                        if (!hasUser)
                        {
                            ctx.Connection.SendReply(new NotOnChannelReply(channel));
                            return;
                        }

                        ChannelUsers.LeaveChannel(channel, ctx.Session);
                    });
                });
            }
        }
示例#3
0
        public void HandleCommand(ClientCommandContext ctx)
        {
            string firstArg = ctx.Arguments.ElementAtOrDefault(0) ?? string.Empty;

            if (firstArg == @"0")  // of course you would leave all channels with the JOIN command
            {
                ChannelUsers.LeaveChannels(ctx.Session);
                return;
            }

            string[] names     = firstArg.Split(',');
            string[] passwords = (ctx.Arguments.ElementAtOrDefault(1) ?? string.Empty).Split(',');

            for (int i = 0; i < names.Length; ++i)
            {
                string name = names[i];

                Channels.GetChannel(c => name.Equals(c.GetIRCName()), channel => {
                    if (channel == null)  // todo: check permissions and allow channel creation
                    {
                        ctx.Connection.SendReply(new BadChannelMaskReply(name));
                        return;
                    }

                    ChannelUsers.HasSession(channel, ctx.Session, hasSession => {
                        // just continue if we're already in the channel
                        if (hasSession)
                        {
                            return;
                        }

                        // introduce channel bans at some point

                        // introduce invites at some point

                        // add rank check

                        ChannelUsers.CheckOverCapacity(channel, ctx.User, isOverCapacity => {
                            if (isOverCapacity)
                            {
                                ctx.Connection.SendReply(new ChannelIsFullReply(channel));
                                return;
                            }

                            string password = passwords.ElementAtOrDefault(i) ?? string.Empty;
                            Channels.VerifyPassword(channel, password, success => {
                                if (!success)
                                {
                                    ctx.Connection.SendReply(new BadChannelKeyReply(channel));
                                    return;
                                }

                                ChannelUsers.JoinChannel(channel, ctx.Session);
                            });
                        });
                    });
                });
            }
        }
示例#4
0
 public void HandleCommand(ClientCommandContext ctx)
 {
     ctx.Connection.SendReply(
         ctx.Arguments.Count() < 2
             ? new NeedMoreParamsReply(NAME)
             : new NoOperatorHostReply()
         );
 }
示例#5
0
 public void HandleCommand(ClientCommandContext ctx)
 {
     if (ctx.Arguments.Any())
     {
         Sessions.DoKeepAlive(ctx.Session);
         ctx.Connection.SendCommand(new ServerPongCommand(Server, ctx.Arguments.FirstOrDefault()));
     }
 }
示例#6
0
        private void HandleChannel(ClientCommandContext ctx, IChannel channel)
        {
            Queue <string> args = new Queue <string>(ctx.Arguments);

            while (args.TryDequeue(out string arg))
            {
                //
            }
        }
示例#7
0
        public void HandleCommand(ClientCommandContext ctx)
        {
            string line   = ctx.Arguments.FirstOrDefault() ?? string.Empty;
            bool   isAway = !string.IsNullOrEmpty(line);

            Users.Update(
                ctx.User,
                status: isAway ? UserStatus.Away : UserStatus.Online,
                statusMessage: line
                );
        }
示例#8
0
        public void HandleCommand(ClientCommandContext ctx)
        {
            //string message = ctx.Arguments.ElementAtOrDefault(0);

            ctx.Connection.Close();

            if (ctx.Session != null)
            {
                Sessions.Destroy(ctx.Connection);
            }
        }
示例#9
0
        public void HandleCommand(ClientCommandContext ctx)
        {
            if (ctx.User == null) // blocking calls to this without an error
            {
                return;
            }

            // TODO: check if user is allowed to set a nick
            //       should prefixes be a thing for IRC?
            //       should the prefix be nuked in favour of a forced name change?

            string nickName = ctx.Arguments.FirstOrDefault();

            if (string.IsNullOrWhiteSpace(nickName))
            {
                ctx.Connection.SendReply(new NoNickNameGivenReply());
                return;
            }

            nickName = nickName.Trim();

            if (nickName.Equals(ctx.User.UserName, StringComparison.InvariantCulture)) // allowing capitalisation changes
            {
                nickName = null;
            }
            else if (nickName.Length > 15)            // should be configurable somewhere, also magic number in Sock Chat's impl
            {
                nickName = nickName.Substring(0, 15); // also Flashii's max username length is 16, guessing it was 15 to account for the ~?
            }
            else if (string.IsNullOrEmpty(nickName))
            {
                nickName = null;
            }

            if (nickName == null)
            {
                Users.Update(ctx.User, nickName: string.Empty);
                return;
            }

            // TODO: global name validation routines
            //ctx.Connection.SendReply(new ErroneousNickNameReply(nickName));

            Users.GetUser(nickName, user => {
                if (user != null)
                {
                    ctx.Connection.SendReply(new NickNameInUseReply(nickName));
                    return;
                }

                Users.Update(ctx.User, nickName: nickName);
            });
        }
示例#10
0
        public void HandleCommand(ClientCommandContext ctx)
        {
            string channelName = ctx.Arguments.ElementAtOrDefault(0);

            if (string.IsNullOrWhiteSpace(channelName))
            {
                ctx.Connection.SendReply(new NoRecipientReply(NAME));
                return;
            }

            string text = ctx.Arguments.ElementAtOrDefault(1);

            if (string.IsNullOrWhiteSpace(text))
            {
                ctx.Connection.SendReply(new NoTextToSendReply());
                return;
            }

            Func <IChannel, bool> predicate = null;
            char channelPrefix = channelName.First();

            if (channelPrefix == '#')
            {
                predicate = new Func <IChannel, bool>(c => channelName.Equals(c.GetIRCName()));
            }

            if (predicate == null)
            {
                ctx.Connection.SendReply(new NoSuchNickReply(channelName));
                return;
            }

            Channels.GetChannel(predicate, channel => {
                if (channel == null)
                {
                    ctx.Connection.SendReply(new NoSuchNickReply(channelName));
                    return;
                }

                ChannelUsers.HasUser(channel, ctx.User, hasUser => {
                    if (!hasUser)
                    {
                        ctx.Connection.SendReply(new CannotSendToChannelReply(channel));
                        return;
                    }

                    Messages.Create(ctx.Session, channel, text);
                });
            });
        }
示例#11
0
        private void HandleUser(ClientCommandContext ctx, IUser user)
        {
            HashSet <char> processed = new HashSet <char>();

            string modeSet = ctx.Arguments.FirstOrDefault();

            if (modeSet.Length < 2)
            {
                return;
            }

            Queue <char> chars = new Queue <char>(modeSet.ToArray());

            char mode = chars.Dequeue();

            if (mode != '+' && mode != '-')
            {
                return;
            }

            bool set = mode == '+';

            while (chars.TryDequeue(out mode))
            {
                if (processed.Contains(mode))
                {
                    continue;
                }
                processed.Add(mode);

                switch (mode)
                {
                case 'i':     // Invisible (appear offline)
                    Users.Update(user, status: set ? UserStatus.Offline : UserStatus.Online);
                    break;

                default:
                    ctx.Connection.SendReply(new UserModeUnknownFlagReply());
                    chars.Clear();
                    return;
                }
            }

            Sessions.CheckIRCSecure(user, isSecure => ctx.Connection.SendReply(new UserModeIsReply(user, isSecure)));
        }
示例#12
0
        public void HandleCommand(ClientCommandContext ctx)
        {
            if (ctx.Connection.HasAuthenticated)
            {
                ctx.Connection.SendReply(new AlreadyRegisteredReply());
                return;
            }

            string password = ctx.Arguments.FirstOrDefault();

            if (string.IsNullOrWhiteSpace(password))
            {
                ctx.Connection.SendReply(new NeedMoreParamsReply(NAME));
                return;
            }

            ctx.Connection.Password = password;
        }
示例#13
0
        public void HandleCommand(ClientCommandContext ctx)
        {
            string userName = ctx.Arguments.ElementAtOrDefault(0) ?? string.Empty;

            Users.GetUser(userName, user => {
                if (user == null)
                {
                    ctx.Connection.SendReply(new NoSuchNickReply(userName));
                    return;
                }

                string channelName = ctx.Arguments.ElementAtOrDefault(1) ?? string.Empty;
                if (string.IsNullOrWhiteSpace(channelName))
                {
                    ctx.Connection.SendReply(new NoSuchChannelReply(channelName));
                    return;
                }

                Channels.GetChannelByName(channelName, channel => {
                    if (channel == null)
                    {
                        ctx.Connection.SendReply(new NoSuchChannelReply(channelName));
                        return;
                    }

                    ChannelUsers.HasUser(channel, user, hasUser => {
                        if (!hasUser)
                        {
                            ctx.Connection.SendReply(new UserOnChannelReply(user, channel));
                            return;
                        }

                        // todo: dispatch invite
                    });
                });
            });
        }
示例#14
0
        public void HandleCommand(ClientCommandContext ctx)
        {
            IEnumerable <string> userNames = ctx.Arguments.Select(u => u.ToLowerInvariant());

            const int     max_length = 400; // allow for 112 characters of overhead
            int           length     = 0;
            List <string> batch      = new List <string>();

            void sendBatch()
            {
                if (length < 1)
                {
                    return;
                }
                ctx.Connection.SendReply(new IsOnReply(batch));
                length = 0;
                batch.Clear();
            };

            Users.GetUsers(u => (u.Status == UserStatus.Online || u.Status == UserStatus.Away) && userNames.Contains(u.GetIRCName()), users => {
                foreach (IUser user in users)
                {
                    string name    = user.GetIRCName();
                    int nameLength = name.Length + 1;

                    if (length + nameLength > max_length)
                    {
                        sendBatch();
                    }

                    length += nameLength;
                    batch.Add(name);
                }

                sendBatch();
            });
        }
示例#15
0
 public void HandleCommand(ClientCommandContext args)
 {
     // lists services, could be used for authentication but i think i'll just use the PASS field
     // not sure how i'm going to tackle auth entirely yet
 }
示例#16
0
 public void HandleCommand(ClientCommandContext args)
 {
     //
 }
示例#17
0
 public void HandleCommand(ClientCommandContext args)
 {
     // (un)silence people
 }
示例#18
0
 public void HandleCommand(ClientCommandContext ctx)
 {
     ctx.Connection.SendReply(new NoPrivilegesReply());
 }
示例#19
0
 public void HandleCommand(ClientCommandContext args)
 {
     // lists users in channel, probably
 }
示例#20
0
        public void HandleCommand(ClientCommandContext ctx)
        {
            if (ctx.Connection.HasAuthenticated)
            {
                ctx.Connection.SendReply(new AlreadyRegisteredReply());
                return;
            }

            // just drop subsequent calls
            if (ctx.Connection.IsAuthenticating)
            {
                return;
            }
            ctx.Connection.IsAuthenticating = true;

            string userName = ctx.Arguments.ElementAtOrDefault(0);
            string modeStr  = ctx.Arguments.ElementAtOrDefault(1);

            //string param3 = ctx.Arguments.ElementAtOrDefault(2);
            //string realName = ctx.Arguments.ElementAtOrDefault(3);

            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(modeStr))
            {
                ctx.Connection.SendReply(new NeedMoreParamsReply(NAME));
                return;
            }

            // TODO: should accept normal text username in the future!!!!
            if (!long.TryParse(userName, out long userId))
            {
                ctx.Connection.SendReply(new PasswordMismatchReply());
                ctx.Connection.Close();
                return;
            }

            if (!int.TryParse(modeStr, out int mode))
            {
                mode = 0;
            }

            bool isInvisible    = (mode & MODE_I) > 0;
            bool receiveWallOps = (mode & MODE_W) > 0;

            Action <Exception> exceptionHandler = new Action <Exception>(ex => {
                Logger.Debug($@"[{ctx.Connection}] Auth fail: {ex.Message}");
                ctx.Connection.SendReply(new PasswordMismatchReply());
                ctx.Connection.Close();
            });

            DataProvider.UserAuthClient.AttemptAuth(
                new UserAuthRequest(userId, ctx.Connection.Password, ctx.Connection.RemoteAddress),
                res => {
                ctx.Connection.Password         = null;
                ctx.Connection.HasAuthenticated = true;

                DataProvider.BanClient.CheckBan(res.UserId, ctx.Connection.RemoteAddress, ban => {
                    if (ban.IsPermanent || ban.Expires > DateTimeOffset.Now)
                    {
                        // should probably include the time

                        ctx.Connection.SendReply(new YouAreBannedReply(@"You have been banned."));
                        ctx.Connection.Close();
                        return;
                    }

                    Users.Connect(res, user => {
                        Sessions.HasAvailableSessions(user, available => {
                            // Enforce a maximum amount of connections per user
                            if (!available)
                            {
                                // map somethign to this
                                //ctx.Connection.SendPacket(new AuthFailPacket(AuthFailReason.MaxSessions));
                                ctx.Connection.Close();
                                return;
                            }

                            Sessions.Create(ctx.Connection, user, session => {
                                ctx.Connection.SendReply(new WelcomeReply(Server, user));
                                ctx.Connection.SendReply(new YourHostReply(Server));
                                ctx.Connection.SendReply(new CreatedReply(Context));
                                ctx.Connection.SendReply(new MyInfoReply(Server));
                                ctx.Connection.SendReply(new ISupportReply(Server));

                                if (WelcomeMessage.HasRandom)
                                {
                                    ctx.Connection.SendReply(new MotdStartReply());

                                    string line = WelcomeMessage.GetRandomString();
                                    if (!string.IsNullOrWhiteSpace(line))
                                    {
                                        ctx.Connection.SendReply(new MotdReply(line));
                                    }

                                    ctx.Connection.SendReply(new MotdEndReply());
                                }
                                else
                                {
                                    ctx.Connection.SendReply(new NoMotdReply());
                                }

                                // are these necessary?
                                ctx.Connection.SendReply(new ListUserClientReply());
                                ctx.Connection.SendReply(new ListUserOperatorsReply());
                                ctx.Connection.SendReply(new ListUserUnknownReply());
                                ctx.Connection.SendReply(new ListUserChannelsReply());
                                ctx.Connection.SendReply(new ListUserMeReply());

                                Channels.GetDefaultChannels(channels => {
                                    foreach (IChannel channel in channels)
                                    {
                                        ChannelUsers.JoinChannel(channel, session);
                                    }
                                });
                            });
                        });
                    });
                }, exceptionHandler);
            },
                exceptionHandler
                );
        }
示例#21
0
 public void HandleCommand(ClientCommandContext args)
 {
     // like privmsg but autoreplies should not be sent
     // should this be supported?
 }
示例#22
0
 public void HandleCommand(ClientCommandContext args)
 {
     // returns version info
 }
示例#23
0
 public void HandleCommand(ClientCommandContext args)
 {
     // kick a user from a channel
 }
示例#24
0
 public void HandleCommand(ClientCommandContext args)
 {
     // returns server user stats
 }
示例#25
0
 public void HandleCommand(ClientCommandContext args)
 {
     // return info about users
 }
示例#26
0
 public void HandleCommand(ClientCommandContext args)
 {
     // gets or sets a channel topic
 }
示例#27
0
 public void HandleCommand(ClientCommandContext args)
 {
     // returns information about users
 }
示例#28
0
 public void HandleCommand(ClientCommandContext args)
 {
     // returns the MOTD
 }
示例#29
0
 public void HandleCommand(ClientCommandContext args)
 {
     // returns the obituary of a deceased user
 }
示例#30
0
        public void HandleCommand(ClientCommandContext ctx)
        {
            string targetName = ctx.Arguments.ElementAtOrDefault(0);

            if (string.IsNullOrWhiteSpace(targetName))
            {
                ctx.Connection.SendReply(new NeedMoreParamsReply(NAME));
                return;
            }

            if (!ctx.Arguments.Any())
            {
                ctx.Connection.SendReply(new NeedMoreParamsReply(NAME));
                return;
            }

            if (targetName.StartsWith('#'))
            {
                Channels.GetChannelByIRCName(targetName, channel => {
                    if (channel == null)
                    {
                        ctx.Connection.SendReply(new NoSuchChannelReply(targetName));
                        return;
                    }

                    if (ctx.Arguments.Count() == 1)
                    {
                        //ctx.Connection.SendCommand(new ServerModeCommand(channel));
                        return;
                    }

                    // owner check

                    HandleChannel(ctx, channel);
                });
            }
            else
            {
                Users.GetUser(targetName, user => {
                    if (user == null)
                    {
                        ctx.Connection.SendReply(new NoSuchNickReply(targetName));
                        return;
                    }

                    if (ctx.Arguments.Count() == 1)
                    {
                        //Sessions.CheckIRCSecure(user, isSecure => ctx.Connection.SendCommand(new ServerModeCommand(user, isSecure)));
                        return;
                    }

                    if (!user.Equals(ctx.User))
                    {
                        // admin check probably
                        ctx.Connection.SendReply(new UsersDoNotMatchReply());
                        return;
                    }

                    HandleUser(ctx, user);
                });
            }
        }