• Produkte
  • Funktionen
  • Mod Master
  • Herunterladen
  • Spiele
  • Blog
  • Preisgestaltung

Adressbibliothek für SKSE-Plugins

Autor:meh321Letzte Aktualisierung:14/02/2024 09:19:5421.1M2.3MB

The Elder Scrolls V: Skyrim Special Edition Adressbibliothek für SKSE-Plugins-1-lagofast mod master

Mod-Einführung

Enthält eine Header-Datei und eine Datenbank, um SKSE-DLL-Plugins einfach versionsunabhängig zu machen.
Wichtig! Diese ist nun in zwei Versionen aufgeteilt: die Special Edition (1.5.x) und die Jubiläumsversion (1.6.x). Die IDs, die auf die Adresse verweisen, werden zwischen den beiden Versionen nicht übereinstimmen (die Spielausführungsdateien sind zu unterschiedlich, um übereinstimmen zu können, und selbst wenn sie übereinstimmen, ist der Code in diesen Funktionen anders).

Beschreibung

Für normale mod-Benutzer: Downloaden und installieren Sie das "All-in-One" Paket aus dem Abschnitt Dateien. Sie können es mit dem mod manager oder manuell ausführen. Die. bin Datei sollte hier angeordnet werden:
Daten/SKSE/Plugins/
Du musst den Rest nicht lesen.

Für SKSE DLL-Plugin-Autor:
Dies ist eine modder-Ressource (Header-Datei). Sie können eine Datenbank laden, in der die Offsets gespeichert werden, so dass Ihre DLL-Plugins versionsunabhängig werden können, ohne dass sie neu kompiliert werden müssen. Die Header-Datei kann aus einem optionalen Teil der Datei heruntergeladen werden. Für die Jubiläumsversion heißt die Headerdatei versionlibdb.h, nicht versiondb.h! Wenn Sie CommonLib verwenden, dann ist das alles bereits eingebaut und Sie brauchen hier nichts.


Wie zu benutzen

Der schnellste Weg:
Spoiler:  
Anzeigen


# enthält "versiondb.h"

void*MyAddress=NULL
Ohne Vorzeichen lang lang MyOffset=0;

bool InitializeOffsets ()
{
//auf dem Stack zugewiesen, so dass diese Funktion entladen wird, wenn wir diese Funktion verlassen.
//Es ist nicht nötig, die gesamte Datenbank zu laden und den Speicher ohne Grund zu erschöpfen.
Versionsdatenbankdatenbank;

//Laden Sie die Datenbank mit der aktuellen ausführbaren Version.
if(!db.Load ())
{
_FATALERROR("Die Versionsdatenbank der aktuellen ausführbaren Datei konnte nicht geladen werden! ");

}
else
{
//"SkyrimSE.exe", "1.5.97.0"
_MESSAGE("Datenbank mit %s Version %s geladen ", db.GetModuleName().c_str (), db.GetLoadedVersionString (). c_str ());
}

//Diese Adresse enthält bereits die Basisadresse des Moduls, so dass wir diese Adresse direkt verwenden können.
MyAddress=db.FindAddressById(123);
if(MyAddress==NULL)
{
_FATALERROR("Adresse nicht gefunden! ");
Rückgabe false;
}

//Dieser Offset enthält keine Basisadresse. Die physische Adresse lautet ModuleBase+MyOffset.
if(!db.FindOffsetById(123, MyOffset))
{
_FATALERROR("Offset für meine Dinge nicht gefunden! ");

}

//Alles war erfolgreich.
Gibt true zurück;
}



Jetzt wollen Sie wissen, was der Wert von "123" dort ist. Dies ist die ID einer Adresse. Verschiedene Versionen der Datenbank haben dieselbe Adress-ID, aber sie kann auf unterschiedliche Werte verweisen. Um eine Liste aller ID- und Wertpaare für eine bestimmte Version abzurufen:

Spoiler:  
Anzeigen


# enthält "versiondb.h"

Boolean Dump SpecificVersion ()
{
Versionsdatenbankdatenbank;

//Versuchen Sie, die Datenbank der Version 1.5.62.0 zu laden, unabhängig von der ausführbaren Version.
If(!db.Load(1,5,62,0))
{
_FATALERROR("Datenbank für 1.5.62.0 konnte nicht geladen werden! ");
Rückgabe false;
}

//Schreiben Sie eine Datei mit dem Namen offsets-1.5.62.0.txt aus, in der jede Zeile die ID und den Offset enthält.
db.Dump("offsets-1.5.62.0.txt ");
_MESSAGE("Dump-Offset für 1.5.62.0 ");
Gibt true zurück;
}



Verwenden Sie nicht 1,5,62,0, sondern die Version, mit der Sie umkehren und vertraut sind. Sie müssen zunächst die entsprechende Datenbankdatei im Verzeichnis /Data/SKSE/Plugins haben.

Nach dem Aufruf sollten Sie eine neue Datei mit dem Namen "offsets-1.5.62.0.txt" oder einen beliebigen Dateinamen im Skyrim Home-Verzeichnis haben. Jede Zeile ist wie folgt formatiert:
Dezimal-ID<tab>Sechskantversatz<newline>

Wenn Sie beispielsweise eine Adresse 142F4DEF8 (statischer Zeiger für den Spielercharakter) in 1.5.62.0 haben, die Sie versionsunabhängig machen möchten, können Sie dies tun:
1. Suchen Sie nach 2F4DEF8 in der offsets-Datei. Weil dies ein Offset ohne Basis 140000000 ist
2. Sehen Sie, dass die ID 517014 ist (Dezimal!)
3. Wenn Sie diese Adresse zur Laufzeit in der DLL aufnehmen möchten, gehen Sie wie folgt vor:


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


Jetzt hast du es.

Die VersionDb-Struktur hat folgende Funktionen:
Spoiler:  
Anzeigen


Boolesche Dumps (konstante Standard::Strings und Pfade); //Dump der aktuell geladenen Datenbank in eine Datei
Bull Load (int major, int minor, int revision, int build); //Laden einer bestimmten Version, wenn db-major-minor-revision-build.bin im Verzeichnis Data/SKSE/Plugins vorhanden ist
bool Load (); //Laden Sie die Version der aktuellen Anwendung
void Clear (); //löschen Sie die aktuell geladene Datenbank
void GetLoadedVersion (int&major, int&minor, int&revision, int&build) Konstante; //Holen Sie sich die Version der Datenbankdatei, die wir jetzt laden
bool GetExecutableVersion(int&major, int&minor, int&revision, int&build) Konstante; //ruft die Version der aktuell ausgeführten Anwendung ab
const std::string & GetModuleName () const; //Ruft den Namen des aktuell geladenen Datenbankmoduls ab, das "SkyrimSE.exe" anzeigen soll
const std::string & GetLoadedVersionString () const; //erhält die aktuell geladene Version als String, z.B. "1.5.62.0"
const std::map<unsigned long long, unsigned long long>& GetOffsetMap () Konstante; //Falls eine manuelle Iteration erforderlich ist, erhält man die Zuordnung der zu verschiebenden IDs
void*FindAddressById (unsigned long id) Konstante; //Suchen Sie die Adresse nach ID, die bereits die Basisadresse enthält und die richtige Adresse ist. Wenn es nicht gefunden wird, gibt es NULL zurück!
bool FindOffsetById (unsigned long id, unsigned long & result) konstant; //Finden Sie den Offset nach ID, der einfach den Offset ohne die Kardinalität einschließt.
bool FindIdByAddress(void * ptr, unsigned long long & result) Konstante; //Suche nach einer ID nach Adresse, die versucht, eine umgekehrte Suche zu versuchen, die Adresse in eine ID zu übersetzen
bool FindIdByOffset (Längenversatz ohne Vorzeichen, Längenversatz ohne Vorzeichen //Finden Sie die ID nach Offset, das versucht, umgekehrt zu suchen, um den Offset in die ID umzuwandeln



Dinge, die Sie wissen und beachten sollten:

1. Sie können beliebige (oder alle) Datenbankdateien in das Plugin einbeziehen, aber dies kann die Dateigröße erheblich erhöhen (ca. 2,5 MB). Bisher war es üblich, diesen mod als Abhängigkeit zu markieren.

2. Sie sollten die Datenbank immer nur einmal beim Start laden, die benötigten Adressen initialisieren/zwischengespeichern und sie entladen lassen. Deinstallation bedeutet einfach, dass die VersionDb-Struktur entfernt oder verloren geht (wenn Sie sie auf dem Stack zuweisen). Dadurch wird sichergestellt, dass Sie keinen unnötigen Speicher verwenden, während das Spiel läuft. Es ist nicht notwendig, die Datenbank während des Spiels geladen zu halten. Wenn Sie CommonLib verwenden, ist dies ein umstrittenes Thema, da es nur einmal geladen wird und nicht für jede DLL.

3. Die Datenbank enthält Adressen von Funktionen, globalen Variablen, RTTI, vtables und alles andere, auf das verwiesen werden kann. Es enthält keine Adressen, die in der Mitte der Funktion oder in der globalen Mitte liegen. Wenn Sie eine Adresse in der Mitte einer Funktion benötigen, sollten Sie die Basisadresse der Funktion suchen und selbst einen zusätzlichen Offset hinzufügen. Es enthält auch keine nutzlosen Dinge wie Ausrichtungen um Funktionen (die in rdata referenziert werden), der pdata-Teil wird verworfen und einige der SEH-Informationen, die vom Compiler aus rdata generiert werden, werden verworfen.

4. Sie sollten immer die Ergebnisse überprüfen, um sicherzustellen, dass die Datenbank erfolgreich geladen wurde (bool Load gibt true zurück) und dass die abgefragte Adresse tatsächlich ein gültiges Ergebnis liefert (nicht NULL). Wenn es nicht geladen wird, bedeutet dies, dass die Datei wahrscheinlich fehlt oder falsch versioniert ist (z. B. wenn Sie versuchen, den SE-Header in AE zu verwenden). Wenn die Abfrage fehlschlägt, bedeutet dies, dass die Adresse in dieser Version nicht gefunden werden kann. Dies kann bedeuten, dass sich der Spielcode stark genug geändert hat, dass die Adresse für diese Version nicht mehr gültig ist, oder dass die Datenbank selbst die richtige Adresse nicht erkennt. Wenn eine dieser beiden Situationen eintritt, sollten Sie die Initialisierung des Plugins fehlschlagen lassen und SKSE wissen lassen, dass Sie es nicht richtig geladen haben. Oder die Fehlermeldung manuell anzeigen.

5. Es ist auch am besten, wenn Sie überprüfen, um sicherzustellen, dass die Adresse in allen Versionen des Spiels existiert, bevor Sie das DLL-Plugin veröffentlichen. Laden Sie dazu jede Version der Datenbankdatei und fragen Sie in jeder Version nach derselben Adress-ID ab, um sicherzustellen, dass sie vorhanden ist:
Spoiler:  
Anzeigen


bool LoadAll(std::vector<VersionDb*>& alle
{
Statische int version [] = {3, 16, 23, 39, 50, 53, 62, 73, 80, 97, -1};
Für (int i=0; version[i] > = 0; i ++)
{
version db * db = neue version db ();
if(!db- > Ladung (1, 5, Version[i], 0))
{
Löschen Sie die Datenbank;
Rückgabe false;
}
all.push_back (db);
}
Gibt true zurück;
}

bool ExistsInAll(std::vector<VersionDb*>& all, lange id ohne Vorzeichen
{
Länge ohne Vorzeichen Ergebnis = 0;

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

}
Gibt true zurück;
}

void FreeAll(std::vector<VersionDb*>& alle
{
Für (automatische Datenbanken: alle)
Löschen Sie die Datenbank;
Alle. clear ();
}

Boolean IsOk ()
{
std::vector<VersionDb*>Alle;
if(!LoadAll(all))
{
_FATALERROR("Eine oder mehrere Versionsdatenbanken der aktuellen ausführbaren Datei konnten nicht geladen werden! ");
FreeAll (alle);
Rückgabe false;
}

if(!ExistsInAll(all,517014))
{
_FATALERROR("517014 existiert nicht in allen Versionen der Datenbank! ");


}

FreeAll (alle);
//OK!
Gibt true zurück;
}



Auf diese Weise können Sie sicherstellen, dass Ihr DLL mod in allen Versionen funktioniert, oder wenn es in einigen Versionen nicht funktioniert, können Sie es auf Ihrer mod-Seite schreiben.

6. Manchmal müssen Sie etwas anderes tun, je nachdem, welche Version des Spiels Sie laufen. Sie können dies mit dem folgenden Code-Snippet tun:
Spoiler:  
Anzeigen


int major = 0, minor = 0, revision = 0, build = 0;
if(!db.GetExecutableVersion(major, minor, revision, build))
{
_FATALERROR("Etwas ist schief gelaufen! ");
Rückgabe false;
}

//Das laufende Spiel ist 1.5.x und mindestens die Version 1.5.39.0
Wenn (Haupt==1&&Minor==5&&Revisions>=39)
{
//Dinge...?
}



7. Denken Sie daran: Wenn Sie Ihre SKSE-DLL im Debug-Modus kompilieren, kann die Ladezeit der Datenbank etwa 14 Sekunden betragen! Im Freigabemodus beträgt dies etwa 0,2 Sekunden. Dies liegt daran, dass der Standardbibliothekscontainer in diesem Modus sehr langsam ist (std map).


Berechtigungen

Du kannst tun, was du willst.
Dieses Tool wird von der Drittpartei [bufftool] bereitgestellt.Hinweis-Symbol

Mods jetzt herunterladen

Installieren Sie LagoFast, starten Sie The Elder Scrolls V: Skyrim Special Edition und spielen Sie mit den Mods, die Sie lieben.