XMODhub Home
Switch language
日本語
SKSE プラグインのアドレスライブラリ Mod Menu

SKSE プラグインのアドレスライブラリ

クリエイター: meh321
更新済み:2020-02-24 19:31:54
2.8MB
Verified by McAfee SECURE
認証
200,000,000+ ユーザーに信頼されています

このモッドについて

SKSE DLL プラグインのバージョンを簡単に独立させるためのヘッダーファイルとデータベースが含まれています.
重要!現在、Special Edition (1.5.x) と Anniversary Edition (1.6.x) の2つのバージョンに分割されています。これらの2つのバージョン間では、アドレスを指すIDは一致しません(ゲームの実行ファイルがあまりにも異なるため一致しませんし、一致したとしても関数内のコードはいずれにしても異なります)。

説明

通常の MOD ユーザーの場合:ファイルセクションから「オールインワン」パッケージをダウンロードしてインストールしてください。modマネージャーを使用するか、手動でインストールできます。.binファイルはここに配置してください。
データ/SKSE/プラグイン/
残りの部分を読む必要はありません。

SKSE DLLプラグイン作成者向け:
これはモッダーリソース(ヘッダーファイル)です。オフセットを格納するデータベースをロードすることで、DLLプラグインを再コンパイルすることなくバージョンに依存しない状態にすることができます。ヘッダーファイルはファイルのオプションセクションからダウンロードできます。Anniversary Editionの場合、ヘッダーファイルはversiondb.hではなくversionlibdb.hです。CommonLibを使用している場合は、これらはすべて既に組み込まれているため、ここから追加する必要はありません。


使い方

最も早い方法:
ネタバレ:
見せる


#include "versiondb.h"

void * MyAddress = NULL;
符号なしlong long MyOffset = 0;

ブール型InitializeOffsets()
{
// スタックに割り当てて、この関数を終了するときにアンロードされるようにします。
// データベース全体をロードして、理由もなくメモリを消費する必要はありません。
バージョンデータベースdb;

// 現在の実行可能バージョンでデータベースを読み込みます。
if (!db.Load())
{
_FATALERROR("現在の実行可能ファイルのバージョンデータベースの読み込みに失敗しました!");
false を返します。
}
それ以外
{
// "SkyrimSE.exe", "1.5.97.0"
_MESSAGE("%s バージョン %s のデータベースをロードしました。", db.GetModuleName().c_str(), db.GetLoadedVersionString().c_str());
}

// このアドレスにはモジュールのベース アドレスがすでに含まれているため、アドレスを直接使用できます。
私の住所 = db.FindAddressById(123);
(MyAddress == NULL)の場合
{
_FATALERROR("アドレスが見つかりませんでした!");
false を返します。
}

// このオフセットにはベースアドレスは含まれません。実際のアドレスはModuleBase + MyOffsetになります。
if (!db.FindOffsetById(123, MyOffset))
{
_FATALERROR("私のもののオフセットが見つかりませんでした!");
false を返します。
}

// すべて成功しました。
true を返します。
}



さて、この「123」という値は一体何なのか、と疑問に思われるかもしれません。これは住所のIDです。異なるバージョンのデータベースでは、同じ住所のIDは同じでも、異なる値を指す場合があります。特定のバージョンのIDと値のペアのリストを取得するには、以下のコマンドを実行してください。

ネタバレ:
見せる


#include "versiondb.h"

ブールダンプ特定バージョン()
{
バージョンデータベースdb;

// 実行中の実行可能ファイルのバージョンに関係なく、バージョン 1.5.62.0 のデータベースをロードしようとします。
if (!db.Load(1, 5, 62, 0))
{
_FATALERROR("1.5.62.0 のデータベースの読み込みに失敗しました!");
false を返します。
}

// offsets-1.5.62.0.txt というファイルを書き出します。各行は ID とオフセットです。
db.Dump("offsets-1.5.62.0.txt");
_MESSAGE("1.5.62.0 のオフセットをダンプしました");
true を返します。
}



1, 5, 62, 0 の代わりに、リバース対象のSKSEのバージョン番号を入力してください。対応するデータベースファイルが/Data/SKSE/Pluginsディレクトリにある必要があります。

これを実行すると、Skyrimのメインディレクトリに「offsets-1.5.62.0.txt」または任意のファイル名の新しいファイルが作成されます。各行は以下の形式になります。
10進数ID六角オフセット

たとえば、1.5.62.0 にアドレス 142F4DEF8 (プレイヤー キャラクターの静的ポインター) があり、これをバージョン非依存にしたい場合は、次のようにします。
1. オフセットファイルで2F4DEF8を検索します。これはベース140000000を除いたオフセットです。
2. ID が 517014 (10 進数) であることを確認します。
3. 実行時にこのアドレスを DLL に含める場合は、次のようにします。


void* addressOf142F4DEF8 = db.FindAddressById(517014);


これで完了です。

VersionDb 構造体には次の機能があります。
ネタバレ:
見せる


bool Dump(const std::string& path); // 現在ロードされているデータベースをファイルにダンプする
bool Load(int major, int minor, int revision, int build); // Data/SKSE/Plugins ディレクトリに db-major-minor-revision-build.bin が存在する場合は特定のバージョンをロードします
bool Load(); // 現在のアプリケーションのバージョンをロードする
void Clear(); // 現在ロードされているデータベースをクリアする
void GetLoadedVersion(int& major, int& minor, int& revision, int& build) const; // 現在ロードされているデータベースファイルのバージョンを取得します
bool GetExecutableVersion(int& major, int& minor, int& revision, int& build) const; // 現在実行中のアプリケーションのバージョンを取得します
const std::string& GetModuleName() const; // 現在ロードされているデータベースモジュールの名前を取得します。「SkyrimSE.exe」と表示されます。
const std::string& GetLoadedVersionString() const; // 現在ロードされているバージョンを文字列として取得します。例: "1.5.62.0"
定数std::map& GetOffsetMap() const; // 手動で反復処理する必要がある場合は、ID とオフセットのマップを取得します。
void* FindAddressById(unsigned long long id) const; // IDでアドレスを検索します。ベースアドレスが既に含まれており、正しいアドレスです。見つからない場合はNULLを返します。
bool FindOffsetById(unsigned long long id, unsigned long long& result) const; // ID でオフセットを検索します。これはベースを含まないオフセットのみになります。
bool FindIdByAddress(void* ptr, unsigned long long& result) const; // アドレスからIDを検索します。これにより、アドレスをIDに変換するための逆引き検索が試行されます。
bool FindIdByOffset(unsigned long long offset, unsigned long long& result) const; // オフセットでIDを検索します。これにより、オフセットをIDに変換するための逆引き検索が試行されます。



知っておくべきこと、心に留めておくべきこと:

1. データベースファイルのいずれか(またはすべて)をプラグインに含めることは可能ですが、ファイルサイズが大幅に増加する可能性があります(約2.5MB)。これまでは、このモジュールを依存関係としてマークすることが一般的でした。

2. データベースは起動時に必ず一度だけ読み込み、必要なアドレスを初期化/キャッシュしてアンロードしてください。アンロードとは、VersionDb構造体が削除または失われることを意味します(スタック上に割り当てた場合)。これにより、ゲーム実行中に不要なメモリ使用量が削減されます。ゲームプレイ中はデータベースをロードしたままにする必要はありません。CommonLibを使用する場合、これは問題になりません。CommonLibはDLLごとにデータベースを読み込むのではなく、一度だけ読み込むからです。

3. データベースには、関数、グローバル変数、RTTI、vtable、その他参照される可能性のあるすべてのアドレスが含まれます。関数の途中やグローバル変数の途中にあるアドレスは含まれません。関数の途中にあるアドレスが必要な場合は、関数のベースアドレスを参照し、オフセットを自分で追加する必要があります。また、関数のアライメント(rdataで参照される)などの不要な情報も含まれません。pdataセクションは破棄され、rdataからコンパイラによって生成されたSEH情報も破棄されます。

4. 結果は常にチェックし、データベースが正常にロードされたか(bool Load が true を返したか)、クエリしたアドレスが実際に有効な結果(NULL ではない)を返したかを確認する必要があります。ロードに失敗した場合は、ファイルが見つからないか、バージョンが間違っている可能性があります(例:AE で SE ヘッダーを使用しようとしている)。クエリが失敗した場合は、そのバージョンでアドレスが見つからなかったことを意味します。これは、ゲームコードが変更されたためにアドレスがそのバージョンで有効でなくなったか、データベース自体が正しいアドレスを検出できなかったことを意味します。これらのどちらかが発生した場合は、プラグインの初期化を失敗させて、SKSE に正しくロードされなかったことを通知する必要があります。または、手動でエラーメッセージを表示してください。

5. DLLプラグインを公開する前に、ゲームの全バージョンにアドレスが存在することを確認することをお勧めします。そのためには、データベースファイルの各バージョンを読み込み、各バージョンで同じアドレスIDをクエリして、存在するかどうかを確認してください。
ネタバレ:
見せる


ブールLoadAll(std::vector& 全て)
{
静的intバージョン[] = { 3, 16, 23, 39, 50, 53, 62, 73, 80, 97, -1 };
(int i = 0; バージョン[i] >= 0; i++)
{
バージョンデータベース * db = 新しいバージョンデータベース();
if (!db->Load(1, 5, バージョン[i], 0))
{
dbを削除します。
false を返します。
}
all.push_back(db);
}
true を返します。
}

ブール型 ExistsInAll(std::vector& すべて、unsigned long long id)
{
unsigned long long 結果 = 0;
(自動データベース: すべて)
{
if (!db->FindOffsetById(id, result))
false を返します。
}
true を返します。
}

void FreeAll(std::vector& 全て)
{
(自動データベース: すべて)
dbを削除します。
すべてクリア();
}

ブール型IsOk()
{
std::vector全て;
if (!LoadAll(すべて))
{
_FATALERROR("現在の実行可能ファイルの 1 つ以上のバージョン データベースの読み込みに失敗しました!");
FreeAll(すべて);
false を返します。
}

if (!ExistsInAll(すべて、517014))
{
_FATALERROR("517014 はデータベースのすべてのバージョンに存在しません!");
FreeAll(すべて);
false を返します。
}

FreeAll(すべて);
// わかりました!
true を返します。
}



この方法により、DLL モッドがすべてのバージョンで動作することを確認できます。また、一部のバージョンで動作しない場合は、その旨をモッド ページに書き込むことができます。

6. 実行中のゲームのバージョンに応じて異なる処理を実行する必要がある場合があります。その場合は、次のコードスニペットを使用します。
ネタバレ:
見せる


int メジャー = 0、マイナー = 0、リビジョン = 0、ビルド = 0;
if (!db.GetExecutableVersion(メジャー、マイナー、リビジョン、ビルド))
{
_FATALERROR("問題が発生しました!");
false を返します。
}

// 実行中のゲームは 1.5.x であり、少なくともバージョン 1.5.39.0 です
if (メジャー == 1 && マイナー == 5 && リビジョン >= 39)
{
// もの ... ?
}



7. SKSE DLLをデバッグモードでコンパイルすると、データベースの読み込み時間は約14秒かかる場合があります。リリースモードでは約0.2秒です。これは、標準ライブラリコンテナ(std map)の読み込み速度が非常に遅いためです。


権限

何でも好きなようにしてください。

Multiverse Loot Hunter向けトップモッド

Multiverse Loot Hunter向けの最高のモッドを探検しよう。新しい機能、向上したグラフィック、そしてゲームプレイ体験を変える刺激的な方法を提供します。

XmodでMultiverse Loot Hunterの可能性を最大限に引き出そう — これらのトップモッドを今日チェック!

Verified by McAfee SECURE
認証
200,000,000+ ユーザーに信頼されています

ダウンロードやインストールでお困りですか?サポートのためにDiscord コミュニティに参加してください!

XMODhub Home
言語
Chinese Traditionalに言語を切り替える
Englishに言語を切り替える
Germanに言語を切り替える
Koreanに言語を切り替える
Thaiに言語を切り替える
Indonesianに言語を切り替える
Vietnameseに言語を切り替える
Turkishに言語を切り替える
Portugueseに言語を切り替える
Japaneseに言語を切り替える
Polishに言語を切り替える
Frenchに言語を切り替える
Spanishに言語を切り替える
Italianに言語を切り替える

ゲームソリューション

リソース

パートナー

フォローしてください

XMODhub DiscordにアクセスXMODhub FacebookにアクセスXMODhub XにアクセスXMODhub YouTubeにアクセス
サポート:
support@xmodhub.com
Xmod_Lily
業務:
dc@xmodhub.com or cathy@business.xmodhub.com
catherine_79237

Larvas Limited

Room 1201, 12/F Tai Sang Bank Building 130-132 Des Voeux Road Central HK