<commit_before>using System;
using System.Collections.Generic;
using System.Linq;

using ACE.Entity;
using ACE.Entity.Enum;
using ACE.Entity.Enum.Properties;
using ACE.Server.Managers;
using ACE.Server.Network.GameEvent.Events;
using ACE.Server.Network.GameMessages.Messages;
using ACE.Server.WorldObjects;

namespace ACE.Server.Entity
{
    public class Fellowship
    {
        /// <summary>
        /// The maximum # of fellowship members
        /// </summary>
        public static int MaxFellows = 9;

        public string FellowshipName;
        public uint FellowshipLeaderGuid;

        public bool ShareXP;    // XP sharing: 0=no, 1=yes
        public bool ShareLoot;  // Loot sharing: 0=no, 1=yes
        public bool EvenShare;  // XP equal sharing: 0=proportional to level, 1=even
        public bool Open;       // Open fellowship: 0=no, 1=yes

        public List<Player> FellowshipMembers = new List<Player>(MaxFellows);
        public List<Player> SharableMembers = new List<Player>(MaxFellows);

        private Dictionary<uint, DateTime> oldFellows = new Dictionary<uint, DateTime>();
        
        public Fellowship(Player leader, string fellowshipName, bool shareXP)
        {
            ShareXP = shareXP;

            // get loot sharing from leader's character options
            ShareLoot = leader.GetCharacterOption(CharacterOption.ShareFellowshipLoot);

            FellowshipLeaderGuid = leader.Guid.Full;
            FellowshipName = fellowshipName;
            EvenShare = false;

            FellowshipMembers = new List<Player> { leader };
            SharableMembers = new List<Player> { leader };

            Open = false;
        }

        public void AddFellowshipMember(Player inviter, Player newMember)
        {
            if (FellowshipMembers.Count == MaxFellows)
            {
                inviter.Session.Network.EnqueueSend(new GameMessageSystemChat("Fellowship is already full", ChatMessageType.Fellowship));
                return;
            }
            if (newMember.Fellowship != null)
            {
                inviter.Session.Network.EnqueueSend(new GameMessageSystemChat($"{newMember.Name} is already in a fellowship", ChatMessageType.Fellowship));
            }
            else
            {
                if (newMember.GetCharacterOption(CharacterOption.AutomaticallyAcceptFellowshipRequests))
                {
                    AddConfirmedMember(inviter, newMember, true);
                }
                else
                {
                    var confirm = new Confirmation(ConfirmationType.Fellowship, $"{inviter.Name} invites to you join a fellowship.", inviter, newMember);
                    ConfirmationManager.AddConfirmation(confirm);

                    newMember.Session.Network.EnqueueSend(new GameEventConfirmationRequest(newMember.Session, ConfirmationType.Fellowship,
                        confirm.ConfirmationID, confirm.Message));
                }
            }
        }

        public void AddConfirmedMember(Player inviter, Player player, bool response)
        {
            if (response)
            {
                if (FellowshipMembers.Count == 9)
                {
                    inviter.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} cannot join as fellowship is full", ChatMessageType.Fellowship));
                }
                else
                {
                    FellowshipMembers.Add(player);
                    CalculateXPSharing();
                    foreach (var member in FellowshipMembers)
                    {
                        inviter.Session.Network.EnqueueSend(new GameEventFellowshipUpdateFellow(inviter.Session, player, ShareXP));
                        //inviter.Session.Network.EnqueueSend(new GameEventFellowshipFellowUpdateDone(inviter.Session));
                    }
                    player.Fellowship = inviter.Fellowship;
                    SendMessageAndUpdate($"{player.Name} joined the fellowship");
                }
            }
            else
            {
                inviter.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} declines your invite", ChatMessageType.Fellowship));
            }
        }
        
        public void RemoveFellowshipMember(Player player)
        {
            foreach (var member in FellowshipMembers)
            {
                member.Session.Network.EnqueueSend(new GameEventFellowshipDismiss(member.Session, player));
                member.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} dismissed from fellowship", ChatMessageType.Fellowship));
            }
            FellowshipMembers.Remove(player);
            player.Fellowship = null;
            CalculateXPSharing();
            UpdateAllMembers();
        }

        private void UpdateAllMembers()
        {
            foreach (var member in FellowshipMembers)
            {
                member.Session.Network.EnqueueSend(new GameEventFellowshipFullUpdate(member.Session));
                //member.Session.Network.EnqueueSend(new GameEventFellowshipFellowUpdateDone(member.Session));
            }
        }

        private void SendMessageAndUpdate(string message)
        {
            foreach (var member in FellowshipMembers)
            {
                member.Session.Network.EnqueueSend(new GameMessageSystemChat(message, ChatMessageType.Fellowship));
                member.Session.Network.EnqueueSend(new GameEventFellowshipFullUpdate(member.Session));
                //member.Session.Network.EnqueueSend(new GameEventFellowshipFellowUpdateDone(member.Session));
            }
        }

        public void QuitFellowship(Player player, bool disband)
        {
            if (player.Guid.Full == FellowshipLeaderGuid)
            {
                if (disband)
                {
                    foreach (var member in FellowshipMembers)
                    {
                        member.Session.Network.EnqueueSend(new GameEventFellowshipQuit(member.Session, member.Guid.Full));
                        if (member.Guid.Full == FellowshipLeaderGuid)
                        {
                            member.Session.Network.EnqueueSend(new GameMessageSystemChat("You disband the fellowship", ChatMessageType.Fellowship));
                        }
                        else
                        {
                            member.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} disbanded the fellowship", ChatMessageType.Fellowship));
                            member.Fellowship = null;
                        }
                    }
                }
                else
                {                 
                    FellowshipMembers.Remove(player);
                    oldFellows.Add(player.Guid.Full, DateTime.Now);
                    player.Session.Network.EnqueueSend(new GameEventFellowshipQuit(player.Session, player.Guid.Full));
                    //member.Session.Network.EnqueueSend(new GameMessageFellowshipQuit(member.Session, player.Guid.Full));
                    AssignNewLeader(null);
                    CalculateXPSharing();
                    SendMessageAndUpdate($"{player.Name} left the fellowship");
                }
            }
            else
            {
                FellowshipMembers.Remove(player);
                oldFellows.Add(player.Guid.Full, DateTime.Now);
                player.Session.Network.EnqueueSend(new GameEventFellowshipQuit(player.Session, player.Guid.Full));
                CalculateXPSharing();
                SendMessageAndUpdate($"{player.Name} left the fellowship");
            }
        }

        public void AssignNewLeader(Player p)
        {<commit_msg>logging off while in fellowship (#1508)<commit_after>using System;
using System.Collections.Generic;
using System.Linq;

using ACE.Entity;
using ACE.Entity.Enum;
using ACE.Entity.Enum.Properties;
using ACE.Server.Managers;
using ACE.Server.Network.GameEvent.Events;
using ACE.Server.Network.GameMessages.Messages;
using ACE.Server.WorldObjects;

namespace ACE.Server.Entity
{
    public class Fellowship
    {
        /// <summary>
        /// The maximum # of fellowship members
        /// </summary>
        public static int MaxFellows = 9;

        public string FellowshipName;
        public uint FellowshipLeaderGuid;

        public bool ShareXP;    // XP sharing: 0=no, 1=yes
        public bool ShareLoot;  // Loot sharing: 0=no, 1=yes
        public bool EvenShare;  // XP equal sharing: 0=proportional to level, 1=even
        public bool Open;       // Open fellowship: 0=no, 1=yes

        public List<Player> FellowshipMembers = new List<Player>(MaxFellows);
        public List<Player> SharableMembers = new List<Player>(MaxFellows);

        private Dictionary<uint, DateTime> oldFellows = new Dictionary<uint, DateTime>();
        
        public Fellowship(Player leader, string fellowshipName, bool shareXP)
        {
            ShareXP = shareXP;

            // get loot sharing from leader's character options
            ShareLoot = leader.GetCharacterOption(CharacterOption.ShareFellowshipLoot);

            FellowshipLeaderGuid = leader.Guid.Full;
            FellowshipName = fellowshipName;
            EvenShare = false;

            FellowshipMembers = new List<Player> { leader };
            SharableMembers = new List<Player> { leader };

            Open = false;
        }

        public void AddFellowshipMember(Player inviter, Player newMember)
        {
            if (FellowshipMembers.Count == MaxFellows)
            {
                inviter.Session.Network.EnqueueSend(new GameMessageSystemChat("Fellowship is already full", ChatMessageType.Fellowship));
                return;
            }
            if (newMember.Fellowship != null)
            {
                inviter.Session.Network.EnqueueSend(new GameMessageSystemChat($"{newMember.Name} is already in a fellowship", ChatMessageType.Fellowship));
            }
            else
            {
                if (newMember.GetCharacterOption(CharacterOption.AutomaticallyAcceptFellowshipRequests))
                {
                    AddConfirmedMember(inviter, newMember, true);
                }
                else
                {
                    var confirm = new Confirmation(ConfirmationType.Fellowship, $"{inviter.Name} invites to you join a fellowship.", inviter, newMember);
                    ConfirmationManager.AddConfirmation(confirm);

                    newMember.Session.Network.EnqueueSend(new GameEventConfirmationRequest(newMember.Session, ConfirmationType.Fellowship,
                        confirm.ConfirmationID, confirm.Message));
                }
            }
        }

        public void AddConfirmedMember(Player inviter, Player player, bool response)
        {
            if (response)
            {
                if (FellowshipMembers.Count == 9)
                {
                    inviter.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} cannot join as fellowship is full", ChatMessageType.Fellowship));
                }
                else
                {
                    FellowshipMembers.Add(player);
                    CalculateXPSharing();
                    foreach (var member in FellowshipMembers)
                    {
                        inviter.Session.Network.EnqueueSend(new GameEventFellowshipUpdateFellow(inviter.Session, player, ShareXP));
                        //inviter.Session.Network.EnqueueSend(new GameEventFellowshipFellowUpdateDone(inviter.Session));
                    }
                    player.Fellowship = inviter.Fellowship;
                    SendMessageAndUpdate($"{player.Name} joined the fellowship");
                }
            }
            else
            {
                inviter.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} declines your invite", ChatMessageType.Fellowship));
            }
        }
        
        public void RemoveFellowshipMember(Player player)
        {
            foreach (var member in FellowshipMembers)
            {
                member.Session.Network.EnqueueSend(new GameEventFellowshipDismiss(member.Session, player));
                member.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} dismissed from fellowship", ChatMessageType.Fellowship));
            }
            FellowshipMembers.Remove(player);
            player.Fellowship = null;
            CalculateXPSharing();
            UpdateAllMembers();
        }

        private void UpdateAllMembers()
        {
            foreach (var member in FellowshipMembers)
            {
                member.Session.Network.EnqueueSend(new GameEventFellowshipFullUpdate(member.Session));
                //member.Session.Network.EnqueueSend(new GameEventFellowshipFellowUpdateDone(member.Session));
            }
        }

        private void SendMessageAndUpdate(string message)
        {
            foreach (var member in FellowshipMembers)
            {
                member.Session.Network.EnqueueSend(new GameMessageSystemChat(message, ChatMessageType.Fellowship));
                member.Session.Network.EnqueueSend(new GameEventFellowshipFullUpdate(member.Session));
                //member.Session.Network.EnqueueSend(new GameEventFellowshipFellowUpdateDone(member.Session));
            }
        }

        public void QuitFellowship(Player player, bool disband)
        {
            if (player.Guid.Full == FellowshipLeaderGuid)
            {
                if (disband)
                {
                    foreach (var member in FellowshipMembers)
                    {
                        member.Session.Network.EnqueueSend(new GameEventFellowshipQuit(member.Session, member.Guid.Full));
                        if (member.Guid.Full == FellowshipLeaderGuid)
                        {
                            member.Session.Network.EnqueueSend(new GameMessageSystemChat("You disband the fellowship", ChatMessageType.Fellowship));
                        }
                        else
                        {
                            member.Session.Network.EnqueueSend(new GameMessageSystemChat($"{player.Name} disbanded the fellowship", ChatMessageType.Fellowship));
                            member.Fellowship = null;
                        }
                    }
                }
                else
                {                 
                    FellowshipMembers.Remove(player);
                    oldFellows.TryAdd(player.Guid.Full, DateTime.Now);
                    player.Session.Network.EnqueueSend(new GameEventFellowshipQuit(player.Session, player.Guid.Full));
                    //member.Session.Network.EnqueueSend(new GameMessageFellowshipQuit(member.Session, player.Guid.Full));
                    AssignNewLeader(null);
                    CalculateXPSharing();
                    SendMessageAndUpdate($"{player.Name} left the fellowship");
                }
            }
            else
            {
                FellowshipMembers.Remove(player);
                oldFellows.TryAdd(player.Guid.Full, DateTime.Now);
                player.Session.Network.EnqueueSend(new GameEventFellowshipQuit(player.Session, player.Guid.Full));
                CalculateXPSharing();
                SendMessageAndUpdate($"{player.Name} left the fellowship");
            }
        }

        public void AssignNewLeader(Player p)
        {
{'fraction_non_alphanumeric': 0.08144475920679886, 'fraction_numerical': 0.001545197012619109, 'mean_word_length': 1.7678189593727727, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6121215', 'n_tokens_mistral': 3919, 'n_tokens_neox': 3641, 'n_words': 701}