我正在尝试通过GitHub向现有项目添加其他功能,该功能已被其创建者放弃,并已获得MIT许可。
目的:
-Monitor DayZServer_x64.ADM进行更改
-抓住最后2nd最后一行(最后一行始终为空行)
-检查字符串是否包含单词"被玩家杀死"
-将括号内的任何东西剥离(包括在内)并清理多余的空间
-发送要宣布的字符串到播音员方法
我的主要问题是对文件流和Steamreader的了解不足。我还遇到一些问题,需要找出初始化日志读取器的正确方法。
任何帮助将不胜感激。我花了一个星期的时间尝试许多方法,但是我得到的最接近的方法严重延迟了(由于触发的方法触发得不够频繁),而且只有部分代码行。
我的仓库的分支可以在这里找到:
//github.com/Wizbaggd/DaRT
我的补充是:
Program.cs:第117行至128行-创建实例(并启动阅读器)
Classs / RCon.cs-行-1008-1022(从日志文件中接收最新行,并确定是否需要将其作为管理员消息发送出去)
Classes / ADMReader.cs-整个文档(不确定在这里是否做过任何事情)
Settings.Default。*包含设置,例如admFile是DayZServer_x64.ADM文件的完整文件路径,并且已设置"using"在Program.cs,ADMReader.cs和RCon.cs中。
FileStream是必需的,因为文件在服务器运行时被服务器写锁定。不幸的是,File.ReadLine()不是一个选项,因为它会使整个过程变得更加容易。
目的:
-Monitor DayZServer_x64.ADM进行更改
-抓住最后2nd最后一行(最后一行始终为空行)
-检查字符串是否包含单词"被玩家杀死"
-将括号内的任何东西剥离(包括在内)并清理多余的空间
-发送要宣布的字符串到播音员方法
我的主要问题是对文件流和Steamreader的了解不足。我还遇到一些问题,需要找出初始化日志读取器的正确方法。
任何帮助将不胜感激。我花了一个星期的时间尝试许多方法,但是我得到的最接近的方法严重延迟了(由于触发的方法触发得不够频繁),而且只有部分代码行。
我的仓库的分支可以在这里找到:
//github.com/Wizbaggd/DaRT
我的补充是:
Program.cs:第117行至128行-创建实例(并启动阅读器)
Classs / RCon.cs-行-1008-1022(从日志文件中接收最新行,并确定是否需要将其作为管理员消息发送出去)
Classes / ADMReader.cs-整个文档(不确定在这里是否做过任何事情)
Settings.Default。*包含设置,例如admFile是DayZServer_x64.ADM文件的完整文件路径,并且已设置"using"在Program.cs,ADMReader.cs和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("被玩家杀死")) {
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是必需的,因为文件在服务器运行时被服务器写锁定。不幸的是,File.ReadLine()不是一个选项,因为它会使整个过程变得更加容易。
Last edited: