Beispiel #1
0
        public async Task GameLogEventDetection_WorksAfterFileSizeReset()
        {
            var reader  = A.Fake <IGameLogReader>();
            var factory = A.Fake <IGameLogReaderFactory>();

            A.CallTo(() => factory.CreateGameLogReader(A <Uri[]> .Ignored, A <IEventParser> .Ignored))
            .Returns(reader);

            var detect = new GameLogEventDetection(serviceProvider.GetService <IW4MServer>(), new Uri[] { new Uri("C:\\test.log") }, factory);

            A.CallTo(() => reader.Length)
            .Returns(100)
            .Once()
            .Then
            .Returns(200)
            .Once()
            .Then
            .Returns(10)
            .Once()
            .Then
            .Returns(100);

            for (int i = 0; i < 4; i++)
            {
                await detect.UpdateLogEvents();
            }

            A.CallTo(() => reader.ReadEventsFromLog(A <long> .Ignored, A <long> .Ignored))
            .MustHaveHappenedTwiceExactly();
        }
Beispiel #2
0
        public async Task Initialize()
        {
            RconParser = Manager.AdditionalRConParsers
                         .FirstOrDefault(_parser => _parser.Version == ServerConfig.RConParserVersion);

            EventParser = Manager.AdditionalEventParsers
                          .FirstOrDefault(_parser => _parser.Version == ServerConfig.EventParserVersion);

            RconParser  = RconParser ?? new BaseRConParser();
            EventParser = EventParser ?? new BaseEventParser();

            RemoteConnection.SetConfiguration(RconParser.Configuration);

            var version = await this.GetDvarAsync <string>("version");

            Version  = version.Value;
            GameName = Utilities.GetGame(version?.Value ?? RconParser.Version);

            if (GameName == Game.UKN)
            {
                GameName = RconParser.GameName;
            }

            if (version?.Value?.Length != 0)
            {
                RconParser  = Manager.AdditionalRConParsers.FirstOrDefault(_parser => _parser.Version == version.Value) ?? RconParser;
                EventParser = Manager.AdditionalEventParsers.FirstOrDefault(_parser => _parser.Version == version.Value) ?? EventParser;
                Version     = RconParser.Version;
            }

            var infoResponse = RconParser.Configuration.CommandPrefixes.RConGetInfo != null ? await this.GetInfoAsync() : null;

            // this is normally slow, but I'm only doing it because different games have different prefixes
            var hostname = infoResponse == null ?
                           (await this.GetDvarAsync <string>("sv_hostname")).Value :
                           infoResponse.Where(kvp => kvp.Key.Contains("hostname")).Select(kvp => kvp.Value).First();
            var mapname = infoResponse == null ?
                          (await this.GetDvarAsync <string>("mapname")).Value :
                          infoResponse["mapname"];
            int maxplayers = (GameName == Game.IW4) ?  // gotta love IW4 idiosyncrasies
                             (await this.GetDvarAsync <int>("party_maxplayers")).Value :
                             infoResponse == null ?
                             (await this.GetDvarAsync <int>("sv_maxclients")).Value :
                             Convert.ToInt32(infoResponse["sv_maxclients"]);
            var gametype = infoResponse == null ?
                           (await this.GetDvarAsync <string>("g_gametype")).Value :
                           infoResponse.Where(kvp => kvp.Key.Contains("gametype")).Select(kvp => kvp.Value).First();
            var basepath = await this.GetDvarAsync <string>("fs_basepath");

            var game = infoResponse == null || !infoResponse.ContainsKey("fs_game") ?
                       (await this.GetDvarAsync <string>("fs_game")).Value :
                       infoResponse["fs_game"];
            var logfile = await this.GetDvarAsync <string>("g_log");

            var logsync = await this.GetDvarAsync <int>("g_logsync");

            var ip = await this.GetDvarAsync <string>("net_ip");

            WorkingDirectory = basepath.Value;

            try
            {
                var website = await this.GetDvarAsync <string>("_website");

                Website = website.Value;
            }

            catch (DvarException)
            {
                Website = loc["SERVER_WEBSITE_GENERIC"];
            }

            InitializeMaps();

            this.Hostname   = hostname.StripColors();
            this.CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map()
            {
                Alias = mapname, Name = mapname
            };
            this.MaxClients = maxplayers;
            this.FSGame     = game;
            this.Gametype   = gametype;
            this.IP         = ip.Value == "localhost" ? ServerConfig.IPAddress : ip.Value ?? ServerConfig.IPAddress;

            if ((logsync.Value == 0 || logfile.Value == string.Empty) && RconParser.CanGenerateLogPath)
            {
                // this DVAR isn't set until the a map is loaded
                await this.SetDvarAsync("logfile", 2);

                await this.SetDvarAsync("g_logsync", 2); // set to 2 for continous in other games, clamps to 1 for IW4

                //await this.SetDvarAsync("g_log", "games_mp.log");
                Logger.WriteWarning("Game log file not properly initialized, restarting map...");
                await this.ExecuteCommandAsync("map_restart");

                logfile = await this.GetDvarAsync <string>("g_log");
            }

            CustomCallback = await ScriptLoaded();

            // they've manually specified the log path
            if (!string.IsNullOrEmpty(ServerConfig.ManualLogPath))
            {
                LogPath = ServerConfig.ManualLogPath;
            }

            else
            {
                string mainPath = EventParser.Configuration.GameDirectory;

                LogPath = string.IsNullOrEmpty(game) ?
                          $"{basepath?.Value?.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile?.Value}" :
                          $"{basepath?.Value?.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{game?.Replace('/', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{logfile?.Value}";

                // fix wine drive name mangling
                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    LogPath = Regex.Replace($"{Path.DirectorySeparatorChar}{LogPath}", @"[A-Z]:/", "");
                }

                if (!File.Exists(LogPath) && ServerConfig.GameLogServerUrl == null)
                {
                    Logger.WriteError(loc["SERVER_ERROR_DNE"].FormatExt(LogPath));
                    throw new ServerException(loc["SERVER_ERROR_DNE"].FormatExt(LogPath));
                }
            }

            LogEvent = new GameLogEventDetection(this, LogPath, ServerConfig.GameLogServerUrl);
            Logger.WriteInfo($"Log file is {LogPath}");

            _ = Task.Run(() => LogEvent.PollForChanges());
#if !DEBUG
            Broadcast(loc["BROADCAST_ONLINE"]);
#endif
        }