Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/VRChatActivityLogViewer/VRChatActivityLogViewer/appsettings.Development.json
/VRChatActivityLogger/VRChatActivityLogger/appsettings.Development.json
110 changes: 109 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ VRChatのログを解析し、活動履歴のデータベースを作成しま

コンソール画面を表示しないで実行したい場合は以下の起動オプションを使用してください。

Windows以外では本起動オプションは無効となります。
```
VRChatActivityLogger.exe -console false
```
Expand All @@ -68,15 +69,68 @@ VRChatActivityLogger.exe -console false

画面上のLoggerボタンをクリックする事でも実行する事ができます。

### appsettings.json

記入例は下記です。
``` json
{
"ConnectionStrings": {
"VRChatActivityLog": "Server=localhost;Database=VRChatActivityLog;Username=usr;Password=pswd;"
},
"DbKind": "MariaDB",

"VRChat": {
"LogFileDir": ""
}
}
```
#### `.ConnectionStrings.VRChatActivityLog`
DBへの接続文字列です。

SQLiteモードのみ、空文字を指定すると`(カレントディレクトリ)\VRChatActivityLog.db`となります。

詳細は各EFCoreのドキュメントをご覧ください。

[MySQL .NET Connection String Options](https://mysqlconnector.net/connection-options/)

[Entity Framework Core > Microsoft.Data.Sqlite > Basic usage](https://github.com/dotnet/efcore?tab=readme-ov-file#basic-usage-1)

#### `.ConnectionStrings.DbKind`
使用するDBの種類です。下記をお使いください。

- `"MariaDB"`
- `"SQLite"`

Note: MySQLでも`"MariaDB"`を指定してください。相違はEFCoreが自動調整します。

#### `.VRChat.LogFileDir`
VRChatのログディレクトリです。

空文字にすると自動的にローカルマシンのアプリケーションデータフォルダとなります。

出力先を変えている方だけご利用ください。

#### 開発時
ローカル環境では`appsettings.json`ではなく`appsettings.Development.json`を使用してください。
`appsettings.Development.json`が存在する場合は`appsettings.json`よりも`appsettings.Development.json`が優先されます。

1. `appsettings.json`をプログラムディレクトリに`appsettings.Development.json`としてコピーする
2. `appsettings.Development.json`を各自環境の設定に書き換える
3. バイナリを実行する

### VRChatActivityLog.db
VRChatActivityLogger.exeを実行すると作成されるデータベースファイルです。
SQLiteモードでVRChatActivityLogger.exeを実行すると作成されるデータベースファイルです。

中身はSQLite3のデータなので、他のアプリと連携したりもできると思います。

ただし、接続文字列の特性上本ファイルのファイル名は可変です。

## 既知の問題

inviteの送信履歴などから送信先となるユーザ名を表示する事はできません。VRChatのログにユーザ名が記録されない為です。

ネットワーク上のDBへ接続出来るか確認ができません。EFCoreの`CanConnect()`が「DBが存在するかを返す」為です。

## ライセンス

このプログラムにはMITライセンスが適用されます。
Expand Down Expand Up @@ -147,11 +201,65 @@ If you have not yet created a database, run VRChatActivityLogger.exe first.

You can also run it by clicking the Logger button on the screen.

### appsettings.json

The sample is below.

``` json
{
"ConnectionStrings": {
"VRChatActivityLog": "Server=localhost;Database=VRChatActivityLog;Username=usr;Password=pswd;"
},
"DbKind": "MariaDB",

"VRChat": {
"LogFileDir": ""
}
}
```

#### `.ConnectionStrings.VRChatActivityLog`

Connection string to your DB.

In only SQLite mode, if you set empty string, this path set to `(current dir.)\VRChatActivityLog.db`.

For more details, see also each EFCore documents.

[MySQL .NET Connection String Options](https://mysqlconnector.net/connection-options/)

[Entity Framework Core > Microsoft.Data.Sqlite > Basic usage](https://github.com/dotnet/efcore?tab=readme-ov-file#basic-usage-1)

#### `.ConnectionStrings.DbKind`

Kind for your DB. Please use below.

- `"MariaDB"`
- `"SQLite"`

Note: If you want to use MySQL, specify `"MariaDB"`. The deference will be fixed by EFCore.

#### `.VRChat.LogFileDir`

Path for VRChat log directory.

If empty specified, automatically set your local machine's application data folder.

Only who changes log output folder can use this option.

#### Development
In local develop enviroment, you can use `appsettings.Development.json` instead of `appsettings.json`.
If `appsettings.Development.json` exists in the directory, `appsettings.Development.json` will be prioritized than `appsettings.json`.

1. Copy `appsettings.json` as `appsettings.Development.json` to your program directory.
2. Edit `appsettings.Development.json` as your enviroment.
3. Run or debug your binary.
### VRChatActivityLog.db
This is the database file that is created when you run VRChatActivityLogger.exe.

The contents are SQLite3 data, so it can be used in conjunction with other applications.

This file name/path are variable due to the connection string.
## Known issues

It is not possible to display the name of the user to whom invitations are sent from the invitations sending history, because the user name is not recorded in the VRChat log.
Expand Down
38 changes: 28 additions & 10 deletions VRChatActivityLogViewer/VRChatActivityLogViewer/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Windows.Controls;
using System.Windows.Input;
using VRChatActivityToolsShared.Database;
using Microsoft.Extensions.Configuration;

namespace VRChatActivityLogViewer
{
Expand All @@ -21,12 +22,23 @@ public partial class MainWindow : Window

private readonly string errorFilePath = "./Logs/VRChatActivityLogger/errorfile.txt";

private readonly IConfigurationRoot _configuration;

private readonly DbOperatorFactory _dbOperatorFactory;

/// <summary>
/// コンストラクタ
/// </summary>
public MainWindow()
{
InitializeComponent();

var env = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? string.Empty;
_configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", true)
.Build();
_dbOperatorFactory = new DbOperatorFactory(new DbConfig(_configuration));
}

/// <summary>
Expand Down Expand Up @@ -68,9 +80,12 @@ private async Task ExecuteSearch()
EnableProcessingMode();

// DBが古い場合はアップグレードする
if (DatabaseMigration.GetCurrentVersion() < DatabaseContext.Version)
using (var context = _dbOperatorFactory.GetDbContext())
{
DatabaseMigration.UpgradeDatabase();
if (_dbOperatorFactory.DbMigration.GetCurrentVersion(context) < ActivityContextBase.Version)
{
_dbOperatorFactory.DbMigration.UpgradeDatabase(context);
}
}

// 検索期間の計算
Expand Down Expand Up @@ -136,7 +151,7 @@ private async Task ExecuteSearch()
IsAcceptInvite = acptInvCheckBox.IsChecked ?? false,
IsAcceptRequestInvite = acptReqInvCheckBox.IsChecked ?? false,
};
var activityLogs = await VRChatActivityLogModel.SearchActivityLogs(parameter);
var activityLogs = await VRChatActivityLogModel.SearchActivityLogs(parameter, _dbOperatorFactory);

// 選択アイテムの保存
var selectedItem = ActivityLogGrid.SelectedItem as ActivityLogGridModel;
Expand Down Expand Up @@ -417,14 +432,17 @@ private void DisableProcessingMode()
taskbarInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.None;
Mouse.OverrideCursor = null;
loggerButton.IsEnabled = true;

if (File.Exists(DatabaseContext.DBFilePath))
using (var context = _dbOperatorFactory.GetDbContext())
{
searchButton.IsEnabled = true;
}
else
{
searchButton.IsEnabled = false;
if (context.Database.CanConnect())
{
searchButton.IsEnabled = true;
}
else
{
searchButton.IsEnabled = false;
}
}

ActivityLogGrid.Focus();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"profiles": {
"VRChatActivityLogViewer": {
"commandName": "Project",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class VRChatActivityLogModel
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public static async Task<List<ActivityLog>> SearchActivityLogs(ActivityLogSearchParameter parameter)
public static async Task<List<ActivityLog>> SearchActivityLogs(ActivityLogSearchParameter parameter, DbOperatorFactory factory)
{
return await Task.Run(() =>
{
Expand Down Expand Up @@ -50,7 +50,7 @@ public static async Task<List<ActivityLog>> SearchActivityLogs(ActivityLogSearch
searchActivityTypes.Add(ActivityType.AcceptRequestInvite);

List<ActivityLog> activityLogs = new List<ActivityLog>();
using (var db = new DatabaseContext())
using (var db = factory.GetDbContext())
{
activityLogs = db.ActivityLogs
.Where(a => searchActivityTypes.Contains(a.ActivityType))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
<None Remove="icon.ico" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="9.0.5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\VRChatActivityToolsShared\VRChatActivityToolsShared\VRChatActivityToolsShared.csproj" />
</ItemGroup>
Expand All @@ -25,4 +29,13 @@
<Resource Include="icon.ico" />
</ItemGroup>

<ItemGroup>
<None Update="appsettings.Development.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"ConnectionStrings": {
"VRChatActivityLog": ""
},
"DbKind": "SQLite",
"DbVersion": ""
}
30 changes: 23 additions & 7 deletions VRChatActivityLogger/VRChatActivityLogger/Program.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
using System;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;

namespace VRChatActivityLogger
{
class Program
{
// 遅延ロードなのでWindows以外でもコールしない限り例外にはならない模様
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern bool AllocConsole();

Expand All @@ -13,23 +17,35 @@ class Program
/// </summary>
/// <param name="rawArgs"></param>
static int Main(string[] rawArgs)
{

{
var logger = Logger.GetLogger();
var args = new Argument(rawArgs)
{
NamedParameters = new Dictionary<string, string> {
NamedParameters = new Dictionary<string, string>
{
{ "console", "true" },
}
};
if (args.NamedParameters["console"].ToLower() != "false")
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && args.NamedParameters["console"].ToLower() != "false")
{
AllocConsole();
}

var logger = Logger.GetLogger();
logger.Info("VRChatActivityLoggerを実行します。");

var app = new VRChatActivityLogger();
var env = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") ?? string.Empty;
var config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", true)
.Build();
var app = new VRChatActivityLogger(new VRChatActivityToolsShared.Database.DbConfig(config));

// VRCログファイルの検索先指定があればそちらを使う
var vrc = config.GetSection("VRChat");
if (vrc != null && !string.IsNullOrEmpty(vrc["LogFileDir"]))
{
app.VRChatLogFilePath = vrc["LogFileDir"];
}
var returnCode = app.Run();

logger.Info("VRChatActivityLoggerを終了します。");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<TargetFramework>netcoreapp3.1</TargetFramework>
<PublishDir>bin\Publish\netcoreapp3.1\</PublishDir>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<TargetFramework>netcoreapp3.1</TargetFramework>
<PublishDir>bin\Publish\netcoreapp3.1\</PublishDir>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup>
</Project>
Loading