private static void Scan()
{
Process process = null;
IntPtr baseAddress = IntPtr.Zero;
IntPtr chatlogPointer = IntPtr.Zero;
DateTime lastPointerUpdate = DateTime.MinValue;
int lastLine = -1;
while (!_stopThread)
{
System.Threading.Thread.Sleep(10);
try
{
// update process and pointer every 10 seconds
if (process == null || DateTime.Now.Subtract(lastPointerUpdate).TotalSeconds > 10.0)
{
Process[] processList = Process.GetProcessesByName("Client");
if (processList != null && processList.Length > 0)
process = processList[0];
else
continue;
// todo: validate process
// cache base address if it is missing
if (baseAddress == IntPtr.Zero)
baseAddress = process.MainModule.BaseAddress;
// cache chatlog pointer tree
chatlogPointer = ReadIntPtr(process.Handle, IntPtr.Add(baseAddress, chatlogOffset));
chatlogPointer = ReadIntPtr(process.Handle, IntPtr.Add(chatlogPointer, 0x50));
chatlogPointer = ReadIntPtr(process.Handle, IntPtr.Add(chatlogPointer, 0x520));
chatlogPointer = ReadIntPtr(process.Handle, IntPtr.Add(chatlogPointer, 0x4));
lastPointerUpdate = DateTime.Now;
}
if (process == null || baseAddress == IntPtr.Zero || chatlogPointer == IntPtr.Zero)
continue;
// read in the # of lines - offset 0x9F60
int lineCount = (int) ReadUInt32(process.Handle, IntPtr.Add(chatlogPointer, 0x9F60));
if (lineCount > 300)
throw new ApplicationException("line count too high: [" + lineCount.ToString() + "].");
if (lineCount == lastLine)
continue;
// first scan - do not parse past data since we do not have timestamps
if (lastLine == -1)
{
lastLine = lineCount;
continue;
}
// check for wrap-around
if (lineCount < lastLine)
lineCount += lastLine;
// assume average line length is 50 characters, preallocate stringbuilder
StringBuilder buffer = new StringBuilder(50 * (lineCount - lastLine));
for (int i = lastLine + 1; i <= lineCount; i++)
{
// pointer to 'chat log line' structure which has std::string at offset 0x0
IntPtr linePointer = IntPtr.Add(chatlogPointer, 0x88 * (i % 300));
string chatLine = ReadStlString(process.Handle, linePointer);
// offset 0x74 is chat code
uint chatCode = ReadUInt32(process.Handle, IntPtr.Add(linePointer, 0x74));
//for (int j = 0; j < 0x80; j+=4)
//buffer.Append(BitConverter.ToUInt32(header, j).ToString("X8") + "|");
buffer.Append(DateTime.Now.ToString("HH:mm:ss.fff", System.Globalization.CultureInfo.InvariantCulture) + "|");
buffer.Append(chatCode.ToString("X2") + "|");
buffer.AppendLine(chatLine);
}
File.AppendAllText(_logFileName, buffer.ToString());
lastLine = lineCount % 300;
}
catch (Exception ex)
{
File.AppendAllText(_logFileName,
DateTime.Now.ToString("HH:mm:ss.fff", System.Globalization.CultureInfo.InvariantCulture) +
"|Error [BNS_Log.Scan] " + ex.ToString().Replace(Environment.NewLine, " "));
// do not exit scan thread, but pause so that the errors dont pile up.
System.Threading.Thread.Sleep(1000);
}
}
}