Compare commits

...

2 Commits

Author SHA1 Message Date
Adrian 7694fb0c03 Library refactoring 3
Add ScnSerializerReader
2016-02-18 02:05:30 +01:00
Adrian 982dc159cf Library refactoring 2
* IScnFactory change
* Deep or shallow generation in default factory
* Some fixes in ScnSerializerWriter
2016-02-18 02:04:49 +01:00
5 changed files with 328 additions and 22 deletions

View File

@ -9,9 +9,9 @@ namespace AdrianKousz.GenieEngine
Scenario.ScnPlayerSettings MakePlayerSettings();
Scenario.ScnMessages MakeMessages();
Scenario.ScnCinematics MakeCinematics();
Scenario.ScnGlobalVictory MakeGlobalVictoryInfo();
Scenario.ScnResourceCopy MakeResourceCopyInfo();
Scenario.ScnGlobalVictory MakeGlobalVictory();
Scenario.ScnResourceCopy MakeResourceCopy();
Scenario.ScnMap MakeMap();
Scenario.ScnUnit MakeUnitInfo();
Scenario.ScnUnit MakeUnit();
}
}

View File

@ -27,10 +27,19 @@ namespace AdrianKousz.GenieEngine
result.Timestamp = System.DateTime.Now;
result.PlayerCount = 2;
result.Messages = MakeMessages();
result.Cinematics = MakeCinematics();
result.GlobalVictory = MakeGlobalVictory();
result.Map = MakeMap();
if (deep) {
result.Messages = MakeMessages();
result.Cinematics = MakeCinematics();
result.GlobalVictory = MakeGlobalVictory();
result.Map = MakeMap();
result.ResourceCopies = new Scenario.ScnResourceCopy[Scenario.NumPlayerSections - 1]
.Fill(MakeResourceCopy);
result.PlayerSettings = new Scenario.ScnPlayerSettings[Scenario.NumPlayers]
.Fill(MakePlayerSettings);
result.Units = new List<Scenario.ScnUnit>[Scenario.NumPlayerSections]
.Fill();
}
return result;
}
@ -53,8 +62,7 @@ namespace AdrianKousz.GenieEngine
result.ResourceGold = 100;
result.ResourceStone = 100;
result.StartingAge = -1;
result.Diplomacy = new int[Scenario.NumPlayers];
result.Diplomacy.Fill(3);
result.Diplomacy = new int[Scenario.NumPlayers].Fill(3);
return result;
}

View File

@ -0,0 +1,292 @@
using System.IO;
using System.IO.Compression;
using System.Collections.Generic;
using AdrianKousz.Util;
namespace AdrianKousz.GenieEngine
{
public class ScnSerializerReader
{
private IScnFactory factory;
public static ScnSerializerReader CreateDefault()
{
var factory = new ScnDefaultFactory();
return new ScnSerializerReader(factory);
}
private ScnSerializerReader(IScnFactory factory)
{
this.factory = factory;
}
public Scenario ReadScenario(ExtendedBinaryReader reader)
{
var Version = 0f;
var number = 0;
var result = factory is ScnDefaultFactory
? factory.MakeScenario(false)
: factory.MakeScenario();
// Uncompressed header
result.VersionString = reader.ReadString(4);
reader.ReadInt32(); // Header Length
result.Unknown1 = reader.ReadInt32();
result.Timestamp = DateTimes.FromUnixTime(reader.ReadInt32());
result.InstructionsUncompressed = reader.ReadZStringInt32();
result.Unknown2 = reader.ReadInt32();
result.PlayerCount = reader.ReadInt32();
// Compression starts
var originalReader = reader;
var compressedPart = new NonDisposingStreamWrapper(reader.BaseStream);
var comp = new DeflateStream(compressedPart, CompressionMode.Decompress);
reader = new ExtendedBinaryReader(comp, originalReader.Encoding);
result.NextId = reader.ReadInt32();
result.VersionNumber = reader.ReadSingle();
Version = result.VersionNumber;
result.PlayerSettings = new Scenario.ScnPlayerSettings[Scenario.NumPlayers]
.Fill(factory.MakePlayerSettings);
// PlayerSettings 1
result.PlayerSettings.ForEach(x => {
x.Name = reader.ReadZString(256);
});
if (Version >= 1.18f) {
result.PlayerSettings.ForEach(x => {
x.NameStringID = reader.ReadInt32();
});
}
result.PlayerSettings.ForEach(x => {
x.Active = reader.ReadBoolean();
x.Human = reader.ReadBoolean();
x.Civ = reader.ReadInt32();
x.UnknownInfo = reader.ReadInt32();
});
result.Unknown3 = reader.ReadInt32();
result.Unknown4 = reader.ReadSByte();
result.Unknown5 = reader.ReadSingle();
result.Filename = reader.ReadStringInt16();
// Messages
result.Messages = factory.MakeMessages();
if (Version >= 1.18f) {
result.Messages.InstructionsStringID = reader.ReadInt32();
result.Messages.HintsStringID = reader.ReadInt32();
result.Messages.VictoryStringID = reader.ReadInt32();
result.Messages.LossStringID = reader.ReadInt32();
result.Messages.HistoryStringID = reader.ReadInt32();
}
if (Version >= 1.22f) {
result.Messages.ScoutsStringID = reader.ReadInt32();
}
result.Messages.Instructions = reader.ReadZStringInt16();
result.Messages.Hints = reader.ReadZStringInt16();
result.Messages.Victory = reader.ReadZStringInt16();
result.Messages.Loss = reader.ReadZStringInt16();
result.Messages.History = reader.ReadZStringInt16();
if (Version >= 1.22f) {
result.Messages.Scouts = reader.ReadZStringInt16();
}
// Cinematics
result.Cinematics = factory.MakeCinematics();
result.Cinematics.FilenamePregame = reader.ReadStringInt16();
result.Cinematics.FilenameVictory = reader.ReadStringInt16();
result.Cinematics.FilenameLoss = reader.ReadStringInt16();
result.Cinematics.FilenameBitmap = reader.ReadStringInt16();
var hasBitmap = reader.ReadBoolean();
result.Cinematics.BitmapWidth = reader.ReadInt32();
result.Cinematics.BitmapHeight = reader.ReadInt32();
result.Cinematics.BitmapUnknown = reader.ReadInt16();
if (hasBitmap) {
result.Cinematics.RawBitmap = BitmapUtil.ReadRawBitmap(reader.BaseStream);
}
// PlayerSettings 2
result.PlayerSettings.ForEach(x => {
x.FilenameAI = reader.ReadStringInt16();
x.FilenameCTY = reader.ReadStringInt16();
x.FilenamePER = reader.ReadStringInt16();
});
result.PlayerSettings.ForEach(x => {
var l1 = reader.ReadInt32();
var l2 = reader.ReadInt32();
var l3 = reader.ReadInt32();
x.ScriptAI = reader.ReadString(l1);
x.ScriptCTY = reader.ReadString(l2);
x.ScriptPER = reader.ReadString(l3);
});
if (Version >= 1.18f) {
result.PlayerSettings.ForEach(x => {
x.AIType = reader.ReadSByte();
});
}
ReadSeparator(reader, "Resources");
// Resources
result.PlayerSettings.ForEach(x => {
x.ResourceGold = reader.ReadInt32();
x.ResourceWood = reader.ReadInt32();
x.ResourceFood = reader.ReadInt32();
x.ResourceStone = reader.ReadInt32();
if (Version >= 1.18f) {
x.ResourceOre = reader.ReadInt32();
if (Version < 1.3f) {
x.UnknownResource = reader.ReadInt32();
}
}
});
ReadSeparator(reader, "Victory");
// Diplomacy
result.GlobalVictory = factory.MakeGlobalVictory();
result.GlobalVictory.RequireConquest = reader.ReadBoolean();
result.GlobalVictory.Ruins = reader.ReadInt32();
result.GlobalVictory.Artifacts = reader.ReadInt32();
result.GlobalVictory.Discovery = reader.ReadInt32();
result.GlobalVictory.PercentExplored = reader.ReadInt32();
result.GlobalVictory.Unknown = reader.ReadInt32();
result.GlobalVictory.RequireAllCustom = reader.ReadBoolean();
result.GlobalVictory.Mode = reader.ReadInt32();
result.GlobalVictory.Score = reader.ReadInt32();
result.GlobalVictory.Time = reader.ReadInt32();
// PlayerSettings 3
result.PlayerSettings.ForEach(x => {
x.Diplomacy = new int[Scenario.NumPlayers].Fill(reader.ReadInt32());
});
result.RawIndividualVictory = reader.ReadBytes(11520);
ReadSeparator(reader, "Player Environment");
result.PlayerSettings.ForEach(x => {
x.AlliedVictory = reader.ReadInt32();
});
if (Version >= 1.15f) number = (Scenario.NumPlayers * ( 20 /*Disables*/) + 3 /*Unknowns*/) * 4 /*Intsize*/;
if (Version >= 1.18f) number = (Scenario.NumPlayers * (3 /*Lengths*/ + 80 /*Disables*/) + 3 /*Unknowns*/) * 4 /*Intsize*/;
if (Version >= 1.30f) number = (Scenario.NumPlayers * (3 /*Lengths*/ + 180 /*Disables*/) + 3 /*Unknowns*/) * 4 /*Intsize*/;
result.RawDisables = reader.ReadBytes(number);
result.PlayerSettings.ForEach(x => {
x.StartingAge = reader.ReadInt32();
});
ReadSeparator("Map");
// Map
result.Map = factory.MakeMap();
if (Version >= 1.18f) {
result.Map.CameraX = reader.ReadInt32();
result.Map.CameraY = reader.ReadInt32();
}
if (Version >= 1.22f) {
result.Map.GeneratorId = reader.ReadInt32();
}
result.Map.SizeX = reader.ReadInt32();
result.Map.SizeY = reader.ReadInt32();
result.Map.LinearTiles = new Scenario.ScnMap.Tile[result.Map.SizeX * result.Map.SizeY]
.Fill(() => new Scenario.ScnMap.Tile(reader.ReadSByte(), reader.ReadSByte(), reader.ReadSByte()));
// ResourceCopies
number = reader.ReadInt32();
result.ResourceCopies = new Scenario.ScnResourceCopy[number - 1]
.Fill(factory.MakeResourceCopy);
result.ResourceCopies.ForEach(x => {
x.ResourceFood = reader.ReadSingle();
x.ResourceWood = reader.ReadSingle();
x.ResourceGold = reader.ReadSingle();
x.ResourceStone = reader.ReadSingle();
if (Version >= 1.18f) {
x.ResourceOre = reader.ReadInt32();
if (Version < 1.3f) {
x.UnknownResource = reader.ReadInt32();
}
}
if (Version >= 1.22f) {
x.PopulationLimit = reader.ReadSingle();
}
});
// Units
result.Units = new List<Scenario.ScnUnit>[number].Fill();
result.Units.ForEach(x => {
var count = reader.ReadInt32();
x.Fill(() => {
var unit = factory.MakeUnit();
unit.PosX = reader.ReadSingle();
unit.PosY = reader.ReadSingle();
unit.Unknown1 = reader.ReadSingle();
unit.Id = reader.ReadInt32();
unit.UnitId = reader.ReadInt16();
unit.Unknown2 = reader.ReadSByte();
unit.Rotation = reader.ReadSingle();
if (Version >= 1.18f) {
unit.InitialFrame = reader.ReadInt16();
unit.GarrisonnedInId = reader.ReadInt32();
}
return unit;
}, count);
});
// More Player Settings and Triggers
var bytestream = new MemoryStream();
reader.BaseStream.CopyTo(bytestream);
result.RawRemaining = bytestream.ToArray();
// End of reading
reader.Dispose();
comp.Dispose();
compressedPart.Dispose();
return result;
}
public void ReadSeparator(ExtendedBinaryReader reader, string name) {
int v = reader.ReadInt32();
if (v != Scenario.Separator) {
var msg = "Separator \"{0}\" = {1}";
msg = string.Format(msg, name, v);
throw new InvalidDataException(msg);
}
}
}
}

View File

@ -36,7 +36,7 @@ namespace AdrianKousz.GenieEngine
var originalWriter = writer;
var compressedPart = new MemoryStream();
var comp = new DeflateStream(compressedPart, CompressionMode.Compress);
writer = new ExtendedBinaryWriter(comp, writer.Encoding);
writer = new ExtendedBinaryWriter(comp, originalWriter.Encoding);
writer.Write(value.NextId);
writer.Write(value.VersionNumber);
@ -54,10 +54,10 @@ namespace AdrianKousz.GenieEngine
}
value.PlayerSettings.ForEach(x => {
writer.WriteStringPadded(x.Active);
writer.WriteStringPadded(x.Human);
writer.WriteStringPadded(x.Civ);
writer.WriteStringPadded(x.UnknownInfo);
writer.Write(x.Active);
writer.Write(x.Human);
writer.Write(x.Civ);
writer.Write(x.UnknownInfo);
});
writer.Write(value.Unknown3);
@ -125,11 +125,13 @@ namespace AdrianKousz.GenieEngine
writer.WriteStringRaw(x.ScriptPER);
});
value.PlayerSettings.ForEach(x => {
writer.Write(x.AIType);
});
if (Version >= 1.18f) {
value.PlayerSettings.ForEach(x => {
writer.Write(x.AIType);
});
}
WriteSeperator(writer, "Resources");
WriteSeparator(writer, "Resources");
// Resources
@ -146,7 +148,7 @@ namespace AdrianKousz.GenieEngine
}
});
WriteSeperator(writer, "Victory");
WriteSeparator(writer, "Victory");
// Diplomacy
@ -171,7 +173,7 @@ namespace AdrianKousz.GenieEngine
writer.Write(value.RawIndividualVictory);
WriteSeperator(writer, "Player Environment");
WriteSeparator(writer, "Player Environment");
value.PlayerSettings.ForEach(x => {
writer.Write(x.AlliedVictory);
@ -183,7 +185,7 @@ namespace AdrianKousz.GenieEngine
writer.Write(x.StartingAge);
});
WriteSeperator(writer, "Map");
WriteSeparator(writer, "Map");
// Map
@ -246,12 +248,15 @@ namespace AdrianKousz.GenieEngine
writer.Write(value.RawRemaining);
// End of writing
writer.Dispose();
comp.Dispose();
compressedPart.Dispose();
originalWriter.Write(compressedPart.ToArray());
}
public void WriteSeperator(ExtendedBinaryWriter writer, string name)
public void WriteSeparator(ExtendedBinaryWriter writer, string name)
{
writer.Write(Scenario.Separator);
}

View File

@ -43,6 +43,7 @@
<Compile Include="AdrianKousz.GenieEngine\IScnFactory.cs" />
<Compile Include="AdrianKousz.GenieEngine\ScnSerializerWriter.cs" />
<Compile Include="AdrianKousz.GenieEngine\Scenario.cs" />
<Compile Include="AdrianKousz.GenieEngine\ScnSerializerReader.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>