Question Seeking some assistance with filestream

Wizbaggd

New member
Joined
Oct 12, 2018
Messages
1
Programming Experience
10+
I'm trying to add an additional functionality to an existing project through GitHub, that has been abandoned by it's creator and is under MIT license.
The Aim:
-Monitor DayZServer_x64.ADM for changes
-Grab last 2nd last line (last line is always an empty line)
-Check if the string contains the words " has been killed by player "
-Strip out anything within (plus including) brackets and cleanup any extra spaces
-Send string to be announced to announcer method

My primary issue is lack of understanding of filestream and steamreader. I'm also having some issues figuring out the correct way to initialize the log reader.

Any assistance would be greatly appreciated. I have spent a week trying many approaches, and the closest I got was badly delayed (due to triggering in a method that did not fire often enough) and only a partial line.

My fork of the repository can be found here:
https://github.com/Wizbaggd/DaRT

My additions are:

Program.cs: Lines - 117 to 128 - Creation of instance (and starting reader)
Classes/RCon.cs - Lines - 1008-1022 (receives latest line from log file and determines if it needs to be sent out as an admin message)
Classes/ADMReader.cs - Entire document (I'm not sure I did anything right in here)

Settings.Default.* contains settings, such as admFile being the full filepath for the DayZServer_x64.ADM file and is set "using" in Program.cs, ADMReader.cs and RCon.cs.

C#:
// From Program.cs: Line 117-128
#region ADM Reader
ADMReader myADMReader = new ADMReader();
if (Settings.Default.admFile.Contains("DayZServer_x64.ADM")) {
    myADMReader.Start(Settings.Default.admFile);
    if (myADMReader.hasUpdated) {
        rcon.HandleKillFeed(myADMReader.currentLineRead);
        myADMReader.hasUpdated = false;
    }
}
#endregion

C#:
// From Classes\RCon.cs Line 1008
public void HandleKillFeed(string killfeedinput) {
    if (Settings.Default.killFeed) {
        if (killfeedinput.Contains(" has been killed by player ")) {
            killfeedinput = Regex.Replace(killfeedinput, @"\(.*\)", "");
            // Remove extra spaces.
            killfeedinput = Regex.Replace(killfeedinput, @"\s+", " ");
            //_form.Log("Kill Feed Message: " + killfeedinput, LogType.Debug, true);
            _client.SendCommand(BattlEyeCommand.Say, "-1 " + killfeedinput);
        }
    }
}

C#:
// File Classes\ADMReader.cs - entire file.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DaRT.Properties; //Contains Settings.Default.*


namespace ADMLogReader {
    class ADMReader {
        static private string _currentLineRead;
        static private bool _hasUpdated;


        public string currentLineRead {
            get {
                return _currentLineRead;
            }
        }


        public bool hasUpdated {
            get {
                return _hasUpdated;
            } set {
                _hasUpdated = value;
            }
        }


        public void Start(string file) {
            hasUpdated = false;
            Watch(file);
        }


        private static void Watch(string file) {
            string admFileName = Path.GetFileName(file);
            string admFileDir = new DirectoryInfo(file).Name;


            var watch = new FileSystemWatcher();
            watch.Path = admFileDir;
            watch.Filter = admFileName;
            watch.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.CreationTime; //more options
            watch.Created += new FileSystemEventHandler(OnChanged);
            watch.Changed += new FileSystemEventHandler(OnChanged);
            watch.EnableRaisingEvents = true;
        }


        private static void OnChanged(object source, FileSystemEventArgs e) {
            if (e.FullPath == Settings.Default.admFile) {
                _hasUpdated = true;
                ReadMyFile();
            } else {
                _hasUpdated = false;
            }
        }


        private static void ReadMyFile() {
            // if you want to read more lines change this to the ammount of lines you want
            const int LINES_KEPT = 2;
            string emptyLineRemover = "";


            Queue<string> meQueue = new Queue<string>();
            using (var fs = new FileStream(Settings.Default.admFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 16384))
            using (var sr = new StreamReader(fs, Encoding.Default)) {
                string lineIn = string.Empty;
                while ((lineIn = sr.ReadLine()) != null) {
                    if (meQueue.Count == LINES_KEPT)
                        meQueue.Dequeue();
                    meQueue.Enqueue(lineIn);
                }
                _currentLineRead = meQueue.Dequeue();
                emptyLineRemover = meQueue.Dequeue();
            }
        }
    }
}

FileStream is required because the file is write-locked by the server while the server is operating. File.ReadLine() is not an option, sadly, as it would have made the whole process a whole lot easier.
 
Last edited:
Back
Top Bottom