<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Media.Media3D;

namespace IL2CDR.Model
{
    public enum EventType
    {
        Unknown = -1,
        MissionStart = 0,               //LET_MISSION_START 
        Hit = 1,                        //LET_HIT 
        Damage = 2,                     //LET_DAMAGE 
        Kill = 3,                       //LET_KILL 
        PlayerAmmo = 4,                 //LET_PLAYER_AMMO 
        TakeOff = 5,                    //LET_TAKEOFF 
        Landing = 6,                    //LET_LANDING 
        MissionEnd = 7,                 //LET_MISSION_END 
        ObjectiveCompleted = 8,         //LET_MISSION_OBJECT 
        AirfieldInfo = 9,               //LET_AIRFIELD 
        PlaneSpawn = 10,                //LET_CREATEPLANE 
        GroupInit = 11,                 //LET_GROUPINIT 
        GameObjectSpawn = 12,           //LET_GAMEOBJECTINVOLVED 
        InfluenceAreaInfo = 13,         //LET_INFLUENCEAREA_HEADER 
        InfluenceAreaBoundary = 14,     //LET_INFLUENCEAREA_BOUNDARY
        Version = 15,                   //LET_LOG_VERSION 
        BotPilotSpawn = 16,                  //TODO: check if that parachute spawn
        Position = 17,                  //LET_POSITION
        Join = 20,                      
        Leave = 21,                     
    }                                   

    public class MissionLogDataBuilder
    {
        private static Dictionary<EventType, Func<MissionLogEventHeader, object>> dataFactory = new Dictionary<EventType, Func<MissionLogEventHeader, object>>() {
            { EventType.MissionStart, (header) => {return new MissionLogEventStart(header);}},
            { EventType.Hit, (header) => {return new MissionLogEventHit(header);}},
            { EventType.Damage, (header) => {return new MissionLogEventDamage(header);}},
            { EventType.Kill, (header) => {return new MissionLogEventKill(header);}},
            { EventType.PlayerAmmo, (header) => {return new MissionLogEventPlayerAmmo(header);}},
            { EventType.TakeOff, (header) => {return new MissionLogEventTakeOff(header);}},
            { EventType.Landing, (header) => {return new MissionLogEventLanding(header);}},
            { EventType.MissionEnd, (header) => {return new MissionLogEventMissionEnd(header);}},
            { EventType.ObjectiveCompleted, (header) => {return new MissionLogEventObjectiveCompleted(header);}},
            { EventType.AirfieldInfo, (header) => {return new MissionLogEventAirfieldInfo(header);}},
            { EventType.PlaneSpawn, (header) => {return new MissionLogEventPlaneSpawn(header);}},
            { EventType.GroupInit, (header) => {return new MissionLogEventGroupInitInfo(header);}},
            { EventType.GameObjectSpawn, (header) => {return new MissionLogEventGameObjectSpawn(header);}},
            { EventType.InfluenceAreaInfo, (header) => {return new MissionLogEventInfluenceAreaInfo(header);}},
            { EventType.InfluenceAreaBoundary, (header) => {return new MissionLogEventInfluenceAreaBoundary(header);}},
            { EventType.Version, (header) => {return new MissionLogEventVersion(header);}},
            { EventType.Join, (header) => {return new MissionLogEventPlayerJoin(header);}},
            { EventType.Leave, (header) => {return new MissionLogEventPlayerLeave(header);}},
        };
        public static object GetData(string text, DateTime missionStartTime, int eventNumber, Server server)
        {
            var header = new MissionLogEventHeader(text, missionStartTime);
            header.Server = server;
            if (header.Type != EventType.Unknown )
            {
                header.EventID = GuidUtility.Create(GuidUtility.IsoOidNamespace, String.Concat(server.ServerId,"_",missionStartTime,"_",eventNumber));
                if (dataFactory.ContainsKey(header.Type))
                    return dataFactory[header.Type](header);
            }
            return null;
        }
    }
    public class MissionLogEventHeader
    {
        private string logLine;

        public EventType Type { get; set; }
        public uint Ticks { get; set; } // 1/50 of second
        public Server Server { get; set; }
        public Guid EventID { get; set; }
        public DateTime MissionStartTime { get; set; }
        public Dictionary<string, string> RawParameters { get; set; }

        public MissionLogEventHeader(MissionLogEventHeader header)
        {
            this.Server = header.Server;
            this.logLine = header.logLine;
            this.Type = header.Type;
            this.Ticks = header.Ticks;
            this.EventID = header.EventID;
            this.MissionStartTime = header.MissionStartTime;
            this.RawParameters = new Dictionary<string, string>(header.RawParameters);
        }
        public MissionLogEventHeader(string logLine, DateTime missionStartTime)
        {
            this.MissionStartTime = missionStartTime;
            this.logLine = logLine;
            Initialize(logLine);
        }
        private void Initialize(string logLine)
        {
            RawParameters = new Dictionary<string, string>();
            Type = EventType.Unknown;
            if( !String.IsNullOrWhiteSpace(logLine))
            {               
                //Parse space separated pairs of param:value and arrays like BC((x,y,z),..) 
                var matches = Regex.Matches(logLine, @"(\b\w+)[:]*(.*?(?=\s\w+:|$|\s\w+\())");

                if (matches.Count <= 0)
                    return;

                foreach( Match match in matches)
                    RawParameters.Add( match.Groups[1].Value, match.Groups[2].Value );

                int type = RawParameters.GetInt("AType");

                //TODO:Handle new ATypes here if EventType enum changed
                if((type >=0 && type <= 15) || type == 20 || type == 21)
                {
                    Type = (EventType)type;
                    Ticks = (uint)RawParameters.GetInt("T");
                }

            }
            else
            {<commit_msg>fix botpilotspawn<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Media.Media3D;

namespace IL2CDR.Model
{
    public enum EventType
    {
        Unknown = -1,
        MissionStart = 0,               //LET_MISSION_START 
        Hit = 1,                        //LET_HIT 
        Damage = 2,                     //LET_DAMAGE 
        Kill = 3,                       //LET_KILL 
        PlayerAmmo = 4,                 //LET_PLAYER_AMMO 
        TakeOff = 5,                    //LET_TAKEOFF 
        Landing = 6,                    //LET_LANDING 
        MissionEnd = 7,                 //LET_MISSION_END 
        ObjectiveCompleted = 8,         //LET_MISSION_OBJECT 
        AirfieldInfo = 9,               //LET_AIRFIELD 
        PlaneSpawn = 10,                //LET_CREATEPLANE 
        GroupInit = 11,                 //LET_GROUPINIT 
        GameObjectSpawn = 12,           //LET_GAMEOBJECTINVOLVED 
        InfluenceAreaInfo = 13,         //LET_INFLUENCEAREA_HEADER 
        InfluenceAreaBoundary = 14,     //LET_INFLUENCEAREA_BOUNDARY
        Version = 15,                   //LET_LOG_VERSION 
        BotPilotSpawn = 16,                  //TODO: check if that parachute spawn
        Position = 17,                  //LET_POSITION
        Join = 20,                      
        Leave = 21,                     
    }                                   

    public class MissionLogDataBuilder
    {
        private static Dictionary<EventType, Func<MissionLogEventHeader, object>> dataFactory = new Dictionary<EventType, Func<MissionLogEventHeader, object>>() {
            { EventType.MissionStart, (header) => {return new MissionLogEventStart(header);}},
            { EventType.Hit, (header) => {return new MissionLogEventHit(header);}},
            { EventType.Damage, (header) => {return new MissionLogEventDamage(header);}},
            { EventType.Kill, (header) => {return new MissionLogEventKill(header);}},
            { EventType.PlayerAmmo, (header) => {return new MissionLogEventPlayerAmmo(header);}},
            { EventType.TakeOff, (header) => {return new MissionLogEventTakeOff(header);}},
            { EventType.Landing, (header) => {return new MissionLogEventLanding(header);}},
            { EventType.MissionEnd, (header) => {return new MissionLogEventMissionEnd(header);}},
            { EventType.ObjectiveCompleted, (header) => {return new MissionLogEventObjectiveCompleted(header);}},
            { EventType.AirfieldInfo, (header) => {return new MissionLogEventAirfieldInfo(header);}},
            { EventType.PlaneSpawn, (header) => {return new MissionLogEventPlaneSpawn(header);}},
            { EventType.GroupInit, (header) => {return new MissionLogEventGroupInitInfo(header);}},
            { EventType.GameObjectSpawn, (header) => {return new MissionLogEventGameObjectSpawn(header);}},
            { EventType.InfluenceAreaInfo, (header) => {return new MissionLogEventInfluenceAreaInfo(header);}},
            { EventType.InfluenceAreaBoundary, (header) => {return new MissionLogEventInfluenceAreaBoundary(header);}},
            { EventType.Version, (header) => {return new MissionLogEventVersion(header);}},
            { EventType.BotPilotSpawn, (header) => {return new MissionLogBotSpawn(header);}},
            { EventType.Join, (header) => {return new MissionLogEventPlayerJoin(header);}},
            { EventType.Leave, (header) => {return new MissionLogEventPlayerLeave(header);}},
        };
        public static object GetData(string text, DateTime missionStartTime, int eventNumber, Server server)
        {
            var header = new MissionLogEventHeader(text, missionStartTime);
            header.Server = server;
            if (header.Type != EventType.Unknown )
            {
                header.EventID = GuidUtility.Create(GuidUtility.IsoOidNamespace, String.Concat(server.ServerId,"_",missionStartTime,"_",eventNumber));
                if (dataFactory.ContainsKey(header.Type))
                    return dataFactory[header.Type](header);
            }
            return null;
        }
    }
    public class MissionLogEventHeader
    {
        private string logLine;

        public EventType Type { get; set; }
        public uint Ticks { get; set; } // 1/50 of second
        public Server Server { get; set; }
        public Guid EventID { get; set; }
        public DateTime MissionStartTime { get; set; }
        public Dictionary<string, string> RawParameters { get; set; }

        public MissionLogEventHeader(MissionLogEventHeader header)
        {
            this.Server = header.Server;
            this.logLine = header.logLine;
            this.Type = header.Type;
            this.Ticks = header.Ticks;
            this.EventID = header.EventID;
            this.MissionStartTime = header.MissionStartTime;
            this.RawParameters = new Dictionary<string, string>(header.RawParameters);
        }
        public MissionLogEventHeader(string logLine, DateTime missionStartTime)
        {
            this.MissionStartTime = missionStartTime;
            this.logLine = logLine;
            Initialize(logLine);
        }
        private void Initialize(string logLine)
        {
            RawParameters = new Dictionary<string, string>();
            Type = EventType.Unknown;
            if( !String.IsNullOrWhiteSpace(logLine))
            {               
                //Parse space separated pairs of param:value and arrays like BC((x,y,z),..) 
                var matches = Regex.Matches(logLine, @"(\b\w+)[:]*(.*?(?=\s\w+:|$|\s\w+\())");

                if (matches.Count <= 0)
                    return;

                foreach( Match match in matches)
                    RawParameters.Add( match.Groups[1].Value, match.Groups[2].Value );

                int type = RawParameters.GetInt("AType");

                //TODO:Handle new ATypes here if EventType enum changed
                if((type >=0 && type <= 16) || type == 20 || type == 21)
                {
                    Type = (EventType)type;
                    Ticks = (uint)RawParameters.GetInt("T");
                }

            }
            else
            {
{'fraction_non_alphanumeric': 0.10601443464314354, 'fraction_numerical': 0.0073777064955894145, 'mean_word_length': 1.9371172868582196, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 56, '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': '4108710', 'n_tokens_mistral': 3432, 'n_tokens_neox': 3245, 'n_words': 702}