Example #1
0
        public async Task BecomeGodfather(IUser actor, IUserShim targetShim)
        {
            var target = await targetShim.Load();

            using (var context = await ContextProvider.Connect())
                using (var transact = context.Database.BeginTransaction(IsolationLevel.Serializable))
                {
                    var godfather = await context.Users.Include(u => u.Membership).SingleAsync(u => u.Id == actor.UserId);

                    // if godfather is not a real member, this method call was super duper obsolete
                    if (godfather.Membership == null)
                    {
                        return;
                    }

                    var guest = await context.Users.Include(u => u.Membership).Include(u => u.GuestInvite)
                                .Include(u => u.PersistentGuest.Godfathers).SingleAsync(u => u.Id == target.UserId);

                    if (guest.PersistentGuest == null)
                    {
                        // only guests can be promoted to persistentguests
                        if (guest.GuestInvite == null)
                        {
                            return;
                        }

                        guest.PersistentGuest = new PersistentGuest
                        {
                            OriginalInvite = guest.GuestInvite,
                        };
                        guest.GuestInvite = null;

                        CertificateCredentials creds;
                        if (Fancyauth.GuestCredentials.TryGetValue(target.UserId, out creds))
                        {
                            guest.CertCredentials.Add(creds);
                        }
                        else
                        {
                            await actor.SendMessage("No certificate found.");

                            return;
                        }
                    }

                    // ignore the nop case
                    if (guest.PersistentGuest.Godfathers.Contains(godfather.Membership))
                    {
                        return;
                    }

                    guest.PersistentGuest.Godfathers.Add(godfather.Membership);

                    await context.SaveChangesAsync();

                    transact.Commit();
                }

            await target.SendMessage("Irgendwann - möglicherweise aber auch nie - werde ich dich bitten, mir eine kleine Gefälligkeit zu erweisen.");
        }
Example #2
0
        public async Task Integrate(IUser actor, IUserShim targetShim)
        {
            var target = await targetShim.Load();

            using (var context = await ContextProvider.Connect())
                using (var transact = context.Database.BeginTransaction(IsolationLevel.Serializable))
                {
                    var targetEntity = await context.Users.Include(x => x.Membership).Include(x => x.PersistentGuest)
                                       .Include(x => x.GuestInvite).SingleAsync(x => x.Id == target.UserId);

                    var actorEntity = await context.Users.Include(x => x.Membership).Include(x => x.PersistentGuest)
                                      .Include(x => x.GuestInvite).Include(x => x.CertCredentials)
                                      .SingleAsync(x => x.Id == actor.UserId);

                    // reqiurements:
                    // * a member
                    // * targets a non-member
                    // * specifically, a non-persistent guest
                    if ((targetEntity.Membership != null) || (targetEntity.PersistentGuest != null) || (actorEntity.Membership == null))
                    {
                        await actor.SendMessage("Integration denied.");

                        return;
                    }

                    CertificateCredentials creds;
                    if (Fancyauth.GuestCredentials.TryGetValue(target.UserId, out creds))
                    {
                        actorEntity.CertCredentials.Add(creds);
                    }
                    else
                    {
                        await actor.SendMessage("No certificate found.");

                        return;
                    }

                    await context.SaveChangesAsync();

                    transact.Commit();
                }

            await targetShim.Kick("You have been integrated into " + actor.Name);
        }
Example #3
0
        public async Task RudeUser(IUser actor, IUserShim targetShim)
        {
            var bytes = new byte[4];

            SecureRng.GetBytes(bytes);
            int seed = BitConverter.ToInt32(bytes, 0);
            var rng  = new Random(seed);

            var target = await targetShim.Load();

            // TODO: Remove this check when guests have UserIds
            if (target.UserId <= 0 || actor.UserId <= 0)
            {
                return;
            }

            var rudeEntity = new RudeEntity
            {
                Id             = -1,
                ActorId        = actor.UserId,
                TargetId       = target.UserId,
                ActualTargetId = null,
                Timestamp      = DateTimeOffset.Now,
            };
            int targetInRudes;
            // if the actor ruded himself, he won't be kicked
            bool kick = false;

            lock (Rudes)
            {
                var oneYear           = DateTimeOffset.Now.AddYears(-1);
                var actorOutRudeQuery = Rudes
                                        // get all rudes which actor has done
                                        .Where(r => r.ActorId == actor.UserId)
                                        // and where he didn't rude himself by ruding too often
                                        .Where(r => r.ActualTargetId == null);

                // if actor rudes himself or has already ruded in last Minute
                bool punishActor = actorOutRudeQuery
                                   // take all rudes, where the actor hasn't kicked someone
                                   //  (kicking by ruding does not have a cooldown)
                                   .Where(r => r.Duration != null)
                                   // test, if the actor has ruded anyone in last minute
                                   .Any(r => r.Timestamp > DateTime.Now.AddMinutes(-1));

                // if actor already ruded in last minute, he will be ruded instead of target
                if (punishActor)
                {
                    rudeEntity.ActualTargetId = rudeEntity.TargetId;
                    rudeEntity.TargetId       = actor.UserId;
                    // he will be the new target
                    target = actor;
                }

                // get active rudes on target and add current rude
                targetInRudes = GetActiveInRudes(target.UserId).Count() + 1;
                if (targetInRudes > PREFIXES.Length && !punishActor)
                {
                    kick = true;
                    rudeEntity.Duration = null;
                }
                else
                {
                    var actorOutRudes = actorOutRudeQuery.Count();
                    var medianQuery   =
                        from r in Rudes
                        where r.Timestamp > oneYear
                        group Math.Log((r.Timestamp - oneYear).TotalMinutes) by r.ActorId into g
                        select g.Sum();

                    var median = medianQuery.Median();

                    double durationFactor = actorOutRudes == 0 ? 2 : median.Value / actorOutRudes;
                    durationFactor  = Math.Max(durationFactor, 0.25);
                    durationFactor  = Math.Min(durationFactor, 2);
                    durationFactor *= rng.NextDouble() * targetInRudes;
                    var duration = TimeSpan.FromHours(durationFactor * 2).Ticks;
                    rudeEntity.Duration = TimeSpan.FromTicks(Math.Min(duration, TimeSpan.FromDays(1).Ticks));
                }

                // add rude
                Rudes.Add(rudeEntity);
            }

            if (kick)
            {
                await target.Kick(REASONS[rng.Next(REASONS.Length)]);
            }
            else
            {
                target.Name = GetUsername(target.Name, targetInRudes, GetReudigLevel(target.UserId));
                await target.SaveChanges();
            }
            await actor.SendMessage("Ruded with: " + rudeEntity.Duration);
        }