logo
vi
Tiếng Việt

Thư viện địa chỉ cho SKSE Plugins

Người tạo: meh321
Đã cập nhật:2020-02-24 19:31:54
2.8MB
mcafee
Nếu McAfee chặn cài đặt, nhấp vào đây.
Được 200,000,000+ người dùng tin tưởng

Về mod này

Chứa tệp tiêu đề và cơ sở dữ liệu để làm cho phiên bản plugin SKSE DLL độc lập dễ dàng.
QUAN TRỌNG!Phiên bản này hiện được chia thành 2 phiên bản: Phiên bản Đặc biệt (1.5.x) và Phiên bản Kỷ niệm (1.6.x). ID trỏ đến các địa chỉ sẽ không khớp giữa 2 phiên bản này (tệp thực thi trò chơi quá khác nhau để khớp, và ngay cả khi chúng khớp thì mã trong các hàm đó vẫn khác nhau).

Sự miêu tả

Đối với người dùng mod thông thường:Tải xuống và cài đặt gói "tất cả trong một" từ mục tệp. Bạn có thể sử dụng trình quản lý mod hoặc thực hiện thủ công. Các tệp .bin sẽ nằm ở đây:
Dữ liệu/SKSE/Plugin/
Bạn không cần phải đọc phần còn lại của bài viết này.

Đối với tác giả plugin SKSE DLL:
Đây là tài nguyên modder (một tệp tiêu đề). Bạn có thể tải một cơ sở dữ liệu lưu trữ các offset để plugin DLL của bạn có thể độc lập với phiên bản mà không cần phải biên dịch lại. Tệp tiêu đề có thể được tải xuống từ phần tùy chọn của các tệp. Đối với Phiên bản Kỷ niệm, tệp tiêu đề được gọi là versionlibdb.h thay vì versiondb.h! Nếu bạn đang sử dụng CommonLib thì tất cả những điều này đã được tích hợp sẵn và bạn không cần bất cứ thứ gì từ đây.


Cách sử dụng

Cách nhanh nhất:
Tiết lộ:
Trình diễn


#include "versiondb.h"

void * Địa chỉ của tôi = NULL;
unsigned long long MyOffset = 0;

bool InitializeOffsets()
{
// Phân bổ trên ngăn xếp để ngăn xếp sẽ được dỡ xuống khi chúng ta thoát khỏi hàm này.
// Không cần phải tải toàn bộ cơ sở dữ liệu và sử dụng hết bộ nhớ mà không có lý do.
Phiên bảnDb db;

// Tải cơ sở dữ liệu với phiên bản thực thi hiện tại.
nếu (!db.Load())
{
_FATALERROR("Không tải được cơ sở dữ liệu phiên bản cho tệp thực thi hiện tại!");
trả về false;
}
khác
{
// "SkyrimSE.exe", "1.5.97.0"
_MESSAGE("Đã tải cơ sở dữ liệu cho phiên bản %s %s.", db.GetModuleName().c_str(), db.GetLoadedVersionString().c_str());
}

// Địa chỉ này đã bao gồm địa chỉ cơ sở của mô-đun nên chúng ta có thể sử dụng địa chỉ trực tiếp.
Địa chỉ của tôi = db.FindAddressById(123);
nếu (Địa chỉ của tôi == NULL)
{
_FATALERROR("Không tìm thấy địa chỉ!");
trả về false;
}

// Giá trị offset này không bao gồm địa chỉ cơ sở. Địa chỉ thực tế sẽ là ModuleBase + MyOffset.
nếu (!db.FindOffsetById(123, MyOffset))
{
_FATALERROR("Không tìm thấy giá trị bù trừ cho vật của tôi!");
trả về false;
}

// Mọi thứ đều thành công.
trả về giá trị đúng;
}



Giờ bạn đang thắc mắc giá trị "123" ở đó là gì. Đây là ID của một địa chỉ. Các cơ sở dữ liệu phiên bản khác nhau sẽ có cùng ID cho một địa chỉ nhưng nó có thể trỏ đến các giá trị khác nhau. Để lấy danh sách tất cả các cặp ID và giá trị cho một phiên bản cụ thể, hãy làm như sau:

Tiết lộ:
Trình diễn


#include "versiondb.h"

bool DumpSpecificVersion()
{
Phiên bảnDb db;

// Thử tải cơ sở dữ liệu phiên bản 1.5.62.0 bất kể đang chạy phiên bản thực thi nào.
nếu (!db.Load(1, 5, 62, 0))
{
_FATALERROR("Không tải được cơ sở dữ liệu cho 1.5.62.0!");
trả về false;
}

// Viết ra một tệp có tên là offsets-1.5.62.0.txt trong đó mỗi dòng là ID và offset.
db.Dump("offsets-1.5.62.0.txt");
_MESSAGE("Đã xóa các giá trị bù trừ cho 1.5.62.0");
trả về giá trị đúng;
}



Thay vì 1, 5, 62, 0, hãy nhập phiên bản bạn đang đảo ngược và quen thuộc. Trước tiên, bạn phải có tệp cơ sở dữ liệu tương ứng trong thư mục /Data/SKSE/Plugins.

Sau khi gọi lệnh này, bạn sẽ có một tệp mới trong thư mục Skyrim chính có tên là "offsets-1.5.62.0.txt" hoặc bất kỳ tên nào bạn đặt làm tên tệp. Tệp sẽ có định dạng như sau:
ID thập phânĐộ lệch lục giác

Ví dụ, nếu bạn có địa chỉ 142F4DEF8 (con trỏ tĩnh của nhân vật người chơi) trong 1.5.62.0 mà bạn muốn làm cho nó không phụ thuộc vào phiên bản, bạn sẽ làm như sau:
1. Tra cứu 2F4DEF8 trong tệp offset. Vì đây là offset không có cơ số 140000000
2. Kiểm tra xem ID có phải là 517014 (số thập phân!) không
3. Nếu bạn muốn địa chỉ này có trong DLL khi chạy, hãy làm như sau:


void* addressOf142F4DEF8 = db.FindAddressById(517014);


Và đó là những gì bạn có.

Cấu trúc VersionDb có các chức năng sau:
Tiết lộ:
Trình diễn


bool Dump(const std::string& path); // Dump cơ sở dữ liệu hiện đang được tải vào tệp
bool Load(int major, int minor, int revision, int build); // Tải một phiên bản cụ thể nếu db-major-minor-revision-build.bin tồn tại trong thư mục Data/SKSE/Plugins
bool Load(); // Tải phiên bản cho ứng dụng hiện tại
void Clear(); // Xóa cơ sở dữ liệu hiện đang được tải
void GetLoadedVersion(int& major, int& minor, int& revision, int& build) const; // Lấy phiên bản của tệp cơ sở dữ liệu mà chúng ta đã tải ngay bây giờ
bool GetExecutableVersion(int& major, int& minor, int& revision, int& build) const; // Lấy phiên bản của ứng dụng đang thực thi
const std::string& GetModuleName() const; // Lấy tên của mô-đun cơ sở dữ liệu hiện đang được tải, điều này sẽ hiển thị "SkyrimSE.exe"
const std::string& GetLoadedVersionString() const; // Lấy phiên bản hiện đang được tải dưới dạng chuỗi, ví dụ: "1.5.62.0"
const std::map& GetOffsetMap() const; // Lấy bản đồ ID để bù trừ nếu bạn cần lặp lại thủ công
void* FindAddressById(unsigned long long id) const; // Tìm địa chỉ theo ID, điều này sẽ bao gồm cả địa chỉ gốc và địa chỉ chính xác. Nó sẽ trả về NULL nếu không tìm thấy!
bool FindOffsetById(unsigned long long id, unsigned long long& result) const; // Tìm offset theo ID, giá trị này sẽ chỉ là offset mà không bao gồm base.
bool FindIdByAddress(void* ptr, unsigned long long& result) const; // Tìm ID theo địa chỉ, điều này sẽ thử tra cứu ngược để chuyển đổi địa chỉ thành ID
bool FindIdByOffset(unsigned long long offset, unsigned long long& result) const; // Tìm ID theo offset, thao tác này sẽ thử tra cứu ngược để chuyển đổi offset thành ID



Những điều bạn nên biết và ghi nhớ:

1. Bạn có thể bao gồm bất kỳ (hoặc tất cả) các tệp cơ sở dữ liệu với plugin của mình, nhưng việc này có thể làm tăng đáng kể kích thước tệp (khoảng 2,5 MB). Cho đến nay, việc đánh dấu bản mod này là phần phụ thuộc vẫn là điều phổ biến.

2. Bạn LUÔN CHỈ NÊN tải cơ sở dữ liệu một lần khi khởi động, khởi tạo/lưu trữ đệm các địa chỉ cần thiết và để nó dỡ tải. Việc dỡ tải chỉ có nghĩa là cấu trúc VersionDb bị xóa hoặc mất (nếu bạn đã cấp phát trên ngăn xếp). Điều này sẽ đảm bảo bạn không sử dụng lượng bộ nhớ không cần thiết trong thời gian chạy trò chơi. Không cần phải giữ cơ sở dữ liệu được tải trong khi chơi. Đây là một điểm cần lưu ý nếu bạn sử dụng CommonLib vì nó chỉ tải một lần thay vì cho mỗi DLL.

3. Cơ sở dữ liệu chứa địa chỉ của các hàm, biến toàn cục, RTTI, vtable và bất kỳ thứ gì khác có thể tham chiếu đến nó. Nó không chứa các địa chỉ nằm giữa các hàm hoặc giữa các biến toàn cục. Nếu bạn cần một địa chỉ ở giữa hàm, bạn nên tra cứu địa chỉ cơ sở của hàm và tự thêm phần bù. Nó cũng không chứa các thành phần vô dụng như căn chỉnh xung quanh các hàm (được tham chiếu trong rdata), phần pdata bị loại bỏ và một số thông tin SEH do trình biên dịch tạo ra từ rdata cũng bị loại bỏ.

4. Bạn nên luôn kiểm tra kết quả để đảm bảo cơ sở dữ liệu đã tải thành công (bool Load trả về true) và các địa chỉ được truy vấn thực sự trả về kết quả hợp lệ (không phải NULL). Nếu không tải được, điều đó có nghĩa là tệp có khả năng bị thiếu hoặc phiên bản không đúng (ví dụ: cố gắng sử dụng tiêu đề SE trong AE). Nếu truy vấn không thành công, điều đó có nghĩa là không tìm thấy địa chỉ trong phiên bản đó. Điều này có thể có nghĩa là mã trò chơi đã thay đổi đủ để địa chỉ không còn hợp lệ cho phiên bản đó HOẶC bản thân cơ sở dữ liệu không phát hiện được địa chỉ chính xác. Nếu một trong hai điều trên xảy ra, bạn sẽ không khởi tạo được plugin để SKSE biết rằng bạn đã tải không đúng. Hoặc hiển thị thông báo lỗi theo cách thủ công.

5. Tốt nhất bạn nên kiểm tra để đảm bảo địa chỉ này tồn tại trong tất cả các phiên bản của trò chơi trước khi xuất bản plugin DLL. Để làm điều đó, hãy tải từng phiên bản của tệp cơ sở dữ liệu và truy vấn cùng một ID địa chỉ trong mỗi phiên bản để đảm bảo nó tồn tại:
Tiết lộ:
Trình diễn


bool LoadAll(std::vector& tất cả)
{
phiên bản int tĩnh[] = { 3, 16, 23, 39, 50, 53, 62, 73, 80, 97, -1 };
đối với (int i = 0; phiên bản[i] >= 0; i++)
{
Phiên bảnDb * db = new Phiên bảnDb();
nếu (!db->Load(1, 5, phiên bản[i], 0))
{
xóa db;
trả về false;
}
all.push_back(db);
}
trả về giá trị đúng;
}

bool ExistsInAll(std::vector& tất cả, id dài không dấu)
{
unsigned long long result = 0;
đối với (cơ sở dữ liệu tự động: tất cả)
{
nếu (!db->FindOffsetById(id, kết quả))
trả về false;
}
trả về giá trị đúng;
}

void FreeAll(std::vector& tất cả)
{
đối với (cơ sở dữ liệu tự động: tất cả)
xóa db;
all.clear();
}

bool IsOk()
{
std::vectortất cả;
nếu (!LoadAll(tất cả))
{
_FATALERROR("Không tải được một hoặc nhiều cơ sở dữ liệu phiên bản cho tệp thực thi hiện tại!");
FreeAll(tất cả);
trả về false;
}

nếu (!ExistsInAll(tất cả, 517014))
{
_FATALERROR("517014 không tồn tại trong mọi phiên bản của cơ sở dữ liệu!");
FreeAll(tất cả);
trả về false;
}

FreeAll(tất cả);
// Được rồi!
trả về giá trị đúng;
}



Bằng cách này, bạn có thể chắc chắn rằng mod DLL của mình sẽ hoạt động trong mọi phiên bản hoặc nếu không hoạt động trong một số phiên bản, bạn có thể ghi điều đó trên trang mod của mình.

6. Đôi khi bạn cần phải làm điều gì đó khác biệt dựa trên phiên bản trò chơi đang chạy. Bạn có thể làm điều đó bằng đoạn mã sau:
Tiết lộ:
Trình diễn


int major = 0, minor = 0, revision = 0, build = 0;
nếu (!db.GetExecutableVersion(chính, phụ, sửa đổi, xây dựng))
{
_FATALERROR("Có gì đó không ổn!");
trả về false;
}

// Trò chơi đang chạy là 1.5.x và ít nhất là phiên bản 1.5.39.0
nếu (chính == 1 && phụ == 5 && sửa đổi >= 39)
{
// Chất liệu ... ?
}



7. Xin lưu ý: nếu bạn biên dịch SKSE DLL ở chế độ gỡ lỗi, thời gian tải cơ sở dữ liệu có thể mất khoảng 14 giây! Ở chế độ phát hành, thời gian này chỉ khoảng 0,2 giây. Điều này là do các container thư viện chuẩn rất chậm ở chế độ đó (bản đồ std).


Quyền

Bạn muốn làm gì thì làm.

Mod hàng đầu cho Legend of Mortal

Khám phá các mod tốt nhất cho Legend of Mortal mang đến các tính năng mới, đồ họa nâng cao và những cách thú vị để biến đổi trải nghiệm chơi game của bạn.

Mở khóa toàn bộ tiềm năng của Legend of Mortal với Xmod — khám phá các mod hàng đầu này ngay hôm nay!

mcafee
Nếu McAfee chặn cài đặt, nhấp vào đây.
Được 200,000,000+ người dùng tin tưởng

Cần trợ giúp về tải xuống hoặc cài đặt? Tham gia cộng đồng Discord của chúng tôi để được hỗ trợ!

logo
Ngôn ngữ

Giải pháp chơi game

Tài nguyên

Đối tác

Theo dõi chúng tôi trên

discordfacebooktwitteryoutube
dc@xmodhub.com or cathy@business.xmodhub.com
Discord: catherine_79237
Điều khoản và Điều kiện
Chính sách bảo mật
Hỗ trợ

Larvas Limited

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