Heutzutage ist es sehr schwierig, solide Informationen und echte Hilfe in Bezug auf S3PI zu finden. Wenn Sie versuchen, ein Programm mit S3PI als Bibliothek zu erstellen, um mit den SIMS -Paketdateien zu interagieren. Darüber hinaus befindet sich die S3PI -Bibliothek nicht auf GitHub und hat hier kein Repository.
Aus diesen Gründen habe ich beschlossen, dieses Repository zu erstellen, um die S3PI -Bibliothek in ihrer Gesamtheit zu speichern, mit Codebeispielen und Tipps zur korrekten Verwendung. Darüber hinaus habe ich hier alle nützlichen Informationen zusammengestellt, die ich im Internet im Zusammenhang mit S3PI gefunden habe!
Wenn Sie weitere Informationen beitragen möchten, erstellen Sie bitte eine Pull -Anfrage oder melden Sie sie über die Registerkarte "Probleme". Ich werde mein Bestes tun, um dieses Repository mit so vielen Informationen und Beispielen wie möglich zu halten. Wenn der Autor von S3PI es jedoch anfordert, werde ich dieses Repository offline machen.
Wichtig
Wenn Sie sich daran erinnern, dass alle Credits für die Erstellung der S3PI -Bibliothek an den unglaublichen "Peter L Jones" gehen!
Die "SIMS 3 Package Interface" bietet eine Kernbibliothek mit tragbarem Code, die SIMS3 -Spielpakete "versteht". Beachten Sie, dass (mit einigen kleinen Verbesserungen) der Core -Bibliothekscode auch andere Spielpaketformate (z. B. SimCity online, SIMS4) versteht.
Zusammen mit der Kernbibliothek gibt es eine Reihe von "Wrappern", die den Hauptteil des Projekts bieten. Diese verarbeiten die Deserialisierung und Serialisierung von Daten innerhalb des Pakets (oder einer anderen Quelle).
Weitere Tools können diese Bibliothek und Wrapper verwenden, um den Dateninhalt von Paketdateien von Sims Games zu manipulieren.
Beachten Sie, dass die Entwicklung dieser Bibliothek und der hier bereitgestellten Verpackungen jetzt fertig ist.
Das "S3PI" ist ein Akronym für "SIMS3 ™ Package Interface". Es bietet Unterstützung für den Zugriff auf die Daten in einzelnen "Paket" -Dateien, die vom Electronic Arts SIMS3 ™ -Pame verwendet werden. Ein "Paket" ist eine Festplattendatei mit einer Dateierweiterung, die normalerweise ".package" (andere Erweiterungen werden verwendet). Die von S3PI verwendete Haupt identifizierende Funktion ist jedoch das vier Byte -Magic Cookie zu Beginn der Datei, die "dbpf" sein muss. Darüber hinaus muss die Versionsnummer der Dateiformat 2 für Sims 3 ™ (oder 3 für Sim City 5 ™, die kaum unterstützt wird).
Beachten Sie, dass "geschützte" Pakete (mit einem magischen Keks von "DBPP") nicht unterstützt werden. Beachten Sie, dass "temporäre" Pakete (mit einem magischen Cookie von "DBBF") derzeit nicht unterstützt werden.
Der S3PI ist eine Reihe von .NET-Assemblys (unten dokumentiert und hier verfügbar), die die Beschreibungen aus dem Sims 3-Wiki implementieren (wobei diese Seiten hier alternativ als Wiki-Mirror verfügbar sind). Beachten Sie, dass es immer lohnt, dort zu überprüfen, ob Sie sich nicht sicher sind, entweder darüber, wie etwas funktionieren sollte oder wenn Sie der Meinung sind, dass Sie in S3PI ein Problem gefunden haben, was nach wie vor möglich ist. Weder das Wiki noch die Bibliothek sind immer richtig - in der Tat kann es sein, dass beide auf unterschiedliche Weise falsch sind.
Die S3PI -Bibliothek verfügt über eine kompilierte Hilfedatei (.Chm), die viel von dem beschreibt, was Sie wissen müssen. Hier können Sie auch auf eine Version davon zugreifen. Diese Seite versucht, einen kurzen Überblick zu geben, da die Bibliothek ziemlich umfangreich ist und es schwierig ist, herauszufinden, was Sie wissen müssen.
Diese Seite ist in drei verbleibende Abschnitte unterteilt.
Sobald Sie verstanden haben, wie Sie einen Wrapper verwenden, um in einem Paket auf Daten zuzugreifen, sollten Sie die SIMS3 -Wiki -Liste der Dateitypen konsultieren, um festzustellen, welche unterstützt werden und wie Sie die Unterstützung erhalten (wenn nicht sogar Teil der S3PI -Verteilung).
Tipp
Wenn Sie unbeantwortete Fragen haben, können Sie hier im Forum/in den Diskussionen hier posten. Es wird eine Freude sein, zu helfen!
Die Bibliothek ist ein Satz von .NET -Assembly -DLLs. Wenn Sie wahrscheinlich an mehr als einem Projekt mit der Bibliothek arbeiten, empfehle ich dringend, sie in einen Ordner zu setzen, der von Ihren Projekt- und Lösungs -Arbeitsbereichen getrennt ist - jedoch in Ihrer Ordnerstruktur. Auf diese Weise ist es einfach, sie alle zu ersetzen, ohne jedes Projekt aktualisieren zu müssen.
Um die Bibliothek aus einem neuen Projekt aus zu verwenden, müssen Sie zunächst wissen, welche Teile der Bibliothek Sie verwenden werden. Ich habe die abhängigen Teile absichtlich getrennt gehalten, damit Ihr Projekt nur auf die DLLs verweisen muss, die es benötigt, und so Ihr Projekt in der Größe niedrig hält. Der Nachteil ist, dass es viele DLLs gibt!
Das erste, was zu bemerken ist, ist, dass viele von ihnen "Wrapper" sind - irgendetwas mit einem Namen wie SomethingResource.DLL . Diese enthalten den Code, um den Inhalt einer oder mehrerer Ressourcen in einer SIMS 3 -Paketdatei zu verstehen.
Schauen wir uns zunächst jeden der verbleibenden Baugruppen an. Danach werde ich einen Überblick darüber geben, wie ein neues Projekt gestartet werden kann. Ich werde mit einigen Gedanken über die Organisation Ihrer Arbeitspraktiken enden.
Notiz
Sie müssen der GPLV3 -Lizenz zustimmen, bevor Sie Ihren Code verteilen. Beachten Sie, dass Sie, wenn Sie mit einer GPLV3-Bibliothek verknüpfen, sie im Wesentlichen wiederverwenden und Ihren Code unter äquivalenten Bedingungen verteilen müssen. Weitere Details auf der Website der kostenlosen Software -Stiftung finden Sie.
Wann einbezieht: Immer - es ist von mehreren anderen Teilen der Bibliothek erforderlich.
Zusammenfassung: Enthält eine Reihe von Klassen, die sich nicht direkt auf "Sims 3" beziehen und keine Verweise auf einen der s3pi.Interfaces -Typen haben. Sie könnten möglicherweise von Nutzen für Projekte sein, die nicht den Rest der S3PI -Bibliothek verwenden (damit sie getrennt halten).
Weitere Lektüre: Wenn Sie diese Versammlung verweisen, erhalten Sie die folgenden ...
System.Collections.Generic.AHandlerList<T> - Abstract -Erweiterung der List<T> Feedback zu Listen -Updates über einen mitgelieferten EventHandler bereitgestellt.System.ArgumentLengthException - repräsentiert einen Fehler in der Länge eines Arguments zu einer Methode.System.Extensions - Nützliche Erweiterungsmethoden, die nicht von LINQ (und ohne aufgeschobene Ausführung) bereitgestellt werden. (Der Klassenname ist zweifelhaft und kann sich ändern ...)System.Security.Cryptography.FNV32 - Fnv32 Hash -RoutineSystem.Security.Cryptography.FNV64 - FNV64 Hash -RoutineSystem.Text.SevenBitString -Lesen und schreiben Sie eine sieben-Bit-codierte Länge-vorgefertigte Zeichenfolge in einer gegebenen Encoding von oder in einen Stream .System.Security.Cryptography.Sims3PackCRC - Berechnen Sie die CRC eines Datenblocks, das in einer SIMS3Pack -Datei gespeichert ist. (OK, dies hat wohl keinen Grund, hier zu sein, aber in Bezug auf Codeabhängigkeiten macht es Sinn!) Wann soll es einbezogen werden: Immer.
Zusammenfassung: Ursprünglich gedacht, dass verschiedene Einstellungen in der Bibliothek durch Ersetzen der DLL geändert werden können. Das ist noch nie passiert.
Weitere Lesen: Nichts.
Wann soll es einbezogen werden: Immer. Die Bibliothek selbst ist nicht nur erforderlich, sondern definiert auch die öffentliche API.
Zusammenfassung: Bietet eine Reihe von Schnittstellen, abstrakten Klassen und Helferklassen, die in der gesamten Bibliothek und Verpackungen verwendet werden, die die öffentlichen Methoden der verschiedenen Bibliotheksklassen definieren.
Weitere Lektüre:
s3pi.Interfaces Namespace -Dokumentation. Beachten Sie, dass der Namespace durch Klassen aus s3pi.GenericRCOL "verschmutzt" wird. Puristen könnten auch einige der Helferklassen als "Verschmutzung" in Betracht ziehen ...
Wann fügen Sie es hinzu: Wenn Sie mit Sims 3 -Paketdateien arbeiten.
Zusammenfassung: Bietet die konkrete Implementierung der abstrakten Klassen und Schnittstellen, die in s3pi.Interfaces definiert sind.
Weitere Lesen: Nichts.
Wann fügen Sie es hinzu: Wenn Sie mit Ressourcenverpackungen arbeiten.
Zusammenfassung: Wenn Sie neue Ressourcen erstellen oder Ressourcen aus einem Paket lesen, ist dies der empfohlene Mechanismus. Alternativen existieren jedoch.
Weitere Lektüre:
s3pi.WrapperDealer.WrapperDealer - Verantwortlich für die Assoziation ResourceType im IResourceIndexEntry mit einer bestimmten Klasse (eine "Wrapper"), die sie oder die Standardverpackung versteht. Die s3pi.DefaultResource und s3pi.GenericRCOLResource bieten die Grundlagen, um zu verstehen, wie Sie eine Ressource verwenden, sobald Sie einen Verweis darauf haben.
Wann fügen Sie es hinzu: Wenn Sie Community -Standard -Dateinamen möchten.
Zusammenfassung: Zu Beginn der SIMS 3 stimmte die Modding -Community ein festgelegtes Format zu, wie eine verpackte Ressource außerhalb einer Paketdatei benannt werden sollte. Diese Baugruppe bietet die Implementierung für die S3PI -Bibliothek.
Weitere Lektüre: s3pi.Extensions namespace. Dieser Bereich der Bibliothek muss noch ordnungsgemäß dokumentiert werden.
Wann fügen Sie es hinzu: Wenn Sie CopyableMessageBox (oder Problemexception) wünschen.
Zusammenfassung: Diese Baugruppe bietet eine Möglichkeit, Nachrichten anzuzeigen, mit denen der Benutzer den Inhalt einfach kopieren kann. In Zukunft können hier andere allgemeine Kontrollen erscheinen.
Weitere Lektüre: CopyableMessageBox -Klasse, CopyableMessageBoxButtons Enumeration und CopyableMessageBoxIcon -Aufzählung.
Wann fügen Sie es hinzu: Wenn Sie eine der benutzerdefinierten Steuerelemente wünschen.
Zusammenfassung: Diese Baugruppe enthält benutzerdefinierte Steuerelemente in Bezug auf Datentypen in S3PI.
Weitere Lektüre: ResourceTypeCombo -Klasse, TGIBlockCombo -Klasse und TGIBlockListEditor -Klasse. Dieser Bereich der Bibliothek muss noch ordnungsgemäß dokumentiert werden.
Wann einbezieht: Wenn Sie DDS -Bilder verwenden und eine Möglichkeit in einer WinForms -Anwendung anzeigen möchten.
Zusammenfassung: Diese Baugruppe bietet eine benutzerdefinierte Steuerung und einen DDS -Ressourcenunterstützung.
Weitere Lektüre: DDSPanel -Klasse und DDSPanel.MaskChannel -Aufzählung.
Wann Sie es einbeziehen: Kann beim Schreiben eines Helfers für S3PE nützlich sein.
Zusammenfassung: Bietet Unterstützung für die Zuordnung einer Ressource auf ein oder mehrere Programme, die sich für diese Art von Ressource möglicherweise interessieren.
Weitere Lektüre: s3pi.Helpers namespace. Dieser Bereich der Bibliothek muss noch ordnungsgemäß dokumentiert werden.
Richten s3pi.Settings die Referenzen ein s3pi.Interfaces die Sie basierend auf dem vorherigen System.Custom benötigen. Darüber hinaus müssen Sie prüfen, ob Sie auf bestimmte Wrapper -Baugruppen verweisen möchten. In den meisten Fällen ist dies der angemessene Ansatz. Ihre referenzierten Baugruppen werden standardmäßig zusammen mit Ihrem Programm in den Projektausgangsordner kopiert.
Beachten Sie, dass bestimmte zusätzliche Komponenten verwendet werden, wie z. B. Konfigurationsdateien, die Sie auch für den Build Ihres Projekts in den Ausgangsordner kopieren müssen (falls neuer).
Vielleicht möchten Sie sich die S3OC- und S3PE -Visual Studio -Lösungen ansehen, um zu sehen, wie ich es gemacht habe.
S3PI bietet eine Reihe von C# -Klasses, mit denen Programme unterstützt werden können, die auf SIMS -3 -Paketdateien und die darin gespeicherten Ressourcen zugreifen möchten. Die "Kernbibliothek" versteht nur den Paketcontainer selbst - sie hat kein Verständnis für den Inhalt von Ressourcen. Das wird an "Wrapper" delegiert. Wrapper sind mit Ressourcen verbunden, indem sie die Liste der von ihnen unterstützten ResourceTypes deklarieren. Die Kernbibliothek gibt eine Instanz der Ableitungsressourcenklasse an den Bibliothek "Client" zurück.
Wrapper haben also zwei Hauptziele: ein "Verständnis" des Inhalts eines oder mehrerer Ressourcentypen zu vermitteln und die Kernbibliothek zu informieren, welche Ressourcentypen sie verstehen. Ein Wrapper kann einen oder mehrere Ressourcenhandler bereitstellen, wenn er anpasst, aber die Autoren werden ermutigt, unterschiedliche Bedenken in verschiedene Wrapper aufzuteilen.
Die Kernbibliothek identifiziert Wrapper, indem die Baugruppen im Ordner S3PI -Bibliothek nach den entsprechenden Schnittstellen durchsucht werden.
Der WrapperDealer verfügt über eine Schnittstelle, mit der Client -Anwendungen bestimmte Kombinationen von ResourceType und Wrapper aktivieren und deaktivieren können.
Ich habe jetzt DefaultResource in die Dokumentation der S3PI -Bibliothek aufgenommen.
Das einfachste Beispiel ist das in DefaultResource in der Quellverteilung angegeben. Es macht nichts über das, was für jede Verpackung wesentlich ist.
Es definiert zwei Klassen:
public class DefaultResource : AResource { }
public class DefaultResourceHandler : AResourceHandler { } Eine Versammlung mit einer Wrapper muss eine Klasse enthalten, die AResourceHandler implementiert. Diese Klasse bietet ein IDictionary<Type, List<string>> suchen zwischen einer Klasse, die AResource implementiert, und eine Liste von Zeichenfolgen, die ResourceType enthalten. (Die verwendeten Zeichenfolgen sind die Werte aus dem TypedValue ResourceType , der in eine Zeichenfolge gegossen wurde, dh eine Hex -Zeichenfolge.)
DefaultResource verwendet "*", um WrapperDealer wissen zu lassen, dass es glücklich ist, alles zu nehmen. Verwenden Sie dies nicht in Ihren Wrappern!
DefaultResource dann.
Es wird dringend empfohlen, dass Sie const Int32 recommendedApiVersion = 1; An der Spitze Ihrer Klasse für zukünftige Kompatibilität. Auf diese Weise können Sie die API Ihres Wrapper -API "Version" "versionieren", wenn Sie sie benötigen. Wahrscheinlich nicht so nützlich in der Praxis.
Sie müssen die Immobilien AApiVersionedFields RecommendedApiVersion haben.
Der Konstruktor für DefaultResource zeigt einen wichtigen Punkt - eine neue Ressource wird erstellt, die nichts kennt. Es kann überprüfen, ob es neu ist, indem Sie prüfen, ob der an den Konstruktor übergebene Stream null ist. Es sollte dann einen MemoryStream erstellen und ihn mit dem minimal gültigen Dateninhalt für die Ressource füllen.
Das war's! Sie müssen nichts anderes tun. Natürlich haben Sie niemanden mit einem Grund zur Verfügung gestellt, Ihre Wrapper zu verwenden ...
Notiz
Nach einigen Gedanken gelten ImageResource und TextResource als veraltet. Sie werden jedoch auf absehbare Zeit in der Bibliothek bleiben. Trotz dessen, was unten geschrieben wurde, halte ich es nicht mehr für eine gute Idee, einen Wrapper für eine Ressource zu haben, die nur ein Byte -Stream ist.
Der Ansatz für DDS -Ressourcen wird als korrekter angesehen. Im Folgenden wird direkt angegeben: Das Design wurde hier von S3PE beeinflusst, anstatt irgendetwas in Bezug auf die Struktur der Daten selbst zu implementieren, was der Zweck eines Wrappers ist. Dies hätte auf ähnliche Weise wie DDS -Ressourcen behandelt werden sollen.
Eine weitere Folge war die Hinzufügung und das Entfernen des _VID -Ressourcenwrappers während eines QS -Zyklus, als festgestellt wurde, dass der Inhalt nur die Ausgabe eines benutzerdefinierten audiovisuellen Codec aus elektronischer Künste war, anstatt nützlich entschlüsselt werden.
Abschließend: "Wert" sollte nur eine Zeichenfolge sein. Normalerweise baut der in der Formatierung eingebaute Formatier eine angemessene aus Ihren öffentlichen Immobilien auf.
Ein etwas komplexeres Beispiel ist die ImageSource. Es haftet an den beiden Klassenmodell:
public class ImageResource : AResource { }
public class ImageResourceHandler : AResourceHandler { }Dieser Wrapper verarbeitet Bilder - viele verschiedene Ressourcentypen werden einfach gespeichert. PNG89 -Dateien.
Der statische Konstruktor für ImageResourceHandler liest eine Liste aller bekannten Bildressourcentypen (aus einer Datei im Ordner, in der sich die Montage befindet). Dies wird dann verwendet, um die Liste IDictionary<Type, List<string>> -Liste im Instanzkonstruktor zu füllen, der dann von WrapperDealer verwendet wird. Dies bedeutet, dass es einfach ist, der Liste, die dieser Wrapper unterstützt, neue Ressourcentypen hinzuzufügen. Bearbeiten Sie einfach die Textdatei und fügen Sie sie hinzu. (Es ist so ein gutes Muster, ich hätte es einfacher machen sollen, wieder zu verbringen ...)
Die ImageResource -Klasse bleibt ziemlich einfach. Sein Konstruktor stellt sicher, dass es ein gültiges PNG89 -Bild gibt, wenn ein Nullstrom übergeben wird. Und es bietet eine einzelne Eigenschaft namens "Wert", die ein System.Drawing.Image zurückgibt. Es unterstützt nicht das Speichern von Bildern auf eine vorhandene Ressource.
Die Value -Eigenschaft ist weiter erwähnt - das S3PI -Demo -Frontend (jetzt als S3PE bekannt) prüft, ob eine Ressource eine Value hat und ob sie eine Art von Bild- oder Zeichenfolgendaten enthält. Es weiß, wie man diese beiden anzeigt (und diese beiden allein). Die Rückgabe des geeigneten kann beim Debuggen nützlich sein.
Sie werden feststellen, dass die Stream -Position vor dem Gebrauch auf Null gesetzt wird - immer davon ausgehen, dass sie sich in einem unbekannten Zustand befindet.
Der TextResource -Wrapper ist sehr ähnlich - Textressourcen werden in einer Datei definiert. Es verfügt über eine "Wert" -Mobilie, die die Ressource als Zeichenfolgenwert zurückgibt. Darüber hinaus verfügt es über einige textspezifische Eigenschaften, einschließlich des Zugriffs auf die Daten als XML. (Es wäre ein besseres Design, den XML -Wrapper als Erweiterung des Textverpackers zu haben und nur bekannte XML -Dateien darin zu verarbeiten ...)
Dieser Wrapper behandelt einen einzelnen Ressourcenart - die Paketname -Karte. Es bietet eine IDictionary<ulong, string> -Schinnee, sodass die Karte gelesen und aktualisiert werden kann. Es ist ein sehr einfaches Beispiel dafür, wie Sie mit Updates umgehen.
So funktioniert es. Dies ist ein einfaches Beispiel, aber das Muster kann auf komplexere Bedürfnisse ausgedehnt werden.
Die Arbeit erfolgt an einer Reihe von Orten:
Die Stream -Eigenschaft prüft, ob die Ressource schmutzt wurde (dh geändert). Wenn ja, verwaltet es den aktuellen Stream und ruft UnParse() auf.
Der Instanzkonstruktor überprüft nach einem Null -Stream und ruft UnParse() die Erstellung der minimal gültigen Ressource auf.
Die Parse(Stream s) liest die Daten in die Datenstruktur, mit der sie manipuliert werden - hier ein Dictionary<ulong, string> . Da dies eine sich wiederholende Struktur unterschiedlicher Längeneinträge ist, mit denen Daten eingefügt werden können, ist es nicht effizient, die Daten im Stream zu verwenden.
Die methodische Methode UnParse() exportiert die Datenstruktur zurück in einen neuen Stream, wodurch bei Bedarf neue Objekte erstellt werden.
Wie oben erwähnt, muss die Stream -Eigenschaft wissen, ob die Ressource schmutzt wurde. Die Implementierung der Schnittstelle von IDictionary<ulong, string> ist dies durch die Aufzeichnung OnResourceChanged(this, EventArgs.Empty) für Aktualisierungsvorgänge. Dies ist auf AResource bereitgestellt und setzt die Ressource auf schmutzig und reserviert die ResourceChanged Handler von allem, was die Veranstaltung hört.
Catalogresource führt wirklich nur die Ideen in Namemapresource weiter. Es verfügt über eine abstrakte Klasse für eine verwandte Reihe von Ressourcen. Ich habe versucht, ein konsequentes Codierungsmuster zu halten, um zu verstehen, was passiert. Ich überlasse es dem Leser als Übung, die Implementierung zu durcharbeiten, um zu sehen, wie alle Klassen interagieren. Hoffentlich sollte es Sinn machen! (Wenn nicht, werde ich verblüfft sein, wenn ein Fehler auftaucht !!)
Dies hat den Vorteil, dass er neu ist, und zwar relativ einfach, hat jedoch einige interessante Teile. Es ist auch einer der Wrapper, die ich beim Schreiben eines neuen am häufigsten selbst beraten kann.
Eine RCOL -Ressource ist wie oben beschrieben eine normale Ressource - mit dem grundlegenden Unterschied, dass es sich um einen Container für andere "Ressourcen" handelt, die als RCOL -Blöcke bezeichnet werden. Jeder Block hat ein Format, das durch einen Vier -Zeichen -Code ("Fourcc" oder Tag) identifiziert wurde. Die Blöcke haben auch Ressourcentypen. Die RCOL -Ressource (im Paket) hat den gleichen Typ wie der erste RCOL -Block (in der Ressource) und die Ressource ist nach diesem ersten RCOL -Block benannt. Einige RCOL -Ressourcen enthalten nur einen einzelnen RCOL -Block. Andere enthalten mehrere RCOL -Blöcke.
Die grundlegende Unterstützung wird von s3pi.GenericRCOLResource bereitgestellt. Zusätzlich zum Lesen von Blöcken von Blöcken und Schreiben von Blöcken in das Paket verfügt der Ressourcenverpackung mit zusätzlichen Methoden, um das RCOL -Format zu unterstützen, und es gibt eine Registrierung von RCOL -Blockhandlern.
(Beachten Sie, dass der Begriff "Chunk" manchmal lose verwendet wird, um auf einen RCOL -Block zu verweisen ...)
Es gibt eine abstrakte Klasse, ARCOLBlock , die die Grundlagen definiert. Es gibt eine Standardimplementierung, DefaultRCOL , denn wenn kein anderer passender RCOL -Block -Handler in der Registrierung definiert ist, was nur minimal unterstützt wird.
Abgesehen von der Erweiterung ARCOLBlock als AResource ist die Aufgabe, einen RCOL -Block -Handler zu schreiben, dem Schreiben eines Ressourcenwrappers sehr ähnlich.
Die elektronischen Kunst / Maxis haben jedoch in letzter Zeit das Leben ein wenig schwieriger gemacht, da einige Einzel-RCOL-Behälter nicht genau dem ursprünglichen Verständnis der Funktionsweise des Containers entsprechen. Beachten Sie dies, wenn Sie den Code lesen oder Ihre eigenen schreiben.
Zunächst müssen Sie Erfahrung haben und bereits wissen, wie Sie die SIMS -Paketdateien mit S3PE -Software bearbeiten. S3PE arbeitet im Grunde genommen als grafische Schnittstelle für S3PI, die gemeinsame Benutzer verwenden können. Daher kann man mit Sicherheit sagen, dass S3PI in der Lage ist, alles zu tun, was S3PE tun kann, und noch mehr.
Notiz
Der S3PE steht auch in diesem Repository zum Download zur Verfügung. Sowohl seine ausführbare Datei als auch die C# Quellcode und die Visual Studio -Lösung.
Wenn Sie dies wissen, müssen Sie s3PI in Ihrem Programm codieren, als würde Ihr Programm S3PE verwenden, um die Aktion auszuführen.
Angenommen, Sie möchten eine bestimmte Ressource aus einer Paketdatei löschen. Wenn Sie S3PE verwenden, öffnen Sie zuerst diese Paketdatei und durchsuchen die Ressource zum Löschen. Anschließend drücken Sie DEL -Taste, um diese Datei zu löschen und dann zu speichern. Sobald die Paketdatei gespeichert ist, würden Sie sie schließen.
Wenn Sie dies mit S3PE tun würden, sollte Ihr Programm dieselben Schritte ausführen, wenn Sie S3PI verwenden, um dieselbe Aktion auszuführen. Siehe den Beispielcode unten, wobei die Aktion der Löschen von Ressourcen "0x00b2d882-0x00000000-0x0a12300000ff0000" aus einer offenen Paketdatei als Beispiel ...
using s3pi ;
using s3pi . Interfaces ;
using s3pi . Package ;
//Open the package
IPackage package = Package . OpenPackage ( 0 , "C:/Folder/someFile.package" , true ) ;
//Search the resource "0x00B2D882-0x00000000-0x0A12300000FF0000" inside the package
foreach ( IResourceIndexEntry item in package . GetResourceList )
{
//Get current entrie resource TGI
string typeHex = GetLongConvertedToHexStr ( item . ResourceType , 8 ) ;
string groupHex = GetLongConvertedToHexStr ( item . ResourceGroup , 8 ) ;
string instanceHex = GetLongConvertedToHexStr ( item . Instance , 16 ) ;
//If is the target resource, delete it
if ( typeHex == "0x00B2D882" && groupHex == "0x00000000" && instanceHex == "0x0A12300000FF0000" )
package . DeleteResource ( item ) ;
}
//Save the changes
package . SavePackage ( ) ;
//Close the package
Package . ClosePackage ( 0 , package ) ; Wichtig
Es ist sehr wichtig, dass Sie immer eine geöffnete Paketdatei schließen, nachdem Sie daran gearbeitet haben.
Notiz
Der Dream Launcher ist ein Launcher für die von "Marcos4503" erstellten Sims 3. Der Dream Launcher nutzt S3PI, um verschiedene Funktionen zu implementieren, z. B. das Zusammenführen von Paketen, die Reinigung von Paraden und andere Funktionen. Sie können diesen Link folgen, um das Dream Launcher -Repository zu lesen und den Quellcode für weitere Beispiele für die Verwendung von S3PI zu lesen. Der Dream Launcher wurde mit C# als Programmiersprache erstellt.
using s3pi ;
using s3pi . Interfaces ;
using s3pi . Package ;
//Creates a new Package that will receive the resources from 2 other Packages
IPackage finalPackage = Package . NewPackage ( 0 ) ;
//Open the Package 1 and copy all resources to the final package
IPackage package1 = Package . OpenPackage ( 0 , "C:/Folder/package1.package" , false ) ;
foreach ( IResourceIndexEntry item in package1 . GetResourceList )
finalPackage . AddResource ( item , ( package1 as APackage ) . GetResource ( item ) , true ) ;
Package . ClosePackage ( 0 , package1 ) ;
//Open the Package 2 and copy all resources to the final package
IPackage package2 = Package . OpenPackage ( 0 , "C:/Folder/package2.package" , false ) ;
foreach ( IResourceIndexEntry item in package2 . GetResourceList )
finalPackage . AddResource ( item , ( package2 as APackage ) . GetResource ( item ) , true ) ;
Package . ClosePackage ( 0 , package2 ) ;
//Enable compression for all viable resources of final merged package (the same way S3PE does)
foreach ( IResourceIndexEntry item in finalPackage . GetResourceList )
item . Compressed = ( ushort ) ( ( item . Filesize != item . Memsize ) ? 0xFFFF : 0x0000 ) ;
//Saves the final Package, result of the merge
finalPackage . SaveAs ( "C:/Folder/finalFile.package" ) ;
Package . ClosePackage ( 0 , finalPackage ) ; using s3pi ;
using s3pi . Interfaces ;
using s3pi . Package ;
//Open a .nhd save file
IPackage nhdSaveFile = Package . OpenPackage ( 0 , "C:/Folder/saveFile.nhd" , false ) ;
//Search inside the package, by the first thumbnail of type "SNAP" (or hex type "0x6B6D837E")
foreach ( IResourceIndexEntry item in nhdSaveFile . GetResourceList )
if ( GetLongConvertedToHexStr ( item . ResourceType , 8 ) == "0x6B6D837E" )
{
//Get the base stream for this resource
Stream aPackageStream = ( nhdSaveFile as APackage ) . GetResource ( item ) ;
//Get the base resource using the "ImageResource" s3pi wrapper***
IResource baseResource = ( IResource ) ( new ImageResource . ImageResource ( 0 , aPackageStream ) ) ;
//Get the bitmap from base resource stream
BitmapImage bitmapImage = new BitmapImage ( ) ;
bitmapImage . BeginInit ( ) ;
bitmapImage . StreamSource = baseResource . Stream ;
bitmapImage . CacheOption = BitmapCacheOption . OnLoad ;
bitmapImage . EndInit ( ) ;
bitmapImage . Freeze ( ) ;
//... continue ...//
//Cancel the search
break ;
}
//Close the save file
Package . ClosePackage ( 0 , nhdSaveFile ) ; *** Beachten Sie, dass wir hier die WrapperDealer -Klasse verwenden können, damit S3PI uns automatisch den richtigen Wrapper für die Ressource zur Verfügung stellen kann. Wenn wir dort WrapperDealer verwenden, würde S3PI uns automatisch den ImageResource -Wrapper bringen, aber WrapperDealer ist mit einigen .NET -Frameworks, wie z. B. WPF selbst, nicht kompatibel. Aus diesem Grund wird immer empfohlen, den Wrapper direkt zu verwenden, wenn Sie mit einer Ressource in der Paketdatei arbeiten. Wenn wir uns für die WrapperDealer -Klasse entscheiden, um das Bild zu erhalten, würde das Code -Snippet so aussehen ...
//...
//Get the resource using WrapperDealer
IResource resource = WrapperDealer . GetResource ( 0 , nhdSaveFile , item , true ) ;
//Get the bitmap from base resource stream
BitmapImage bitmapImage = new BitmapImage ( ) ;
bitmapImage . BeginInit ( ) ;
bitmapImage . StreamSource = resource . Stream ;
bitmapImage . CacheOption = BitmapCacheOption . OnLoad ;
bitmapImage . EndInit ( ) ;
bitmapImage . Freeze ( ) ;
//... using s3pi ;
using s3pi . Interfaces ;
using s3pi . Package ;
//Open a package that contains a CASP resource
IPackage openedPackage = Package . OpenPackage ( 0 , "C:/Folder/clothes.package" , true ) ;
//Search the first CASP (or hex type 0x034AEECB) resource inside the package
foreach ( IResourceIndexEntry item in openedPackage . GetResourceList )
if ( GetLongConvertedToHexStr ( item . ResourceType , 8 ) == "0x034AEECB" )
{
//Get the CASP stream
Stream caspStream = WrapperDealer . GetResource ( 1 , openedPackage , item , true ) . Stream ;
//Get the CASP resource
CASPartResource . CASPartResource sourceCASpart = new CASPartResource . CASPartResource ( 1 , caspStream ) ;
//Allow this CASP for Random Sims
sourceCaspart . ClothingCategory |= CASPartResource . ClothingCategoryFlags . ValidForRandom ;
//Disallow this CASP for Random Sims
sourceCaspart . ClothingCategory &= ~ CASPartResource . ClothingCategoryFlags . ValidForRandom ;
//Delete the old CASP resource
openedPackage . DeleteResource ( item ) ;
//Add the new modified resource
openedPackage . AddResource ( ( ( IResourceKey ) item ) , ( ( AResource ) sourceCaspart ) . Stream , true ) ;
//Release streams
caspStream . Dispose ( ) ;
caspStream . Close ( ) ;
( ( AResource ) sourceCaspart ) . Stream . Dispose ( ) ;
( ( AResource ) sourceCaspart ) . Stream . Close ( ) ;
}
//Save the package and close it
openedPackage . SavePackage ( ) ;
Package . ClosePackage ( 0 , openedPackage ) ; Notiz
Hier verwenden wir WrapperDealer , um auf die CASP -Ressource zuzugreifen, aber wir könnten auch Wrapper CASPartResource direkt verwenden, um auf die CAP -Ressource zuzugreifen.
Wie Sie wahrscheinlich bereits verstanden haben, sind die Sims -Paketdateien wie eine "ZIP -Datei", die mehrere andere Dateien in sich enthält. Jede Datei/Ressource in einer Paketdatei ist ein TGI zugeordnet.
Der TGI ist im Grunde genommen Typ, Gruppe und Instanz. Typ und Gruppe sind 8-stellige Hexadezimal, während die Instanz ein 16-stelliges Hexadezimal ist. Um Konflikte zwischen Ressourcen zu vermeiden, wenn sie durch das Spiel geladen werden, muss jede Ressource, die in allen vom Spiel geladenen Paketen vorhanden ist, eine einzigartige TGI -Kombination haben.
Wenn Sie eine Paketdatei mit S3PE öffnen, können Sie leicht den Typ, die Gruppe und die Instanz jeder im geöffneten Paket vorhandenen Ressource sehen. Beachten Sie nun, dass Sie bei der Bearbeitung der Sims -Paketdateien immer sicherstellen sollten, dass die Ressourcen, die Sie in Paketdateien einfügen, immer ein eindeutiges TGI haben müssen.
Wenn Sie weitere Fragen dazu haben, können Sie diesen Artikel lesen, in dem es sehr gut spricht und erklärt, welche Modkonflikte in den MOD -Konflikten, wie sie auftreten, wie man sie behebt usw.
Wenn Sie so weit gelesen haben, sollten Sie ein anständiges Verständnis dafür haben, was S3PI ist und wie Sie es verwenden. Wenn Sie auf das alte offizielle S3PI -Repository zugreifen möchten, können Sie diesen Link verwenden. Wenn Sie sich daran erinnern, dass alle Krediten für die Erstellung der S3PI -Bibliothek an Peter L Jones gelten.
Repository erstellt mit von Marcos Tomaz