2025-10-08 01:39:13 +02:00
2025-10-08 01:39:13 +02:00
2025-10-08 01:39:13 +02:00
2025-10-08 01:39:13 +02:00
2025-10-08 01:39:13 +02:00
2025-10-08 01:39:13 +02:00
2025-10-08 01:39:13 +02:00
2025-10-07 23:35:49 +00:00
2025-10-08 01:39:13 +02:00
2025-10-08 01:39:13 +02:00
2025-10-08 01:39:13 +02:00
2025-10-08 01:39:13 +02:00

TownOfUs Stats Exporter

A standalone BepInEx plugin that exports Town of Us Mira game statistics to a cloud API.

Overview

This plugin is 100% standalone and works alongside Town of Us Mira without requiring any modifications to the main mod. It uses reflection to access public classes and Harmony patches to hook into the game's event flow.

Features

  • Zero modifications to TOU Mira code
  • Reflection-based access to public game data
  • Harmony patches for event integration
  • Completely optional for users
  • Can be installed/removed without rebuilding TOU Mira
  • Exports comprehensive game statistics including:
    • Player roles and role changes (e.g., Amnesiac remembering)
    • Player modifiers
    • Kill statistics (correct/incorrect kills, assassin kills)
    • Task completion data
    • Game results and winning team
    • Player platforms and friend codes

Installation

For Users

  1. Download TownOfUsStatsExporter.dll
  2. Copy to Among Us/BepInEx/plugins/
  3. Start the game once to generate ApiSet.ini
  4. Edit the configuration file (see Configuration section)
  5. Restart the game

For Developers

Building the project:

cd TownOfUsStatsExporter
dotnet build -c Release

The compiled DLL will be in bin/Release/TownOfUsStatsExporter.dll

Configuration

The plugin looks for ApiSet.ini in two locations (in order):

  1. Game directory (where the DLL is located)
  2. Documents/TownOfUs/ApiSet.ini

Configuration File Format

# TownOfUs Stats Exporter Configuration

# Whether to enable API export (true/false)
EnableApiExport=true

# API Authentication Token
ApiToken=your_secret_token_here

# API Endpoint URL
ApiEndpoint=https://api.example.com/api/among-data

# Whether to save local backup copies (true/false)
SaveLocalBackup=true

# Additional secret/password for API authentication
Secret=your_secret_key_here

Local Backups

When SaveLocalBackup=true, game statistics are saved to:

Documents/TownOfUs/GameLogs/Game_YYYYMMDD_HHMMSS_<gameId>.json

Exported Data Format

The plugin exports data in JSON format with the following structure:

{
  "token": "your_api_token",
  "secret": "your_secret",
  "gameInfo": {
    "gameId": "unique-game-id",
    "timestamp": "2025-10-07T20:30:00Z",
    "lobbyCode": "ABCDEF",
    "gameMode": "Normal",
    "duration": 450.5,
    "map": "The Skeld"
  },
  "players": [
    {
      "playerId": 0,
      "playerName": "PlayerName",
      "playerTag": "PlayerName#1234",
      "platform": "Steam",
      "role": "Sheriff",
      "roles": ["Sheriff"],
      "modifiers": ["Giant"],
      "isWinner": true,
      "stats": {
        "totalTasks": 5,
        "tasksCompleted": 5,
        "kills": 2,
        "correctKills": 2,
        "incorrectKills": 0,
        "correctAssassinKills": 0,
        "incorrectAssassinKills": 0
      }
    }
  ],
  "gameResult": {
    "winningTeam": "Crewmates"
  }
}

Version Compatibility

Tested Versions

  • TOU Mira 1.2.1
  • TOU Mira 1.2.0

Probably Compatible

  • ⚠️ TOU Mira 1.3.x (same major version)

The plugin will log compatibility warnings if used with an untested version.

Architecture

TownOfUsStatsExporter.dll
├── TownOfUsStatsPlugin.cs          # BepInEx plugin entry point
├── Patches/
│   └── EndGameExportPatch.cs       # Harmony patch (low priority)
├── Reflection/
│   ├── TouMiraReflectionBridge.cs  # Main reflection interface
│   ├── ReflectionCache.cs          # Cached reflection metadata
│   ├── VersionCompatibility.cs     # Version checking
│   └── IL2CPPHelper.cs             # IL2CPP type conversions
├── Export/
│   ├── StatsExporter.cs            # Main export orchestrator
│   ├── DataTransformer.cs          # Transform TOU data to export format
│   └── ApiClient.cs                # HTTP client for API
├── Config/
│   ├── ApiConfigManager.cs         # INI file reader
│   └── ApiConfig.cs                # Config model
└── Models/
    ├── GameStatsData.cs            # Export data models
    └── ReflectedData.cs            # DTOs for reflected data

How It Works

  1. Plugin Loading: The plugin initializes when BepInEx loads all mods
  2. Reflection Bridge: Caches metadata for TOU Mira's public classes
  3. Harmony Patch: Patches EndGameManager.Start with low priority (runs AFTER TOU Mira)
  4. Data Collection: Uses reflection to access:
    • EndGamePatches.EndGameData.PlayerRecords
    • GameHistory.RoleHistory
    • GameHistory.PlayerStats
    • GameHistory.KilledPlayers
    • GameHistory.WinningFaction
  5. Data Transformation: Converts reflected data to export format
  6. Export: Sends to API and/or saves local backup (async, doesn't block UI)

Performance Impact

Operation Time Impact
Data Collection (reflection) ~22ms Negligible
Export (async) ~1500ms 0ms UI block

The export runs asynchronously and doesn't block the game UI.

Troubleshooting

Plugin Not Loading

Check:

  • DLL is in Among Us/BepInEx/plugins/
  • BepInEx is installed correctly
  • Check BepInEx console (F10) for error messages

"Failed to initialize reflection bridge"

Solutions:

  • Update to a compatible TOU Mira version
  • Check that TOU Mira is actually loaded
  • Update stats exporter to latest version

No Data Exported

Check:

  • EnableApiExport=true in ApiSet.ini
  • Game mode (Hide & Seek is skipped)
  • Check BepInEx logs for errors

API Errors

Check:

  • ApiToken is correct
  • ApiEndpoint URL is correct and accessible
  • Secret matches server configuration

Limitations

What Works

  • Access to public classes and properties
  • Role history tracking (including role changes)
  • Player modifiers
  • Kill statistics
  • Task completion data
  • JSON export and API transmission

What Doesn't Work

  • Access to internal/private members
  • Direct type safety (uses reflection)
  • Compile-time type checking
  • Guaranteed compatibility across major version changes

Development Notes

The plugin uses C# reflection extensively, which is ~100x slower than direct access. However:

  • Reflection metadata is cached for performance
  • Export runs asynchronously (no UI blocking)
  • Total overhead per game is <2 seconds

License

Same as Town of Us Mira

Credits

Built for the Town of Us Mira community

Description
No description provided
Readme MIT 169 KiB
2025-10-10 21:00:48 +00:00
Languages
C# 100%