Skip to content

Commit 906e544

Browse files
Bug fix to correctly write XSEQ;
Properly resolve hash values to handle hash collisions;
1 parent 0b5770b commit 906e544

21 files changed

+217
-217
lines changed

XtractQuery/Logic.Business.Level5ScriptManagement/Logic.Business.Level5ScriptManagement/Level5ScriptManagementWorkflow.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -279,10 +279,10 @@ private void PrintHelp()
279279
Console.WriteLine("Following commands exist:");
280280
Console.WriteLine(" -h, --help\t\tShows this help message.");
281281
Console.WriteLine(" -o, --operation\tThe operation to take on the file");
282+
Console.WriteLine(" Valid operations are: e for extraction, c for creation, d for decompression");
282283
Console.WriteLine(" -t, --type\t\tThe type of file given");
283284
Console.WriteLine(" Valid types are: xq32, xseq");
284285
Console.WriteLine(" The type is automatically detected when extracting; This argument will not have any effect on operation 'e'");
285-
Console.WriteLine(" Valid operations are: e for extraction, c for creation, d for decompression");
286286
Console.WriteLine(" -f, --file\t\tThe file to process");
287287
Console.WriteLine(" -n, --no-compression\t[Optional] If the file uses a compression layer");
288288
Console.WriteLine(" This option is automatically detected when extracting; This argument will not have any effect on operation 'e'");

XtractQuery/Logic.Domain.Level5/Logic.Domain.Level5.Contract/Script/IScriptHashStringCache.cs

-19
This file was deleted.

XtractQuery/Logic.Domain.Level5/Logic.Domain.Level5.Contract/Script/IScriptReader.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ public interface IScriptReader
1313
IList<ScriptFunction> ReadFunctions(ScriptTable functionTable, ScriptStringTable? stringTable);
1414
IList<ScriptJump> ReadJumps(ScriptTable jumpTable, ScriptStringTable? stringTable);
1515
IList<ScriptInstruction> ReadInstructions(ScriptTable instructionTable);
16-
IList<ScriptArgument> ReadArguments(ScriptTable argumentTable, ScriptStringTable? stringTable);
16+
IList<ScriptArgument> ReadArguments(ScriptTable argumentTable, ScriptTable instructionTable, ScriptStringTable? stringTable);
1717
}
1818
}

XtractQuery/Logic.Domain.Level5/Logic.Domain.Level5.Contract/Script/IStringTable.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public interface IStringTable
1616
string Read(long offset);
1717
long Write(string value);
1818

19-
string GetByHash(uint hash);
19+
IList<string> GetByHash(uint hash);
2020
uint ComputeHash(string value);
2121
}
2222
}

XtractQuery/Logic.Domain.Level5/Logic.Domain.Level5.Contract/Script/Xq32/IXq32ScriptHashStringCache.cs

-15
This file was deleted.

XtractQuery/Logic.Domain.Level5/Logic.Domain.Level5.Contract/Script/Xq32/IXq32ScriptReader.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ public interface IXq32ScriptReader : IScriptReader
1616
IList<ScriptFunction> CreateFunctions(IReadOnlyList<Xq32Function> functions, ScriptStringTable? stringTable = null);
1717
IList<ScriptJump> CreateJumps(IReadOnlyList<Xq32Jump> jumps, ScriptStringTable? stringTable = null);
1818
IList<ScriptInstruction> CreateInstructions(IReadOnlyList<Xq32Instruction> instructions);
19-
IList<ScriptArgument> CreateArguments(IReadOnlyList<Xq32Argument> arguments, ScriptStringTable? stringTable = null);
19+
IList<ScriptArgument> CreateArguments(IReadOnlyList<Xq32Argument> arguments, IReadOnlyList<ScriptInstruction> instructions, ScriptStringTable? stringTable = null);
2020
}
2121
}

XtractQuery/Logic.Domain.Level5/Logic.Domain.Level5.Contract/Script/Xseq/IXseqScriptHashStringCache.cs

-15
This file was deleted.

XtractQuery/Logic.Domain.Level5/Logic.Domain.Level5.Contract/Script/Xseq/IXseqScriptReader.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ public interface IXseqScriptReader : IScriptReader
1616
IList<ScriptFunction> CreateFunctions(IReadOnlyList<XseqFunction> functions, ScriptStringTable? stringTable = null);
1717
IList<ScriptJump> CreateJumps(IReadOnlyList<XseqJump> jumps, ScriptStringTable? stringTable = null);
1818
IList<ScriptInstruction> CreateInstructions(IReadOnlyList<XseqInstruction> instructions);
19-
IList<ScriptArgument> CreateArguments(IReadOnlyList<XseqArgument> arguments, ScriptStringTable? stringTable = null);
19+
IList<ScriptArgument> CreateArguments(IReadOnlyList<XseqArgument> arguments, IReadOnlyList<ScriptInstruction> instructions, ScriptStringTable? stringTable = null);
2020
}
2121
}

XtractQuery/Logic.Domain.Level5/Logic.Domain.Level5/Script/ScriptReader.cs

+24-15
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public ScriptFile Read(ScriptContainer container)
3232
IList<ScriptFunction> functions = ReadFunctions(container.FunctionTable, container.StringTable, length!.Value);
3333
IList<ScriptJump> jumps = ReadJumps(container.JumpTable, container.StringTable, length!.Value);
3434
IList<ScriptInstruction> instructions = ReadInstructions(container.InstructionTable, length!.Value);
35-
IList<ScriptArgument> arguments = ReadArguments(container.ArgumentTable, container.StringTable, length!.Value);
35+
IList<ScriptArgument> arguments = ReadArguments(container.ArgumentTable, instructions.AsReadOnly(), container.StringTable, length!.Value);
3636

3737
return new ScriptFile
3838
{
@@ -69,12 +69,12 @@ public IList<ScriptInstruction> ReadInstructions(ScriptTable instructionTable)
6969
return ReadInstructions(instructionTable, length!.Value);
7070
}
7171

72-
public IList<ScriptArgument> ReadArguments(ScriptTable argumentTable, ScriptStringTable? stringTable)
72+
public IList<ScriptArgument> ReadArguments(ScriptTable argumentTable, ScriptTable instructionTable, ScriptStringTable? stringTable)
7373
{
7474
if (!TryDetectTablePointerLength(argumentTable, _entrySizeProvider.GetArgumentEntrySize, out PointerLength? length))
7575
throw new InvalidOperationException("Could not detect pointer length.");
7676

77-
return ReadArguments(argumentTable, stringTable, length!.Value);
77+
return ReadArguments(argumentTable, instructionTable, stringTable, length!.Value);
7878
}
7979

8080
public abstract IReadOnlyList<TFunction> ReadFunctions(Stream functionStream, int entryCount, PointerLength length);
@@ -119,60 +119,69 @@ public IList<ScriptInstruction> CreateInstructions(IReadOnlyList<TInstruction> i
119119
return result;
120120
}
121121

122-
public IList<ScriptArgument> CreateArguments(IReadOnlyList<TArgument> arguments, ScriptStringTable? stringTable = null)
122+
public IList<ScriptArgument> CreateArguments(IReadOnlyList<TArgument> arguments, IReadOnlyList<ScriptInstruction> instructions, ScriptStringTable? stringTable = null)
123123
{
124124
using IBinaryReaderX? stringReader = stringTable == null ? null : _binaryFactory.CreateReader(stringTable.Stream, true);
125125

126126
var result = new ScriptArgument[arguments.Count];
127127

128+
var instructionTypes = new (int, int)[arguments.Count];
129+
foreach (ScriptInstruction instruction in instructions)
130+
{
131+
for (var i = 0; i < instruction.ArgumentCount; i++)
132+
instructionTypes[instruction.ArgumentIndex + i] = (instruction.Type, i);
133+
}
134+
128135
var counter = 0;
129136
foreach (TArgument argument in arguments)
130-
result[counter++] = CreateArgument(argument, stringReader);
137+
{
138+
(int instructionType, int argumentIndex) = instructionTypes[counter];
139+
result[counter++] = CreateArgument(argument, instructionType, argumentIndex, stringReader);
140+
}
131141

132142
return result;
133143
}
134144

135145
protected abstract ScriptFunction CreateFunction(TFunction function, IBinaryReaderX? stringReader);
136146
protected abstract ScriptJump CreateJump(TJump jump, IBinaryReaderX? stringReader);
137147
protected abstract ScriptInstruction CreateInstruction(TInstruction instruction);
138-
protected abstract ScriptArgument CreateArgument(TArgument argument, IBinaryReaderX? stringReader);
148+
protected abstract ScriptArgument CreateArgument(TArgument argument, int instructionType, int argumentIndex, IBinaryReaderX? stringReader);
139149

140150
protected abstract IEnumerable<TFunction> OrderFunctions(IReadOnlyList<TFunction> functions);
141151

142152
private IList<ScriptFunction> ReadFunctions(ScriptTable functionTable, ScriptStringTable? stringTable, PointerLength length)
143153
{
144-
using IBinaryReaderX br = _binaryFactory.CreateReader(functionTable.Stream, true);
145-
146154
IReadOnlyList<TFunction> functions = ReadFunctions(functionTable.Stream, functionTable.EntryCount, length);
147155

148156
return CreateFunctions(functions, stringTable);
149157
}
150158

151159
private IList<ScriptJump> ReadJumps(ScriptTable jumpTable, ScriptStringTable? stringTable, PointerLength length)
152160
{
153-
using IBinaryReaderX br = _binaryFactory.CreateReader(jumpTable.Stream, true);
154-
155161
IReadOnlyList<TJump> jumps = ReadJumps(jumpTable.Stream, jumpTable.EntryCount, length);
156162

157163
return CreateJumps(jumps, stringTable);
158164
}
159165

160166
private IList<ScriptInstruction> ReadInstructions(ScriptTable instructionTable, PointerLength length)
161167
{
162-
using IBinaryReaderX br = _binaryFactory.CreateReader(instructionTable.Stream, true);
163-
164168
IReadOnlyList<TInstruction> instructions = ReadInstructions(instructionTable.Stream, instructionTable.EntryCount, length);
165169

166170
return CreateInstructions(instructions);
167171
}
168172

169-
private IList<ScriptArgument> ReadArguments(ScriptTable argumentTable, ScriptStringTable? stringTable, PointerLength length)
173+
private IList<ScriptArgument> ReadArguments(ScriptTable argumentTable, ScriptTable instructionTable, ScriptStringTable? stringTable, PointerLength length)
170174
{
171-
using IBinaryReaderX br = _binaryFactory.CreateReader(argumentTable.Stream, true);
175+
IList<ScriptInstruction> instructions = ReadInstructions(instructionTable, length);
172176

177+
return ReadArguments(argumentTable, instructions.AsReadOnly(), stringTable, length);
178+
}
179+
180+
private IList<ScriptArgument> ReadArguments(ScriptTable argumentTable, IReadOnlyList<ScriptInstruction> instructions, ScriptStringTable? stringTable, PointerLength length)
181+
{
173182
IReadOnlyList<TArgument> arguments = ReadArguments(argumentTable.Stream, argumentTable.EntryCount, length);
174183

175-
return CreateArguments(arguments, stringTable);
184+
return CreateArguments(arguments, instructions, stringTable);
176185
}
177186

178187
private bool TryDetectPointerLength(ScriptContainer container, out PointerLength? length)

XtractQuery/Logic.Domain.Level5/Logic.Domain.Level5/Script/Xq32/Xq32ScriptHashStringCache.cs

-13
This file was deleted.

XtractQuery/Logic.Domain.Level5/Logic.Domain.Level5/Script/Xq32/Xq32ScriptReader.cs

+45-9
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ namespace Logic.Domain.Level5.Script.Xq32
99
internal class Xq32ScriptReader : ScriptReader<Xq32Function, Xq32Jump, Xq32Instruction, Xq32Argument>, IXq32ScriptReader
1010
{
1111
private readonly IBinaryFactory _binaryFactory;
12-
private readonly IXq32ScriptHashStringCache _cache;
12+
private readonly Dictionary<uint, IList<string>> _functionCache;
13+
private readonly Dictionary<uint, IList<string>> _jumpCache;
1314

14-
public Xq32ScriptReader(IXq32ScriptDecompressor decompressor, IXq32ScriptHashStringCache cache,
15-
IXq32ScriptEntrySizeProvider entrySizeProvider, IBinaryFactory binaryFactory)
15+
public Xq32ScriptReader(IXq32ScriptDecompressor decompressor, IXq32ScriptEntrySizeProvider entrySizeProvider,
16+
IBinaryFactory binaryFactory)
1617
: base(decompressor, entrySizeProvider, binaryFactory)
1718
{
1819
_binaryFactory = binaryFactory;
19-
_cache = cache;
20+
_functionCache = new Dictionary<uint, IList<string>>();
21+
_jumpCache = new Dictionary<uint, IList<string>>();
2022
}
2123

2224
public override IReadOnlyList<Xq32Function> ReadFunctions(Stream functionStream, int entryCount, PointerLength length)
@@ -183,7 +185,10 @@ protected override ScriptFunction CreateFunction(Xq32Function function, IBinaryR
183185
stringReader.BaseStream.Position = function.nameOffset;
184186
name = stringReader.ReadCStringSJIS();
185187

186-
_cache.Set(function.crc32, name);
188+
if (!_functionCache.TryGetValue(function.crc32, out IList<string>? functionNames))
189+
_functionCache[function.crc32] = functionNames = new List<string>();
190+
191+
functionNames.Add(name);
187192
}
188193

189194
return new ScriptFunction
@@ -211,7 +216,10 @@ protected override ScriptJump CreateJump(Xq32Jump jump, IBinaryReaderX? stringRe
211216
stringReader.BaseStream.Position = jump.nameOffset;
212217
name = stringReader.ReadCStringSJIS();
213218

214-
_cache.Set(jump.crc32, name);
219+
if (!_jumpCache.TryGetValue(jump.crc32, out IList<string>? jumpNames))
220+
_jumpCache[jump.crc32] = jumpNames = new List<string>();
221+
222+
jumpNames.Add(name);
215223
}
216224

217225
return new ScriptJump
@@ -235,7 +243,7 @@ protected override ScriptInstruction CreateInstruction(Xq32Instruction instructi
235243
};
236244
}
237245

238-
protected override ScriptArgument CreateArgument(Xq32Argument argument, IBinaryReaderX? stringReader)
246+
protected override ScriptArgument CreateArgument(Xq32Argument argument, int instructionType, int argumentIndex, IBinaryReaderX? stringReader)
239247
{
240248
int rawType = -1;
241249
ScriptArgumentType type;
@@ -252,8 +260,36 @@ protected override ScriptArgument CreateArgument(Xq32Argument argument, IBinaryR
252260
type = ScriptArgumentType.StringHash;
253261
value = argument.value;
254262

255-
if (_cache.TryGet(argument.value, out string name))
256-
value = name;
263+
if (argumentIndex != 0)
264+
{
265+
if (_functionCache.TryGetValue((ushort)argument.value, out IList<string>? names)
266+
|| _jumpCache.TryGetValue((ushort)argument.value, out names))
267+
value = names.First();
268+
break;
269+
}
270+
271+
switch (instructionType)
272+
{
273+
case 20:
274+
if (_functionCache.TryGetValue((ushort)argument.value, out IList<string>? names))
275+
value = names.First();
276+
break;
277+
278+
case 30:
279+
if (_jumpCache.TryGetValue((ushort)argument.value, out names))
280+
value = names.First();
281+
break;
282+
283+
case 31:
284+
if (_jumpCache.TryGetValue((ushort)argument.value, out names))
285+
value = names.First();
286+
break;
287+
288+
case 33:
289+
if (_jumpCache.TryGetValue((ushort)argument.value, out names))
290+
value = names.First();
291+
break;
292+
}
257293

258294
break;
259295

0 commit comments

Comments
 (0)