profile picture

VSCode に Rust の Mod の開発環境を構築する

Published on 2024/02/29 , Last updated 2024/10/16
Tags game rust mod vscode

概要

Visual Studio CodeRust(ビデオゲーム) の Mod の開発環境を構築します。

前提条件

環境

環境構築

Oxide.Rust

  1. GitHub から Oxide.Rust-linux.zip をダウンロードします。

  2. ダウンロードした Oxide.Rust-linux.zip を展開します。

  3. Oxide をインストール済みサーバーの RustDedicated_Data/Managed/Rust.Data.dllOxide.Rust-linux/RustDedicated_Data/Managed フォルダにコピーします。

開発コンテナー構成ファイルの追加

C# の開発コンテナー構成ファイルを追加します。詳細は Quick start: Try a development container を参照して下さい。

  1. Visual Studio Code を開いて 1F キーを押下しコマンドパレットを表示します。

  2. コマンドパレットに Dev Containers: add Dev Container Configuration Files を入力し 開発コンテナー: 開発コンテナー構成ファイルを追加 を選択します。

  3. ワークスペースに構成を追加する を選択します。

  4. C# の開発コンテナー構成ファイル C# (.NET) を選択します。

  5. 既定の .NET version を選択します。

  6. 追加機能はインストールしないので未選択のまま OK を選択します。

  7. 開発コンテナー構成ファイル .devcontainer/devcontainer.json が追加されるので、customizations を編集します。

       "customizations": {
          "vscode": {
             "settings": {
                "editor.formatOnSave": true,
                "dotnet.server.useOmnisharp": true,
                "[csharp]": {
                   "editor.maxTokenizationLineLength": 2500,
                   "editor.defaultFormatter": "ms-dotnettools.csharp",
                   "editor.codeActionsOnSave": {
                      "source.organizeImports": "explicit"
                   }
                }
             },
             "extensions": [
                "ms-dotnettools.csdevkit",
                "icsharpcode.ilspy-vscode"
             ]
          }
       }
    

開発コンテナーを開く

C# の開発コンテナーを開きます。

  1. コマンドパレットに Dev Containers: Reopen in Container を入力し 開発コンテナー: コンテナーで再度開く を選択します。

Mod の実装

次のドキュメントを参考に Mod を実装します。今回は UMod Getting Started のコードを参考にします。

  1. 開発コンテナーに Oxide.Rust-linux フォルダをコピーします。

  2. ソリューションファイルを作成します。

    dotnet new sln
    
  3. クラスライブラリ のプロジェクト EpicStuff を作成します。

    dotnet new classlib -o EpicStuff
    
  4. EpicStuff/EpicStuff.csproj に依存関係を追加します。

    <Project Sdk="Microsoft.NET.Sdk">
    
    <PropertyGroup>
       <TargetFramework>net8.0</TargetFramework>
       <ImplicitUsings>enable</ImplicitUsings>
       <Nullable>enable</Nullable>
    </PropertyGroup>
    
    <ItemGroup>
       <PackageReference Include="OpenMod.UnityEngine.Redist" Version="2021.3.29.1" />
    </ItemGroup>
    
    <ItemGroup>
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Assembly-CSharp.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Facepunch.Console.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Facepunch.Network.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Facepunch.Rcon.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Facepunch.Sqlite.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Facepunch.UnityEngine.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Mono.Data.Tds.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/MySql.Data.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.Common.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.Core.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.CSharp.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.MySql.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.References.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.Rust.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.SQLite.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.Unity.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Rust.Clans.Local.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Rust.Data.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Configuration.Install.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Data.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Data.SQLite.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Drawing.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Runtime.Serialization.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Transactions.dll" />
    </ItemGroup>
    
    </Project>
    
  5. EpicStuff/EpicStuff.csproj をソリューションファイルに追加します。

    dotnet sln add EpicStuff/EpicStuff.csproj
    
  6. クラスファイル EpicStuff/Class1.cs のファイル名を EpicStuff.cs に変更します。

  7. クラスファイル EpicStuff/EpicStuff.cs の内容を UMod Getting Started を参考に書き換えます。

    namespace Oxide.Plugins
    {
       [Info("Epic Stuff", "Unknown Author", "0.1.0")]
       [Description("Makes epic stuff happen")]
       class EpicStuff : CovalencePlugin
       {
          private void Init()
          {
                Puts(GetMessage());
          }
    
          private static string GetMessage()
          {
                return "A baby plugin is born!";
          }
       }
    }
    
  8. ビルドが問題なく実行できることを確認します。

    dotnet build
    

Mod の実行

  1. クラスファイル EpicStuff/EpicStuff.cs をサーバーの oxide/plugins フォルダにコピーします。

  2. サーバーを起動します。

  3. サーバーのログに A baby plugin is born! が出力されていることを確認します。

    rust-1  | [Epic Stuff] A baby plugin is born!
    

Unit Test の実装

  1. テストプロジェクトを作成します。

    dotnet new xunit -o EpicStuffTests
    
  2. EpicStuffTests/EpicStuffTests.csproj に依存関係を追加します。

    <Project Sdk="Microsoft.NET.Sdk">
    
    <PropertyGroup>
       <TargetFramework>net8.0</TargetFramework>
       <ImplicitUsings>enable</ImplicitUsings>
       <Nullable>enable</Nullable>
    
       <IsPackable>false</IsPackable>
       <IsTestProject>true</IsTestProject>
    </PropertyGroup>
    
    <ItemGroup>
       <PackageReference Include="coverlet.collector" Version="6.0.0" />
       <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
       <PackageReference Include="xunit" Version="2.5.3" />
       <PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
    </ItemGroup>
    
    <ItemGroup>
       <Using Include="Xunit" />
    </ItemGroup>
    
    <ItemGroup>
       <PackageReference Include="OpenMod.UnityEngine.Redist" Version="2021.3.29.1" />
    </ItemGroup>
    
    <ItemGroup>
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Assembly-CSharp.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Facepunch.Console.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Facepunch.Network.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Facepunch.Rcon.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Facepunch.Sqlite.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Facepunch.UnityEngine.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Mono.Data.Tds.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/MySql.Data.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.Common.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.Core.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.CSharp.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.MySql.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.References.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.Rust.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.SQLite.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Oxide.Unity.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Rust.Clans.Local.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/Rust.Data.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Configuration.Install.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Data.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Data.SQLite.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Drawing.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Runtime.Serialization.dll" />
       <Reference Include="/workspaces/rust-mod-dev/Oxide.Rust-linux/RustDedicated_Data/Managed/System.Transactions.dll" />
    </ItemGroup>
    
    </Project>
    
  3. テストプロジェクトの依存関係としてテスト対象の csproj ファイルを追加します。

    dotnet add EpicStuffTests/EpicStuffTests.csproj reference EpicStuff/EpicStuff.csproj
    
  4. ソリューションファイルにテストプロジェクトを追加します。

    dotnet sln add EpicStuffTests/EpicStuffTests.csproj
    
  5. EpicStuff/AssemblyInfo.cs を作成し InternalsVisibleTo を追加してテストプロジェクトから internal メソッドの利用を許可します。

    using System.Runtime.CompilerServices;
    
    [assembly: InternalsVisibleTo("EpicStuffTests")]
    
  6. EpicStuff/EpicStuff.cs にテスト対象のプライベートメソッドのラッパーを作成します。

    protected internal static string GetMessageWrapper()
    {
       return GetMessage();
    }
    
  7. EpicStuffTests/UnitTest1.cs にテストを実装します。

    using Oxide.Plugins;
    
    namespace EpicStuffTests
    {
       public class UnitTest1
       {
          [Fact]
          public void Test1()
          {
                var expected = "A baby plugin is born!";
                var actual = EpicStuff.GetMessageWrapper();
    
                Assert.Equal(expected, actual);
          }
       }
    }
    
  8. テストを実行します。

    dotnet test