• สินค้า
  • คุณสมบัติ
  • Mod Master
  • ดาวน์โหลด
  • เกม
  • บล็อก
  • การกำหนดราคา

ไลบรารีที่อยู่สำหรับปลั๊กอิน SKSE

ผู้แต่ง:meh321ปรับปรุงล่าสุด :2024-02-14 09:19:5421.1M2.3MB

The Elder Scrolls V: Skyrim Special Edition ไลบรารีที่อยู่สำหรับปลั๊กอิน SKSE-1-ม็อดมาสเตอร์ Lagofast

การแนะนำ Mod

ประกอบด้วยไฟล์ส่วนหัวและฐานข้อมูลเพื่อทำให้ปลั๊กอิน SKSE DLL แยกจากเวอร์ชันได้อย่างง่ายดาย
สำคัญ! ตอนนี้แบ่งออกเป็น 2 เวอร์ชัน: เวอร์ชันพิเศษ (1.5.x) และเวอร์ชันครบรอบ (1.6.x) รหัสที่ชี้ไปที่ที่อยู่จะไม่ตรงกันระหว่าง 2 เวอร์ชันนั้น (ไฟล์ปฏิบัติการของเกมแตกต่างกันเกินกว่าจะจับคู่ได้ และแม้ว่าจะตรงกับรหัสภายในฟังก์ชันเหล่านั้นก็ตามก็แตกต่างกันไปก็ตาม)

คำอธิบาย, คำอธิบาย

สำหรับผู้ใช้ mod ปกติ: ดาวน์โหลดและติดตั้งแพ็คเกจ "all-in-one" จากส่วนไฟล์ คุณสามารถใช้ตัวจัดการ mod หรือทำด้วยตนเองได้ ไฟล์ .bin ควรไปที่นี่:
ข้อมูล/SKSE/ปลั๊กอิน/
คุณไม่จำเป็นต้องอ่านส่วนที่เหลือของสิ่งนี้

สำหรับผู้เขียนปลั๊กอิน SKSE DLL:
นี่คือทรัพยากร modder (ไฟล์ส่วนหัว) คุณสามารถโหลดฐานข้อมูลที่จัดเก็บออฟเซ็ตได้ เพื่อให้ปลั๊กอิน DLL ของคุณสามารถเป็นอิสระจากเวอร์ชันได้โดยไม่ต้องคอมไพล์ใหม่ สามารถดาวน์โหลดไฟล์ส่วนหัวได้จากส่วนเสริมของไฟล์ สำหรับฉบับครบรอบ ไฟล์ส่วนหัวเรียกว่า versionlibdb.h แทนที่จะเป็น versiondb.h! หากคุณใช้ CommonLib ทั้งหมดนี้ถูกสร้างขึ้นแล้วและคุณไม่ต้องการอะไรจากที่นี่


วิธีการใช้งาน

วิธีที่เร็วที่สุด:
สปอยเลอร์:  
แสดง, แสดง


#รวม "versiondb.h"

void * MyAddress = NULL;
MyOffset ยาวที่ไม่มีลายเซ็น = 0;

bool InitializeOffsets ()
{
// จัดสรรบนสแต็กเพื่อให้จะถอดโหลดเมื่อเราออกจากฟังก์ชันนี้
//ไม่จำเป็นต้องโหลดฐานข้อมูลทั้งหมดและใช้หน่วยความจำหมดโดยไม่มีเหตุผล
เวอร์ชันdb db;

// โหลดฐานข้อมูลที่มีเวอร์ชันปฏิบัติการปัจจุบัน
ถ้า (!db.Load())
{
_FATALERROR("ไม่สามารถโหลดฐานข้อมูลเวอร์ชันสำหรับไฟล์ปฏิบัติการปัจจุบัน!");

}
อื่น ๆ
{
// "SkyrimSE.exe", "1.5.97.0"
_MESSAGE("โหลดฐานข้อมูลสำหรับ %s เวอร์ชัน %s.", db.GetModuleName().c_str(), db.GetLoadedVersionString().c_str());
}

// ที่อยู่นี้มีที่อยู่ฐานของโมดูลอยู่แล้ว ดังนั้นเราจึงสามารถใช้ที่อยู่ได้โดยตรง
MyAddress = db.FindAddressById(123);
ถ้า (ที่อยู่MyAddress==ว่าง)
{
_FATALERROR("ไม่พบที่อยู่!");
ส่งคืนเท็จ;
}

// ออฟเซ็ตนี้ไม่รวมที่อยู่ฐาน ที่อยู่จริงจะเป็น modulebase myoffset
ถ้า (!db.FindOffsetById(123, MyOffset))
{
_FATALERROR("ไม่พบการชดเชยสำหรับสิ่งของฉัน!");

}

//ทุกอย่างประสบความสำเร็จ
คืนความจริง;
}



ตอนนี้คุณกำลังสงสัยว่าค่า "123" นั่นคืออะไร นี่คือรหัสของที่อยู่ ฐานข้อมูลเวอร์ชันที่แตกต่างกันจะมีรหัสเดียวกันสำหรับที่อยู่ แต่อาจชี้ไปที่ค่าที่แตกต่างกัน เพื่อรับรายการคู่ ID และค่าทั้งหมดสำหรับเวอร์ชันเฉพาะ ทำดังนี้:

สปอยเลอร์:  
แสดง, แสดง


#รวม "versiondb.h"

บูลีนดัมพ์ SpecificVersion()
{
เวอร์ชันdb db;

// ลองโหลดฐานข้อมูลเวอร์ชัน 1.5.62.0 โดยไม่คำนึงถึงเวอร์ชันปฏิบัติการที่กำลังทำงานอยู่
ถ้า (!db.Load(1,5,62,0))
{
_FATALERROR("ไม่สามารถโหลดฐานข้อมูลสำหรับ 1.5.62.0!");
ส่งคืนเท็จ;
}

// เขียนไฟล์ที่เรียกว่า offsets-1.5.62.0.txt โดยแต่ละบรรทัดเป็น ID และ offset
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" หรืออะไรก็ตามที่คุณใส่เป็นชื่อไฟล์ มันจะอยู่ในรูปแบบที่แต่ละบรรทัดคือ:
รหัสทศนิยม<tab>การชดเชยหกสิบ<newline>

ตัวอย่างเช่น หากคุณมีที่อยู่ 142F4DEF8 (ตัวชี้คงที่อักขระผู้เล่น) ใน 1.5.62.0 ที่คุณต้องการทำให้เวอร์ชันเป็นอิสระจาก คุณจะทำเช่นนี้:
1. ค้นหา 2F4DEF8 ในไฟล์ออฟเซต เพราะนี่คือการออฟเซ็ตโดยไม่มีฐาน 140000000
2. ดูว่ารหัสคือ 517014 (ทศนิยม!)
3. หากคุณต้องการที่อยู่นี้ใน DLL ของคุณที่รันไทม์ทำสิ่งนี้:


void * addressOf142F4DEF8 = db.FindAddressById(517014);


และคุณมีมันอยู่ที่นั่น

โครงสร้าง VersionDb มีฟังก์ชันดังต่อไปนี้:
สปอยเลอร์:  
แสดง, แสดง


บูลดัมป์ (const std::สตริง // ทิ้งฐานข้อมูลที่โหลดอยู่ปัจจุบันไปยังไฟล์
โหลด bool (int major, int minor, int revision, int build); // โหลดเวอร์ชันเฉพาะหาก db-major-minor-revision-build.bin มีอยู่ในไดเรกทอรี Data/SKSE/Plugins
โหลดโบูล (); // โหลดเวอร์ชันสำหรับแอปพลิเคชันปัจจุบัน
void Clear (); // ล้างฐานข้อมูลที่โหลดอยู่ปัจจุบัน
void GetLoadedVersion (int // รับเวอร์ชันของไฟล์ฐานข้อมูลที่เราโหลดแล้วตอนนี้
bool GetExecutableVersion (int // รับเวอร์ชันของแอปพลิเคชันที่กำลังดำเนินการอยู่
const std::string // รับชื่อโมดูลฐานข้อมูลที่โหลดอยู่ปัจจุบัน สิ่งนี้ควรแสดง "SkyrimSE.exe"
const std::string // รับเวอร์ชันที่โหลดอยู่ปัจจุบันเป็นสตริง เช่น "1.5.62.0"
const std::แผนที่<unsigned long long, unsigned long long>& GetOffsetMap() const; // รับแผนที่ของ ID เพื่อชดเชยหากคุณต้องการทำซ้ำด้วยตนเอง
void * FindAddressById (รหัสยาวที่ไม่มีลายเซ็น) const; // ค้นหาที่อยู่ตามรหัส ซึ่งจะรวมที่อยู่ฐานและเป็นที่อยู่ที่ถูกต้องแล้ว มันจะกลับมาเป็นโมฆะหากไม่พบ!
bool FindOffsetById (รหัสยาวที่ไม่มีลายเซ็น, ไม่มีลายเซ็นยาว // ค้นหาการชดเชยตามรหัส สิ่งนี้จะถูกชดเชยโดยไม่รวมฐาน
bool findbyaddress (void * ptr, ไม่มีลายเซ็นยาว // ค้นหา ID ตามที่อยู่ สิ่งนี้จะพยายามค้นหาย้อนกลับเพื่อแปลงที่อยู่เป็น ID
bool findbyoffset (ชดเชยยาวที่ไม่มีลายเซ็น ชดเชยยาวที่ไม่มีลายเซ็น // ค้นหา ID โดย offset ซึ่งจะพยายามค้นหาย้อนกลับเพื่อแปลง offset เป็น ID



สิ่งที่คุณควรรู้และจำไว้:

1. คุณสามารถรวมไฟล์ฐานข้อมูลใด ๆ (หรือทั้งหมด) กับปลั๊กอินของคุณ แต่อาจเพิ่มขนาดไฟล์อย่างมาก (ประมาณ 2.5mb) จนถึงตอนนี้ เป็นเรื่องปกติที่จะทำเครื่องหมาย mod นี้ว่าเป็นการพึ่งพาแทน

2. คุณควรโหลดฐานข้อมูลเพียงครั้งเดียวเมื่อเริ่มต้นเริ่มต้น / แคชที่อยู่ที่คุณต้องการและปล่อยให้มันถอนโหลด การขนถ่ายหมายความว่าโครงสร้าง VersionDb จะถูกลบหรือสูญหาย (หากคุณจัดสรรบนสแต็ก) สิ่งนี้จะทำให้แน่ใจว่าคุณจะไม่ใช้หน่วยความจำจำนวนไม่จำเป็นในระหว่างรันไทม์เกม ไม่จำเป็นต้องโหลดฐานข้อมูลระหว่างการเล่นเกม นี่เป็นจุดถกเถียงกันหากคุณใช้ CommonLib เนื่องจากโหลดเพียงครั้งเดียวแทนที่จะโหลดสำหรับแต่ละ DLL

3. ฐานข้อมูลประกอบด้วยที่อยู่ของฟังก์ชัน, ตัวแปรทั่วโลก, RTTI, vtables และอื่น ๆ ที่อาจมีการอ้างอิงถึงมัน มันไม่มีที่อยู่ที่อยู่ตรงกลางของฟังก์ชันหรือตรงกลางของโลก หากคุณต้องการที่อยู่ตรงกลางของฟังก์ชัน คุณควรค้นหาที่อยู่ฐานของฟังก์ชันและเพิ่มชดเชยพิเศษด้วยตัวเอง นอกจากนี้ยังไม่มีสิ่งที่ไร้ประโยชน์ เช่น การจัดตำแหน่งรอบฟังก์ชัน (ซึ่งอ้างอิงใน rdata) ส่วน pdata จะถูกทิ้ง และข้อมูล SEH ที่สร้างโดยคอมไพเลอร์จาก rdata จะถูกทิ้ง

4. คุณควรตรวจสอบผลลัพธ์เสมอเพื่อให้แน่ใจว่าฐานข้อมูลที่โหลดสำเร็จ (โหลด bool ส่งคืนความจริง) และที่อยู่ที่สืบค้นจะส่งคืนผลลัพธ์ที่ถูกต้อง (ไม่ใช่ NULL) หากโหลดล้มเหลว แสดงว่าไฟล์หายไปมากที่สุดหรือเวอร์ชันผิด (เช่น พยายามใช้ส่วนหัว SE ใน AE) หากแบบสอบถามล้มเหลว หมายความว่าไม่พบที่อยู่ในเวอร์ชันนั้น นี่อาจหมายความว่ารหัสเกมมีการเปลี่ยนแปลงเพียงพอที่จะทำให้ที่อยู่ไม่ถูกต้องสำหรับเวอร์ชันนั้นอีกต่อไป หรือฐานข้อมูลเองไม่สามารถตรวจจับที่อยู่ที่ถูกต้องได้ หากสิ่งเหล่านี้เกิดขึ้น คุณควรล้มเหลวในการเริ่มต้นปลั๊กอินเพื่อแจ้งให้ SKSE ทราบว่าคุณโหลดไม่ถูกต้อง หรือแสดงข้อความแสดงข้อผิดพลาดด้วยตนเอง

5. มันจะเป็นการดีที่สุดถ้าคุณตรวจสอบเพื่อให้แน่ใจว่าที่อยู่มีอยู่ในทุกเวอร์ชันของเกมก่อนที่จะเผยแพร่ปลั๊กอิน DLL ของคุณ เพื่อทำการโหลดไฟล์ฐานข้อมูลแต่ละเวอร์ชันและสืบค้นรหัสที่อยู่เดียวกันในแต่ละไฟล์เพื่อให้แน่ใจว่ามีอยู่:
สปอยเลอร์:  
แสดง, แสดง


โหลด bool (std::เวกเตอร์<VersionDb*>& ทั้งหมด)
{
เวอร์ชัน int คงที่ [] = {3, 16, 23, 39, 50, 53, 62, 73, 80, 97, -1};
สำหรับ (int i=0;version[i]>=0;i++)
{
เวอร์ชัน * db = เวอร์ชันใหม่ ();
if(!db->โหลด(1, 5,เวอร์ชัน [i], 0))
{
ลบ db;
ส่งคืนเท็จ;
}
all.push_back(db);
}
คืนความจริง;
}

bool existensinall (std::เวกเตอร์<VersionDb*>& ทั้งหมด id ยาวที่ไม่มีลายเซ็น)
{
ผลลัพธ์ยาวที่ไม่ได้ลงนาม = 0;

{
if(!db-> FindOffsetById(id, ผลลัพธ์))

}
คืนความจริง;
}

void FreeAll (std::เวกเตอร์<VersionDb*>& ทั้งหมด)
{
สำหรับ (อัตโนมัติ db: ทั้งหมด)
ลบ db;
all.clear();
}

บูลีน IsOk()
{
std::เวกเตอร์<VersionDb*>ทั้งหมด;
ถ้า (!LoadAll (ทั้งหมด))
{
_FATALERROR ("ล้มเหลวในการโหลดฐานข้อมูลเวอร์ชันหนึ่งฉบับขึ้นไปสำหรับไฟล์ปฏิบัติการปัจจุบัน!");
ฟรีทั้งหมด (ทั้งหมด);
ส่งคืนเท็จ;
}

ถ้า (! existensinall (ทั้งหมด, 517014))
{
_FATALERROR("517014 ไม่มีอยู่ในฐานข้อมูลทุกเวอร์ชัน!");


}

ฟรีทั้งหมด (ทั้งหมด);
//โอเค!
คืนความจริง;
}



ด้วยวิธีนี้ คุณสามารถมั่นใจได้ว่า DLL mod ของคุณจะทำงานได้ในทุกเวอร์ชัน หรือหากไม่ทำงานในบางเวอร์ชัน คุณสามารถเขียนไว้ในหน้า mod ของคุณได้

6. บางครั้งคุณจะต้องทำสิ่งที่แตกต่างกันตามเวอร์ชันเกมที่กำลังทำงานอยู่ คุณสามารถทำได้ด้วยตัวอย่างโค้ดนี้:
สปอยเลอร์:  
แสดง, แสดง


int major = 0, minor = 0, แก้ไข = 0, build = 0;
if(!db.GetExecutableVersion(หลัก, รอง, การแก้ไข, สร้าง))
{
_FATALERROR("มีบางอย่างผิดปกติ!");
ส่งคืนเท็จ;
}

//รันเกมคือ 1.5.x และอย่างน้อยเวอร์ชัน 1.5.39.0
ถ้า (หลัก = 1 & & รอง = = 5 & & แก้ไข > = 39)
{
// ของ...?
}



7. โปรดจำไว้: หากคุณรวบรวม SKSE DLL ของคุณในโหมดการดีบักเวลาโหลดของฐานข้อมูลอาจประมาณ 14 วินาที! ในโหมดปล่อยประมาณ 0.2 วินาที นี่เป็นเพราะคอนเทนเนอร์ไลบรารีมาตรฐานช้ามากในโหมดนั้น (แผนที่ std)


สิทธิ์, การอนุญาต

ทำทุกอย่างที่คุณต้องการ
เครื่องมือนี้จัดทำโดยบุคคลที่สาม [bufftool]ความสนใจระดับปกติ

ดาวน์โหลด Mods ทันที

ติดตั้ง LagoFast เริ่มต้น The Elder Scrolls V: Skyrim Special Edition และเล่นกับ mod ที่คุณชื่นชอบ