logo
zh-tw
繁中

SKSE插件的地址庫

創作者: meh321
已更新:2024-02-14 09:19:54
2.3MB
mcafee
驗證
獲得 200,000,000+ 位用戶信任

關於此模組

包含頭檔和資料庫,以便輕鬆實現 SKSE DLL 插件的版本獨立性。
重要! 這現在分為兩個版本:特別版(1.5.x)和周年紀念版(1.6.x)。 指向地址的id在這兩個版本之間不會匹配(遊戲可執行文件差異太大,無法匹配,即使它們匹配了,這些函數中的代碼也是不同的)。

說明

對於普通mod用戶: 從文件部分下載並安裝“一體化”軟件包。 您可以使用mod manager或手動執行。 .bin文件應該放在這裏:
數據/SKSE/插件/
你沒有必要閱讀其餘的內容。

對於SKSE DLL插件作者:
這是一個modder資源(頭文件)。 您可以加載一個存儲偏移量的數據庫,這樣您的DLL插件就可以獨立於版本,而不需要重新編譯。 頭文件可以從文件的可選部分下載。 對於周年紀念版,頭文件名為versionlibdb.h,而不是versiondb.h! 如果您使用的是CommonLib,那麼所有這些都已經內置了,您不需要這裏的任何東西。


如何使用

最快的方法:
劇透:  
Show


#包括“versiondb.h”

void*MyAddress=NULL
無符號long long MyOffset=0;

bool InitializeOffsets()
{
//在堆棧上分配,這樣當我們退出這個函數時,它將被卸載。
//不需要加載整個數據庫並無緣無故地耗盡內存。
版本數據庫數據庫;

//使用當前可執行版本加載數據庫。
if(!db.Load())
{
_FATALERROR(“無法加載當前可執行文件的版本數據庫!”);

}
else
{
//"SkyrimSE.exe","1.5.97.0"
_MESSAGE("已加載%s版本%s的數據庫",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(“找不到我的東西的偏移量!”);

}

//一切都很成功。
返回true;
}



現在你想知道那裡的“123”值是多少。 這是一個地址的ID。 不同版本的數據庫將具有相同的地址ID,但它可能指向不同的值。 要獲取特定版本的所有ID和值對的列表,請執行以下操作:

劇透:  
Show


#包括“versiondb.h”

布爾轉儲SpecificVersion()
{
版本數據庫數據庫;

//嘗試加載1.5.62.0版本的數據庫,而不管運行的可執行版本如何。
如果(!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,而是用你正在反轉和熟悉的版本。 您必須首先在/Data/SKSE/Plugins目錄中擁有相應的數據庫文件。

調用后,您應該在Skyrim主目錄中有一個名為“offsets-1.5.62.0.txt”的新文件,或者您輸入的任何文件名。 每行的格式如下:
十進制ID六角偏移

例如,如果您在1.5.62.0中有一個地址142F4DEF8(玩家角色靜態指針),您希望使其與版本無關,您可以這樣做:
1.在offsets文件中查找2F4DEF8。 因為這是沒有基數140000000的偏移量
2.看到ID是517014(十進制!)
3.如果您希望在運行時將此地址包含在DLL中,請執行以下操作:


void*addressof 142 f 4 def8=db.FindAddressById(517014);


現在你有了。

VersionDb結構具有以下功能:
劇透:  
Show


布爾轉儲(常量標準::字符串和路徑); //將當前加載的數據庫轉儲到文件
布爾加載(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)常量; //獲取我們現在加載的數據庫文件的版本
bool GetExecutableVersion(int&major,int&minor,int&revision,int&build)常量; //獲取當前執行的應用程序的版本
const std::string&GetModuleName()const; //獲取當前加載的數據庫模塊的名稱,這應該顯示“SkyrimSE.exe”
const std::string&GetLoadedVersionString()const; //以字符串形式獲取當前加載的版本,例如“1.5.62.0”
const std::map&GetOffsetMap()常量; //如果需要手動迭代,則獲取要偏移的ID的映射
void*FindAddressById(無符號長長id)常量; //按ID查找地址,這將已經包括基址並且是正確的地址。 如果找不到,它將返回NULL!
bool FindOffsetById(無符號長長id,無符號長長&結果)常量; //按ID查找偏移量,這將只是不包括基數的偏移量。
bool FindIdByAddress(void*ptr,無符號long long&result)常量; //按地址查找ID,這將嘗試反向查找以將地址轉換為ID
bool FindIdByOffset(無符號長長偏移量,無符號長長&結果)常量; //按偏移量查找ID,這將嘗試反向查找以將偏移量轉換為ID



你應該知道和記住的事情:

1.您可以在插件中包含任何(或所有)數據庫文件,但這可能會大大增加文件大小(大約2.5 mb)。 到目前為止,通常將這個mod標記為依賴項。

2.您應該始終只在啟動時加載數據庫一次,初始化/緩存您需要的地址並讓它卸載。 卸載只是意味着VersionDb結構被刪除或丟失(如果您在堆棧上分配)。 這將確保您在遊戲運行時不會使用不必要的內存。 在遊戲過程中沒有必要保持數據庫的加載。 如果您使用CommonLib,這是一個有爭議的問題,因為它只加載一次,而不是為每個DLL加載。

3.數據庫包含函數、全局變量、RTTI、vtables以及其他任何可能對其有引用的內容的地址。 它不包含位於函數中間或全局中間的地址。 如果您需要函數中間的地址,您應該查找函數基址並自己添加額外的偏移量。 它也不包含無用的東西,如函數周圍的對齊(在rdata中引用),pdata部分被丟棄,一些編譯器從rdata生成的SEH信息被丟棄。

4.您應該始終檢查結果,以確保數據庫加載成功(bool Load返回true),並且查詢的地址實際上返回了有效的結果(而不是NULL)。 如果它無法加載,這意味着文件很可能丟失或版本錯誤(例如,試圖在AE中使用SE頭)。 如果查詢失敗,則意味着在該版本中找不到該地址。 這可能意味着遊戲代碼發生了足夠大的變化,以至於地址對該版本不再有效,或者數據庫本身未能檢測到正確的地址。 如果這兩種情況中的任何一種發生,你應該讓插件初始化失敗,讓SKSE知道你沒有正確加載。 或手動顯示錯誤消息。

5.如果您在發布DLL插件之前檢查以確保該地址存在於遊戲的所有版本中,那也是最好的。 為此,請加載數據庫文件的每個版本,並在每個版本中查詢相同的地址ID以確保其存在:
劇透:  
Show


bool LoadAll(std::vector(&all)
{
靜態int版本[]={3,16,23,39,50,53,62,73,80,97,-1};
對於(int i=0;版本[i]>=0;i++)
{
version db*db=new version db();
if(!db->Load(1, 5,版本[i], 0))
{
刪除數據庫;
返回false;
}
all.push_back(db);
}
返回true;
}

bool ExistsInAll(std::vector(&all,無符號長id)
{
無符號長長結果=0;

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

}
返回true;
}

void FreeAll(std::vector(&all)
{
對於(自動數據庫:全部)
刪除數據庫;
全部。clear();
}

布爾IsOk()
{
std::vector全部;
if(!LoadAll(all))
{
_FATALERROR(“無法加載當前可執行文件的一個或多個版本數據庫!”);
FreeAll(全部);
返回false;
}

if(!ExistsInAll(all, 517014))
{
_FATALERROR("517014不存在於所有版本的數據庫中!");


}

FreeAll(全部);
//好的!
返回true;
}



這樣你可以確保你的DLL mod在所有版本中都能工作,或者如果它在某些版本中不能工作,你可以在你的mod頁面上寫出來。

6.有時你需要根據運行的遊戲版本做一些不同的事情。 您可以使用以下代碼片段執行此操作:
劇透:  
Show


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版本
如果(主要==1&&次要==5&&修訂>=39)
{
//東西...?
}



7.請記住:如果你在調試模式下編譯你的SKSE DLL,數據庫的加載時間可以在14秒左右! 在釋放模式下,這大約是0.2秒。 這是因為標準庫容器在該模式下非常慢(std map)。


權限

你想做什麼就做什麼。

The Elder Scrolls V: Skyrim Special Edition 的熱門模組

探索適用於 The Elder Scrolls V: Skyrim Special Edition 的最佳模組,帶來新功能、升級畫面,以及令人興奮的方式來改變您的遊戲體驗。
天空使用者介面
schlangster2017-10-04 05:03:26
介面優雅,對電腦友好,並具有許多高級功能。
非官方《上古卷軸5:天際》特別版補丁 - USSEP
Arthmoor2025-09-01 07:56:09
一款針對《上古卷軸V:天際特別版》的綜合性錯誤修復模組。非官方天際特別版補丁(簡稱USSEP)的目標是最終修復《天際特別版》中所有尚未被官方修復的錯誤。
Mod組織者2
ModOrganizerTeam2024-08-04 16:31:44
Mod Organizer(MO)是一個用於管理任意大小的Mod集合的工具。 它是專門為那些喜歡嘗試mods的人設計的,因此需要一種簡單可靠的方法來安裝和卸載它們。
靜態網格改進模組 - SMIM
Brumbek2018-07-05 02:28:26
這是一個旨在大幅提升《上古卷軸5:天際》中無數靜態3D模型外觀的大型專案。簡而言之,我希望透過這個計畫讓天際的建築、雜物、家具和景觀更加美觀。
SKSE插件的地址庫
meh3212024-02-14 09:19:54
包含頭檔和資料庫,以便輕鬆實現 SKSE DLL 插件的版本獨立性。
比賽選單
expired69782024-01-27 03:38:17
角色創建選單全面改版,新增多種自訂功能,例如多種RGBA戰紋、身體彩繪、手部彩繪和腳部彩繪。 (需要SKSE)
Fores Skyrim SE-FNIS SE中的新閑置
NexusModsCaretaker2020-02-19 01:47:03
Skyrim沒有可能的自定義動畫? 錯了。 FNIS行為允許添加不同類型的動畫到遊戲:閑置/姿勢,順序,傢具,配對,殺戮,生物,等等。
一張高品質的世界地圖
Chesko2016-12-11 16:48:33
提供一套全新的高精度 3D 或紙質世界地圖紋理,包含道路!另外也新增了一張精細的索爾斯泰姆地圖。

使用 Xmod 解鎖 The Elder Scrolls V: Skyrim Special Edition 的全部潛力 — 今天就探索這些頂級模組!

mcafee
驗證
獲得 200,000,000+ 位用戶信任

需要下載或安裝幫助嗎?加入我們的Discord 社群尋求支援。

logo
語言

遊戲解決方案

資源

合作夥伴

關注我們

discordfacebooktwitteryoutube
dc@xmodhub.com or cathy@business.xmodhub.com
Discord: catherine_79237
條款與條件
隱私政策
支援

Larvas Limited

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