1 | using System;
|
---|
2 | using System.Collections.Generic;
|
---|
3 | using System.IO;
|
---|
4 | using Oni.Metadata;
|
---|
5 |
|
---|
6 | namespace Oni
|
---|
7 | {
|
---|
8 | internal sealed class InstanceDescriptor
|
---|
9 | {
|
---|
10 | private InstanceFile file;
|
---|
11 | private string fullName;
|
---|
12 | private int index;
|
---|
13 | private Template template;
|
---|
14 | private int dataOffset;
|
---|
15 | private int nameOffset;
|
---|
16 | private int dataSize;
|
---|
17 | private InstanceDescriptorFlags flags;
|
---|
18 |
|
---|
19 | internal static InstanceDescriptor Read(InstanceFile file, BinaryReader reader, int index)
|
---|
20 | {
|
---|
21 | var metadata = InstanceMetadata.GetMetadata(file);
|
---|
22 |
|
---|
23 | var descriptor = new InstanceDescriptor
|
---|
24 | {
|
---|
25 | file = file,
|
---|
26 | index = index,
|
---|
27 | template = metadata.GetTemplate((TemplateTag)reader.ReadInt32()),
|
---|
28 | dataOffset = reader.ReadInt32(),
|
---|
29 | nameOffset = reader.ReadInt32(),
|
---|
30 | dataSize = reader.ReadInt32(),
|
---|
31 | flags = (InstanceDescriptorFlags)(reader.ReadInt32() & 0xff)
|
---|
32 | };
|
---|
33 |
|
---|
34 | if (descriptor.IsPlaceholder && !descriptor.HasName)
|
---|
35 | throw new InvalidDataException("Empty descriptors must have names");
|
---|
36 |
|
---|
37 | return descriptor;
|
---|
38 | }
|
---|
39 |
|
---|
40 | public InstanceFile File => file;
|
---|
41 |
|
---|
42 | public int Index => index;
|
---|
43 |
|
---|
44 | public string FullName
|
---|
45 | {
|
---|
46 | get
|
---|
47 | {
|
---|
48 | if (fullName == null)
|
---|
49 | fullName = index.ToString();
|
---|
50 |
|
---|
51 | return fullName;
|
---|
52 | }
|
---|
53 | }
|
---|
54 |
|
---|
55 | public string Name
|
---|
56 | {
|
---|
57 | get
|
---|
58 | {
|
---|
59 | string name = FullName;
|
---|
60 |
|
---|
61 | if (name.StartsWith(Template.Tag.ToString(), StringComparison.Ordinal))
|
---|
62 | name = name.Substring(4);
|
---|
63 |
|
---|
64 | return name;
|
---|
65 | }
|
---|
66 | }
|
---|
67 |
|
---|
68 | public Template Template => template;
|
---|
69 |
|
---|
70 | public bool HasName => ((flags & InstanceDescriptorFlags.Private) == 0);
|
---|
71 |
|
---|
72 | public bool IsPlaceholder => ((flags & InstanceDescriptorFlags.Placeholder) != 0 || dataSize == 0 || dataOffset == 0);
|
---|
73 |
|
---|
74 | public int DataOffset => file.Header.DataTableOffset + dataOffset;
|
---|
75 |
|
---|
76 | public int DataSize => dataSize;
|
---|
77 |
|
---|
78 | internal void ReadName(Dictionary<int, string> names)
|
---|
79 | {
|
---|
80 | if (!HasName)
|
---|
81 | return;
|
---|
82 |
|
---|
83 | if (IsPlaceholder || file.Header.Version == InstanceFileHeader.Version31)
|
---|
84 | {
|
---|
85 | names.TryGetValue(nameOffset, out fullName);
|
---|
86 | }
|
---|
87 | else
|
---|
88 | {
|
---|
89 | fullName = Importer.DecodeFileName(file.FilePath);
|
---|
90 |
|
---|
91 | string tagName = template.Tag.ToString();
|
---|
92 |
|
---|
93 | if (!fullName.StartsWith(tagName, StringComparison.Ordinal))
|
---|
94 | fullName = tagName + fullName;
|
---|
95 | }
|
---|
96 | }
|
---|
97 |
|
---|
98 | internal void SetName(string newName)
|
---|
99 | {
|
---|
100 | flags &= ~InstanceDescriptorFlags.Private;
|
---|
101 | fullName = newName;
|
---|
102 | }
|
---|
103 |
|
---|
104 | public List<InstanceDescriptor> GetReferencedDescriptors() => file.GetReferencedDescriptors(this);
|
---|
105 |
|
---|
106 | internal BinaryReader OpenRead()
|
---|
107 | {
|
---|
108 | if (IsPlaceholder)
|
---|
109 | throw new InvalidOperationException();
|
---|
110 |
|
---|
111 | return new BinaryReader(file.FilePath, file)
|
---|
112 | {
|
---|
113 | Position = DataOffset
|
---|
114 | };
|
---|
115 | }
|
---|
116 |
|
---|
117 | internal BinaryReader OpenRead(int offset)
|
---|
118 | {
|
---|
119 | if (IsPlaceholder)
|
---|
120 | throw new InvalidOperationException();
|
---|
121 |
|
---|
122 | return new BinaryReader(file.FilePath, file)
|
---|
123 | {
|
---|
124 | Position = DataOffset + offset
|
---|
125 | };
|
---|
126 | }
|
---|
127 |
|
---|
128 | internal BinaryReader GetRawReader(int offset) => file.GetRawReader(offset);
|
---|
129 |
|
---|
130 | internal BinaryReader GetSepReader(int offset)
|
---|
131 | {
|
---|
132 | if (!IsMacFile)
|
---|
133 | return GetRawReader(offset);
|
---|
134 |
|
---|
135 | return file.GetSepReader(offset);
|
---|
136 | }
|
---|
137 |
|
---|
138 | internal bool IsMacFile => (file.Header.TemplateChecksum == InstanceFileHeader.OniMacTemplateChecksum);
|
---|
139 |
|
---|
140 | public long TemplateChecksum => file.Header.TemplateChecksum;
|
---|
141 |
|
---|
142 | public string FilePath => file.FilePath;
|
---|
143 |
|
---|
144 | public bool HasRawParts()
|
---|
145 | {
|
---|
146 | if (IsPlaceholder)
|
---|
147 | return false;
|
---|
148 |
|
---|
149 | switch (template.Tag)
|
---|
150 | {
|
---|
151 | case TemplateTag.AKVA:
|
---|
152 | case TemplateTag.AGDB:
|
---|
153 | case TemplateTag.BINA:
|
---|
154 | case TemplateTag.TXMP:
|
---|
155 | case TemplateTag.OSBD:
|
---|
156 | case TemplateTag.SNDD:
|
---|
157 | case TemplateTag.SUBT:
|
---|
158 | case TemplateTag.TRAM:
|
---|
159 | return true;
|
---|
160 |
|
---|
161 | default:
|
---|
162 | return false;
|
---|
163 | }
|
---|
164 | }
|
---|
165 | }
|
---|
166 | }
|
---|