في الوقت الحاضر ، من الصعب للغاية العثور على معلومات قوية ومساعدة حقيقية فيما يتعلق بـ S3PI ، حتى أكثر من ذلك إذا كنت تحاول إنشاء برنامج باستخدام S3PI كمكتبة للتفاعل مع ملفات حزمة SIMS. علاوة على ذلك ، فإن مكتبة S3PI ليست على github وليس لديها مستودع هنا.
لهذه الأسباب ، قررت إنشاء هذا المستودع لتخزين مكتبة S3PI بالكامل ، مع أمثلة رمز ونصائح حول كيفية استخدامه بشكل صحيح. بالإضافة إلى ذلك ، قمت بتجميع هنا جميع المعلومات المفيدة التي وجدتها على الإنترنت المتعلقة بـ S3PI!
إذا كنت ترغب في المساهمة بمزيد من المعلومات ، فيرجى إنشاء طلب سحب أو الإبلاغ عنه عبر علامة التبويب "المشكلات". سأبذل قصارى جهدي للحفاظ على هذا المستودع بأكبر قدر ممكن من المعلومات والأمثلة ، ولكن إذا طلب مؤلف S3PI ذلك ، فسوف آخذ هذا المستودع في وضع عدم الاتصال.
مهم
تذكر أن جميع الاعتمادات لإنشاء مكتبة S3PI تذهب إلى "بيتر ل جونز" لا تصدق!
توفر "واجهة حزمة Sims 3" مكتبة أساسية من الكود المحمول "يفهم" حزم لعبة SIMS3. لاحظ أنه (مع بعض التعديلات البسيطة) يفهم رمز المكتبة الأساسية أيضًا تنسيقات حزمة اللعبة الأخرى (على سبيل المثال SimCity Online ، SIMS4).
جنبا إلى جنب مع المكتبة الأساسية هي عدد من "الأغطية" التي توفر الجزء الرئيسي من المشروع. هذه تعامل هجرات وتسلسل البيانات داخل الحزمة (أو أي مصدر آخر).
يمكن للأدوات الإضافية استخدام هذه المكتبة والأغلفة لمعالجة محتوى بيانات ملفات حزم ألعاب Sims.
لاحظ أن التطوير على هذه المكتبة والملفات المقدمة هنا قد انتهى الآن.
"S3PI" عبارة عن اختصار لـ "واجهة حزمة Sims3 ™". يوفر الدعم للوصول إلى البيانات داخل ملفات "الحزمة" الفردية التي تستخدمها لعبة SIMS3 ™ Electronic Arts. "الحزمة" عبارة عن ملف قرص يحتوي على ملحق ملف عادةً ".package" (ولكن يتم استخدام ملحقات أخرى). ومع ذلك ، فإن ميزة التعريف الرئيسية التي تستخدمها S3PI هي ملف تعريف الارتباط السحري الأربعة في بداية الملف ، والتي يجب أن تكون "DBPF". بالإضافة إلى ذلك ، يجب أن يكون رقم إصدار تنسيق الملف 2 لـ Sims 3 ™ (أو 3 لـ Sim City 5 ™ ، والذي بالكاد مدعوم).
لاحظ أن الحزم "المحمية" (مع ملف تعريف الارتباط السحري من "DBPP") غير مدعومة. لاحظ أن الحزم "المؤقتة" (مع ملف تعريف ارتباط سحري من "DBBF") غير مدعومة حاليًا.
S3PI عبارة عن مجموعة من مجموعات .NET (موثقة أدناه ومتاحة هنا) التي تنفذ الأوصاف من Wiki Sims 3 (مع هذه الصفحات بدلا من ذلك كـ Wiki-Mirror). لاحظ أنه من المفيد دائمًا التحقق من هناك إذا لم تكن متأكدًا من شيء ما ، إما حول كيفية عمل شيء ما أو إذا كنت تعتقد أنك قد وجدت مشكلة في S3PI ، والتي تظل ممكنة تمامًا. لا يوجد Wiki أو المكتبة على صواب دائمًا - في الواقع ، يمكن أن يكون كلاهما مخطئًا بطرق مختلفة.
تأتي مكتبة S3PI مع ملف تعليمات مجمعة (.chm) يصف الكثير مما تحتاج إلى معرفته. يمكنك أيضًا الوصول إلى إصدار من هذا ، هنا. تحاول هذه الصفحة تقديم نظرة عامة سريعة ، لأن المكتبة واسعة النطاق إلى حد كبير وقد يكون من الصعب تحديد ما تحتاج إلى معرفته.
تنقسم هذه الصفحة إلى ثلاثة أقسام متبقية.
بمجرد أن تفهم كيفية استخدام غلاف للوصول إلى البيانات في حزمة ، يجب عليك استشارة قائمة أنواع الملفات Sims3 لمعرفة أيها المدعوم وكيفية الحصول على الدعم (إن لم يكن جزءًا من توزيع S3PI).
نصيحة
إذا كان لديك أسئلة لم تتم الإجابة عليها ، فلا تتردد في النشر هنا في المنتدى/المناقشات. سيكون من دواعي سروري المساعدة!
المكتبة هي مجموعة من DLLs .NET Assembly. إذا كان من المحتمل أن تعمل على أكثر من مشروع باستخدام المكتبة ، فإنني أنصح بشدة وضعها في مجلد منفصل عن مشروعك ومساحات حلول الحل - ولكن في بنية المجلد. وبهذه الطريقة ، من السهل استبدالها جميعًا دون الحاجة إلى تحديث كل مشروع.
لاستخدام المكتبة من مشروع جديد ، تحتاج أولاً إلى معرفة أجزاء المكتبة التي ستستخدمها. لقد حافظت عمداً على الأجزاء التابعة منفصلة بحيث لا يحتاج مشروعك إلا إلى الرجوع إلى DLLs التي يحتاجها ، وبالتالي الحفاظ على حجم مشروعك. الجانب السلبي هو أن هناك الكثير من DLLs!
أول ما يلاحظه هو أن العديد منهم "مغلفون" - أي شيء يحمل اسمًا مثل SomethingResource.DLL . تحتوي هذه الرمز لفهم محتوى موارد أو أكثر في ملف حزمة SIMS 3.
أولاً ، دعنا نلقي نظرة على كل من التجميعات المتبقية. بعد ذلك ، سأقدم مخططًا عن كيفية بدء مشروع جديد. سأنتهي ببعض الأفكار حول تنظيم ممارسات العمل الخاصة بك.
ملحوظة
يجب أن توافق على ترخيص GPLV3 قبل توزيع الكود الخاص بك. لاحظ أنه أثناء الربط بمكتبة GPLV3 ، فأنت تعيد استخدامها بشكل أساسي ويجب أن توزع الكود الخاص بك ضمن شروط مكافئة. يمكنك العثور على مزيد من التفاصيل على موقع Free Software Foundation.
متى يجب تضمينها: دائمًا - يتطلب الأمر عدة أجزاء أخرى من المكتبة.
ملخص: يحتوي على عدد من الفئات التي لا تتعلق مباشرة بـ "The Sims 3" وليس لها أي إشارات إلى أي من أنواع s3pi.Interfaces . يمكن أن يكونوا مفيدين للمشاريع التي لا تستخدم بقية مكتبة S3PI (وبالتالي إبقائها منفصلة).
مزيد من القراءة: من خلال الرجوع إلى هذه التجمع ، ستحصل على ما يلي ...
System.Collections.Generic.AHandlerList<T> - الامتداد التجريدي List<T> تقديم ملاحظات على تحديثات القائمة من خلال EventHandler الموردة.System.ArgumentLengthException - يمثل خطأ في طول وسيطة إلى طريقة ما.System.Extensions - طرق تمديد مفيدة لا توفرها LINQ (وبدون التنفيذ المؤجل). (اسم الفصل مشكوك فيه وقد يتغير ...)System.Security.Cryptography.FNV32 - FNV32 Hash RoutineSystem.Security.Cryptography.FNV64 - FNV64 روتين التجزئةSystem.Text.SevenBitString اقرأ واكتب سلسلة مشفرة ذات طول مشفر بسبعة بت في Encoding معين من أو إلى Stream .System.Security.Cryptography.Sims3PackCRC - حساب اتفاقية حقوق الطفل من قطعة البيانات المخزنة في ملف sims3pack. (حسنًا ، يمكن القول أن هذا ليس له سبب هنا ولكن من حيث تبعيات الكود ، فمن المنطقي!) متى يجب تضمينها: دائمًا.
ملخص: يهدف في الأصل إلى تغيير الإعدادات الداخلية للمكتبة عن طريق استبدال DLL. هذا لم يحدث أبدا.
مزيد من القراءة: لا شيء.
متى يجب تضمينها: دائمًا. لا يقتصر الأمر على المكتبة نفسها ولكنها تحدد واجهة برمجة التطبيقات العامة.
ملخص: يوفر عددًا من الواجهات والفئات المجردة وفصول المساعدة المستخدمة في جميع أنحاء المكتبة والأغليف ، والتي تحدد الأساليب العامة التي توفرها فئات المكتبة المختلفة.
مزيد من القراءة:
s3pi.Interfaces وثائق مساحة الاسم. لاحظ أن مساحة الاسم "ملوثة" بواسطة فئات من s3pi.GenericRCOL . قد ينظر المتغيرون أيضًا في بعض فصول المساعد "التلوث" ...
متى يجب تضمينها: عند العمل مع ملفات حزمة Sims 3.
ملخص: يوفر التنفيذ الملموس للفئات والواجهات المجردة المحددة في s3pi.Interfaces .
مزيد من القراءة: لا شيء.
متى يجب تضمينها: عند العمل مع أغلفة الموارد.
ملخص: إذا كنت تقوم بإنشاء موارد جديدة أو موارد قراءة من حزمة ، فهذه هي الآلية الموصى بها. ومع ذلك ، توجد بدائل.
مزيد من القراءة:
s3pi.WrapperDealer.WrapperDealer - المسؤول عن ربط ResourceType في IResourceIndexEntry مع فئة معينة ("غلاف") يفهمه أو الغلاف الافتراضي. يوفر s3pi.DefaultResource و s3pi.GenericRCOLResource الأساسيات لفهم كيفية استخدام مورد بمجرد الحصول على إشارة إليه.
متى يجب تضمينها: إذا كنت تريد أسماء الملفات القياسية للمجتمع.
ملخص: في بداية SIMS 3 ، وافق مجتمع Modding على تنسيق محدد لكيفية تسمية المورد المعبأ عند ملف حزمة خارج. يوفر هذا التجميع تنفيذ مكتبة S3PI.
مزيد من القراءة: مساحة الاسم s3pi.Extensions . لا تزال هذه المنطقة من المكتبة تحتاج إلى توثيق بشكل صحيح.
متى يجب تضمينها: عندما تريد copyableMessageBox (أو issuexception).
ملخص: يوفر هذا التجميع طريقة لعرض الرسائل التي تسمح للمستخدم بنسخ المحتوى بسهولة. في المستقبل ، قد تظهر الضوابط العامة الأخرى هنا.
مزيد من القراءة: CopyableMessageBox فئة ، CopyableMessageBoxButtons التعداد وتعداد CopyableMessageBoxIcon .
متى يجب تضمينها: عندما تريد أحد عناصر التحكم المخصصة.
ملخص: توفر هذه المجموعة عناصر تحكم مخصصة تتعلق بأنواع البيانات في S3PI.
مزيد من القراءة: فئة ResourceTypeCombo ، فئة TGIBlockCombo وفئة TGIBlockListEditor . لا تزال هذه المنطقة من المكتبة تحتاج إلى توثيق بشكل صحيح.
متى يجب تضمينها: عند استخدام صور DDS وتريد طريقة لعرضها في تطبيق WinForms.
ملخص: يوفر هذا التجميع عنصر تحكم مخصص ودعم موارد DDS.
مزيد من القراءة: DDSPanel فئة و DDSPanel.MaskChannel التعداد.
متى يجب تضمينها: قد تكون مفيدة عند كتابة مساعد لـ S3PE.
ملخص: يوفر الدعم لتخطيط مورد لبرنامج واحد أو أكثر من البرامج التي قد تكون مهتمة بهذا النوع من الموارد.
مزيد من القراءة: مساحة الاسم s3pi.Helpers . لا تزال هذه المنطقة من المكتبة تحتاج إلى توثيق بشكل صحيح.
قم بإعداد المراجع التي تحتاجها بناءً على System.Custom ، s3pi.Settings ، s3pi.Interfaces وأي غيرها. بالإضافة إلى ذلك ، ستحتاج إلى التفكير فيما إذا كنت تريد الرجوع إلى مجموعات غلاف محددة. في معظم الحالات ، سيكون هذا هو النهج المناسب. سيتم نسخ التجميعات المرجعية الخاصة بك ، افتراضيًا ، إلى مجلد إخراج المشروع ، إلى جانب البرنامج.
لاحظ أن هناك بعض المكونات الإضافية المستخدمة ، مثل ملفات التكوين ، ستحتاج أيضًا إلى ترتيب بناء مشروعك لنسخ (إذا أحدث) إلى مجلد الإخراج.
قد ترغب في إلقاء نظرة على حلول S3OC و S3PE Visual Studio لمعرفة كيف قمت بذلك.
يوفر S3PI عددًا من فئات C# لمساعدة البرامج التي ترغب في الوصول إلى ملفات حزمة SIMS 3 والموارد المخزنة داخلها. "المكتبة الأساسية" تتفهم فقط حاوية الحزمة نفسها - ليس لها أي فهم لمحتوى الموارد. يتم تفويض ذلك إلى "مغلفة". ترتبط الأغلفة بالموارد من خلال إعلان قائمة ResourceTypes التي تدعمها. تقوم المكتبة الأساسية بإرجاع مثيل فئة الموارد المتميزة إلى المكتبة "العميل".
لذلك ، لدى الأغلفة هدفان رئيسيان: توفير "فهم" لمحتوى نوع أو أكثر من أنواع الموارد ولإعلام المكتبة الأساسية بأنواع الموارد التي يفهمونها. يمكن أن يوفر الغلاف معالجات الموارد واحدة أو أكثر لأنها تراها مناسبة ولكن يتم تشجيع المؤلفين على الحفاظ على مخاوف مختلفة مفصولة إلى مغلفة مختلفة.
تحدد المكتبة الأساسية الأغطية عن طريق البحث من خلال التجميعات في مجلد مكتبة S3PI لأولئك الذين لديهم الواجهة المناسبة.
يحتوي WrapperDealer على واجهة تتيح لتطبيقات العميل تمكين وتعطيل مجموعات معينة من ResourceType و Wrapper.
لقد قمت الآن بتضمين DefaultResource في وثائق مكتبة S3PI.
أبسط مثال هو أنه يرد في DefaultResource في توزيع المصدر. إنه "لا يفعل شيئًا" يتجاوز ما هو ضروري لأي غلاف.
يحدد فئتين:
public class DefaultResource : AResource { }
public class DefaultResourceHandler : AResourceHandler { } يجب أن يحتوي التجميع الذي يحتوي على غلاف فئة تنفذ AResourceHandler . توفر هذه الفئة IDictionary<Type, List<string>> البحث بين الفئة التي تنفذ AResource وقائمة من الأوتار التي تحتوي على قيم ResourceType . (الأوتار المستخدمة هي القيم من TypedValue ResourceType المصبوب إلى سلسلة ، أي سلسلة سداسية.)
يستخدم DefaultResource "*" للسماح WrapperDealer بمعرفة أنه من الجيد أن تأخذ كل شيء. لا تستخدم هذا في أغلفةك!
DefaultResource ، ثم.
يوصى بشدة أن يكون لديك const Int32 recommendedApiVersion = 1; في الجزء العلوي من صفك للتوافق في المستقبل. هذا يتيح لك "إصدار" واجهة برمجة تطبيقات Wrapper إذا كنت في حاجة إليها. ربما ليس ذلك مفيدًا في الممارسة العملية.
يجب أن يكون لديك الممتلكات AApiVersionedFields RecommendedApiVersion .
يوضح مُنشئ DefaultResource نقطة مهمة - يتم إنشاء مورد جديد لمعرفة أي شيء . يمكن أن تحقق أنه جديد عن طريق التحقق من أن البث الذي تم تمريره إلى المُنشئ هو فارغ. يجب أن يقوم بعد ذلك بإنشاء MemoryStream وملءها مع الحد الأدنى من محتوى البيانات الصحيح للمورد.
هذا كل شيء! لا يوجد شيء آخر يجب أن تفعله. بالطبع ، لم تقدم لأي شخص سببًا لاستخدام الغلاف الخاص بك بعد ...
ملحوظة
بعد بعض التفكير ، يعتبر ImageResource و TextResource إهمالًا. ومع ذلك ، سيبقون في المكتبة في المستقبل المنظور. على الرغم من ما هو مكتوب أدناه ، لم أعد أعتبر أنه من الجيد أن يكون لديك غلاف لمورد يمثل مجرد دفق بايت.
يعتبر النهج المتبع لموارد DDS أكثر صحة. يتم ذكر Corollory مباشرة أدناه: لقد تأثر التصميم هنا بـ S3PE بدلاً من تنفيذ أي شيء فيما يتعلق ببنية البيانات نفسها ، وهو الغرض من الغلاف. كان ينبغي التعامل مع هذا بطريقة مماثلة لموارد DDS.
كان الإضافات الإضافية الإضافة ، ثم إزالة غلاف الموارد _VID أثناء دورة QA عندما تم اكتشاف أن المحتوى كان محضًا ناتج عن برنامج ترميز Audiovual Asseual Electronic Electronic ، بدلاً من وجود أي محتوى قابل للفك.
في الختام: يجب أن تكون "القيمة" مجرد سلسلة. عادة ، يبني التنسيق المدمج واحدة مناسبة من ممتلكاتك العامة.
مثال أكثر تعقيدًا قليلاً هو Imageresource. تتمسك بنموذج الفصل:
public class ImageResource : AResource { }
public class ImageResourceHandler : AResourceHandler { }يعالج هذا الغلاف الصور - العديد من أنواع الموارد المختلفة يتم تخزينها ببساطة ملفات PNG89.
يقرأ المنشئ الثابت لـ ImageResourceHandler قائمة بجميع أنواع موارد الصور المعروفة (من ملف في المجلد الذي يوجد فيه التجميع). ثم يتم استخدام هذا لملء IDictionary<Type, List<string>> القائمة في مُنشئ المثيل ، والذي يتم استخدامه بعد ذلك بواسطة WrapperDealer . هذا يعني أنه من السهل إضافة أنواع موارد جديدة إلى القائمة التي يدعمها هذا الغلاف - فقط قم بتحرير الملف النصي وإضافتها ، لا حاجة إلى إعادة الترجمة. (إنه نمط جيد ، كان ينبغي علي أن أسهل إعادة استخدام ...)
لا تزال فئة ImageResource بسيطة إلى حد ما. يضمن مُنشئه وجود صورة PNG89 صالحة إذا تم تمرير دفق فارغ. ويوفر خاصية واحدة تسمى "القيمة" التي تُرجع System.Drawing.Image تم إنشاؤها من بيانات PNG89. لا يدعم حفظ الصور مرة أخرى إلى مورد موجود.
تجدر الإشارة إلى أن خاصية Value تجدر الإشارة إلى المزيد - تتحقق الواجهة الأمامية التجريبية S3PI (المعروفة الآن باسم S3PE) مما إذا كان لدى المورد خاصية Value ، وإذا كان الأمر كذلك ، سواء كان لديه نوع من بيانات الصورة أو السلسلة. إنها تعرف كيفية عرض هذين (وهذين وحدهما ، حاليًا). إرجاع واحد مناسب يمكن أن يكون مفيدًا في تصحيح الأخطاء.
ستلاحظ أن وضع الدفق يتم تعيينه على الصفر قبل الاستخدام - افترض دائمًا أنه في حالة غير معروفة.
غلاف TextResource متشابه جدًا - يتم تعريف الموارد النصية في ملف ؛ لديها خاصية "قيمة" إرجاع المورد كقيمة سلسلة. بالإضافة إلى ذلك ، يحتوي على بعض الخصائص الخاصة بالنص ، بما في ذلك الوصول إلى البيانات كـ XML. (سيكون من الأفضل التصميم أن يكون لديك غلاف XML كامتداد لملفات النص والتعامل فقط مع ملفات XML المعروفة فيه ...)
يعالج هذا الغلاف نوع مورد واحد - خريطة اسم الحزمة. يوفر واجهة IDictionary<ulong, string> ، مما يسمح بقراءة الخريطة وتحديثها. إنه مثال بسيط للغاية على كيفية التعامل مع التحديثات.
إليكم كيف يعمل. هذا مثال بسيط ولكن يمكن تمديد النمط إلى احتياجات أكثر تعقيدًا.
يتم العمل في عدد من الأماكن:
يتحقق خاصية Stream ما إذا كان المورد قد تم ترحيله (أي تم تغييره). إذا كان الأمر كذلك ، فإنه يتجاهل الدفق الحالي ويستدعي UnParse() .
يتحقق مُنشئ المثيل لدفق فارغ ويتصل UnParse() لإنشاء الحد الأدنى من المورد الصحيح.
تقرأ طريقة Parse(Stream s) البيانات في بنية البيانات المستخدمة لمعالجةها - هنا Dictionary<ulong, string> . نظرًا لأن هذا هو بنية متكررة لإدخالات الطول المختلفة التي تسمح بإدراج البيانات ، فليس من الفعال استخدام البيانات في الدفق.
تقوم طريقة UnParse() بتصدير بنية البيانات إلى دفق جديد ، وإنشاء كائنات جديدة عند الاقتضاء.
كما ذكر أعلاه ، تحتاج خاصية Stream إلى معرفة ما إذا كان المورد قد تم ترحيله. يعتني بتنفيذ IDictionary<ulong, string> هذا من خلال استدعاء OnResourceChanged(this, EventArgs.Empty) لعمليات التحديث. يتم توفير ذلك على AResource ويضع المورد إلى القذرة ، وكذلك استدعاء معالجات ResourceChanged لأي شيء يستمع إلى الحدث.
Catalogresource حقًا يأخذ الأفكار في NamemapResource بشكل أكبر. لديها فئة مجردة لمجموعة ذات صلة من الموارد. لقد حاولت الاحتفاظ بنمط ثابت من الترميز للمساعدة في فهم ما يحدث. أترك الأمر كتمرين للقارئ للعمل من خلال التنفيذ لمعرفة كيف تتفاعل جميع الفصول. نأمل أن يكون من المنطقي! (إذا لم يكن الأمر كذلك ، فسوف أتعثر عندما يأتي خطأ !!)
هذا له فائدة من أن تكون حديثًا ، وفي حين أن البسيط نسبيًا ، لديه بعض البتات المثيرة للاهتمام. إنها أيضًا واحدة من الأغلفة التي أتشاورها في أغلب الأحيان عند كتابة واحدة جديدة.
مورد RCOL هو مورد عادي ، كما هو موضح أعلاه - مع الفرق الأساسي بأنه حاوية لـ "الموارد" الأخرى ، والمعروفة باسم كتل RCOL. كل كتلة لها تنسيق تم تحديده بواسطة رمز أحرف أربعة ("FourCC" أو علامة) ؛ تحتوي الكتل أيضًا على أنواع الموارد. يحتوي مورد RCOL (في الحزمة) على نفس النوع مثل كتلة RCOL الأولى في (في المورد) ويتم تسمية المورد بعد هذا الكتلة RCOL الأولى. تحتوي بعض موارد RCOL فقط على كتلة RCOL واحدة ؛ يحتوي البعض الآخر على كتل RCOL متعددة.
يتم توفير الدعم الأساسي بواسطة s3pi.GenericRCOLResource . بالإضافة إلى كتل القراءة من كتل وكتابة الكتل إلى الحزمة ، فإن لفائف الموارد لديها طرق إضافية لدعم تنسيق RCOL وهناك سجل لمرافبي كتلة RCOL.
(لاحظ أن مصطلح "قطعة" يستخدم بشكل فضفاض للإشارة إلى كتلة RCOL في بعض الأحيان ...)
هناك فئة مجردة ، ARCOLBlock ، تحدد الأساسيات. هناك تنفيذ افتراضي ، DefaultRCOL ، لأنه عندما لا يتم تعريف معالج كتلة RCOL المطابقة الأخرى في السجل ، والذي يوفر الحد الأدنى من الدعم.
بخلاف تمديد ARCOLBlock بدلاً من AResource ، فإن مهمة كتابة معالج كتلة RCOL تشبه إلى حد كبير كتابة غلاف الموارد.
ومع ذلك ، بدأت الفنون / maxis الإلكترونية مؤخرًا في جعل الحياة أكثر صعوبة قليلاً في أن بعض حاويات RCOL الواحدة لا تتوافق تمامًا مع الفهم الأصلي لكيفية عمل الحاوية. كن على دراية بهذا عند قراءة الكود أو كتابة بنفسك.
أولاً ، يجب أن تكون لديك خبرة وتعرف بالفعل كيفية تحرير ملفات حزمة SIMS ، باستخدام برنامج S3PE. يعمل S3PE بشكل أساسي كواجهة رسومية لـ S3PI ، والتي يمكن للمستخدمين المشتركين استخدامها. لذلك ، من الآمن القول أن S3PI قادر على فعل كل ما يمكن أن يفعله S3PE ، وأكثر من ذلك.
ملحوظة
S3PE متاح أيضًا للتنزيل في هذا المستودع. كل من ملفه القابل للتنفيذ و C# Code Source Solution و Visual Studio Solution.
مع العلم بذلك ، لتنفيذ S3PI في برنامجك ، تحتاج إلى رمز كما لو كان برنامجك يستخدم S3PE لأداء الإجراء.
دعنا نقول أنك تريد حذف مورد معين من ملف حزمة. إذا كنت تستخدم S3PE ، فستفتح أولاً ملف الحزمة هذا ، ابحث عن المورد الذي يجب حذفه. ثم يمكنك الضغط على DEL Key لحذف هذا الملف ، ثم حفظ. بمجرد حفظ ملف الحزمة ، ستغلقه.
إذا كنت ستفعل ذلك باستخدام S3PE ، فيجب أن يقوم برنامجك بنفس الخطوات إذا كنت تستخدم S3PI لتنفيذ هذا الإجراء نفسه. راجع رمز العينة أدناه ، وإجراء إجراء حذف مورد "0x00B2D882-0X0000000000000000000000000000-0X0A12300000FF0000" من ملف حزمة مفتوحة ، كمثال ...
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 ) ; مهم
من المهم جدًا أن تغلق دائمًا ملف حزمة مفتوح بعد الانتهاء من العمل عليه.
ملحوظة
The Dream Launcher هو قاذفة لـ Sims 3 التي تم إنشاؤها بواسطة "Marcos4503". يستخدم Dream Launcher S3PI لتنفيذ ميزات مختلفة ، مثل دمج الحزم ، وتنظيف عمليات حفظ ، وغيرها من الوظائف. يمكنك متابعة هذا الرابط للتحقق من مستودع Dream Launcher وإلقاء نظرة على الكود المصدر لمزيد من الأمثلة على استخدام S3PI. تم إنشاء قاذفة الحلم باستخدام C# كلغة البرمجة.
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 ) ; *** لاحظ أنه هنا ، يمكننا استخدام فئة WrapperDealer بحيث يوفر لنا S3PI الغلاف الصحيح للمورد الذي نعمل معه ، تلقائيًا. إذا استخدمنا WrapperDealer هناك ، فإن S3PI ستجلب لنا تلقائيًا غلاف ImageResource ، ومع ذلك ، من المعروف أن WrapperDealer غير متوافق مع بعض أطر عمل .NET ، مثل WPF نفسه ، مما تسبب في تعطل. لهذا السبب ، يوصى دائمًا باستخدام الغلاف مباشرة ، عند العمل مع مورد داخل ملف الحزمة. إذا اخترنا استخدام فئة WrapperDealer للحصول على الصورة ، فإن مقتطف الكود سيبدو هكذا ...
//...
//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 ) ; ملحوظة
نستخدم هنا WrapperDealer للوصول إلى مورد CASP ، ولكن يمكننا أيضًا استخدام CASPartResource Wrapper مباشرة للوصول إلى مورد CASP.
كما تفهم بالفعل ، فإن ملفات حزمة SIMS تشبه "ملف zip" ، والتي تحتوي على عدة ملفات أخرى بداخلها. يحتوي كل ملف/مورد داخل ملف حزمة على TGI المرتبط به.
TGI هو في الأساس النوع والمجموعة والمثيل. النوع والمجموعة هما سداسي عشرة مكونة من 8 أرقام ، في حين أن المثال سداسي عشري من 16 رقماً. من أجل تجنب النزاعات بين الموارد عند تحميلها بواسطة اللعبة ، يجب أن يكون لكل مورد موجود في جميع الحزم التي يتم تحميلها بواسطة اللعبة مزيج TGI فريد من نوعه.
عند فتح ملف حزمة باستخدام S3PE ، يمكنك بسهولة رؤية النوع والمجموعة ومثيل كل مورد موجود في الحزمة المفتوحة. الآن بعد أن عرفت ذلك ، ضع في اعتبارك أنه أثناء تحرير ملفات حزمة SIMS ، يجب عليك دائمًا التأكد من أن الموارد التي تدخلها في ملفات الحزمة يجب أن تحتوي دائمًا على TGI فريدة من نوعها.
إذا كان لديك أي أسئلة أخرى حول هذا الموضوع ، فيمكنك قراءة هذه المقالة ، والتي تتحدث عنها وتشرح جيدًا ما هي تعارضات وزارة الدفاع ، وكيفية حدوثها ، وكيفية حلها ، إلخ.
إذا كنت قد قرأت هذا بعيدًا ، فيجب أن يكون لديك فهم لائق لماهية S3PI وكيفية استخدامه. إذا كنت ترغب في الوصول إلى مستودع S3PI الرسمي القديم ، فيمكنك استخدام هذا الرابط. تذكر أن كل الفضل في إنشاء مكتبة S3PI يذهب إلى بيتر إل جونز.
مستودع تم إنشاؤه مع ماركوس توماز