<commit_before>﻿using _7DTDManager.Interfaces;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace _7DTDManager.LineHandlers
{
    public class lineListLandProtection : BaseLineHandler,ICalloutCallback
    {
        static Logger logger = LogManager.GetCurrentClassLogger();
        static Regex rgLLPStart = new Regex("Player \"(?<name>.*) \\((?<steamid>[0-9]+)\\)\" owns (?<keystones>[0-9]+) keystones.*");
        static Regex rgLLPLine = new Regex("   \\((?<pos>.*)\\)");
        static Regex rgLLPEnd = new Regex("Total of (?<numstones>[0-9]+) keystones in the game");

        private IPlayer currentPlayer = null;
        private List<IAreaDefiniton> found = null;
        bool IsFirst = true;
        
        int countStones = 0;

        public override bool ProcessLine(IServerConnection serverConnection, string currentLine)
        {
            if (rgLLPStart.IsMatch(currentLine)) // Start of ListLandProtections deteced
            {
                PriorityProcess = true;

                if (IsFirst)
                {
                    countStones = 0;
                    found = new List<IAreaDefiniton>();  
                }
                
                Match match = rgLLPStart.Match(currentLine);
                GroupCollection groups = match.Groups;

                IPlayer p = serverConnection.AllPlayers.FindPlayerBySteamID(groups["steamid"].Value);
                currentPlayer = p;
                
                if (p != null)
                {
                    logger.Debug("Parsing LandProtections of {0}", p.Name);                                      
                }
                else
                {
                    logger.Debug("Player {0} unknown! {1}", groups["name"].Value,currentLine);
                }
                IsFirst = false;
                return true;
            }
            if (rgLLPLine.IsMatch(currentLine))
            {
                Match match = rgLLPLine.Match(currentLine);
                GroupCollection groups = match.Groups;
                IPosition newLP = serverConnection.CreatePosition(groups["pos"].Value);
                if ( (newLP != null) && (currentPlayer != null))
                {
                    
                    IAreaDefiniton protection = (from p in currentPlayer.LandProtections.Items where p.Center.Equals(newLP) select p).FirstOrDefault();
                    if (protection == null)
                    {
                        protection = serverConnection.CreateArea(currentPlayer,newLP,10.0);
                        currentPlayer.LandProtections.Add(protection);                        
                    }
                    found.Add(protection);
                    countStones++;
                }
                return true;
            }
            if (rgLLPEnd.IsMatch(currentLine))
            {
                Match match = rgLLPEnd.Match(currentLine);
                GroupCollection groups = match.Groups;

                PriorityProcess = false;
                IsFirst = true;
                int targetNum = Int32.Parse(groups["numstones"].Value);
                if (countStones != targetNum)
                {
                    logger.Warn("Number mismatch in ListLandProtection! {0} != {1}",targetNum,countStones);
                }
                logger.Info("LandProtection Parsing done.");                
                CleanupProtections(serverConnection);
                serverConnection.AllPlayers.Save(true);
                return true;
            }
            return false;
        }

        private void CleanupProtections(IServerConnection server)
        {
            foreach (var checkPlayer in server.AllPlayers.Players)
            {
                IAreaDefiniton[] oldList = checkPlayer.LandProtections.Items.ToArray();
                foreach (var item in oldList)
                {
                    IAreaDefiniton protection = (from p in found where p.Center == item.Center select p).FirstOrDefault();
                    if (protection == null)
                    {
                        logger.Info("KeyStone {0} ({1}) destroyed ({2})", item.Identifier, item.Center.ToString(), checkPlayer.Name);
                        item.OnDestroy();
                        currentPlayer.LandProtections.Remove(item); //TODO: Does not remove item?
                    }
                }
                
            }
        }
       

        public bool CalloutCallback(ICallout c, IServerConnection serverConnection)
        {<commit_msg>Fixes NullReferenceException in LLP<commit_after>﻿using _7DTDManager.Interfaces;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace _7DTDManager.LineHandlers
{
    public class lineListLandProtection : BaseLineHandler,ICalloutCallback
    {
        static Logger logger = LogManager.GetCurrentClassLogger();
        static Regex rgLLPStart = new Regex("Player \"(?<name>.*) \\((?<steamid>[0-9]+)\\)\" owns (?<keystones>[0-9]+) keystones.*");
        static Regex rgLLPLine = new Regex("   \\((?<pos>.*)\\)");
        static Regex rgLLPEnd = new Regex("Total of (?<numstones>[0-9]+) keystones in the game");

        private IPlayer currentPlayer = null;
        private List<IAreaDefiniton> found = null;
        bool IsFirst = true;
        
        int countStones = 0;

        public override bool ProcessLine(IServerConnection serverConnection, string currentLine)
        {
            if (rgLLPStart.IsMatch(currentLine)) // Start of ListLandProtections deteced
            {
                PriorityProcess = true;

                if (IsFirst)
                {
                    countStones = 0;
                    found = new List<IAreaDefiniton>();  
                }
                
                Match match = rgLLPStart.Match(currentLine);
                GroupCollection groups = match.Groups;

                IPlayer p = serverConnection.AllPlayers.FindPlayerBySteamID(groups["steamid"].Value);
                currentPlayer = p;
                
                if (p != null)
                {
                    logger.Debug("Parsing LandProtections of {0}", p.Name);                                      
                }
                else
                {
                    logger.Debug("Player {0} unknown! {1}", groups["name"].Value,currentLine);
                }
                IsFirst = false;
                return true;
            }
            if (rgLLPLine.IsMatch(currentLine))
            {
                Match match = rgLLPLine.Match(currentLine);
                GroupCollection groups = match.Groups;
                IPosition newLP = serverConnection.CreatePosition(groups["pos"].Value);
                if ( (newLP != null) && (currentPlayer != null))
                {
                    
                    IAreaDefiniton protection = (from p in currentPlayer.LandProtections.Items where p.Center.Equals(newLP) select p).FirstOrDefault();
                    if (protection == null)
                    {
                        protection = serverConnection.CreateArea(currentPlayer,newLP,10.0);
                        currentPlayer.LandProtections.Add(protection);                        
                    }
                    found.Add(protection);
                    countStones++;
                }
                return true;
            }
            if (rgLLPEnd.IsMatch(currentLine))
            {
                Match match = rgLLPEnd.Match(currentLine);
                GroupCollection groups = match.Groups;

                PriorityProcess = false;
                IsFirst = true;
                int targetNum = Int32.Parse(groups["numstones"].Value);
                if (countStones != targetNum)
                {
                    logger.Warn("Number mismatch in ListLandProtection! {0} != {1}",targetNum,countStones);
                }
                logger.Info("LandProtection Parsing done.");                
                CleanupProtections(serverConnection);
                serverConnection.AllPlayers.Save(true);
                return true;
            }
            return false;
        }

        private void CleanupProtections(IServerConnection server)
        {
            foreach (var checkPlayer in server.AllPlayers.Players)
            {
                IAreaDefiniton[] oldList = checkPlayer.LandProtections.Items.ToArray();
                foreach (var item in oldList)
                {
                    IAreaDefiniton protection = (from p in found where p.Center == item.Center select p).FirstOrDefault();
                    if (protection == null)
                    {
                        logger.Info("KeyStone {0} ({1}) destroyed ({2})", item.Identifier, item.Center.ToString(), checkPlayer.Name);
                        item.OnDestroy();
                        checkPlayer.LandProtections.Remove(item); //TODO: Does not remove item?
                    }
                }
                
            }
        }
       

        public bool CalloutCallback(ICallout c, IServerConnection serverConnection)
        {
{'fraction_non_alphanumeric': 0.09307312888698263, 'fraction_numerical': 0.004932446922582029, 'mean_word_length': 1.444182389937107, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4938719', 'n_tokens_mistral': 2382, 'n_tokens_neox': 2174, 'n_words': 481}