• 製品
  • 特長
  • Mod Master
  • ダウンロード
  • ゲーム
  • ブログ
  • 価格

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

著者:meh321最終更新日:2024-02-14 09:19:5421.1M2.3MB

The Elder Scrolls V: Skyrim Special Edition SKSEプラグイン用アドレスライブラリ-1-ラゴファスト モッドマスター

Mod紹介

SKSE DLL プラグインをバージョンに依存しないようにするためのヘッダー ファイルとデータベースが含まれています。
重要! これは現在、特別版(1.5.x)と記念版(1.6.x)の2つのバージョンに分割されています。アドレスを指すIDは、これら2つのバージョンの間で一致しません(ゲーム実行ファイルはあまりにも異なり、一致することができません。たとえそれらの関数内のコードと一致したとしても、とにかく異なります)。

説明

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

SKSE DLLプラグインの著者向け:
これはモッダーリソース(ヘッダーファイル)です。オフセットを保存するデータベースをロードすることで、DLLプラグインを再コンパイルすることなくバージョンに依存しないようにできます。ヘッダーファイルは、ファイルのオプションのセクションからダウンロードできます。記念日版の場合、ヘッダーファイルはversiondb.hではなくversionlibdb.hと呼ばれます。CommonLibを使用している場合は、これらすべてがすでに組み込まれており、ここから何も必要ありません。


~の使い方

最も迅速な方法:
ネタバレ:  
表示する


#「versiondb.h」を含みます

void*MyAddress=NULL;
符号なしの長い長いMyOffset=0;

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

//現在の実行可能バージョンでデータベースをロードします。
if(!db.Load())
{
_FATALERROR("現在の実行ファイルのバージョンデータベースをロードできませんでした!");

}
それ以外の
{
//"SkyrimSE.exe","1.5.97.0"
_MESSAGE("%s version%s for loaded database.", db.GetModuleName().c_str(), db.GetLoadedVersionString().c_str());
}

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

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

}

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



今、あなたはそこにある「123」の値が何であるか疑問に思っています。これはアドレスのIDです。さまざまなバージョンのデータベースは、アドレスに同じIDを持ちますが、異なる値を指す可能性があります。特定のバージョンのすべてのIDと値ペアのリストを取得するには、次の手順を実行します。

ネタバレ:  
表示する


#「versiondb.h」を含みます

ブールダンプSpecificVersion()
{
バージョンdb db;

//実行可能バージョンの実行に関係なく、バージョン1.5.62.0のデータベースをロードしてみてください。
if(!db.Load(1, 5, 62, 0))
{
_FATALERROR("1.5.62.0のデータベースをロードできませんでした!");
falseを返します。
}

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



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

これを呼び出した後、メインSkyrimディレクトリに「offsets-1.5.62.0.txt」という新しいファイル、またはファイル名として置くものが必要です。各行が次の形式になります。
10進数ID<tab>六角オフセット<newline>

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


void*addressOf142F4DEF8=db.FindAddressById(517014);


そしてそこにそれがあります。

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


boolダンプ(const std::string//現在ロードされているデータベースをファイルにダンプします
bool負荷(int major、int minor、int revision、int build);//db-major-minor-revision-build.binがData/SKSE/Pluginsディレクトリに存在する場合は、特定のバージョンをロードします
bool負荷();//現在のアプリケーションのバージョンをロードします
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"
const std::map<unsigned long long, unsigned long long>&GetOffsetMap()const;//手動で反復する必要がある場合は、オフセットするIDのマップを取得します
void*FindAddressById(符号なしの長い長いid)const;//IDでアドレスを見つけると、これにはすでにベースが含まれ、正しいアドレスが含まれます。見つからない場合はNULLに戻ります。
bool FindOffsetById(署名されていない長い長いid、署名されていない長い長い&結果)const;//IDでオフセットを見つけます。これは、ベースを含まずにオフセットされます。
bool FindIdByAddress(void*ptr、署名されていない長い長い//アドレスごとにIDを見つけると、逆ルックアップを試みてアドレスをIDに変換します。
bool FindIdByOffset(署名されていない長い長いオフセット、署名されていない長い長い&結果)const;//オフセットごとにIDを見つけると、逆ルックアップを試みてオフセットをIDに変換します



あなたが知っておくべきことと覚えておくべきこと:

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

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

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

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

5.また、DLLプラグインを公開する前に、ゲームのすべてのバージョンにアドレスが存在することを確認することをチェックした場合も最善です。データベースファイルの各バージョンをロードし、それぞれに同じアドレスIDをクエリして存在することを確認するには、次の手順に従います。
ネタバレ:  
表示する


bool LoadAll(std::ベクトル<VersionDb*>(&すべて)
{
静的intバージョン[]={3, 16, 23, 39, 50, 53, 62, 73, 80, 97,-1};
for(int i=0;version[i]>=0;i++)
{
VersionDb*db=新しいVersionDb();
if(!db->Load(1, 5,バージョン[i], 0))
{
dbを削除;
falseを返します。
}
all.push_back(db);
}
真を返します。
}

bool existensinall(std::ベクトル<VersionDb*>&all、署名されていない長い長いid)
{
署名されていない長い長い結果=0;

{
if(!db->FindOffsetById(id, result))

}
trueを返す。
}

void FreeAll(std::vector<VersionDb*>(&すべて)
{
for(auto db:all)
dbを削除;
all.clear();
}

ブールIsOk()
{
std::ベクトル<VersionDb*>すべて;
if(!LoadAll(all))
{
_FATALERROR(「現在の実行ファイルの1つ以上のバージョンデータベースをロードできませんでした!」);
フリーオール(すべて);
falseを返します。
}

if(!existensinall(all, 517014))
{
_FATALERROR("517014はデータベースのすべてのバージョンに存在するわけではありません!");


}

フリーオール(すべて);
//わかりました!
trueを返す。
}



このようにして、DLL modがすべてのバージョンで動作することを確認することができます。または、一部のバージョンで動作しない場合は、それをmodページに書くことができます。

6.ゲームバージョンの実行に基づいて何か異なることをする必要がある場合があります。このコードスニペットを使用してそれを行うことができます。
ネタバレ:  
表示する


int major=0、minor=0、revision=0、build=0;
if(!db.GetExecutableVersion(major, minor, revision, build))
{
_FATALERROR("何か問題が発生しました!");
falseを返します。
}

//実行中のゲームは1.5.xで、少なくともバージョン1.5.39.0です
if(メジャー==1
{
//もの...?
}



7.覚えておいてください:デバッグモードでSKSE DLLをコンパイルすると、データベースのロード時間は約14秒になる可能性があります!リリースモードでは約0.2秒です。これは、標準ライブラリコンテナがそのモード(std map)で非常に遅いためです。


権限

好きなことは何でもしてください。
本ツールはサードパーティの[bufftool]によって提供されています注意アイコン

今すぐMODをダウンロード

LagoFast をインストールし、The Elder Scrolls V: Skyrim Special Edition を起動して、お気に入りの MOD で遊んでみましょう。