v2019.08.19

This commit is contained in:
pypy
2019-08-19 23:21:08 +09:00
parent d725c8f1e3
commit 26b371fd0f
19 changed files with 768 additions and 515 deletions

View File

@@ -5,176 +5,194 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
namespace VRCX
{
public class VRCX_LogWatcher
public class LogWatcherFile
{
public long Length;
public long Position;
}
public class LogWatcher
{
private static readonly ReaderWriterLockSlim m_Lock = new ReaderWriterLockSlim();
private static List<string[]> m_GameLog = new List<string[]>();
private static Thread m_Thread;
private static bool m_Reset;
public static void Start()
// NOTE
// FileSystemWatcher() is unreliable
public static void Init()
{
if (m_Thread == null)
m_Thread = new Thread(() =>
{
m_Thread = new Thread(() =>
var D = new Dictionary<string, LogWatcherFile>();
var di = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"Low\VRChat\VRChat");
while (m_Thread != null)
{
var lastPosition = 0L;
var firstLine = string.Empty;
while (m_Thread != null)
try
{
if (m_Reset)
Thread.Sleep(1000);
}
catch
{
// ThreadInterruptedException
}
if (m_Reset)
{
m_Reset = false;
D.Clear();
m_Lock.EnterWriteLock();
try
{
m_Reset = false;
firstLine = string.Empty;
lastPosition = 0;
m_GameLog.Clear();
}
var info = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"Low\VRChat\VRChat");
if (info != null &&
info.Exists)
finally
{
var files = info.GetFiles("output_log_*.txt", SearchOption.TopDirectoryOnly);
if (files != null &&
files.Length >= 1)
m_Lock.ExitWriteLock();
}
}
var S = new HashSet<string>(D.Keys);
di.Refresh();
if (di.Exists)
{
var files = di.GetFiles("output_log_*.txt", SearchOption.TopDirectoryOnly);
Array.Sort(files, (A, B) => A.CreationTime.CompareTo(B.CreationTime));
var bias = DateTime.Now.AddMinutes(-5d);
foreach (var fi in files)
{
if (bias.CompareTo(fi.LastWriteTime) <= 0)
{
Array.Sort(files, (A, B) => B.LastWriteTime.CompareTo(A.LastWriteTime));
if (firstLine == string.Empty)
fi.Refresh();
}
if (D.TryGetValue(fi.Name, out LogWatcherFile F))
{
S.Remove(fi.Name);
if (F.Length == fi.Length)
{
for (var i = files.Length - 1; i >= 1; --i)
continue;
}
}
else
{
F = new LogWatcherFile();
D.Add(fi.Name, F);
}
F.Length = fi.Length;
Parse(fi, ref F.Position);
}
}
foreach (var key in S)
{
D.Remove(key);
}
}
})
{
IsBackground = true
};
m_Thread.Start();
}
public static void Exit()
{
var T = m_Thread;
m_Thread = null;
T.Interrupt();
T.Join();
}
public static void Parse(FileInfo info, ref long position)
{
try
{
using (var stream = info.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
stream.Position = position;
var s = string.Empty;
while ((s = reader.ReadLine()) != null)
{
if (s.Length > 35)
{
var c = s[35];
if (c == 'R')
{
// 2019.07.31 22:26:24 Log - [RoomManager] Joining wrld_4432ea9b-729c-46e3-8eaf-846aa0a37fdd:6974~private(usr_4f76a584-9d4b-46f6-8209-8305eb683661)~nonce(0000000000000000000000000000000000000000000000000000000000000000)
// 2019.07.31 22:26:24 Log - [RoomManager] Joining or Creating Room: VRChat Home
if (s.Length > 56 &&
string.Compare(s, 34, "[RoomManager] Joining ", 0, "[RoomManager] Joining ".Length, StringComparison.Ordinal) == 0 &&
string.Compare(s, 56, "or ", 0, "or ".Length, StringComparison.Ordinal) != 0)
{
var item = new[]
{
using (var stream = files[i].Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
var line = string.Empty;
while ((line = reader.ReadLine()) != null)
{
if (line.Length > 32 &&
line[31] == '-')
{
ParseLine(line);
}
}
}
ConvertLogTimeToISO8601(s),
"Location",
s.Substring(56)
};
m_Lock.EnterWriteLock();
try
{
m_GameLog.Add(item);
}
finally
{
m_Lock.ExitWriteLock();
}
}
using (var stream = files[0].Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var reader = new StreamReader(stream, Encoding.UTF8))
}
else if (c == 'N')
{
// 2019.07.31 22:41:18 Log - [NetworkManager] OnPlayerJoined pypy
if (s.Length > 66 &&
string.Compare(s, 34, "[NetworkManager] OnPlayerJoined ", 0, "[NetworkManager] OnPlayerJoined ".Length, StringComparison.Ordinal) == 0)
{
var line = reader.ReadLine();
if (line != null)
var item = new[]
{
if (string.Equals(firstLine, line))
{
stream.Position = lastPosition;
}
else
{
firstLine = line;
}
do
{
lastPosition = stream.Position;
ParseLine(line);
}
while ((line = reader.ReadLine()) != null);
ConvertLogTimeToISO8601(s),
"OnPlayerJoined",
s.Substring(66)
};
m_Lock.EnterWriteLock();
try
{
m_GameLog.Add(item);
}
finally
{
m_Lock.ExitWriteLock();
}
}
// 2019.07.31 22:29:31 Log - [NetworkManager] OnPlayerLeft pypy
else if (s.Length > 64 &&
string.Compare(s, 34, "[NetworkManager] OnPlayerLeft ", 0, "[NetworkManager] OnPlayerLeft ".Length, StringComparison.Ordinal) == 0)
{
var item = new[]
{
ConvertLogTimeToISO8601(s),
"OnPlayerLeft",
s.Substring(64)
};
m_Lock.EnterWriteLock();
try
{
m_GameLog.Add(item);
}
finally
{
m_Lock.ExitWriteLock();
}
}
}
}
try
{
Thread.Sleep(3000);
}
catch
{
// ThreadInterruptedException
}
}
});
m_Thread.Start();
}
}
public static void Stop()
{
var thread = m_Thread;
if (thread != null)
{
m_Thread = null;
try
{
thread.Interrupt();
thread.Join();
}
catch
{
}
}
}
private static string ConvertLogTimeToISO8601(string s)
{
// 2019.07.31 22:26:24
var dt = new DateTime(
int.Parse(s.Substring(0, 4)),
int.Parse(s.Substring(5, 2)),
int.Parse(s.Substring(8, 2)),
int.Parse(s.Substring(11, 2)),
int.Parse(s.Substring(14, 2)),
int.Parse(s.Substring(17, 2)),
DateTimeKind.Local
).ToUniversalTime();
return $"{dt:yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'}";
}
private static void ParseLine(string line)
{
try
{
// 2019.07.31 22:26:24 Log - [RoomManager] Joining wrld_4432ea9b-729c-46e3-8eaf-846aa0a37fdd:6974~private(usr_4f76a584-9d4b-46f6-8209-8305eb683661)~nonce(0000000000000000000000000000000000000000000000000000000000000000)
// 2019.07.31 22:26:24 Log - [RoomManager] Joining or Creating Room: VRChat Home
if (string.Compare(line, 34, "[RoomManager] Joining ", 0, "[RoomManager] Joining ".Length) == 0 &&
string.Compare(line, 56, "or ", 0, "or ".Length) != 0)
{
lock (m_GameLog)
{
m_GameLog.Add(new[]
{
ConvertLogTimeToISO8601(line),
"Location",
line.Substring(56)
});
}
}
// 2019.07.31 22:41:18 Log - [NetworkManager] OnPlayerJoined pypy
else if (string.Compare(line, 34, "[NetworkManager] OnPlayerJoined ", 0, "[NetworkManager] OnPlayerJoined ".Length) == 0)
{
lock (m_GameLog)
{
m_GameLog.Add(new[]
{
ConvertLogTimeToISO8601(line),
"OnPlayerJoined",
line.Substring(66)
});
}
}
// 2019.07.31 22:29:31 Log - [NetworkManager] OnPlayerLeft pypy
else if (string.Compare(line, 34, "[NetworkManager] OnPlayerLeft ", 0, "[NetworkManager] OnPlayerLeft ".Length) == 0)
{
lock (m_GameLog)
{
m_GameLog.Add(new[]
{
ConvertLogTimeToISO8601(line),
"OnPlayerLeft",
line.Substring(64)
});
}
position = stream.Position;
}
}
catch
@@ -182,31 +200,54 @@ namespace VRCX
}
}
private static string ConvertLogTimeToISO8601(string s)
{
// 2019.07.31 22:26:24
if (!DateTime.TryParseExact(s.Substring(0, 19),
"yyyy.MM.dd HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeLocal,
out DateTime dt))
{
dt = DateTime.UtcNow;
}
return $"{dt:yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'}";
}
public void Reset()
{
lock (m_GameLog)
if (m_Thread != null)
{
m_Reset = true;
m_GameLog.Clear();
m_Thread.Interrupt();
}
m_Thread.Interrupt();
}
public string[][] GetLogs()
public string[][] Get()
{
lock (m_GameLog)
m_Lock.EnterUpgradeableReadLock();
try
{
if (m_Reset ||
m_GameLog.Count == 0)
{
return new string[][] { };
}
var array = m_GameLog.ToArray();
m_GameLog.Clear();
m_Lock.EnterWriteLock();
try
{
m_GameLog.Clear();
}
finally
{
m_Lock.ExitWriteLock();
}
return array;
}
}
public bool HasLog()
{
lock (m_GameLog)
finally
{
return m_GameLog.Count > 0;
m_Lock.ExitUpgradeableReadLock();
}
}
}