Guest User

Untitled

a guest
Apr 17th, 2017
335
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.99 KB | None | 0 0
  1. namespace MEAExplorerWV.FB
  2. {
  3.  
  4.     public class STR
  5.     {
  6.         public uint ID;
  7.         public String Value;
  8.     }
  9.  
  10.     public class TalkTableAsset
  11.     {
  12.         public List<STR> Strings;
  13.  
  14.         List<int> NodeList;
  15.         List<StringID> StringList;
  16.         List<uint> BitStream;
  17.  
  18.         public class HuffNode
  19.         {
  20.             public HuffNode e0;
  21.             public HuffNode e1;
  22.             public char c;
  23.             public long w;
  24.             public int index;
  25.             public bool hasIndex;
  26.             public HuffNode(char chr, long weight)
  27.             {
  28.                 e0 = e1 = null;
  29.                 c = chr;
  30.                 w = weight;
  31.                 hasIndex = false;
  32.             }
  33.         }
  34.  
  35.         public class AlphaEntry
  36.         {
  37.             public bool[] list;
  38.             public char c;
  39.         }
  40.  
  41.         public class StringID
  42.         {
  43.             public uint ID;
  44.             public uint offset;
  45.         }
  46.  
  47.         public uint magic;
  48.         public int unk01;
  49.         public int DataOffset;
  50.         public ushort unk02;
  51.         public ushort unk03;
  52.         public int unk04;
  53.         public int unk05;
  54.         public int Data1Count;
  55.         public int Data1Offset;
  56.         public int Data2Count;
  57.         public int Data2Offset;
  58.         public int Data3Count;
  59.         public int Data3Offset;
  60.         public int Data4Count;
  61.         public int Data4Offset;
  62.         public int Data5Count;
  63.         public int Data5Offset;
  64.         public List<int> Data1;
  65.         public List<uint> StringIDs;
  66.         public List<int> StringData;
  67.         public List<uint> Data;
  68.  
  69.         public bool Read(MemoryStream s)
  70.         {
  71.             magic = Helpers.ReadUInt(s);
  72.             if (magic != 0xD78B40EB)
  73.                 return false;
  74.  
  75.             unk01 = Helpers.ReadInt(s);
  76.             DataOffset = Helpers.ReadInt(s);
  77.             unk02 = Helpers.ReadUShort(s);
  78.             unk03 = Helpers.ReadUShort(s);
  79.             unk04 = Helpers.ReadInt(s);
  80.             unk05 = Helpers.ReadInt(s);
  81.             Data1Count = Helpers.ReadInt(s);
  82.             Data1Offset = Helpers.ReadInt(s);
  83.             Data2Count = Helpers.ReadInt(s);
  84.             Data2Offset = Helpers.ReadInt(s);
  85.             Data3Count = Helpers.ReadInt(s);
  86.             Data3Offset = Helpers.ReadInt(s);
  87.             Data4Count = Helpers.ReadInt(s);
  88.             Data4Offset = Helpers.ReadInt(s);
  89.             if (Data4Count > 0)
  90.             {
  91.                 Data5Count = Helpers.ReadInt(s);
  92.                 Data5Offset = Helpers.ReadInt(s);
  93.             }
  94.             s.Seek(Data1Offset, SeekOrigin.Begin);
  95.             Data1 = new List<int>();
  96.             for (int i = 0; i < Data1Count; i++)
  97.                 Data1.Add(Helpers.ReadInt(s));
  98.             s.Seek(Data2Offset, SeekOrigin.Begin);
  99.             StringIDs = new List<uint>();
  100.             StringData = new List<int>();
  101.             for (int i = 0; i < Data2Count; i++)
  102.             {
  103.                 StringIDs.Add(Helpers.ReadUInt(s));
  104.                 StringData.Add(Helpers.ReadInt(s));
  105.             }
  106.             s.Seek(DataOffset, SeekOrigin.Begin);
  107.             Data = new List<uint>();
  108.             while (s.Position < s.Length)
  109.                 Data.Add(Helpers.ReadUInt(s));
  110.             Strings = new List<STR>();
  111.             for (int i = 0; i < StringIDs.Count; i++)
  112.             {
  113.                 STR ValueString = new STR();
  114.                 ValueString.ID = StringIDs[i];
  115.                 ValueString.Value = "";
  116.                 int Index = StringData[i] >> 5;
  117.                 int Shift = StringData[i] & 0x1F;
  118.                 StringBuilder sb = new StringBuilder();
  119.                 while (true)
  120.                 {
  121.                     int e = (Data1.Count / 2) - 1;
  122.                     while (e >= 0)
  123.                     {
  124.                         uint d = Data[Index];
  125.                         int offset = (int)((d >> Shift) & 1);
  126.                         e = Data1[(e * 2) + offset];
  127.  
  128.                         Shift++;
  129.                         Index += (Shift >> 5);
  130.                         Shift %= 32;
  131.                     }
  132.                     ushort c;
  133.                     if ((e & 0xFF00) == 0xFF)
  134.                         c = (ushort)(0xFFFFFFFF - (uint)e);
  135.                     else
  136.                         c = (ushort)(0xFFFF - (ushort)e);
  137.                     if (c == 0)
  138.                         break;
  139.                     else
  140.                         sb.Append((char)c);
  141.                 }
  142.                 ValueString.Value = sb.ToString();
  143.                 Strings.Add(ValueString);
  144.             }
  145.             return true;
  146.         }
  147.  
  148.         public void Save(Stream s)
  149.         {
  150.             long[] weights = new long[256 * 256];
  151.             foreach (STR line in Strings)
  152.             {
  153.                 weights[0]++;
  154.                 foreach (char c in line.Value)
  155.                     weights[(ushort)c]++;
  156.             }
  157.             Dictionary<char, long> weighttable = new Dictionary<char, long>();
  158.             for (int i = 0; i < 256 * 256; i++)
  159.                 if (weights[i] > 0)
  160.                     weighttable.Add((char)i, weights[i]);
  161.             List<HuffNode> nodes = new List<HuffNode>();
  162.             foreach (KeyValuePair<char, long> w in weighttable)
  163.                 nodes.Add(new HuffNode(w.Key, w.Value));
  164.             while (nodes.Count > 1)
  165.             {
  166.                 bool run = true;
  167.                 while (run)
  168.                 {
  169.                     run = false;
  170.                     for (int i = 0; i < nodes.Count - 1; i++)
  171.                         if (nodes[i].w > nodes[i + 1].w)
  172.                         {
  173.                             run = true;
  174.                             HuffNode t = nodes[i];
  175.                             nodes[i] = nodes[i + 1];
  176.                             nodes[i + 1] = t;
  177.                         }
  178.                 }
  179.                 HuffNode e0 = nodes[0];
  180.                 HuffNode e1 = nodes[1];
  181.                 HuffNode combine = new HuffNode(' ', e0.w + e1.w);
  182.                 combine.e0 = e0;
  183.                 combine.e1 = e1;
  184.                 nodes.RemoveAt(1);
  185.                 nodes.RemoveAt(0);
  186.                 nodes.Add(combine);
  187.             }
  188.             HuffNode root = nodes[0];
  189.             NodeList = new List<int>();
  190.             while (!root.hasIndex)
  191.                 CalcIndex(root);
  192.             AlphaEntry[] alphabet = GetAlphabet(root, new List<bool>());
  193.             BitStream = new List<uint>();
  194.             StringList = new List<StringID>();
  195.             uint curr = 0;
  196.             uint index = 0;
  197.             byte shift = 0;
  198.             foreach (STR str in Strings)
  199.             {
  200.                 StringID t = new StringID();
  201.                 t.ID = str.ID;
  202.                 t.offset = index << 5;
  203.                 t.offset += shift;
  204.                 string line = str.Value + "\0";
  205.                 foreach (char c in line)
  206.                 {
  207.                     AlphaEntry alpha = null;
  208.                     foreach (AlphaEntry a in alphabet)
  209.                         if (a.c == c)
  210.                             alpha = a;
  211.                     foreach (bool step in alpha.list)
  212.                     {
  213.                         byte b = 0;
  214.                         if (step)
  215.                             b = 1;
  216.                         if (shift < 32)
  217.                         {
  218.                             curr += (uint)(b << shift);
  219.                             shift++;
  220.                         }
  221.                         if (shift == 32)
  222.                         {
  223.                             BitStream.Add(curr);
  224.                             index++;
  225.                             shift = 0;
  226.                             curr = 0;
  227.                         }
  228.                     }
  229.                 }
  230.                 StringList.Add(t);
  231.             }
  232.             BitStream.Add(curr);
  233.             Helpers.WriteInt(s, (int)magic);
  234.             Helpers.WriteInt(s, (int)unk01);
  235.             Helpers.WriteInt(s, 0x38 + NodeList.Count * 4 + StringList.Count * 8);
  236.             Helpers.WriteUShort(s, 4);
  237.             Helpers.WriteUShort(s, unk03);
  238.             Helpers.WriteInt(s, (int)unk04);
  239.             Helpers.WriteInt(s, (int)unk05);
  240.             Helpers.WriteInt(s, NodeList.Count);
  241.             Helpers.WriteInt(s, 0x38);
  242.             Helpers.WriteInt(s, StringList.Count);
  243.             Helpers.WriteInt(s, 0x38 + NodeList.Count * 4);
  244.             Helpers.WriteInt(s, 0);
  245.             Helpers.WriteInt(s, 0x38 + NodeList.Count * 4 + StringList.Count * 8);
  246.             Helpers.WriteInt(s, 0);
  247.             Helpers.WriteInt(s, 0x38 + NodeList.Count * 4 + StringList.Count * 8);
  248.             foreach (int i in NodeList)
  249.                 Helpers.WriteInt(s, i);
  250.             foreach (StringID sid in StringList)
  251.             {
  252.                 Helpers.WriteInt(s, (int)sid.ID);
  253.                 Helpers.WriteInt(s, (int)sid.offset);
  254.             }
  255.             foreach (int i in BitStream)
  256.                 Helpers.WriteInt(s, i);
  257.         }
  258.  
  259.         public void CalcIndex(HuffNode h)
  260.         {
  261.             if (h.e0 == null && h.e1 == null && !h.hasIndex)
  262.             {
  263.                 int u;
  264.                 if (((ushort)h.c) >= 0x100)
  265.                     u = (short)(0xFFFF - (ushort)h.c);
  266.                 else
  267.                     u = (int)(0xFFFFFFFF - (uint)h.c);
  268.                 h.index = u;
  269.                 h.hasIndex = true;
  270.             }
  271.             else
  272.             {
  273.                 CalcIndex(h.e0);
  274.                 CalcIndex(h.e1);
  275.                 if (h.e0.hasIndex && h.e1.hasIndex)
  276.                 {
  277.                     h.index = NodeList.Count / 2;
  278.                     h.hasIndex = true;
  279.                     NodeList.Add(h.e0.index);
  280.                     NodeList.Add(h.e1.index);
  281.                 }
  282.             }
  283.         }
  284.  
  285.         public AlphaEntry[] GetAlphabet(HuffNode h, List<bool> list)
  286.         {
  287.             List<AlphaEntry> result = new List<AlphaEntry>();
  288.             if (h.e0.e0 == null)
  289.             {
  290.                 AlphaEntry e = new AlphaEntry();
  291.                 e.c = h.e0.c;
  292.                 List<bool> t = new List<bool>();
  293.                 t.AddRange(list);
  294.                 t.Add(false);
  295.                 e.list = t.ToArray();
  296.                 result.Add(e);
  297.             }
  298.             else
  299.             {
  300.                 List<bool> t = new List<bool>();
  301.                 t.AddRange(list);
  302.                 t.Add(false);
  303.                 result.AddRange(GetAlphabet(h.e0, t));
  304.             }
  305.             if (h.e1.e0 == null)
  306.             {
  307.                 AlphaEntry e = new AlphaEntry();
  308.                 e.c = h.e1.c;
  309.                 List<bool> t = new List<bool>();
  310.                 t.AddRange(list);
  311.                 t.Add(true);
  312.                 e.list = t.ToArray();
  313.                 result.Add(e);
  314.             }
  315.             else
  316.             {
  317.                 List<bool> t = new List<bool>();
  318.                 t.AddRange(list);
  319.                 t.Add(true);
  320.                 result.AddRange(GetAlphabet(h.e1, t));
  321.             }
  322.             return result.ToArray();
  323.         }
  324.     }
  325. }
Advertisement
Add Comment
Please, Sign In to add comment