// ReSharper disable once UnusedMember.Global public async Task RunMonitorLogFile([TimerTrigger("*/5 * * * * *")] TimerInfo myTimer, ILogger log) { log.LogDebug($"Start RunMonitorLogFile @ {DateTime.UtcNow}"); var stopWatch = new Stopwatch(); stopWatch.Start(); var filterModel = new FileMonitorFilterModel(); var fileMonitorStates = (await _logFileMonitorStateRepository.GetLogFileMonitorStates(filterModel)) .Where(fm => fm.PlayerCount > 0) .ToList(); if (!fileMonitorStates.Any()) { return; } foreach (var logFileMonitor in fileMonitorStates) { logFileMonitor.LastReadAttempt = DateTime.UtcNow; await _logFileMonitorStateRepository.UpdateState(logFileMonitor); var requestPath = $"ftp://{logFileMonitor.FtpHostname}{logFileMonitor.FilePath}"; log.LogDebug($"Performing request for {logFileMonitor.ServerTitle} against file {requestPath} as player count is {logFileMonitor.PlayerCount}"); if (logFileMonitor.RemoteSize == -1 || logFileMonitor.LastRead < DateTime.UtcNow.AddMinutes(-1)) { log.LogDebug($"The remote file for {logFileMonitor.ServerTitle} ({requestPath}) has not been read in the past minute"); try { var fileSize = _ftpHelper.GetFileSize(logFileMonitor.FtpHostname, logFileMonitor.FilePath, logFileMonitor.FtpUsername, logFileMonitor.FtpPassword); log.LogDebug($"The remote file size for {logFileMonitor.ServerTitle} is {fileSize} bytes"); logFileMonitor.LastRead = DateTime.UtcNow; logFileMonitor.RemoteSize = fileSize; await _logFileMonitorStateRepository.UpdateState(logFileMonitor); } catch (Exception ex) { log.LogError(ex, $"Failed to read log file for {logFileMonitor.ServerTitle} against file {requestPath}"); log.LogError(ex.Message); if (ex.InnerException != null) { log.LogError(ex.InnerException.Message); } } } else { try { FtpClient ftpClient; if (FtpClients.ContainsKey(logFileMonitor.ServerId)) { ftpClient = FtpClients[logFileMonitor.ServerId]; } else { var ftpHostname = logFileMonitor.FtpHostname; var ftpPort = 21; var ftpParts = logFileMonitor.FtpHostname.Split(":"); if (ftpParts.Count() > 1) { ftpHostname = ftpParts[0]; ftpPort = Convert.ToInt32(ftpParts[1]); } ftpClient = new FtpClient { Host = ftpHostname, Port = ftpPort, Credentials = new NetworkCredential(logFileMonitor.FtpUsername, logFileMonitor.FtpPassword) }; FtpClients.TryAdd(logFileMonitor.ServerId, ftpClient); } if (!ftpClient.IsConnected) { ftpClient.Connect(); } using var streamReader = new StreamReader(ftpClient.OpenRead(logFileMonitor.FilePath, FtpDataType.ASCII, logFileMonitor.RemoteSize)); var prev = -1; var byteList = new List <byte>(); while (true) { var cur = streamReader.Read(); if (cur == -1) { break; } byteList.Add((byte)cur); if (prev == '\r' && cur == '\n') { logFileMonitor.RemoteSize += byteList.Count; logFileMonitor.LastRead = DateTime.UtcNow; await _logFileMonitorStateRepository.UpdateState(logFileMonitor); var line = Encoding.UTF8.GetString(byteList.ToArray()).TrimEnd('\n'); try { line = line.Replace("\r\n", ""); line = line.Trim(); line = line.Substring(line.IndexOf(' ') + 1); line = line.Replace("\u0015", ""); if (line.StartsWith("say;") || line.StartsWith("sayteam;")) { var chatType = ChatType.All; if (line.StartsWith("sayteam;")) { chatType = ChatType.Team; } log.LogDebug($"[{logFileMonitor.ServerTitle}] {line}"); try { var parts = line.Split(';'); var guid = parts[1]; var name = parts[3]; var message = parts[4].Trim(); var chatMessageHandlers = _serviceProvider.GetServices <IChatMessageHandler>().ToList(); foreach (var handler in chatMessageHandlers) { await handler.HandleChatMessage(logFileMonitor.ServerId, name, guid, message, chatType); } } catch (Exception ex) { log.LogWarning(ex, $"Failed to handle chat message for {logFileMonitor.ServerTitle} with data {line}"); log.LogWarning(ex.Message); if (ex.InnerException != null) { log.LogWarning(ex.InnerException.Message); } } } } catch (Exception ex) { log.LogWarning(ex, $"Failed to process chat message for {logFileMonitor.ServerTitle} with data {line}"); log.LogWarning(ex.Message); if (ex.InnerException != null) { log.LogWarning(ex.InnerException.Message); } } byteList = new List <byte>(); } prev = cur; } } catch (Exception ex) { log.LogError(ex, $"Failed to read log file for {logFileMonitor.ServerTitle} against file {requestPath}"); log.LogError(ex.Message); if (ex.InnerException != null) { log.LogError(ex.InnerException.Message); } } } } stopWatch.Stop(); log.LogDebug($"Stop RunMonitorLogFile @ {DateTime.UtcNow} after {stopWatch.ElapsedMilliseconds} milliseconds"); }
public async Task ImportLatestBanFiles([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer, ILogger log) { log.LogDebug($"Start BanFileImportAndUpdate @ {DateTime.UtcNow}"); var stopWatch = new Stopwatch(); stopWatch.Start(); var banFileMonitors = await _banFileMonitorsRepository.GetBanFileMonitors(new BanFileMonitorFilterModel()); foreach (var banFileMonitor in banFileMonitors) { try { _logger.LogDebug("Checking ban file for {server}", banFileMonitor.GameServer.Title); var remoteFileSize = _ftpHelper.GetFileSize( banFileMonitor.GameServer.FtpHostname, banFileMonitor.FilePath, banFileMonitor.GameServer.FtpUsername, banFileMonitor.GameServer.FtpPassword); var banFileSize = await _banFilesRepository.GetBanFileSizeForGame(banFileMonitor.GameServer.GameType); if (remoteFileSize == 0) { _logger.LogInformation("Remote ban file on {server} at {path} is zero - updating file", banFileMonitor.GameServer.Title, banFileMonitor.FilePath); var banFileStream = await _banFilesRepository.GetBanFileForGame(banFileMonitor.GameServer.GameType); await _ftpHelper.UpdateRemoteFileFromStream( banFileMonitor.GameServer.FtpHostname, banFileMonitor.FilePath, banFileMonitor.GameServer.FtpUsername, banFileMonitor.GameServer.FtpPassword, banFileStream); banFileMonitor.RemoteFileSize = banFileSize; await _banFileMonitorsRepository.UpdateBanFileMonitor(banFileMonitor); continue; } if (remoteFileSize != banFileMonitor.RemoteFileSize) { _logger.LogInformation("Remote ban file on {server} at {path} has changed since last sync: {current} != {last}", banFileMonitor.GameServer.Title, banFileMonitor.FilePath, remoteFileSize, banFileMonitor.RemoteFileSize); var remoteBanFileData = _ftpHelper.GetRemoteFileData( banFileMonitor.GameServer.FtpHostname, banFileMonitor.FilePath, banFileMonitor.GameServer.FtpUsername, banFileMonitor.GameServer.FtpPassword); await _banFileIngest.IngestBanFileDataForGame(banFileMonitor.GameServer.GameType, remoteBanFileData); banFileMonitor.RemoteFileSize = remoteFileSize; await _banFileMonitorsRepository.UpdateBanFileMonitor(banFileMonitor); } else { _logger.LogDebug("Remote ban file on {server} at {path} has not been modified since last sync", banFileMonitor.GameServer.Title, banFileMonitor.FilePath); } if (remoteFileSize != banFileSize && remoteFileSize == banFileMonitor.RemoteFileSize) { _logger.LogInformation("Remote ban file on {server} at {path} is not the latest version", banFileMonitor.GameServer.Title, banFileMonitor.FilePath); var banFileStream = await _banFilesRepository.GetBanFileForGame(banFileMonitor.GameServer.GameType); await _ftpHelper.UpdateRemoteFileFromStream( banFileMonitor.GameServer.FtpHostname, banFileMonitor.FilePath, banFileMonitor.GameServer.FtpUsername, banFileMonitor.GameServer.FtpPassword, banFileStream); banFileMonitor.RemoteFileSize = banFileSize; await _banFileMonitorsRepository.UpdateBanFileMonitor(banFileMonitor); } else { _logger.LogDebug("Remote ban file on {server} at {path} has the latest ban file", banFileMonitor.GameServer.Title, banFileMonitor.FilePath); } banFileMonitor.LastSync = DateTime.UtcNow; await _banFileMonitorsRepository.UpdateBanFileMonitor(banFileMonitor); } catch (Exception ex) { _logger.LogError(ex, "Failed to check ban file for {server}", banFileMonitor.GameServer.Title); } } stopWatch.Stop(); log.LogDebug($"Stop BanFileImportAndUpdate @ {DateTime.UtcNow} after {stopWatch.ElapsedMilliseconds} milliseconds"); }