Hep me for PangLib.IFF

I am trying to use PangLib.IFF I have exceeded in getting use it
Seeing that this is not easy.
I tried to update the data reading as:
Part
SetItem
Item
QuestItem
CaddyItem
and others

but it seems that does not understand well how they do to read the files, for me it is not so easy to manipulate

public GetItemName ()> return name of the searched item
public GetData ()> check if the item exists and return all your available data

I tried to modify the classes

AuxPart

to AuxPart (Public Class)

yesterday I was able to play PangLib.IFF
I have used it the way it came, I am facing doubts because of the public struct since I am a low level developer and I have not dealt with this type of class knowing it is the same
public class

I’ve done the IFFTest works and read
but it seems that iff Manipulator does not load all iff
only charges 1 at a time
different from my friend, it reads and keeps the data loaded and returns when requested
but Andy’s IFF ready is good, but needs a good fit for everyone to use

First of all, thanks for using my toolchain!

PangLib.IFF works like this:

  • Using the filename, PangLib.IFF tries to figure out what data model to use. If it can’t find a model matching the filename, it will return “Unknown”. If you want to add a new model, you need to add it to the list of models in the IFFFile.cs file as well.
  • If the IFF file given is not a ZIP file (the root IFF file in Pangya data/ is a ZIP file), PangLib.IFF will proceed to read information like the record count, and record length (record length = (file length - 8L) / record count)
  • Now to the core, the Parse method:
    • First, we get sure that the type of the file is not “Unknown” and the file is not a ZIP file
    • We then check for the magic number being in place (by now I’ve found out that this is the IFF file version)
    • Now, we loop through all available records. Jumping to the starting position of a record using the JumpToRecord method. Here we read RecordLength bytes. Next thing we do is get an instance of the C# type of the data model our file matches to, for Ball.iff we get the C# type PangLib.IFF.DataModels.Ball (the Ball structure). Using C# marshalling, we then map the read bytes to the structure (basically a shorter way instead of setting everything manually). Once that is done, we put the filled-in data set into the Entries property of the IFFFile instance.

If you want to add more IFF file types to get parsed, you need to do the following:

  • Create a file with the name of the structure you want to add in DataModels/ and follow the namespace convention of the other files. Inside that file, only define a structure for the model with the same name as the model file Ball.iff -> public struct Ball.
  • Once you added the file and added all the parseable fields to it, you need to add the name of the type to the “DataModels” list in the IFFFile class, this ensures that if you create an instance of the IFF file using IFFFile IFF = new IFFFile("Part.iff") the resulting type will not be “Unknown”.
  • If everything was done properly, the file should be parsed and the entries should be found in the Entries property.

Speaking of that, as I recently found out that the int32 present at byte 4, which I previously assumed was just a “magic number” (a lot of people talked about it that way), is actually a version. This is prevalent when you try to parse a Pangya JP Season 8 file using PangLib.IFF, which doesn’t work, because the common structure (the first few fields like name, level, etc.) have changed. So I need to add version specific IFF file structures to the whole library as well.

I also want to refactor the library as a whole and instead of having the library “guess” what type the file has, have the user specifically choose it, I imagined something like turning the library generic, so

IFFFile IFF = new IFFFile("Ball.iff");

would turn into something like

IFFFile<Ball> BallIFF = new IFFFile<Ball>("Ball.iff");

where the developer has to pass in the DataModel, so unclear stuff like using the List<object> Entries can use the actual type and developers don’t have to cast data before being able to use it properly.

Also, as noted in the README, you currently cannot save back IFF changes into files, but as part of the refactor, I’m working on this!

thanks for the reply
some people may find it difficult to want to test
why the IFFFile class had changes
to get a chance to be used with some app running PangLib.IFF

I thought that IFFFile would read all files listed in the DataList

Yeah, maybe I need to clarify that a bit more, but in general for the library it works like so: One instance of IFFFile is for one file specifically.

People themselves can build a library that loops over all files in a folder and create several instances, that shouldn’t be too hard! I’m just giving (simple) developer tools.

Most of those are really in it’s beginning stages, but I try to make them more usable and easier to understand over time!

thanks for information xD

Just as a notice, I updated PangLib.IFF a lot over the past day!

The newest version 4.2.0 now has following changes:

  • IFFFile is now powered by generics, changing to IFFFile<T>
  • Loading is not a constructor based action anymore, you can now use the static method IFFFile<T>.Load(filePath) which returns an instance of IFFFile<T>
  • Saving of files is now supported (IFFFile<T>.Save(filePath))
  • Removed the ExtractToDirectory method, people can utilize ZipArchive themselves, once an IFFFile was loaded using the Load method, if the file is a ZIP file, the property IsZipFile will be true
  • Loading an existing file into an IFFFile instance will now yield an error if the structure and record data length mismatches (for example, a IFF file record is longer than the struct we have defined for it), this means that you might need to adjust your data models (and some of the default DataModels don’t work anymore as well)

Here an example of loading Character.iff, changing Nuri, the first entry, in it and saving it to Character2.iff:

IFFFile<Character> IFF = IFFFile<Character>.Load(System.Environment.CurrentDirectory + "\\Character.iff");

Character Nuri = IFF.Entries[0];
Nuri.Header.Name = "Male Base";
IFF.Entries.Insert(0, Nuri);

IFF.Save(System.Environment.CurrentDirectory + "\\Character2.iff");

Now the main task left is adding all data models, and also versioned data models for the different region versions so everything can be parsed properly. The base library is fairly solid now!

Attention:

This is a modified version that I did contains part of the codes quoted in this post, original codes still belong to the Creator.

IFFFileCollection> data IFF collector
IFFFile> returns data collected by the IFFFileCollection
IFFFileManager> iff file handler

will load all iff quoted in the FileName of this folder
var IFF = new IFFFileManager (“data //”);

however unfinished and incomplete is version
still not figure out an easy way to do it works
but it’s quite simple, you can get more accurate data
you just need to use
Exemples:

public class AuxPart : IFFFile

{
internal override string FileName { get { return “AuxPart.iff”; } }
}

IFF.Caddie.GetByID (id); // search and return data by itemid

IFF.Caddie.GetByName (“Name”) // search and return data by item name

CodeSource

I quickly spun up a prototype that I didn’t test, but this should work, without adding a lot of custom code to what I have written so far: https://gist.github.com/pixeldesu/3d6d5dc9a62376d651d2b3bc25cd9134

That would be way cleaner, wouldn’t it?

I tried solving it without the switch..case but that would require generic type inflection and I really haven’t done that and my quick experiments on it didn’t work.

1 Like

oow, would this be a new version?

yes, allowing a query on the loaded data much faster and less codes, everything is viable

I’m using some functions I found here and have some data similar to davedevils created

Link