Skip to content

Instantly share code, notes, and snippets.

@SirusDoma
Last active July 2, 2025 16:45
Show Gist options
  • Select an option

  • Save SirusDoma/d7fc2a57f2f6648dad045392b40b973a to your computer and use it in GitHub Desktop.

Select an option

Save SirusDoma/d7fc2a57f2f6648dad045392b40b973a to your computer and use it in GitHub Desktop.
[O2Jam] ItemData Parsing
==================================================
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
-------------------------
==================================================
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