Skip to content
SARDONYX edited this page Oct 20, 2024 · 49 revisions

DAR to OAR Converter(GUI & CLI) v0.8.0

Features

  • DAR to OAR conversion(CLI & GUI applications)
  • DAR Syntax error reporting
  • Implemented sub commands (Remove OAR dir, Unhide DAR files)
  • Mapping table complements OAR's readability on GUI
  • Localization system(Could be customized)
  • Could edit JavaScript & CSS

Getting Started for User

Explanation of the type of distribution

  • Windows: g_dar2oar_{VERSON}_x64_en-US.msi or g_dar2oar_{VERSON}_x64-setup.exe

  • Intel macOS: g_dar2oar_{VERSION}_x64.dmg (Arm version requires manual build)

  • LInux: g-dar2oar_{VERSION}_amd64.AppImage or g-dar2oar_{VERSION}_amd64.deb

  • What is the one marked DAR_to_OAR_Converter-{OS_NAME}-Portable.zip?

    It is a compressed file that contains the GUI and CLI, it is not an installer, so it does not automatically install the dependent libraries needed to start the GUI.

GUI

Installation & Run

1.Download the latest place binary from either.

2.Click g_dar2oar.exe(on Windows)

convert-page-with-javascript

How to customize our translations

There are 2 methods.

1.Write and import Json(See the following sample.)

2.Write and execute JavaScript within the editor.(See the following sample.)

Next, Go to the Settings page -> Scroll to the bottom -> Click language tab -> Click Import language

CLI

It is suitable for those who automate by executing commands without using the mouse and do not want to create extra configuration files.

Installation & Run

1.Download the latest binary.

2.Use Command. (A sample command is immediately below)

Conversion sample of one mod

./dar2oar convert "./test/data/UNDERDOG Animations" --mapping-file "./test/mapping_tables/UnderDog Animations_v1.9.6_mapping_table.txt" --run-parallel --stdout

Conversion sample of multiple mods

<# Example dir status
D:/Programming/rust/dar-to-oar
  ├─── test
  │     └─── data
  │           ├─── Modern Female Sitting Animations Overhaul
  │           └─── UNDERDOG Animations
  └─── logs

D:/Programming/rust/dar-to-oar/target/release
  └─── dar2oar.exe
#>

$base_dir = "D:/Programming/rust/dar-to-oar" # Convert target base directory
$bin_dir = "D:/Programming/rust/dar-to-oar/target/release" # Directory with dar2oar.exe
$mod_directory = "$base_dir/test/data/" # Root mod directory.

if (!$(Get-Command dar2oar -ErrorAction SilentlyContinue)) {
  # Temporarily pass through to access without specifying an absolute path.
  $env:Path += ";$bin_dir"
}

# Create log dir if it doesn't exist.
if (!$(Test-Path "$base_dir/logs")) {
  New-Item -ItemType Directory "$base_dir/logs"
}


function Convert-Mods($base, $mods_dir, $log_level) {
  Get-ChildItem $mods_dir -Directory |
  ForEach-Object {
    # The following values are expected for `$_.FullName`.
    # - D:/Programming/rust/dar-to-oar/test/data/Modern Female Sitting Animations Overhaul
    # - D:/Programming/rust/dar-to-oar/test/data/UNDERDOG Animations

    # The following values are expected for `$_.Name`.
    # - Modern Female Sitting Animations Overhaul
    # - UNDERDOG Animations
    dar2oar convert $_.FullName `
      --run-parallel `
      --stdout `
      --log-level $log_level `
      --log-path "$base_dir/logs/convert-$($_.Name).log"
    Write-Host ""
  }
}

function Show-Dar($base, $mods_dir, $log_level) {
  Get-ChildItem $mods_dir -Directory |
  ForEach-Object {
    dar2oar unhide-dar $_.FullName `
      --stdout `
      --log-level $log_level `
      --log-path "$base_dir/logs/show-dar-$($_.Name).log"
    Write-Host ""
  }
}

function Remove-Oar($base, $mods_dir, $log_level) {
  Get-ChildItem $mods_dir -Directory |
  ForEach-Object {
    dar2oar remove-oar $_.FullName `
      --stdout `
      --log-level $log_level `
      --log-path "$base_dir/logs/unhide-oar-$($_.Name).log"
    Write-Host ""
  }
}

function Get-Help() {
  dar2oar --help
  dar2oar --help
  dar2oar convert --help
  dar2oar remove-oar --help
  dar2oar unhide-dar --help
}

# Convert-Mods $base_dir $mod_directory "debug"
# Remove-Oar  $base_dir $mod_directory "debug"
# Show-Dar $base_dir $mod_directory "debug"
Get-Help

CLI Help

  • All
dar2oar 0.8.0
DAR to OAR Converter CLI

USAGE:
    dar2oar.exe <SUBCOMMAND>

OPTIONS:
    -h, --help       Print help information
    -V, --version    Print version information

SUBCOMMANDS:
    convert       Convert DAR to OAR
    help          Print this message or the help of the given subcommand(s)
    remove-oar    Find and delete `OpenAnimationReplacer` directory
    unhide-dar    Unhide all files in the `DynamicAnimationReplacer` directory by removing the
                      `mohidden` extension
  • Convert
dar2oar.exe-convert
Convert DAR to OAR

USAGE:
    dar2oar.exe convert [OPTIONS] <SOURCE>

ARGS:
    <SOURCE>
            Path containing the "DynamicAnimationReplacer" directory

OPTIONS:
        --author <AUTHOR>
            Mod author in config.json

        --destination <DESTINATION>
            "OpenAnimationReplacer" directory output destination (if none, inferred from DAR path)

    -h, --help
            Print help information

        --hide-dar
            After conversion, add ".mohidden" to all DAR files to hide them(For MO2 user)

        --log-level <LOG_LEVEL>
            Log level

            trace | debug | info | warn | error

            [default: error]

        --log-path <LOG_PATH>
            Output path of log file

            [default: ./convert.log]

        --mapping-1person-file <MAPPING_1PERSON_FILE>
            Path to section name table(For _1st_person)

        --mapping-file <MAPPING_FILE>
            Path to section name table

            - See more details
            https://github.com/SARDONYX-sard/dar-to-oar/wiki#what-is-the-mapping-file

        --name <NAME>
            Mod name in config.json & directory name (if none, inferred from DAR path)

        --run-parallel
            Use multi thread

            [Note] More than twice the processing speed can be expected, but the concurrent
            processing results in thread termination timings being out of order, so log writes will
            be out of order as well, greatly reducing readability of the logs.

        --stdout
            Log output to standard output as well
  • Remove OAR
dar2oar.exe-remove-oar
Find and delete `OpenAnimationReplacer` directory

USAGE:
    dar2oar.exe remove-oar [OPTIONS] <TARGET_PATH>

ARGS:
    <TARGET_PATH>
            Path containing the "OpenAnimationReplacer" directory

OPTIONS:
    -h, --help
            Print help information

        --log-level <LOG_LEVEL>
            Log level

            trace | debug | info | warn | error

            [default: error]

        --log-path <LOG_PATH>
            Output path of log file

            [default: ./convert.log]

        --stdout
            Log output to stdout as well
  • Unhide DAR
dar2oar.exe-unhide-dar
Unhide all files in the `DynamicAnimationReplacer` directory by removing the `mohidden` extension

USAGE:
    dar2oar.exe unhide-dar [OPTIONS] <DAR_DIR>

ARGS:
    <DAR_DIR>
            DAR directory containing files with ".mohidden" extension

OPTIONS:
    -h, --help
            Print help information

        --log-level <LOG_LEVEL>
            Log level

            trace | debug | info | warn | error

            [default: error]

        --log-path <LOG_PATH>
            Output path of log file

            [default: ./convert.log]

        --stdout
            Log output to stdout as well

What is the mapping file?

This application handles the following.(But consider that the meaning is almost the same in both cases.)

  • Mapping File: A file describing the mapping table.

  • Mapping Table: The contents of the table itself, mapping DAR preferred directory names to arbitrary names.

The "mapping table" is just to change the name of the directory from a number to an arbitrary name to make it easier to maintain. It does not affect the game in any particular way.

DAR priority directory name -> A specific name

Samples is here.

The mapping table journey

1/3 As a sample, try converting the following mod (1st person only)

Animated Armoury DAR Modified Conditions v2.3.2d

2/3: Write the mapping table

  • Animated Armoury DAR Modified Conditions_v2.3.2.d_mapping_table_1stperson.txt
// This is a line comment. It is ignored until a line break comes, so you can freely write notes.
10 Rapier
11 Pikes
12 Halberds
13 QuarterStaffs
14 Claw
15 Cestus
18 Whips
19 Katanas
29 Claw in Left hand
30 Claws-in-both-hands
31 Whip-in-Left-hand
  • dar2oar mapping table format
<key><space><value>
//<line comment>
  • Special behavior of the mapping table parser

    We can leave <value> blank. If left blank, a sequential number will be appended to the end.

Example:

8000000 Combat
8000001
8000002

Parse to

8000000 Combat
8000001 Combat_1
8000002 Combat_2

3/3: Convert & Result(The mapping file specified)

Animated Armoury DAR Modified Conditions
└─Meshes
    └─actors
        └─character
            └─_1stperson
                └─animations
                    └─OpenAnimationReplacer
                        └─Animated Armoury DAR Modified Conditions_1st_person
                            ├─Claw
                            ├─Claw-in-Left-hand
                            ├─Claws-in-both-hands
                            ├─Halberds
                            ├─Katanas
                            ├─Pikes
                            ├─QuarterStaffs
                            ├─Rapier
                            ├─Whip-in-Left-hand
                            └─Whips

The name in config.json will also be the same as each directory name.

3/3: Convert & Result(The mapping file isn't specified)

The name of the priority directly is used.

Animated Armoury DAR Modified Conditions
└─Meshes
    └─actors
        └─character
            └─_1stperson
                └─animations
                    └─OpenAnimationReplacer
                        └─Animated Armoury DAR Modified Conditions_1st_person
                            ├─10
                            ├─11
                            ├─12
                            ├─13
                            ├─14
                            ├─18
                            ├─19
                            ├─29
                            ├─30
                            └─31

The name in config.json will also be the same as each directory name.

The mapping table for ActorBase path(since verion 0.7.0)

  • DAR: meshes\actors\character\animations\DynamicAnimationReplacer\Skyrim.esm\0001A692
  • OAR: meshes\actors\character\animations\OpenAnimationReplacer\0001A692

In ActorBase, priority is always 0. Therefore, separate conditional expressions can be correctly applied by using the plugin ID as the name.

The mapping table for ActorBase is shown below.

// <ActorID> <Rename to>
0001A692 Male2hm

The mapping table (another journey)

1/5 Let's look together at the need for a mapping table through an example of a DAR path

We are trying to convert _condition.txt in the following DAR path.

C:\UNDERDOG Animations\meshes\actors\character\animations\DynamicAnimationReplacer_CustomConditions\2000000000\_conditions.txt

2/5 If we try the conversion by entering only the DAR path without specifying a mapping table

The OAR path will be as follows.

C:\UNDERDOG Animations\meshes\actors\character\animations\OpenAnimationReplacer\UNDERDOG Animations\2000000000\config.json

3/5 We can see the number "2000000000" in the GUI menu of OAR in the game

But We don't know which motion file it is.

Therefore, it was necessary to establish a way to map the number to the converted name.

4/5: We wrote the following in mapping_table.txt and tried the conversion again

  • mapping_table.txt(The name of mapping_table.txt can be any UTF-8 string.)
// This is comment lines.
// Mapping table format: <number><space><Any string>
// Any string: A string of something up to a newline (May contain spaces, but must be a string that OAR can display).
2000000000 sneak right att intro

Technical talk: The path is passed from the front-end JavaScript's string type(internally UTF-16) to the back-end Rust's String type (Vec<u8> guaranteed to be UTF-8) via inter-process communication(IPC), and then converted on the Rust back-end using that information.

5/5: After converting to OAR

We expect the following path.

C:\UNDERDOG Animations\meshes\actors\character\animations\OpenAnimationReplacer\UNDERDOG Animations\sneak right att intro

and config.json

{
  "name": "sneak right att intro",
  "description": "",
  "priority": 2000000000,
  "conditions": [
    {
      "condition": "IsActorBase",
      "requiredVersion": "1.0.0.0",
      "Actor base": {
        "pluginName": "Skyrim.esm",
        "formID": "7"
      }
    }
  ]
}

With the name filled in in the config.json name we can finally see the name in the OAR GUI in the game in a way that is easy to understand.

Source code for the mapping table parser

At the end of the journey, I'll put a link to the actual Rust code at the end. If I am wrong, the machine is not wrong. As long as this code passes the test, its behavior is true. It is most effective to check the facts.

mapping_table.rs

For Developer

If you fork and use GitHub CI

  1. Only a GitHub account is required.
  2. Manually running a workflow. See the following link.

Build on your own PC

1.Requirements

Mode Description
Development Binary generation is fast, but not very optimized.
Release Binary generation is slow, but execution is fast and binary size is small.

2.Execute build commands

GUI

First of all, execute npm install to install dependencies.

  • Development mode

SSR rendered and can be built by reloading with reloading. Note that this is not a single application, as it depends on an external directory called out directory in this state.

npm run dev
  • Release mode
npm run build

CLI

  • Development mode and show help

    The first -- is a statement that it is an option for dar2.oar.exe, not for cargo run.

cargo run -- --help
  • Release mode
cargo build --release

Used as a static link library

If you can use Rust, you can easily incorporate my code into your software as a library. More information can be found in the following documents.

Acknowledgements and Credits

Without the source code of the original application (DAR to OAR Converter) made in C# and the bug report submitted by Nexus, this Rust converter could not have been created.

Thanks to everyone for their help.