Last active
July 2, 2025 16:45
-
-
Save SirusDoma/d7fc2a57f2f6648dad045392b40b973a to your computer and use it in GitHub Desktop.
[O2Jam] ItemData Parsing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ================================================== | |
| Itemdata.dat Documentation | |
| CXO2 a.k.a SirusDoma | |
| 05-09-2015 | |
| ================================================== | |
| ===== Header Itemdata.dat ======================== | |
| Offset Size Summary | |
| 0 int32 Total Items in Itemdata.dat | |
| ================================================== | |
| ==== Item Info =================================== | |
| Offset Size Summary | |
| 4 uint32 ID of Items | |
| 8 byte Kind of Item | |
| 9 byte Planet Origin of Item | |
| 10 uint16 Gender of Item (Bitflag) | |
| 12 uint16 Quantity (Attributive Item) | |
| 14 byte Modifier (Attributive Item) | |
| 15 byte Attribute (Attributive Item) | |
| 16 byte Price Kind | |
| 17 uint32 Price GEM | |
| 21 uint32 Price MCash | |
| 25 byte Position | |
| -- KOREAN VERSION ONLY ----------------------- | |
| 26 uint32 Special Item Flag (Male) (Value: 0 or 10 (0x0A)) | |
| 30 uint32 Special Item Flag (Female) (Value: 0 or 10 (0x0A)) | |
| ---------------------------------------------- | |
| 26 uint32 Item Name Length (fn) | |
| 30 string(fn) Item Name | |
| 30 + fn uint32 Item Description Length (desc) | |
| 34 + fn string(desc) Item Description | |
| Item Files Header | |
| Repeat 42x: | |
| i byte Sign of Item File Slot (0x01) | |
| i + 1 int32 Length Text of File Name (ojs) | |
| i + 5 string(ojs) OJS File Name. | |
| ================================================== | |
| --- Item Kind ----------- | |
| 0 = Body | |
| 1 = Left Arm | |
| 2 = Right Arm | |
| 3 = Left Hand | |
| 4 = Right Hand | |
| 5 = Face | |
| 6 = Hair | |
| 7 = Glasses | |
| 8 = Earring | |
| 9 = Necklace | |
| 10 = Armlet | |
| 11 = Accessories | |
| 12 = Grove | |
| 13 = Pants | |
| 14 = Shoes | |
| 15 = Musical Instrument - Piano | |
| 16 = Musical Instrument - Bass | |
| 17 = Musical Instrument - Drum | |
| 18 = Musical Instrument - Guitar | |
| 19 = Shirts | |
| 20 = Wings | |
| 21 = Musical Accessories | |
| 22 = Pet | |
| 23 = Hair Accessories | |
| 24 = Attributive Item (Skill) | |
| ------------------------- | |
| --- Planet -------------- | |
| All = 0 | |
| O2Planet = 1 | |
| Aqua = 2 | |
| Eliten = 3 | |
| Graffiti = 4 | |
| Bikini = 5 | |
| Crush = 6 | |
| Wonderland = 7 | |
| Meganut = 8 | |
| Crystal = 9 | |
| Draconic = 10 | |
| Event = 11 | |
| ------------------------- | |
| --- Gender -------------- | |
| Gender is BitFlag | |
| Clean Conversion (Gender): ((num >> 7) & 15) | |
| 0 = Female | |
| 1 = Male | |
| 2 = Commonness (Both) | |
| Clean Conversion (New Flag): (num >> 11) | |
| 0 = Not New | |
| 1 = New | |
| Raw Value Version: | |
| 0 = Female (00 00) | |
| 128 = Male (80 00) | |
| 256 = Commonness (Both) (00 01) | |
| 2048 = New Female (00 08) | |
| 2176 = New Male (80 08) | |
| 2304 = New Commoness (Both) (00 09) | |
| ------------------------- | |
| --- Attributive --------- | |
| Defines behavior of Attributive Item | |
| (Skill in gameplay) | |
| Quantity = Amount of Attributive Items | |
| Modifier = Attributive Modifier Effect | |
| Attribute = Attributive Category | |
| Modifier: | |
| 0 = None | |
| 1 = Power | |
| 2 = Mirror | |
| 3 = Random | |
| 4 = Panic | |
| 5 = Hidden | |
| 6 = Sudden | |
| 7 = Dark | |
| Attribute: | |
| 0 = None | |
| 1 = Power | |
| 2 = Arrangement | |
| 3 = Visibility | |
| ------------------------- | |
| --- Price Kind ---------- | |
| 0 = Not for Sell | |
| 1 = Gem | |
| 2 = MCash | |
| ------------------------- | |
| --- Position ------------ | |
| Value Item Kind Item Kind Code | |
| 0 Musical Instrument 15,16,17,18 | |
| 1 Hair 6 | |
| 2 Accessories 11 | |
| 3 Glove 12 | |
| 4 Necklace 9 | |
| 5 Shirts 19 | |
| 6 Pants 13 | |
| 7 Glasses 7 | |
| 8 Earring 8 | |
| 9 Armlet 10 | |
| 10 Shoes 14 | |
| 11 Face 5 | |
| 12 Wing 20 | |
| 13 Musical Accessories 21 | |
| 14 Pet 22 | |
| 15 Hair Accessories 23 | |
| 255 Body 0 | |
| 255 Left Arm 1 | |
| 255 Right Arm 2 | |
| 255 Left Hand 3 | |
| 255 Right Hand 4 | |
| 255 Attributive Item 24 | |
| ------------------------- | |
| ---- Items File Header -- | |
| byte - Signature | |
| 0 = Invalid / Unused / Padding | |
| 1 = Valid | |
| int32 - Filename Length (fn) | |
| The length of ojs filename that being referenced. | |
| string (fn) - Filename | |
| The exact filename of ojs that being referenced. | |
| Index | |
| The order of these file signature matters; it represent which part of the body that will be rendered in game. | |
| For example, a glove may contains 2 parts of body: left hand and right hand, and each instrument has it's own render animation. | |
| Index (n-th) Summary | |
| 0 Preview / Thumbnail (Small) | |
| 1 Preview / Thumbnail (Big) | |
| 2 Body - No Instrument (Male) | |
| 3 Body - No Instrument (Female) | |
| 4 Body - Bass (Male) | |
| 5 Body - Bass (Female) | |
| 6 Body - Guitar (Male) | |
| 7 Body - Guitar (Female) | |
| 8 Body - Keyboard (Male) | |
| 9 Body - Keyboard (Female) | |
| 10 Body - Drum (Male) | |
| 11 Body - Drum (Female) | |
| 12 Right Arm - No Instrument (Male) | |
| 13 Left Arm - No Instrument (Female) | |
| 14 Left Arm - Bass (Male) | |
| 15 Left Arm - Bass (Female) | |
| 16 Left Arm - Guitar (Male) | |
| 17 Left Arm - Guitar (Female) | |
| 18 Left Arm - Keyboard (Male) | |
| 19 Left Arm - Keyboard (Female) | |
| 20 Left Arm - Drum (Male) | |
| 21 Left Arm - Drum (Female) | |
| 22 Right Arm - No Instrument (Male) | |
| 23 Right Arm - No Instrument (Female) | |
| 24 Right Arm - Bass (Male) | |
| 25 Right Arm - Bass (Female) | |
| 26 Right Arm - Guitar (Male) | |
| 27 Right Arm - Guitar (Female) | |
| 28 Right Arm - Keyboard (Male) | |
| 29 Right Arm - Keyboard (Female) | |
| 30 Right Arm - Drum (Male) | |
| 31 Right Arm - Drum (Female) | |
| 32 Cape - No Instrument (Male) | |
| 33 Cape - No Instrument (Female) | |
| 34 Cape - Bass (Male) | |
| 35 Cape - Bass (Female) | |
| 36 Cape - Guitar (Male) | |
| 37 Cape - Guitar (Female) | |
| 38 Cape - Keyboard (Male) | |
| 39 Cape - Keyboard (Female) | |
| 40 Cape - Drum (Male) | |
| 41 Cape - Drum (Female) | |
| Total Items File Header = 42 | |
| ------------------------- | |
| ================================================== |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Text; | |
| using System.Collections.Generic; | |
| using System.IO; | |
| public enum Planet : byte | |
| { | |
| Any = 0, | |
| O2Planet = 1, | |
| Aqua = 2, | |
| Eliten = 3, | |
| Graffiti = 4, | |
| Bikini = 5, | |
| Crush = 6, | |
| Wonderland = 7, | |
| Meganut = 8, | |
| Crystal = 9, | |
| Draconic = 10, | |
| Event = 11 | |
| } | |
| public enum Gender | |
| { | |
| Female = 0, | |
| Male = 1, | |
| Any = 2 | |
| } | |
| public enum Modifier : byte | |
| { | |
| None = 0, | |
| Power = 1, | |
| Mirror = 2, | |
| Random = 3, | |
| Panic = 4, | |
| Hidden = 5, | |
| Sudden = 6, | |
| Dark = 7 | |
| } | |
| public enum ModifierType : byte | |
| { | |
| None = 0, | |
| Power = 1, | |
| Arrangement = 2, | |
| Visibility = 3 | |
| } | |
| public enum Currency : byte | |
| { | |
| NotForSale = 0, | |
| Gem = 1, | |
| MCash = 2 | |
| } | |
| public enum ItemKind : byte | |
| { | |
| Body = 0, | |
| LeftArm = 1, | |
| RightArm = 2, | |
| LeftHand = 3, | |
| RightHand = 4, | |
| Face = 5, | |
| Hair = 6, | |
| Glasses = 7, | |
| Earrings = 8, | |
| Necklace = 9, | |
| Armlet = 10, | |
| Accessories = 11, | |
| Glove = 12, | |
| Pants = 13, | |
| Shoes = 14, | |
| Piano = 15, | |
| Bass = 16, | |
| Drum = 17, | |
| Guitar = 18, | |
| Jacket = 19, | |
| Wings = 20, | |
| MusicalAccessories = 21, | |
| Pet = 22, | |
| HairAccessories = 23, | |
| AttributiveItem = 24 | |
| } | |
| public enum ItemPart : byte | |
| { | |
| Instrument = 0, | |
| Hair = 1, | |
| Accessories = 2, | |
| Glove = 3, | |
| Necklace = 4, | |
| Jacket = 5, | |
| Pants = 6, | |
| Glasses = 7, | |
| Earrings = 8, | |
| Armlet = 9, | |
| Shoes = 10, | |
| Face = 11, | |
| Wings = 12, | |
| MusicalAccessories = 13, | |
| Pet = 14, | |
| HairAccessories = 15, | |
| Body , | |
| LeftArm , | |
| RightArm , | |
| LeftHand , | |
| RightHand , | |
| AttributiveItem | |
| } | |
| public enum RenderPart | |
| { | |
| SmallPreview, | |
| LargePreview, | |
| Body, | |
| LeftArm, | |
| RightArm, | |
| Head | |
| } | |
| public enum Instrument | |
| { | |
| Default, | |
| Bass, | |
| Guitar, | |
| Piano, | |
| Drum | |
| } | |
| public enum ItemDataFormat | |
| { | |
| Old, | |
| New | |
| } | |
| public class ItemPriceInfo | |
| { | |
| public Currency Currency { get; set; } | |
| public int Gem { get; set; } | |
| public int MCash { get; set; } | |
| } | |
| public class ItemSpecialAttribute | |
| { | |
| public Gender Gender { get; set; } | |
| } | |
| public class ItemData | |
| { | |
| public int ID { get; set; } | |
| public ItemPart ItemPart { get; set; } | |
| public ItemKind ItemKind { get; set; } | |
| public Planet Origin { get; set; } | |
| public Gender Gender { get; set; } | |
| public bool IsNew { get; set; } | |
| public short Quantity { get; set; } | |
| public Modifier Modifier { get; set; } | |
| public ModifierType ModifierType { get; set; } | |
| public ItemPriceInfo Price { get; set; } | |
| public string Name { get; set; } | |
| public string Description { get; set; } | |
| public ItemSpecialAttribute Special { get; set; } | |
| public List<ItemRenderFrame> RenderFrames { get; set; } | |
| public ItemData() | |
| { | |
| RenderFrames = new List<ItemRenderFrame>(); | |
| Price = new ItemPriceInfo(); | |
| } | |
| } | |
| public class ItemRenderFrame | |
| { | |
| public RenderPart RenderPart { get; set; } | |
| public Instrument Instrument { get; set; } | |
| public Gender Gender { get; set; } | |
| public string Reference { get; set; } | |
| } | |
| public static class ItemDataParser | |
| { | |
| public static ItemData[] Parse(byte[] data, ItemDataFormat format) | |
| { | |
| var items = new List<ItemData>(); | |
| using (var stream = new MemoryStream(data)) | |
| using (var reader = new BinaryReader(stream)) | |
| { | |
| int count = reader.ReadInt32(); | |
| for (int i = 0; i < count; i++) | |
| { | |
| var item = new ItemData(); | |
| item.ID = reader.ReadInt32(); | |
| item.ItemKind = (ItemKind) reader.ReadByte(); | |
| item.Origin = (Planet) reader.ReadByte(); | |
| short bitflag = reader.ReadInt16(); | |
| item.Gender = (Gender)((bitflag >> 7) & 15); | |
| item.IsNew = (bitflag >> 11) == 1; | |
| item.Quantity = reader.ReadInt16(); | |
| item.Modifier = (Modifier) reader.ReadByte(); | |
| item.ModifierType = (ModifierType) reader.ReadByte(); | |
| item.Price.Currency = (Currency)reader.ReadByte(); | |
| item.Price.Gem = reader.ReadInt32(); | |
| item.Price.MCash = reader.ReadInt32(); | |
| byte part = reader.ReadByte(); | |
| if (part == 255) | |
| { | |
| switch (item.ItemKind) | |
| { | |
| case ItemKind.Body: item.ItemPart = ItemPart.Body; break; | |
| case ItemKind.LeftArm: item.ItemPart = ItemPart.LeftArm; break; | |
| case ItemKind.RightArm: item.ItemPart = ItemPart.RightArm; break; | |
| case ItemKind.LeftHand: item.ItemPart = ItemPart.LeftHand; break; | |
| case ItemKind.RightHand: item.ItemPart = ItemPart.RightHand; break; | |
| case ItemKind.AttributiveItem: item.ItemPart = ItemPart.AttributiveItem; break; | |
| default: item.ItemPart = ItemPart.Body; break; | |
| } | |
| } | |
| else | |
| item.ItemPart = (ItemPart)part; | |
| // O2KR Item Data | |
| // Special animated item, (similar to O2MO Costume) | |
| if (format == ItemDataFormat.New) | |
| { | |
| bool special = false; | |
| var specialGender = Gender.Any; | |
| if (reader.ReadInt32() == 10) | |
| { | |
| special = true; | |
| specialGender = Gender.Male; | |
| } | |
| if (reader.ReadInt32() == 10) | |
| { | |
| special = true; | |
| specialGender = specialGender == Gender.Male ? Gender.Any : Gender.Female; | |
| } | |
| if (special) | |
| item.Special = new ItemSpecialAttribute {Gender = specialGender}; | |
| } | |
| else | |
| item.Special = null; | |
| item.Name = Encoding.GetEncoding("EUC-KR").GetString(reader.ReadBytes(reader.ReadInt32())); | |
| item.Description = Encoding.GetEncoding("EUC-KR").GetString(reader.ReadBytes(reader.ReadInt32())); | |
| foreach (RenderPart renderPart in Enum.GetValues(typeof(RenderPart))) | |
| { | |
| if (renderPart == RenderPart.SmallPreview || renderPart == RenderPart.LargePreview) | |
| { | |
| bool valid = reader.ReadBoolean(); | |
| if (!valid) | |
| continue; | |
| var frame = new ItemRenderFrame(); | |
| frame.RenderPart = renderPart; | |
| frame.Reference = Encoding.UTF8.GetString(reader.ReadBytes(reader.ReadInt32())).Trim('\0'); | |
| item.RenderFrames.Add(frame); | |
| continue; | |
| } | |
| foreach (Instrument instrument in Enum.GetValues(typeof(Instrument))) | |
| { | |
| foreach (Gender gender in new[] {Gender.Male, Gender.Female}) | |
| { | |
| bool valid = reader.ReadBoolean(); | |
| if (!valid) | |
| continue; | |
| var frame = new ItemRenderFrame(); | |
| frame.RenderPart = renderPart; | |
| frame.Instrument = instrument; | |
| frame.Gender = gender; | |
| frame.Reference = Encoding.UTF8.GetString(reader.ReadBytes(reader.ReadInt32())).Trim('\0'); | |
| item.RenderFrames.Add(frame); | |
| } | |
| } | |
| } | |
| items.Add(item); | |
| } | |
| } | |
| return items.ToArray(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment