|
You last visited: Today at 08:02
Advertisement
*.2dt files
Discussion on *.2dt files within the SRO Coding Corner forum part of the Silkroad Online category.
05/18/2015, 18:10
|
#1
|
elite*gold: 25
Join Date: Sep 2012
Posts: 209
Received Thanks: 343
|
*.2dt files
Hello there,
Is there anyone who knows the structure for *.2dt files here?
Short info:
*.2dt files are new interface system which works on new clients(such as isro, csro, vsro), which placed at "Media.pk2\res_ui\".
I'm working on to make a proper editor for those files, any kind of help will be perfect.
|
|
|
05/23/2015, 14:00
|
#2
|
elite*gold: 60
Join Date: Jan 2010
Posts: 48
Received Thanks: 253
|
Hello,
I remember spending some time on these files.
The structure is pretty simple. Please note that I haven't figured out the complete format yet.
The file basically consists of a specified amount of fixed-size data blocks. Each block has a total size of 976 bytes. The first four bytes of the file specify the amount of blocks that will follow.
So the basic structure looks like this:
Code:
[INT32] Number of blocks
for (int i = 0; i < numberOfBlocks; i++)
{
[976 bytes] Data block
}
This also means that the size of the file can be calculated like this: totalSize = 4 + (numberOfBlocks*976)
Now, each data block can be interpreted as follows:
Code:
[STR64] name
[STR256] texture1
[STR256] texture2
[STR128] text
[STR64] description
[STR64] prototype
[INT32] type
[INT32] id
[INT32] parentId
[INT32] unk1
[INT32] unk2
[INT32] unk3
[UINT8] colorR
[UINT8] colorG
[UINT8] colorB
[UINT8] colorA
[INT32] rectX
[INT32] rectY
[INT32] rectWidth
[INT32] rectHeight
[FLOAT] Texture coordinate top left (U)
[FLOAT] Texture coordinate top left (V)
[FLOAT] Texture coordinate top right (U)
[FLOAT] Texture coordinate top right (V)
[FLOAT] Texture coordinate bottom right (U)
[FLOAT] Texture coordinate bottom right (V)
[FLOAT] Texture coordinate bottom left (U)
[FLOAT] Texture coordinate bottom left (V)
[INT32] unk4
[INT32] unk5
[INT32] unk6
[INT32] unk7
[INT32] unk8
[INT32] unk9
[INT32] unk10
[INT32] unk11
[INT32] unk12
[INT32] unk13
[INT32] unk14
[INT32] unk15
[INT32] unk16
[INT32] unk17
[INT32] unk18
[INT32] unk19
[INT32] unk20
As you can see, I haven't figured out what most of pieces in the data block mean, so there's still some work to do.
Probably you could use the old interface format to figure those unkown pieces out.
With this information I wrote a simple C# application which converts the .2dt file into a human-readable JSON file and vice versa.
This program depends on  (Newtonsoft)
Code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using Newtonsoft.Json;
namespace SrInterface
{
static class Extensions
{
public static string ReadFixedSizeString(this BinaryReader reader, int size)
{
var buffer = reader.ReadBytes(size);
int idx;
for (idx = 0; idx < buffer.Length; idx++)
{
if (buffer[idx] == 0) break;
}
return Encoding.Default.GetString(buffer, 0, idx);
}
public static void WriteFixedSizeString(this BinaryWriter writer, string value, int size)
{
var strBuffer = Encoding.Default.GetBytes(value);
var buffer = new byte[size];
Buffer.BlockCopy(strBuffer, 0, buffer, 0, strBuffer.Length > size ? size : strBuffer.Length);
writer.Write(buffer);
}
}
class Color
{
public byte R;
public byte G;
public byte B;
public byte A;
public Color(byte r, byte g, byte b, byte a)
{
R = r;
G = g;
B = b;
A = a;
}
}
struct Rectangle
{
public int X;
public int Y;
public int Width;
public int Height;
public Rectangle(int x, int y, int width, int heigt)
{
X = x;
Y = y;
Width = width;
Height = heigt;
}
}
class TexCoord
{
public float U;
public float V;
public TexCoord(float u, float v)
{
U = u;
V = v;
}
}
class TexCoordConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var coord = value as TexCoord;
if (coord == null) throw new Exception("Expected a TexCoord value");
writer.WriteValue(string.Format("{0}, {1}", coord.U, coord.V));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType != JsonToken.String)
throw new Exception("Unexpected token type");
var split = (reader.Value as string).Split(',');
return new TexCoord(float.Parse(split[0]), float.Parse(split[1]));
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof (TexCoord);
}
}
class BlockJson
{
[JsonProperty("block")] public Block Block;
}
class Block
{
public string Name;
public string Texture1;
public string Texture2;
public string Text;
public string Description;
public string Prototype;
public int Type;
public int Id;
public int ParentId;
public int Unk1;
public int Unk2;
public int Unk3;
public Color Color;
public Rectangle Rectangle;
[JsonProperty("TexCoordLt")]
[JsonConverter(typeof(TexCoordConverter))]
public TexCoord TexCoordLeftTop;
[JsonProperty("TexCoordRt")]
[JsonConverter(typeof(TexCoordConverter))]
public TexCoord TexCoordRightTop;
[JsonProperty("TexCoordRb")]
[JsonConverter(typeof(TexCoordConverter))]
public TexCoord TexCoordRightBottom;
[JsonProperty("TexCoordLb")]
[JsonConverter(typeof(TexCoordConverter))]
public TexCoord TexCoordLeftBottom;
public int Unk4;
public int Unk5;
public int Unk6;
public int Unk7;
public int Unk8;
public int Unk9;
public int Unk10;
public int Unk11;
public int Unk12;
public int Unk13;
public int Unk14;
public int Unk15;
public int Unk16;
public int Unk17;
public int Unk18;
public int Unk19;
public int Unk20;
}
class Program
{
static void Decode(string filename)
{
var outputFilename = string.Format("{0}.json", Path.GetFileNameWithoutExtension(filename));
using (var stream = File.OpenRead(filename))
using (var reader = new BinaryReader(stream))
using (var streamOut = File.Create(outputFilename))
using (var writer = new StreamWriter(streamOut))
using (var jsonWriter = new JsonTextWriter(writer))
{
const int blockSize = 976;
jsonWriter.Formatting = Formatting.Indented;
var blockCount = reader.ReadInt32();
if ((blockCount*blockSize) + 4 != stream.Length)
{
Console.WriteLine("Invalid file size");
return;
}
var blocks = new List<BlockJson>(blockCount);
for (int i = 0; i < blockCount; i++)
{
blocks.Add(new BlockJson
{
Block = new Block
{
Name = reader.ReadFixedSizeString(64),
Texture1 = reader.ReadFixedSizeString(256),
Texture2 = reader.ReadFixedSizeString(256),
Text = reader.ReadFixedSizeString(128),
Description = reader.ReadFixedSizeString(64),
Prototype = reader.ReadFixedSizeString(64),
Type = reader.ReadInt32(),
Id = reader.ReadInt32(),
ParentId = reader.ReadInt32(),
Unk1 = reader.ReadInt32(),
Unk2 = reader.ReadInt32(),
Unk3 = reader.ReadInt32(),
Color = new Color(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte()),
Rectangle = new Rectangle(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32()),
TexCoordLeftTop = new TexCoord(reader.ReadSingle(), reader.ReadSingle()),
TexCoordRightTop = new TexCoord(reader.ReadSingle(), reader.ReadSingle()),
TexCoordRightBottom = new TexCoord(reader.ReadSingle(), reader.ReadSingle()),
TexCoordLeftBottom = new TexCoord(reader.ReadSingle(), reader.ReadSingle()),
Unk4 = reader.ReadInt32(),
Unk5 = reader.ReadInt32(),
Unk6 = reader.ReadInt32(),
Unk7 = reader.ReadInt32(),
Unk8 = reader.ReadInt32(),
Unk9 = reader.ReadInt32(),
Unk10 = reader.ReadInt32(),
Unk11 = reader.ReadInt32(),
Unk12 = reader.ReadInt32(),
Unk13 = reader.ReadInt32(),
Unk14 = reader.ReadInt32(),
Unk15 = reader.ReadInt32(),
Unk16 = reader.ReadInt32(),
Unk17 = reader.ReadInt32(),
Unk18 = reader.ReadInt32(),
Unk19 = reader.ReadInt32(),
Unk20 = reader.ReadInt32()
}
});
}
var serializer = new JsonSerializer();
serializer.Serialize(jsonWriter, blocks);
}
}
static void Encode(string filename)
{
var outputFilename = string.Format("{0}.2dt", Path.GetFileNameWithoutExtension(filename));
using (var stream = File.OpenRead(filename))
using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader))
using (var streamOut = File.Create(outputFilename))
using (var writer = new BinaryWriter(streamOut))
{
var serializer = new JsonSerializer();
var blocks = serializer.Deserialize<List<BlockJson>>(jsonReader);
writer.Write(blocks.Count);
foreach (var jsonBlock in blocks)
{
var block = jsonBlock.Block;
writer.WriteFixedSizeString(block.Name, 64);
writer.WriteFixedSizeString(block.Texture1, 256);
writer.WriteFixedSizeString(block.Texture2, 256);
writer.WriteFixedSizeString(block.Text, 128);
writer.WriteFixedSizeString(block.Description, 64);
writer.WriteFixedSizeString(block.Prototype, 64);
writer.Write(block.Type);
writer.Write(block.Id);
writer.Write(block.ParentId);
writer.Write(block.Unk1);
writer.Write(block.Unk2);
writer.Write(block.Unk3);
writer.Write(block.Color.R);
writer.Write(block.Color.G);
writer.Write(block.Color.B);
writer.Write(block.Color.A);
writer.Write(block.Rectangle.X);
writer.Write(block.Rectangle.Y);
writer.Write(block.Rectangle.Width);
writer.Write(block.Rectangle.Height);
writer.Write(block.TexCoordLeftTop.U);
writer.Write(block.TexCoordLeftTop.V);
writer.Write(block.TexCoordRightTop.U);
writer.Write(block.TexCoordRightTop.V);
writer.Write(block.TexCoordRightBottom.U);
writer.Write(block.TexCoordRightBottom.V);
writer.Write(block.TexCoordLeftBottom.U);
writer.Write(block.TexCoordLeftBottom.V);
writer.Write(block.Unk4);
writer.Write(block.Unk5);
writer.Write(block.Unk6);
writer.Write(block.Unk7);
writer.Write(block.Unk8);
writer.Write(block.Unk9);
writer.Write(block.Unk10);
writer.Write(block.Unk11);
writer.Write(block.Unk12);
writer.Write(block.Unk13);
writer.Write(block.Unk14);
writer.Write(block.Unk15);
writer.Write(block.Unk16);
writer.Write(block.Unk17);
writer.Write(block.Unk18);
writer.Write(block.Unk19);
writer.Write(block.Unk20);
}
}
}
static void Main(string[] args)
{
if (args.Length < 2)
{
Console.WriteLine("Usage: {mode} [filenames]");
return;
}
var mode = args[0].ToLower();
for (int i = 1; i < args.Length; i++)
{
if (mode == "decode") Decode(args[i]);
else if (mode == "encode") Encode(args[i]);
}
}
}
}
Using this program to convert the nifeventword.2dt file into a JSON file, I got the following output:
Code:
[
{
"block": {
"Name": "CNIFEventWord",
"Texture1": "",
"Texture2": "",
"Text": "",
"Description": "±ÛÀÚ¸ðÀ¸±â ¸ÞÀÎ",
"Prototype": "",
"Type": 18,
"Id": 178,
"ParentId": 0,
"Unk1": 0,
"Unk2": 0,
"Unk3": 0,
"Color": {
"R": 255,
"G": 255,
"B": 255,
"A": 255
},
"Rectangle": {
"X": 492,
"Y": 158,
"Width": 42,
"Height": 42
},
"TexCoordLt": "0, 0",
"TexCoordRt": "1, 0",
"TexCoordRb": "1, 1",
"TexCoordLb": "0, 1",
"Unk4": 0,
"Unk5": 0,
"Unk6": 1,
"Unk7": 0,
"Unk8": 0,
"Unk9": 0,
"Unk10": 0,
"Unk11": 0,
"Unk12": 0,
"Unk13": 0,
"Unk14": 0,
"Unk15": 0,
"Unk16": 0,
"Unk17": 0,
"Unk18": 0,
"Unk19": 0,
"Unk20": 65792
}
},
{
"block": {
"Name": "",
"Texture1": "",
"Texture2": "icon\\item\\etc\\event_news_box.ddj",
"Text": "",
"Description": "ÇѱÛÀÚ ¹è°æ",
"Prototype": "",
"Type": 5,
"Id": 5,
"ParentId": 178,
"Unk1": 0,
"Unk2": 0,
"Unk3": 0,
"Color": {
"R": 255,
"G": 255,
"B": 255,
"A": 255
},
"Rectangle": {
"X": 497,
"Y": 163,
"Width": 32,
"Height": 32
},
"TexCoordLt": "0, 0",
"TexCoordRt": "1, 0",
"TexCoordRb": "1, 1",
"TexCoordLb": "0, 1",
"Unk4": 0,
"Unk5": 0,
"Unk6": 0,
"Unk7": 0,
"Unk8": 0,
"Unk9": 0,
"Unk10": 0,
"Unk11": 0,
"Unk12": 0,
"Unk13": 0,
"Unk14": 0,
"Unk15": 0,
"Unk16": 0,
"Unk17": 0,
"Unk18": 0,
"Unk19": 0,
"Unk20": 65792
}
},
{
"block": {
"Name": "",
"Texture1": "",
"Texture2": "icon\\item\\etc\\event_news_a.ddj",
"Text": "",
"Description": "ÇѱÛÀÚ",
"Prototype": "",
"Type": 5,
"Id": 6,
"ParentId": 178,
"Unk1": 0,
"Unk2": 0,
"Unk3": 0,
"Color": {
"R": 255,
"G": 255,
"B": 255,
"A": 255
},
"Rectangle": {
"X": 497,
"Y": 163,
"Width": 32,
"Height": 32
},
"TexCoordLt": "0, 0",
"TexCoordRt": "1, 0",
"TexCoordRb": "1, 1",
"TexCoordLb": "0, 1",
"Unk4": 0,
"Unk5": 0,
"Unk6": 0,
"Unk7": 0,
"Unk8": 0,
"Unk9": 0,
"Unk10": 0,
"Unk11": 0,
"Unk12": 0,
"Unk13": 0,
"Unk14": 0,
"Unk15": 0,
"Unk16": 0,
"Unk17": 0,
"Unk18": 0,
"Unk19": 0,
"Unk20": 65792
}
}
]
If you find any error our just have an idea for improvement, let me know!
I hope I could help you a little.
Stratti
|
|
|
05/24/2015, 15:22
|
#3
|
elite*gold: 135
Join Date: May 2015
Posts: 648
Received Thanks: 753
|
Check this
|
|
|
All times are GMT +1. The time now is 08:02.
|
|