Esempio n. 1
0
        public void LogFileReplay()
        {
            var mgr = A.Fake <IManager>();

            A.CallTo(() => mgr.GetLogger(A <long> .Ignored)).Returns(logger);

            var server = new IW4MServer(mgr,
                                        new SharedLibraryCore.Configuration.ServerConfiguration()
            {
                IPAddress = "127.0.0.1", Port = 28960
            },
                                        A.Fake <ITranslationLookup>(), A.Fake <IRConConnectionFactory>(), A.Fake <IGameLogReaderFactory>(), A.Fake <IMetaService>());

            var parser = new BaseEventParser(A.Fake <IParserRegexFactory>(), A.Fake <ILogger>(), A.Fake <ApplicationConfiguration>());

            parser.Configuration.GuidNumberStyle = System.Globalization.NumberStyles.Integer;

            var  log         = System.IO.File.ReadAllLines("Files\\T6Game.log");
            long lastEventId = 0;

            foreach (string line in log)
            {
                var e = parser.GenerateGameEvent(line);
                server.Logger.WriteInfo($"{e.GameTime}");
                if (e.Origin != null)
                {
                    e.Origin.CurrentServer = server;
                }

                server.ExecuteEvent(e).Wait();
                lastEventId = e.Id;
            }

            Assert.GreaterOrEqual(lastEventId, log.Length);
        }
 public GameLogEventDetection(ILogger <GameLogEventDetection> logger, IW4MServer server, Uri[] gameLogUris, IGameLogReaderFactory gameLogReaderFactory)
 {
     _reader     = gameLogReaderFactory.CreateGameLogReader(gameLogUris, server.EventParser);
     _server     = server;
     _ignoreBots = server?.Manager.GetApplicationSettings().Configuration().IgnoreBots ?? false;
     _logger     = logger;
 }
Esempio n. 3
0
        public void GameTimeFalseQuitTest()
        {
            var mgr    = A.Fake <IManager>();
            var server = new IW4MServer(mgr,
                                        new SharedLibraryCore.Configuration.ServerConfiguration()
            {
                IPAddress = "127.0.0.1", Port = 28960
            },
                                        A.Fake <ITranslationLookup>(), A.Fake <IRConConnectionFactory>(), A.Fake <IGameLogReaderFactory>(), A.Fake <IMetaService>());

            var parser = new BaseEventParser(A.Fake <IParserRegexFactory>(), A.Fake <ILogger>(), A.Fake <ApplicationConfiguration>());

            parser.Configuration.GuidNumberStyle = System.Globalization.NumberStyles.Integer;

            var log = System.IO.File.ReadAllLines("Files\\T6MapRotation.log");

            foreach (string line in log)
            {
                var e = parser.GenerateGameEvent(line);
                if (e.Origin != null)
                {
                    e.Origin.CurrentServer = server;
                }

                server.ExecuteEvent(e).Wait();
            }
        }
Esempio n. 4
0
        public void Test_GenerateLogPath_Basic()
        {
            string expected = "C:\\Game\\main\\log.log";
            var    info     = new LogPathGeneratorInfo()
            {
                BasePathDirectory = "C:\\Game",
                GameDirectory     = "main",
                LogFile           = "log.log"
            };
            string generated = IW4MServer.GenerateLogPath(info);

            Assert.AreEqual(expected, generated);
        }
Esempio n. 5
0
        public void Test_GenerateLogPath_FixWineDriveMangling()
        {
            string expected = "/opt/server/game/log.log";
            var    info     = new LogPathGeneratorInfo()
            {
                BasePathDirectory = "Z:\\opt\\server",
                GameDirectory     = "game",
                LogFile           = "log.log",
                IsWindows         = false
            };
            string generated = IW4MServer.GenerateLogPath(info).Replace('\\', '/');

            Assert.AreEqual(expected, generated);
        }
Esempio n. 6
0
        public void Test_GenerateLogPath_WithBaseGameAndMod()
        {
            string expected = "C:\\GameAlt\\mods\\mod\\log.log";
            var    info     = new LogPathGeneratorInfo()
            {
                BaseGameDirectory = "C:\\GameAlt",
                BasePathDirectory = "C:\\Game",
                GameDirectory     = "main",
                ModDirectory      = "mods\\mod",
                LogFile           = "log.log"
            };
            string generated = IW4MServer.GenerateLogPath(info);

            Assert.AreEqual(expected, generated);
        }
Esempio n. 7
0
        public void Setup()
        {
            serviceProvider = new ServiceCollection()
                              .BuildBase()
                              .AddSingleton <ActionController>()
                              .AddSingleton <IManagerCommand, BanCommand>()
                              .AddSingleton <IManagerCommand, TempBanCommand>()
                              .AddSingleton <IManagerCommand, UnbanCommand>()
                              .AddSingleton <IManagerCommand, KickCommand>()
                              .AddSingleton <IManagerCommand, FlagClientCommand>()
                              .AddSingleton <IManagerCommand, UnflagClientCommand>()
                              .AddSingleton <IManagerCommand, SayCommand>()
                              .AddSingleton <IManagerCommand, SetLevelCommand>()
                              .BuildServiceProvider()
                              .SetupTestHooks();

            contextFactory = serviceProvider.GetRequiredService <IDatabaseContextFactory>();
            server         = serviceProvider.GetRequiredService <IW4MServer>();
            manager        = serviceProvider.GetRequiredService <IManager>();
            A.CallTo(() => manager.GetServers())
            .Returns(new[] { server });
            A.CallTo(() => manager.GetActiveClients())
            .Returns(new[] { ClientGenerators.CreateBasicClient(server) });
        }
Esempio n. 8
0
        public async Task Init()
        {
            #region DATABASE
            var ipList = (await ClientSvc.Find(c => c.Level > Player.Permission.Trusted))
                         .Select(c => new
            {
                c.Password,
                c.PasswordSalt,
                c.ClientId,
                c.Level,
                c.Name
            });

            foreach (var a in ipList)
            {
                try
                {
                    PrivilegedClients.Add(a.ClientId, new Player()
                    {
                        Name         = a.Name,
                        ClientId     = a.ClientId,
                        Level        = a.Level,
                        PasswordSalt = a.PasswordSalt,
                        Password     = a.Password
                    });
                }

                catch (ArgumentException)
                {
                    continue;
                }
            }
            #endregion

            #region CONFIG
            var config = ConfigHandler.Configuration();

            // copy over default config if it doesn't exist
            if (config == null)
            {
                var defaultConfig = new BaseConfigurationHandler <DefaultConfiguration>("DefaultSettings").Configuration();
                ConfigHandler.Set((ApplicationConfiguration) new ApplicationConfiguration().Generate());
                var newConfig = ConfigHandler.Configuration();

                newConfig.AutoMessagePeriod = defaultConfig.AutoMessagePeriod;
                newConfig.AutoMessages      = defaultConfig.AutoMessages;
                newConfig.GlobalRules       = defaultConfig.GlobalRules;
                newConfig.Maps = defaultConfig.Maps;

                if (newConfig.Servers == null)
                {
                    ConfigHandler.Set(newConfig);
                    newConfig.Servers = new List <ServerConfiguration>();

                    do
                    {
                        newConfig.Servers.Add((ServerConfiguration) new ServerConfiguration().Generate());
                    } while (Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationSet["SETUP_SERVER_SAVE"]));

                    config = newConfig;
                    await ConfigHandler.Save();
                }
            }

            else if (config != null)
            {
                if (string.IsNullOrEmpty(config.Id))
                {
                    config.Id = Guid.NewGuid().ToString();
                    await ConfigHandler.Save();
                }

                if (string.IsNullOrEmpty(config.WebfrontBindUrl))
                {
                    config.WebfrontBindUrl = "http://127.0.0.1:1624";
                    await ConfigHandler.Save();
                }
            }

            else if (config.Servers.Count == 0)
            {
                throw new ServerException("A server configuration in IW4MAdminSettings.json is invalid");
            }

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            Utilities.EncodingType = Encoding.GetEncoding(!string.IsNullOrEmpty(config.CustomParserEncoding) ? config.CustomParserEncoding : "windows-1252");

            #endregion
            #region PLUGINS
            SharedLibraryCore.Plugins.PluginImporter.Load(this);

            foreach (var Plugin in SharedLibraryCore.Plugins.PluginImporter.ActivePlugins)
            {
                try
                {
                    await Plugin.OnLoadAsync(this);
                }

                catch (Exception e)
                {
                    Logger.WriteError($"An error occured loading plugin {Plugin.Name}");
                    Logger.WriteDebug($"Exception: {e.Message}");
                    Logger.WriteDebug($"Stack Trace: {e.StackTrace}");
                }
            }
            #endregion

            #region COMMANDS
            if (ClientSvc.GetOwners().Result.Count == 0)
            {
                Commands.Add(new COwner());
            }

            Commands.Add(new CQuit());
            Commands.Add(new CKick());
            Commands.Add(new CSay());
            Commands.Add(new CTempBan());
            Commands.Add(new CBan());
            Commands.Add(new CWhoAmI());
            Commands.Add(new CList());
            Commands.Add(new CHelp());
            Commands.Add(new CFastRestart());
            Commands.Add(new CMapRotate());
            Commands.Add(new CSetLevel());
            Commands.Add(new CUsage());
            Commands.Add(new CUptime());
            Commands.Add(new CWarn());
            Commands.Add(new CWarnClear());
            Commands.Add(new CUnban());
            Commands.Add(new CListAdmins());
            Commands.Add(new CLoadMap());
            Commands.Add(new CFindPlayer());
            Commands.Add(new CListRules());
            Commands.Add(new CPrivateMessage());
            Commands.Add(new CFlag());
            Commands.Add(new CReport());
            Commands.Add(new CListReports());
            Commands.Add(new CListBanInfo());
            Commands.Add(new CListAlias());
            Commands.Add(new CExecuteRCON());
            Commands.Add(new CPlugins());
            Commands.Add(new CIP());
            Commands.Add(new CMask());
            Commands.Add(new CPruneAdmins());
            Commands.Add(new CKillServer());
            Commands.Add(new CSetPassword());
            Commands.Add(new CPing());

            foreach (Command C in SharedLibraryCore.Plugins.PluginImporter.ActiveCommands)
            {
                Commands.Add(C);
            }
            #endregion

            #region INIT
            async Task Init(ServerConfiguration Conf)
            {
                try
                {
                    var ServerInstance = new IW4MServer(this, Conf);
                    await ServerInstance.Initialize();

                    lock (_servers)
                    {
                        _servers.Add(ServerInstance);
                    }

                    Logger.WriteVerbose($"Now monitoring {ServerInstance.Hostname}");

                    // this way we can keep track of execution time and see if problems arise.
                    var Status = new AsyncStatus(ServerInstance, UPDATE_FREQUENCY);
                    lock (TaskStatuses)
                    {
                        TaskStatuses.Add(Status);
                    }
                }

                catch (ServerException e)
                {
                    Logger.WriteError($"Not monitoring server {Conf.IPAddress}:{Conf.Port} due to uncorrectable errors");
                    if (e.GetType() == typeof(DvarException))
                    {
                        Logger.WriteDebug($"Could not get the dvar value for {(e as DvarException).Data["dvar_name"]} (ensure the server has a map loaded)");
                    }
                    else if (e.GetType() == typeof(NetworkException))
                    {
                        Logger.WriteDebug(e.Message);
                    }

                    // throw the exception to the main method to stop before instantly exiting
                    throw e;
                }
            }

            await Task.WhenAll(config.Servers.Select(c => Init(c)).ToArray());

            #endregion

            Running = true;
        }
Esempio n. 9
0
        public async Task Init()
        {
            Running           = true;
            ExternalIPAddress = await Utilities.GetExternalIP();

            #region PLUGINS
            SharedLibraryCore.Plugins.PluginImporter.Load(this);

            foreach (var Plugin in SharedLibraryCore.Plugins.PluginImporter.ActivePlugins)
            {
                try
                {
                    await Plugin.OnLoadAsync(this);
                }

                catch (Exception ex)
                {
                    Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_PLUGIN"]} {Plugin.Name}");
                    Logger.WriteDebug(ex.GetExceptionInfo());
                }
            }
            #endregion

            #region CONFIG
            var config = ConfigHandler.Configuration();

            // copy over default config if it doesn't exist
            if (config == null)
            {
                var defaultConfig = new BaseConfigurationHandler <DefaultConfiguration>("DefaultSettings").Configuration();
                ConfigHandler.Set((ApplicationConfiguration) new ApplicationConfiguration().Generate());
                var newConfig = ConfigHandler.Configuration();

                newConfig.AutoMessages          = defaultConfig.AutoMessages;
                newConfig.GlobalRules           = defaultConfig.GlobalRules;
                newConfig.Maps                  = defaultConfig.Maps;
                newConfig.DisallowedClientNames = defaultConfig.DisallowedClientNames;
                newConfig.QuickMessages         = defaultConfig.QuickMessages;

                if (newConfig.Servers == null)
                {
                    ConfigHandler.Set(newConfig);
                    newConfig.Servers = new List <ServerConfiguration>();

                    do
                    {
                        var serverConfig = new ServerConfiguration();
                        foreach (var parser in AdditionalRConParsers)
                        {
                            serverConfig.AddRConParser(parser);
                        }

                        foreach (var parser in AdditionalEventParsers)
                        {
                            serverConfig.AddEventParser(parser);
                        }

                        newConfig.Servers.Add((ServerConfiguration)serverConfig.Generate());
                    } while (Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["SETUP_SERVER_SAVE"]));

                    config = newConfig;
                    await ConfigHandler.Save();
                }
            }

            else
            {
                if (string.IsNullOrEmpty(config.Id))
                {
                    config.Id = Guid.NewGuid().ToString();
                    await ConfigHandler.Save();
                }

                if (string.IsNullOrEmpty(config.WebfrontBindUrl))
                {
                    config.WebfrontBindUrl = "http://0.0.0.0:1624";
                    await ConfigHandler.Save();
                }

                foreach (var serverConfig in config.Servers)
                {
                    Migration.ConfigurationMigration.ModifyLogPath020919(serverConfig);

                    if (serverConfig.RConParserVersion == null || serverConfig.EventParserVersion == null)
                    {
                        foreach (var parser in AdditionalRConParsers)
                        {
                            serverConfig.AddRConParser(parser);
                        }

                        foreach (var parser in AdditionalEventParsers)
                        {
                            serverConfig.AddEventParser(parser);
                        }

                        serverConfig.ModifyParsers();
                    }
                    await ConfigHandler.Save();
                }
            }

            if (config.Servers.Count == 0)
            {
                throw new ServerException("A server configuration in IW4MAdminSettings.json is invalid");
            }

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            Utilities.EncodingType = Encoding.GetEncoding(!string.IsNullOrEmpty(config.CustomParserEncoding) ? config.CustomParserEncoding : "windows-1252");

            #endregion

            #region DATABASE
            using (var db = new DatabaseContext(GetApplicationSettings().Configuration()?.ConnectionString,
                                                GetApplicationSettings().Configuration()?.DatabaseProvider))
            {
                await new ContextSeed(db).Seed();
            }

            PrivilegedClients = (await ClientSvc.GetPrivilegedClients()).ToDictionary(_client => _client.ClientId);
            #endregion

            #region COMMANDS
            if (ClientSvc.GetOwners().Result.Count == 0)
            {
                Commands.Add(new COwner());
            }

            Commands.Add(new CQuit());
            Commands.Add(new CKick());
            Commands.Add(new CSay());
            Commands.Add(new CTempBan());
            Commands.Add(new CBan());
            Commands.Add(new CWhoAmI());
            Commands.Add(new CList());
            Commands.Add(new CHelp());
            Commands.Add(new CFastRestart());
            Commands.Add(new CMapRotate());
            Commands.Add(new CSetLevel());
            Commands.Add(new CUsage());
            Commands.Add(new CUptime());
            Commands.Add(new CWarn());
            Commands.Add(new CWarnClear());
            Commands.Add(new CUnban());
            Commands.Add(new CListAdmins());
            Commands.Add(new CLoadMap());
            Commands.Add(new CFindPlayer());
            Commands.Add(new CListRules());
            Commands.Add(new CPrivateMessage());
            Commands.Add(new CFlag());
            Commands.Add(new CUnflag());
            Commands.Add(new CReport());
            Commands.Add(new CListReports());
            Commands.Add(new CListBanInfo());
            Commands.Add(new CListAlias());
            Commands.Add(new CExecuteRCON());
            Commands.Add(new CPlugins());
            Commands.Add(new CIP());
            Commands.Add(new CMask());
            Commands.Add(new CPruneAdmins());
            Commands.Add(new CKillServer());
            Commands.Add(new CSetPassword());
            Commands.Add(new CPing());
            Commands.Add(new CSetGravatar());
            Commands.Add(new CNextMap());
            Commands.Add(new RequestTokenCommand());

            foreach (Command C in SharedLibraryCore.Plugins.PluginImporter.ActiveCommands)
            {
                Commands.Add(C);
            }
            #endregion

            #region META
            async Task <List <ProfileMeta> > getProfileMeta(int clientId, int offset, int count, DateTime?startAt)
            {
                var metaList = new List <ProfileMeta>();

                // we don't want to return anything because it means we're trying to retrieve paged meta data
                if (count > 1)
                {
                    return(metaList);
                }

                var lastMapMeta = await _metaService.GetPersistentMeta("LastMapPlayed", new EFClient()
                {
                    ClientId = clientId
                });

                if (lastMapMeta != null)
                {
                    metaList.Add(new ProfileMeta()
                    {
                        Id    = lastMapMeta.MetaId,
                        Key   = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_MAP"],
                        Value = lastMapMeta.Value,
                        Show  = true,
                        Type  = ProfileMeta.MetaType.Information,
                    });
                }

                var lastServerMeta = await _metaService.GetPersistentMeta("LastServerPlayed", new EFClient()
                {
                    ClientId = clientId
                });

                if (lastServerMeta != null)
                {
                    metaList.Add(new ProfileMeta()
                    {
                        Id    = lastServerMeta.MetaId,
                        Key   = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_SERVER"],
                        Value = lastServerMeta.Value,
                        Show  = true,
                        Type  = ProfileMeta.MetaType.Information
                    });
                }

                var client = await GetClientService().Get(clientId);

                metaList.Add(new ProfileMeta()
                {
                    Id     = client.ClientId,
                    Key    = $"{Utilities.CurrentLocalization.LocalizationIndex["GLOBAL_TIME_HOURS"]} {Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_PLAYER"]}",
                    Value  = Math.Round(client.TotalConnectionTime / 3600.0, 1).ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)),
                    Show   = true,
                    Column = 1,
                    Order  = 0,
                    Type   = ProfileMeta.MetaType.Information
                });

                metaList.Add(new ProfileMeta()
                {
                    Id     = client.ClientId,
                    Key    = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_FSEEN"],
                    Value  = Utilities.GetTimePassed(client.FirstConnection, false),
                    Show   = true,
                    Column = 1,
                    Order  = 1,
                    Type   = ProfileMeta.MetaType.Information
                });

                metaList.Add(new ProfileMeta()
                {
                    Id     = client.ClientId,
                    Key    = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_LSEEN"],
                    Value  = Utilities.GetTimePassed(client.LastConnection, false),
                    Show   = true,
                    Column = 1,
                    Order  = 2,
                    Type   = ProfileMeta.MetaType.Information
                });

                metaList.Add(new ProfileMeta()
                {
                    Id     = client.ClientId,
                    Key    = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_CONNECTIONS"],
                    Value  = client.Connections.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)),
                    Show   = true,
                    Column = 1,
                    Order  = 3,
                    Type   = ProfileMeta.MetaType.Information
                });

                metaList.Add(new ProfileMeta()
                {
                    Key       = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_MASKED"],
                    Value     = client.Masked ? Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_TRUE"] : Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_FALSE"],
                    Sensitive = true,
                    Column    = 1,
                    Order     = 4,
                    Type      = ProfileMeta.MetaType.Information
                });

                return(metaList);
            }

            async Task <List <ProfileMeta> > getPenaltyMeta(int clientId, int offset, int count, DateTime?startAt)
            {
                if (count <= 1)
                {
                    return(new List <ProfileMeta>());
                }

                var penalties = await GetPenaltyService().GetClientPenaltyForMetaAsync(clientId, count, offset, startAt);

                return(penalties.Select(_penalty => new ProfileMeta()
                {
                    Id = _penalty.Id,
                    Type = _penalty.PunisherId == clientId ? ProfileMeta.MetaType.Penalized : ProfileMeta.MetaType.ReceivedPenalty,
                    Value = _penalty,
                    When = _penalty.TimePunished,
                    Sensitive = _penalty.Sensitive
                })
                       .ToList());
            }

            MetaService.AddRuntimeMeta(getProfileMeta);
            MetaService.AddRuntimeMeta(getPenaltyMeta);
            #endregion

            #region INIT
            int       failedServers  = 0;
            int       successServers = 0;
            Exception lastException  = null;

            async Task Init(ServerConfiguration Conf)
            {
                // setup the event handler after the class is initialized

                Handler = new GameEventHandler(this);

                try
                {
                    var ServerInstance = new IW4MServer(this, Conf);
                    await ServerInstance.Initialize();

                    lock (_servers)
                    {
                        _servers.Add(ServerInstance);
                    }

                    Logger.WriteVerbose(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_MONITORING_TEXT"].FormatExt(ServerInstance.Hostname));
                    // add the start event for this server

                    var e = new GameEvent()
                    {
                        Type  = GameEvent.EventType.Start,
                        Data  = $"{ServerInstance.GameName} started",
                        Owner = ServerInstance
                    };

                    Handler.AddEvent(e);
                    successServers++;
                }

                catch (ServerException e)
                {
                    Logger.WriteError(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_UNFIXABLE"].FormatExt($"[{Conf.IPAddress}:{Conf.Port}]"));

                    if (e.GetType() == typeof(DvarException))
                    {
                        Logger.WriteDebug($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_DVAR"].FormatExt((e as DvarException).Data["dvar_name"])} ({Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_DVAR_HELP"]})");
                    }

                    else if (e.GetType() == typeof(NetworkException))
                    {
                        Logger.WriteDebug(e.Message);
                    }

                    failedServers++;
                    lastException = e;
                }
            }

            await Task.WhenAll(config.Servers.Select(c => Init(c)).ToArray());

            if (successServers - failedServers <= 0)
            {
                if (!Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_START_WITH_ERRORS"]))
                {
                    throw lastException;
                }
            }
            #endregion
        }
Esempio n. 10
0
        public void TestKDR()
        {
            var mgr    = A.Fake <IManager>();
            var config = A.Fake <IConfigurationHandler <StatsConfiguration> >();
            var plugin = serviceProvider.GetRequiredService <IW4MAdmin.Plugins.Stats.Plugin>();

            A.CallTo(() => config.Configuration())
            .Returns(new StatsConfiguration()
            {
                EnableAntiCheat = true
            });

            A.CallTo(() => handlerFactory.GetConfigurationHandler <StatsConfiguration>(A <string> .Ignored))
            .Returns(config);

            A.CallTo(() => mgr.GetLogger(A <long> .Ignored))
            .Returns(logger);

            var server = new IW4MServer(mgr,
                                        new SharedLibraryCore.Configuration.ServerConfiguration()
            {
                IPAddress = "127.0.0.1", Port = 28960
            },
                                        A.Fake <ITranslationLookup>(),
                                        A.Fake <IRConConnectionFactory>(), A.Fake <IGameLogReaderFactory>(), A.Fake <IMetaService>());

            var parser = new BaseEventParser(A.Fake <IParserRegexFactory>(), A.Fake <ILogger>(), A.Fake <ApplicationConfiguration>());

            parser.Configuration.GuidNumberStyle = System.Globalization.NumberStyles.Integer;

            var log = System.IO.File.ReadAllLines("Files\\T6GameStats.log");

            plugin.OnLoadAsync(mgr).Wait();
            plugin.OnEventAsync(new SharedLibraryCore.GameEvent()
            {
                Type = SharedLibraryCore.GameEvent.EventType.Start, Owner = server
            }, server).Wait();

            var clientList = new Dictionary <long, EFClient>();

            foreach (string line in log)
            {
                var e = parser.GenerateGameEvent(line);
                if (e.Origin != null)
                {
                    //if (!clientList.ContainsKey(e.Origin.NetworkId))
                    //{
                    //    clientList.Add(e.Origin.NetworkId, e.Origin);
                    //}

                    //else
                    //{
                    //    e.Origin = clientList[e.Origin.NetworkId];
                    //}

                    e.Origin = server.GetClientsAsList().FirstOrDefault(_client => _client.NetworkId == e.Origin.NetworkId) ?? e.Origin;
                    e.Origin.CurrentServer = server;
                }

                if (e.Target != null)
                {
                    //if (!clientList.ContainsKey(e.Target.NetworkId))
                    //{
                    //    clientList.Add(e.Target.NetworkId, e.Target);
                    //}

                    //else
                    //{
                    //    e.Target = clientList[e.Target.NetworkId];
                    //}

                    e.Target = server.GetClientsAsList().FirstOrDefault(_client => _client.NetworkId == e.Target.NetworkId) ?? e.Target;
                    e.Target.CurrentServer = server;
                }

                server.ExecuteEvent(e).Wait();
                plugin.OnEventAsync(e, server).Wait();
            }

            var client = server.GetClientsAsList().First(_client => _client?.NetworkId == 2028755667);
            var stats  = client.GetAdditionalProperty <EFClientStatistics>("ClientStats");
        }