diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..58b9869c --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +Substrate.Tests/Data filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index 013fcec7..621ece58 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,29 @@ -**/Debug/* -**/bin/* -**/obj/* -*.suo -SubstrateCS/Release/ -*.sdf -*.user +**/bin/* +**/obj/* +**/publish/* +*.suo +*.sdf +*.user +*.opensdf +/.vs/ + +Substrate/obj/net35-Release/ +Substrate/obj/ +Substrate/bin/ +Examples/CPPCLI/BlockReplace/BlockReplace/Debug/ +Examples/CPPCLI/BlockReplace/Debug/ +Examples/CS/BlockReplace/bin/ +Examples/CS/BlockReplace/obj/ +Examples/CS/Convert/bin/ +Examples/CS/Convert/obj/ +Examples/CS/CustomBlocks/bin/ +Examples/CS/CustomBlocks/obj/ +Examples/CS/FlatMap/bin/ +Examples/CS/FlatMap/obj/ +Examples/CS/GiveItem/bin/ +Examples/CS/GiveItem/obj/ +Substrate.Tests/obj/ +Substrate.Tests/bin/ +Substrate.Entities/obj/ +Substrate.Entities/bin/ +/packages/ diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 00000000..e02470c8 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,56 @@ + + + + + net40;net45;netcoreapp3.1;net5.0 + + + + DEBUG;TRACE + + + TRACE + + + disable + false + 1701;1702;1591 + publish\ + + + + + true + 2.0.47-alpha + + Substrate.Entities + SDK for loading and modifying Minecraft worlds + Copyright © Justin Aquadro + MIT + https://github.com/minecraft-dotnet/Substrate + https://github.com/minecraft-dotnet/Substrate.git + github + minecraft level client world .net + en-US + 2.0.47.0 + 2.0.47.0 + + + + true + + true + + embedded + + + true + + + + + + + + + \ No newline at end of file diff --git a/SubstrateCPPCLI/BlockReplace/BlockReplace.sln b/Examples/CPPCLI/BlockReplace/BlockReplace.sln similarity index 100% rename from SubstrateCPPCLI/BlockReplace/BlockReplace.sln rename to Examples/CPPCLI/BlockReplace/BlockReplace.sln diff --git a/SubstrateCPPCLI/BlockReplace/BlockReplace/BlockReplace.vcxproj b/Examples/CPPCLI/BlockReplace/BlockReplace/BlockReplace.vcxproj similarity index 92% rename from SubstrateCPPCLI/BlockReplace/BlockReplace/BlockReplace.vcxproj rename to Examples/CPPCLI/BlockReplace/BlockReplace/BlockReplace.vcxproj index 1ea08574..cd5bf829 100644 --- a/SubstrateCPPCLI/BlockReplace/BlockReplace/BlockReplace.vcxproj +++ b/Examples/CPPCLI/BlockReplace/BlockReplace/BlockReplace.vcxproj @@ -1,84 +1,86 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {17FC8A42-7A3B-412F-882D-7D0B60D64959} - v4.0 - ManagedCProj - BlockReplace - - - - Application - true - true - Unicode - - - Application - false - true - Unicode - - - - - - - - - - - - - true - - - false - - - - Level3 - Disabled - WIN32;_DEBUG;%(PreprocessorDefinitions) - - - true - - - E:\Workspace\Managed\Substrate\SubstrateCS\bin\Release\NET4;%(AdditionalLibraryDirectories) - - - - - Level3 - WIN32;NDEBUG;%(PreprocessorDefinitions) - - - true - - - - - - - - - - - E:\Workspace\Managed\Substrate\SubstrateCS\bin\Release\NET4\Substrate.dll - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {17FC8A42-7A3B-412F-882D-7D0B60D64959} + v4.0 + ManagedCProj + BlockReplace + + + + Application + true + true + Unicode + v120 + + + Application + false + true + Unicode + v120 + + + + + + + + + + + + + true + + + false + + + + Level3 + Disabled + WIN32;_DEBUG;%(PreprocessorDefinitions) + + + true + + + E:\Workspace\Managed\Substrate\SubstrateCS\bin\Release\NET4;%(AdditionalLibraryDirectories) + + + + + Level3 + WIN32;NDEBUG;%(PreprocessorDefinitions) + + + true + + + + + + + + + + + ..\..\..\..\Substrate\bin\Release\Substrate.net40-client.dll + + + + + \ No newline at end of file diff --git a/SubstrateCPPCLI/BlockReplace/BlockReplace/BlockReplace.vcxproj.filters b/Examples/CPPCLI/BlockReplace/BlockReplace/BlockReplace.vcxproj.filters similarity index 100% rename from SubstrateCPPCLI/BlockReplace/BlockReplace/BlockReplace.vcxproj.filters rename to Examples/CPPCLI/BlockReplace/BlockReplace/BlockReplace.vcxproj.filters diff --git a/SubstrateCPPCLI/BlockReplace/BlockReplace/Program.cpp b/Examples/CPPCLI/BlockReplace/BlockReplace/Program.cpp similarity index 100% rename from SubstrateCPPCLI/BlockReplace/BlockReplace/Program.cpp rename to Examples/CPPCLI/BlockReplace/BlockReplace/Program.cpp diff --git a/SubstrateCS/Examples/BlockReplace/BlockReplace.csproj b/Examples/CS/BlockReplace/BlockReplace.csproj similarity index 89% rename from SubstrateCS/Examples/BlockReplace/BlockReplace.csproj rename to Examples/CS/BlockReplace/BlockReplace.csproj index c720072c..5dc23596 100644 --- a/SubstrateCS/Examples/BlockReplace/BlockReplace.csproj +++ b/Examples/CS/BlockReplace/BlockReplace.csproj @@ -36,9 +36,8 @@ 4 - - False - ..\..\bin\Release\NET2\Substrate.dll + + ..\..\..\Substrate\bin\Release\Substrate.net40-client.dll diff --git a/SubstrateCS/Examples/BlockReplace/Program.cs b/Examples/CS/BlockReplace/Program.cs similarity index 100% rename from SubstrateCS/Examples/BlockReplace/Program.cs rename to Examples/CS/BlockReplace/Program.cs diff --git a/SubstrateCS/Examples/BlockReplace/Properties/AssemblyInfo.cs b/Examples/CS/BlockReplace/Properties/AssemblyInfo.cs similarity index 100% rename from SubstrateCS/Examples/BlockReplace/Properties/AssemblyInfo.cs rename to Examples/CS/BlockReplace/Properties/AssemblyInfo.cs diff --git a/SubstrateCS/Examples/Convert/Convert.csproj b/Examples/CS/Convert/Convert.csproj similarity index 91% rename from SubstrateCS/Examples/Convert/Convert.csproj rename to Examples/CS/Convert/Convert.csproj index e0cc4189..212b44e2 100644 --- a/SubstrateCS/Examples/Convert/Convert.csproj +++ b/Examples/CS/Convert/Convert.csproj @@ -36,8 +36,8 @@ 4 - - ..\..\bin\Release\NET2\Substrate.dll + + ..\..\..\Substrate\bin\Release\Substrate.net40-client.dll diff --git a/SubstrateCS/Examples/Convert/Program.cs b/Examples/CS/Convert/Program.cs similarity index 100% rename from SubstrateCS/Examples/Convert/Program.cs rename to Examples/CS/Convert/Program.cs diff --git a/SubstrateCS/Examples/Convert/Properties/AssemblyInfo.cs b/Examples/CS/Convert/Properties/AssemblyInfo.cs similarity index 100% rename from SubstrateCS/Examples/Convert/Properties/AssemblyInfo.cs rename to Examples/CS/Convert/Properties/AssemblyInfo.cs diff --git a/SubstrateCS/Examples/CustomBlocks/CustomBlocks.csproj b/Examples/CS/CustomBlocks/CustomBlocks.csproj similarity index 72% rename from SubstrateCS/Examples/CustomBlocks/CustomBlocks.csproj rename to Examples/CS/CustomBlocks/CustomBlocks.csproj index 8b9fefa3..7e43c7e2 100644 --- a/SubstrateCS/Examples/CustomBlocks/CustomBlocks.csproj +++ b/Examples/CS/CustomBlocks/CustomBlocks.csproj @@ -1,56 +1,54 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {B01AD681-31A7-43A0-A84B-F839FBCB2F01} - Exe - Properties - CustomBlocks - CustomBlocks - v2.0 - - - 512 - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - False - ..\..\bin\Release\NET2\Substrate.dll - - - - - - - - + + + + Debug + x86 + 8.0.30703 + 2.0 + {B01AD681-31A7-43A0-A84B-F839FBCB2F01} + Exe + Properties + CustomBlocks + CustomBlocks + v4.0 + + + 512 + + + true + bin\Debug\ + DEBUG;TRACE + full + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + bin\Release\ + TRACE + true + pdbonly + AnyCPU + prompt + MinimumRecommendedRules.ruleset + + + + ..\..\..\Substrate\bin\Release\Substrate.net40-client.dll + + + + + + + + + --> \ No newline at end of file diff --git a/SubstrateCS/Examples/CustomBlocks/Program.cs b/Examples/CS/CustomBlocks/Program.cs similarity index 100% rename from SubstrateCS/Examples/CustomBlocks/Program.cs rename to Examples/CS/CustomBlocks/Program.cs diff --git a/SubstrateCS/Examples/CustomBlocks/Properties/AssemblyInfo.cs b/Examples/CS/CustomBlocks/Properties/AssemblyInfo.cs similarity index 100% rename from SubstrateCS/Examples/CustomBlocks/Properties/AssemblyInfo.cs rename to Examples/CS/CustomBlocks/Properties/AssemblyInfo.cs diff --git a/Examples/CS/Examples.sln b/Examples/CS/Examples.sln new file mode 100644 index 00000000..a254dd96 --- /dev/null +++ b/Examples/CS/Examples.sln @@ -0,0 +1,76 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Convert", "Convert\Convert.csproj", "{5BD42656-9BCF-4C55-8272-A5D3507EFDF3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlatMap", "FlatMap\FlatMap.csproj", "{EDA894F2-00AF-456B-9D07-591ED61A9AE7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlockReplace", "BlockReplace\BlockReplace.csproj", "{6D24D262-34D3-43A6-B066-1312A0C72B16}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiveItem", "GiveItem\GiveItem.csproj", "{426B01F4-B0C0-488E-8A5A-5531C8DFA98C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoveSpawn", "MoveSpawn\MoveSpawn.csproj", "{15C04C0C-FD50-47E9-B62C-AA0A814189ED}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Relight", "Relight\Relight.csproj", "{EBDD447B-01FA-4A29-B4AB-380EC4379B5F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maze", "Maze\Maze.csproj", "{62D70576-FE3A-4530-B283-889C14B52E9E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PurgeEntities", "PurgeEntities\PurgeEntities.csproj", "{A64F274A-D5B7-45C2-92BA-4C9A64863DDC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoodyChest", "GoodyChest\GoodyChest.csproj", "{6A998912-C939-4029-9F1D-D5C2A5E9C804}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomBlocks", "CustomBlocks\CustomBlocks.csproj", "{B01AD681-31A7-43A0-A84B-F839FBCB2F01}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Release|Any CPU.Build.0 = Release|Any CPU + {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Release|Any CPU.Build.0 = Release|Any CPU + {6D24D262-34D3-43A6-B066-1312A0C72B16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6D24D262-34D3-43A6-B066-1312A0C72B16}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6D24D262-34D3-43A6-B066-1312A0C72B16}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6D24D262-34D3-43A6-B066-1312A0C72B16}.Release|Any CPU.Build.0 = Release|Any CPU + {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Release|Any CPU.Build.0 = Release|Any CPU + {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Release|Any CPU.Build.0 = Release|Any CPU + {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Release|Any CPU.Build.0 = Release|Any CPU + {62D70576-FE3A-4530-B283-889C14B52E9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62D70576-FE3A-4530-B283-889C14B52E9E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62D70576-FE3A-4530-B283-889C14B52E9E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62D70576-FE3A-4530-B283-889C14B52E9E}.Release|Any CPU.Build.0 = Release|Any CPU + {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Release|Any CPU.Build.0 = Release|Any CPU + {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Release|Any CPU.Build.0 = Release|Any CPU + {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/SubstrateCS/Examples/FlatMap/FlatMap.csproj b/Examples/CS/FlatMap/FlatMap.csproj similarity index 92% rename from SubstrateCS/Examples/FlatMap/FlatMap.csproj rename to Examples/CS/FlatMap/FlatMap.csproj index eed7d352..a4f2c370 100644 --- a/SubstrateCS/Examples/FlatMap/FlatMap.csproj +++ b/Examples/CS/FlatMap/FlatMap.csproj @@ -50,13 +50,6 @@ prompt 4 - - - False - ..\..\bin\Release\NET2\Substrate.dll - - - @@ -83,6 +76,12 @@ true + + + ..\..\..\Substrate\bin\Release\Substrate.net40-client.dll + + + + + + Substrate.Entities + Substrate.Entities + + + + publish\Substrate.net.xml + + + + minecraft-dotnet.Substrate.Entities + Substrate.Entities + Justin Aquadro + + + + + + + diff --git a/SubstrateCS/Source/TileEntities/TileEntityBeacon.cs b/Substrate.Entities/TileEntities/TileEntityBeacon.cs similarity index 93% rename from SubstrateCS/Source/TileEntities/TileEntityBeacon.cs rename to Substrate.Entities/TileEntities/TileEntityBeacon.cs index 369d9961..38c1b065 100644 --- a/SubstrateCS/Source/TileEntities/TileEntityBeacon.cs +++ b/Substrate.Entities/TileEntities/TileEntityBeacon.cs @@ -11,9 +11,9 @@ public class TileEntityBeacon : TileEntity public static readonly SchemaNodeCompound BeaconSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") { new SchemaNodeString("id", TypeId), - new SchemaNodeScaler("Levels", TagType.TAG_INT), - new SchemaNodeScaler("Primary", TagType.TAG_INT), - new SchemaNodeScaler("Secondary", TagType.TAG_INT), + new SchemaNodeScalar("Levels", TagType.TAG_INT), + new SchemaNodeScalar("Primary", TagType.TAG_INT), + new SchemaNodeScalar("Secondary", TagType.TAG_INT), }); public static string TypeId diff --git a/SubstrateCS/Source/TileEntities/TileEntityBrewingStand.cs b/Substrate.Entities/TileEntities/TileEntityBrewingStand.cs similarity index 96% rename from SubstrateCS/Source/TileEntities/TileEntityBrewingStand.cs rename to Substrate.Entities/TileEntities/TileEntityBrewingStand.cs index 176780a9..565268c0 100644 --- a/SubstrateCS/Source/TileEntities/TileEntityBrewingStand.cs +++ b/Substrate.Entities/TileEntities/TileEntityBrewingStand.cs @@ -10,8 +10,8 @@ public class TileEntityBrewingStand : TileEntity, IItemContainer public static readonly SchemaNodeCompound BrewingStandSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") { new SchemaNodeString("id", TypeId), - new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.Schema), - new SchemaNodeScaler("BrewTime", TagType.TAG_SHORT), + new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.ItemSchema), + new SchemaNodeScalar("BrewTime", TagType.TAG_SHORT), }); public static string TypeId diff --git a/SubstrateCS/Source/TileEntities/TileEntityChest.cs b/Substrate.Entities/TileEntities/TileEntityChest.cs similarity index 95% rename from SubstrateCS/Source/TileEntities/TileEntityChest.cs rename to Substrate.Entities/TileEntities/TileEntityChest.cs index 38efcb36..167a00ea 100644 --- a/SubstrateCS/Source/TileEntities/TileEntityChest.cs +++ b/Substrate.Entities/TileEntities/TileEntityChest.cs @@ -1,98 +1,98 @@ -using System; -using System.Collections.Generic; -using Substrate.Core; -using Substrate.Nbt; - -namespace Substrate.TileEntities -{ - public class TileEntityChest : TileEntity, IItemContainer - { - public static readonly SchemaNodeCompound ChestSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") - { - new SchemaNodeString("id", TypeId), - new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.Schema), - }); - - public static string TypeId - { - get { return "Chest"; } - } - - private const int _CAPACITY = 27; - - private ItemCollection _items; - - protected TileEntityChest (string id) - : base(id) - { - _items = new ItemCollection(_CAPACITY); - } - - public TileEntityChest () - : this(TypeId) - { - } - - public TileEntityChest (TileEntity te) - : base(te) - { - TileEntityChest tec = te as TileEntityChest; - if (tec != null) { - _items = tec._items.Copy(); - } - else { - _items = new ItemCollection(_CAPACITY); - } - } - - #region ICopyable Members - - public override TileEntity Copy () - { - return new TileEntityChest(this); - } - - #endregion - - - #region IItemContainer Members - - public ItemCollection Items - { - get { return _items; } - } - - #endregion - - - #region INBTObject Members - - public override TileEntity LoadTree (TagNode tree) - { - TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null || base.LoadTree(tree) == null) { - return null; - } - - TagNodeList items = ctree["Items"].ToTagList(); - _items = new ItemCollection(_CAPACITY).LoadTree(items); - - return this; - } - - public override TagNode BuildTree () - { - TagNodeCompound tree = base.BuildTree() as TagNodeCompound; - tree["Items"] = _items.BuildTree(); - - return tree; - } - - public override bool ValidateTree (TagNode tree) - { - return new NbtVerifier(tree, ChestSchema).Verify(); - } - - #endregion - } -} +using System; +using System.Collections.Generic; +using Substrate.Core; +using Substrate.Nbt; + +namespace Substrate.TileEntities +{ + public class TileEntityChest : TileEntity, IItemContainer + { + public static readonly SchemaNodeCompound ChestSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") + { + new SchemaNodeString("id", TypeId), + new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.ItemSchema), + }); + + public static string TypeId + { + get { return "Chest"; } + } + + private const int _CAPACITY = 27; + + private ItemCollection _items; + + protected TileEntityChest (string id) + : base(id) + { + _items = new ItemCollection(_CAPACITY); + } + + public TileEntityChest () + : this(TypeId) + { + } + + public TileEntityChest (TileEntity te) + : base(te) + { + TileEntityChest tec = te as TileEntityChest; + if (tec != null) { + _items = tec._items.Copy(); + } + else { + _items = new ItemCollection(_CAPACITY); + } + } + + #region ICopyable Members + + public override TileEntity Copy () + { + return new TileEntityChest(this); + } + + #endregion + + + #region IItemContainer Members + + public ItemCollection Items + { + get { return _items; } + } + + #endregion + + + #region INBTObject Members + + public override TileEntity LoadTree (TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null || base.LoadTree(tree) == null) { + return null; + } + + TagNodeList items = ctree["Items"].ToTagList(); + _items = new ItemCollection(_CAPACITY).LoadTree(items); + + return this; + } + + public override TagNode BuildTree () + { + TagNodeCompound tree = base.BuildTree() as TagNodeCompound; + tree["Items"] = _items.BuildTree(); + + return tree; + } + + public override bool ValidateTree (TagNode tree) + { + return new NbtVerifier(tree, ChestSchema).Verify(); + } + + #endregion + } +} diff --git a/SubstrateCS/Source/TileEntities/TileEntityControl.cs b/Substrate.Entities/TileEntities/TileEntityControl.cs similarity index 96% rename from SubstrateCS/Source/TileEntities/TileEntityControl.cs rename to Substrate.Entities/TileEntities/TileEntityControl.cs index d9d6a5dd..7e88ab9a 100644 --- a/SubstrateCS/Source/TileEntities/TileEntityControl.cs +++ b/Substrate.Entities/TileEntities/TileEntityControl.cs @@ -11,7 +11,7 @@ public class TileEntityControl : TileEntity public static readonly SchemaNodeCompound ControlSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") { new SchemaNodeString("id", TypeId), - new SchemaNodeScaler("Command", TagType.TAG_STRING), + new SchemaNodeScalar("Command", TagType.TAG_STRING), }); public static string TypeId diff --git a/SubstrateCS/Source/TileEntities/TileEntityEnchantmentTable.cs b/Substrate.Entities/TileEntities/TileEntityEnchantmentTable.cs similarity index 100% rename from SubstrateCS/Source/TileEntities/TileEntityEnchantmentTable.cs rename to Substrate.Entities/TileEntities/TileEntityEnchantmentTable.cs diff --git a/SubstrateCS/Source/TileEntities/TileEntityEndPortal.cs b/Substrate.Entities/TileEntities/TileEntityEndPortal.cs similarity index 100% rename from SubstrateCS/Source/TileEntities/TileEntityEndPortal.cs rename to Substrate.Entities/TileEntities/TileEntityEndPortal.cs diff --git a/SubstrateCS/Source/TileEntities/TileEntityFurnace.cs b/Substrate.Entities/TileEntities/TileEntityFurnace.cs similarity index 91% rename from SubstrateCS/Source/TileEntities/TileEntityFurnace.cs rename to Substrate.Entities/TileEntities/TileEntityFurnace.cs index b25c0304..4f93f94a 100644 --- a/SubstrateCS/Source/TileEntities/TileEntityFurnace.cs +++ b/Substrate.Entities/TileEntities/TileEntityFurnace.cs @@ -1,123 +1,123 @@ -using System; -using System.Collections.Generic; -using Substrate.Core; -using Substrate.Nbt; - -namespace Substrate.TileEntities -{ - public class TileEntityFurnace : TileEntity, IItemContainer - { - public static readonly SchemaNodeCompound FurnaceSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") - { - new SchemaNodeString("id", TypeId), - new SchemaNodeScaler("BurnTime", TagType.TAG_SHORT), - new SchemaNodeScaler("CookTime", TagType.TAG_SHORT), - new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.Schema), - }); - - public static string TypeId - { - get { return "Furnace"; } - } - - private const int _CAPACITY = 3; - - private short _burnTime; - private short _cookTime; - - private ItemCollection _items; - - public int BurnTime - { - get { return _burnTime; } - set { _burnTime = (short)value; } - } - - public int CookTime - { - get { return _cookTime; } - set { _cookTime = (short)value; } - } - - protected TileEntityFurnace (string id) - : base(id) - { - _items = new ItemCollection(_CAPACITY); - } - - public TileEntityFurnace () - : this(TypeId) - { - } - - public TileEntityFurnace (TileEntity te) - : base(te) - { - TileEntityFurnace tec = te as TileEntityFurnace; - if (tec != null) { - _cookTime = tec._cookTime; - _burnTime = tec._burnTime; - _items = tec._items.Copy(); - } - else { - _items = new ItemCollection(_CAPACITY); - } - } - - - #region ICopyable Members - - public override TileEntity Copy () - { - return new TileEntityFurnace(this); - } - - #endregion - - - #region IItemContainer Members - - public ItemCollection Items - { - get { return _items; } - } - - #endregion - - - #region INBTObject Members - - public override TileEntity LoadTree (TagNode tree) - { - TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null || base.LoadTree(tree) == null) { - return null; - } - - _burnTime = ctree["BurnTime"].ToTagShort(); - _cookTime = ctree["CookTime"].ToTagShort(); - - TagNodeList items = ctree["Items"].ToTagList(); - _items = new ItemCollection(_CAPACITY).LoadTree(items); - - return this; - } - - public override TagNode BuildTree () - { - TagNodeCompound tree = base.BuildTree() as TagNodeCompound; - tree["BurnTime"] = new TagNodeShort(_burnTime); - tree["CookTime"] = new TagNodeShort(_cookTime); - tree["Items"] = _items.BuildTree(); - - return tree; - } - - public override bool ValidateTree (TagNode tree) - { - return new NbtVerifier(tree, FurnaceSchema).Verify(); - } - - #endregion - } -} +using System; +using System.Collections.Generic; +using Substrate.Core; +using Substrate.Nbt; + +namespace Substrate.TileEntities +{ + public class TileEntityFurnace : TileEntity, IItemContainer + { + public static readonly SchemaNodeCompound FurnaceSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") + { + new SchemaNodeString("id", TypeId), + new SchemaNodeScalar("BurnTime", TagType.TAG_SHORT), + new SchemaNodeScalar("CookTime", TagType.TAG_SHORT), + new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.ItemSchema), + }); + + public static string TypeId + { + get { return "Furnace"; } + } + + private const int _CAPACITY = 3; + + private short _burnTime; + private short _cookTime; + + private ItemCollection _items; + + public int BurnTime + { + get { return _burnTime; } + set { _burnTime = (short)value; } + } + + public int CookTime + { + get { return _cookTime; } + set { _cookTime = (short)value; } + } + + protected TileEntityFurnace (string id) + : base(id) + { + _items = new ItemCollection(_CAPACITY); + } + + public TileEntityFurnace () + : this(TypeId) + { + } + + public TileEntityFurnace (TileEntity te) + : base(te) + { + TileEntityFurnace tec = te as TileEntityFurnace; + if (tec != null) { + _cookTime = tec._cookTime; + _burnTime = tec._burnTime; + _items = tec._items.Copy(); + } + else { + _items = new ItemCollection(_CAPACITY); + } + } + + + #region ICopyable Members + + public override TileEntity Copy () + { + return new TileEntityFurnace(this); + } + + #endregion + + + #region IItemContainer Members + + public ItemCollection Items + { + get { return _items; } + } + + #endregion + + + #region INBTObject Members + + public override TileEntity LoadTree (TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null || base.LoadTree(tree) == null) { + return null; + } + + _burnTime = ctree["BurnTime"].ToTagShort(); + _cookTime = ctree["CookTime"].ToTagShort(); + + TagNodeList items = ctree["Items"].ToTagList(); + _items = new ItemCollection(_CAPACITY).LoadTree(items); + + return this; + } + + public override TagNode BuildTree () + { + TagNodeCompound tree = base.BuildTree() as TagNodeCompound; + tree["BurnTime"] = new TagNodeShort(_burnTime); + tree["CookTime"] = new TagNodeShort(_cookTime); + tree["Items"] = _items.BuildTree(); + + return tree; + } + + public override bool ValidateTree (TagNode tree) + { + return new NbtVerifier(tree, FurnaceSchema).Verify(); + } + + #endregion + } +} diff --git a/SubstrateCS/Source/TileEntities/TileEntityMobSpawner.cs b/Substrate.Entities/TileEntities/TileEntityMobSpawner.cs similarity index 88% rename from SubstrateCS/Source/TileEntities/TileEntityMobSpawner.cs rename to Substrate.Entities/TileEntities/TileEntityMobSpawner.cs index 9ea5ec04..5b031ffb 100644 --- a/SubstrateCS/Source/TileEntities/TileEntityMobSpawner.cs +++ b/Substrate.Entities/TileEntities/TileEntityMobSpawner.cs @@ -1,262 +1,262 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Substrate.TileEntities -{ - using Substrate.Nbt; - - public class TileEntityMobSpawner : TileEntity - { - public static readonly SchemaNodeCompound MobSpawnerSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") - { - new SchemaNodeString("id", TypeId), - new SchemaNodeScaler("EntityId", TagType.TAG_STRING), - new SchemaNodeScaler("Delay", TagType.TAG_SHORT), - new SchemaNodeScaler("MaxSpawnDelay", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("MinSpawnDelay", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("SpawnCount", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("SpawnRange", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("MaxNearbyEnemies", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("RequiredPlayerRange", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("MaxExperience", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("RemainingExperience", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("ExperienceRegenTick", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("ExperienceRegenRate", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("ExperienceRegenAmount", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeCompound("SpawnData", SchemaOptions.OPTIONAL), - }); - - public static string TypeId - { - get { return "MobSpawner"; } - } - - private short _delay; - private string _entityID; - private short? _maxDelay; - private short? _minDelay; - private short? _spawnCount; - private short? _spawnRange; - private short? _maxNearbyEnemies; - private short? _requiredPlayerRange; - private int? _maxExperience; - private int? _remainingExperience; - private int? _experienceRegenTick; - private int? _experienceRegenRate; - private int? _experienceRegenAmount; - private TagNodeCompound _spawnData; - - public int Delay - { - get { return _delay; } - set { _delay = (short)value; } - } - - public TagNodeCompound SpawnData - { - get { return _spawnData; } - set { _spawnData = value; } - } - - public string EntityID - { - get { return _entityID; } - set { _entityID = value; } - } - - public short MaxSpawnDelay - { - get { return _maxDelay ?? 0; } - set { _maxDelay = value; } - } - - public short MinSpawnDelay - { - get { return _minDelay ?? 0; } - set { _minDelay = value; } - } - - public short SpawnCount - { - get { return _spawnCount ?? 0; } - set { _spawnCount = value; } - } - - public short SpawnRange - { - get { return _spawnRange ?? 0; } - set { _spawnRange = value; } - } - - public short MaxNearbyEnemies - { - get { return _maxNearbyEnemies ?? 0; } - set { _maxNearbyEnemies = value; } - } - - public short RequiredPlayerRange - { - get { return _requiredPlayerRange ?? 0; } - set { _requiredPlayerRange = value; } - } - - public int MaxExperience - { - get { return _maxExperience ?? 0; } - set { _maxExperience = value; } - } - - public int RemainingExperience - { - get { return _remainingExperience ?? 0; } - set { _remainingExperience = value; } - } - - public int ExperienceRegenTick - { - get { return _experienceRegenTick ?? 0; } - set { _experienceRegenTick = value; } - } - - public int ExperienceRegenRate - { - get { return _experienceRegenRate ?? 0; } - set { _experienceRegenRate = value; } - } - - public int ExperienceRegenAmount - { - get { return _experienceRegenAmount ?? 0; } - set { _experienceRegenAmount = value; } - } - - protected TileEntityMobSpawner (string id) - : base(id) - { - } - - public TileEntityMobSpawner () - : this(TypeId) - { - } - - public TileEntityMobSpawner (TileEntity te) - : base(te) - { - TileEntityMobSpawner tes = te as TileEntityMobSpawner; - if (tes != null) { - _delay = tes._delay; - _entityID = tes._entityID; - _maxDelay = tes._maxDelay; - _minDelay = tes._minDelay; - _spawnCount = tes._spawnCount; - _spawnRange = tes._spawnRange; - _maxNearbyEnemies = tes._maxNearbyEnemies; - _requiredPlayerRange = tes._requiredPlayerRange; - _maxExperience = tes._maxExperience; - _remainingExperience = tes._remainingExperience; - _experienceRegenTick = tes._experienceRegenTick; - _experienceRegenRate = tes._experienceRegenRate; - _experienceRegenAmount = tes._experienceRegenAmount; - - if (tes._spawnData != null) - _spawnData = tes._spawnData.Copy() as TagNodeCompound; - } - } - - - #region ICopyable Members - - public override TileEntity Copy () - { - return new TileEntityMobSpawner(this); - } - - #endregion - - - #region INBTObject Members - - public override TileEntity LoadTree (TagNode tree) - { - TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null || base.LoadTree(tree) == null) { - return null; - } - - _delay = ctree["Delay"].ToTagShort(); - _entityID = ctree["EntityId"].ToTagString(); - - if (ctree.ContainsKey("MaxSpawnDelay")) - _maxDelay = ctree["MaxSpawnDelay"].ToTagShort(); - if (ctree.ContainsKey("MinSpawnDelay")) - _minDelay = ctree["MinSpawnDelay"].ToTagShort(); - if (ctree.ContainsKey("SpawnCount")) - _spawnCount = ctree["SpawnCount"].ToTagShort(); - if (ctree.ContainsKey("SpawnRange")) - _spawnRange = ctree["SpawnRange"].ToTagShort(); - if (ctree.ContainsKey("MaxNearbyEnemies")) - _maxNearbyEnemies = ctree["MaxNearbyEnemies"].ToTagShort(); - if (ctree.ContainsKey("RequiredPlayerRange")) - _requiredPlayerRange = ctree["RequiredPlayerRange"].ToTagShort(); - if (ctree.ContainsKey("MaxExperience")) - _maxExperience = ctree["MaxExperience"].ToTagInt(); - if (ctree.ContainsKey("RemainingExperience")) - _remainingExperience = ctree["RemainingExperience"].ToTagInt(); - if (ctree.ContainsKey("ExperienceRegenTick")) - _experienceRegenTick = ctree["ExperienceRegenTick"].ToTagInt(); - if (ctree.ContainsKey("ExperienceRegenRate")) - _experienceRegenRate = ctree["ExperienceRegenRate"].ToTagInt(); - if (ctree.ContainsKey("ExperienceRegenAmount")) - _experienceRegenRate = ctree["ExperienceRegenAmount"].ToTagInt(); - - if (ctree.ContainsKey("SpawnData")) - _spawnData = ctree["SpawnData"].ToTagCompound(); - - return this; - } - - public override TagNode BuildTree () - { - TagNodeCompound tree = base.BuildTree() as TagNodeCompound; - tree["EntityId"] = new TagNodeString(_entityID); - tree["Delay"] = new TagNodeShort(_delay); - - if (_maxDelay != null) - tree["MaxSpawnDelay"] = new TagNodeShort(_maxDelay ?? 0); - if (_minDelay != null) - tree["MinSpawnDelay"] = new TagNodeShort(_minDelay ?? 0); - if (_spawnCount != null) - tree["SpawnCount"] = new TagNodeShort(_spawnCount ?? 0); - if (_spawnRange != null) - tree["SpawnRange"] = new TagNodeShort(_spawnRange ?? 0); - if (_maxNearbyEnemies != null) - tree["MaxNearbyEnemies"] = new TagNodeShort(_maxNearbyEnemies ?? 0); - if (_requiredPlayerRange != null) - tree["RequiredPlayerRange"] = new TagNodeShort(_requiredPlayerRange ?? 0); - if (_maxExperience != null) - tree["MaxExperience"] = new TagNodeInt(_maxExperience ?? 0); - if (_remainingExperience != null) - tree["RemainingExperience"] = new TagNodeInt(_remainingExperience ?? 0); - if (_experienceRegenTick != null) - tree["ExperienceRegenTick"] = new TagNodeInt(_experienceRegenTick ?? 0); - if (_experienceRegenRate != null) - tree["ExperienceRegenRate"] = new TagNodeInt(_experienceRegenRate ?? 0); - if (_experienceRegenAmount != null) - tree["ExperienceRegenAmount"] = new TagNodeInt(_experienceRegenAmount ?? 0); - - if (_spawnData != null && _spawnData.Count > 0) - tree["SpawnData"] = _spawnData; - - return tree; - } - - public override bool ValidateTree (TagNode tree) - { - return new NbtVerifier(tree, MobSpawnerSchema).Verify(); - } - - #endregion - } -} +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.TileEntities +{ + using Substrate.Nbt; + + public class TileEntityMobSpawner : TileEntity + { + public static readonly SchemaNodeCompound MobSpawnerSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") + { + new SchemaNodeString("id", TypeId), + new SchemaNodeScalar("EntityId", TagType.TAG_STRING), + new SchemaNodeScalar("Delay", TagType.TAG_SHORT), + new SchemaNodeScalar("MaxSpawnDelay", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("MinSpawnDelay", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("SpawnCount", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("SpawnRange", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("MaxNearbyEnemies", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("RequiredPlayerRange", TagType.TAG_SHORT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("MaxExperience", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("RemainingExperience", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("ExperienceRegenTick", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("ExperienceRegenRate", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("ExperienceRegenAmount", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeCompound("SpawnData", SchemaOptions.OPTIONAL), + }); + + public static string TypeId + { + get { return "MobSpawner"; } + } + + private short _delay; + private string _entityID; + private short? _maxDelay; + private short? _minDelay; + private short? _spawnCount; + private short? _spawnRange; + private short? _maxNearbyEnemies; + private short? _requiredPlayerRange; + private int? _maxExperience; + private int? _remainingExperience; + private int? _experienceRegenTick; + private int? _experienceRegenRate; + private int? _experienceRegenAmount; + private TagNodeCompound _spawnData; + + public int Delay + { + get { return _delay; } + set { _delay = (short)value; } + } + + public TagNodeCompound SpawnData + { + get { return _spawnData; } + set { _spawnData = value; } + } + + public string EntityID + { + get { return _entityID; } + set { _entityID = value; } + } + + public short MaxSpawnDelay + { + get { return _maxDelay ?? 0; } + set { _maxDelay = value; } + } + + public short MinSpawnDelay + { + get { return _minDelay ?? 0; } + set { _minDelay = value; } + } + + public short SpawnCount + { + get { return _spawnCount ?? 0; } + set { _spawnCount = value; } + } + + public short SpawnRange + { + get { return _spawnRange ?? 0; } + set { _spawnRange = value; } + } + + public short MaxNearbyEnemies + { + get { return _maxNearbyEnemies ?? 0; } + set { _maxNearbyEnemies = value; } + } + + public short RequiredPlayerRange + { + get { return _requiredPlayerRange ?? 0; } + set { _requiredPlayerRange = value; } + } + + public int MaxExperience + { + get { return _maxExperience ?? 0; } + set { _maxExperience = value; } + } + + public int RemainingExperience + { + get { return _remainingExperience ?? 0; } + set { _remainingExperience = value; } + } + + public int ExperienceRegenTick + { + get { return _experienceRegenTick ?? 0; } + set { _experienceRegenTick = value; } + } + + public int ExperienceRegenRate + { + get { return _experienceRegenRate ?? 0; } + set { _experienceRegenRate = value; } + } + + public int ExperienceRegenAmount + { + get { return _experienceRegenAmount ?? 0; } + set { _experienceRegenAmount = value; } + } + + protected TileEntityMobSpawner (string id) + : base(id) + { + } + + public TileEntityMobSpawner () + : this(TypeId) + { + } + + public TileEntityMobSpawner (TileEntity te) + : base(te) + { + TileEntityMobSpawner tes = te as TileEntityMobSpawner; + if (tes != null) { + _delay = tes._delay; + _entityID = tes._entityID; + _maxDelay = tes._maxDelay; + _minDelay = tes._minDelay; + _spawnCount = tes._spawnCount; + _spawnRange = tes._spawnRange; + _maxNearbyEnemies = tes._maxNearbyEnemies; + _requiredPlayerRange = tes._requiredPlayerRange; + _maxExperience = tes._maxExperience; + _remainingExperience = tes._remainingExperience; + _experienceRegenTick = tes._experienceRegenTick; + _experienceRegenRate = tes._experienceRegenRate; + _experienceRegenAmount = tes._experienceRegenAmount; + + if (tes._spawnData != null) + _spawnData = tes._spawnData.Copy() as TagNodeCompound; + } + } + + + #region ICopyable Members + + public override TileEntity Copy () + { + return new TileEntityMobSpawner(this); + } + + #endregion + + + #region INBTObject Members + + public override TileEntity LoadTree (TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null || base.LoadTree(tree) == null) { + return null; + } + + _delay = ctree["Delay"].ToTagShort(); + _entityID = ctree["EntityId"].ToTagString(); + + if (ctree.ContainsKey("MaxSpawnDelay")) + _maxDelay = ctree["MaxSpawnDelay"].ToTagShort(); + if (ctree.ContainsKey("MinSpawnDelay")) + _minDelay = ctree["MinSpawnDelay"].ToTagShort(); + if (ctree.ContainsKey("SpawnCount")) + _spawnCount = ctree["SpawnCount"].ToTagShort(); + if (ctree.ContainsKey("SpawnRange")) + _spawnRange = ctree["SpawnRange"].ToTagShort(); + if (ctree.ContainsKey("MaxNearbyEnemies")) + _maxNearbyEnemies = ctree["MaxNearbyEnemies"].ToTagShort(); + if (ctree.ContainsKey("RequiredPlayerRange")) + _requiredPlayerRange = ctree["RequiredPlayerRange"].ToTagShort(); + if (ctree.ContainsKey("MaxExperience")) + _maxExperience = ctree["MaxExperience"].ToTagInt(); + if (ctree.ContainsKey("RemainingExperience")) + _remainingExperience = ctree["RemainingExperience"].ToTagInt(); + if (ctree.ContainsKey("ExperienceRegenTick")) + _experienceRegenTick = ctree["ExperienceRegenTick"].ToTagInt(); + if (ctree.ContainsKey("ExperienceRegenRate")) + _experienceRegenRate = ctree["ExperienceRegenRate"].ToTagInt(); + if (ctree.ContainsKey("ExperienceRegenAmount")) + _experienceRegenRate = ctree["ExperienceRegenAmount"].ToTagInt(); + + if (ctree.ContainsKey("SpawnData")) + _spawnData = ctree["SpawnData"].ToTagCompound(); + + return this; + } + + public override TagNode BuildTree () + { + TagNodeCompound tree = base.BuildTree() as TagNodeCompound; + tree["EntityId"] = new TagNodeString(_entityID); + tree["Delay"] = new TagNodeShort(_delay); + + if (_maxDelay != null) + tree["MaxSpawnDelay"] = new TagNodeShort(_maxDelay ?? 0); + if (_minDelay != null) + tree["MinSpawnDelay"] = new TagNodeShort(_minDelay ?? 0); + if (_spawnCount != null) + tree["SpawnCount"] = new TagNodeShort(_spawnCount ?? 0); + if (_spawnRange != null) + tree["SpawnRange"] = new TagNodeShort(_spawnRange ?? 0); + if (_maxNearbyEnemies != null) + tree["MaxNearbyEnemies"] = new TagNodeShort(_maxNearbyEnemies ?? 0); + if (_requiredPlayerRange != null) + tree["RequiredPlayerRange"] = new TagNodeShort(_requiredPlayerRange ?? 0); + if (_maxExperience != null) + tree["MaxExperience"] = new TagNodeInt(_maxExperience ?? 0); + if (_remainingExperience != null) + tree["RemainingExperience"] = new TagNodeInt(_remainingExperience ?? 0); + if (_experienceRegenTick != null) + tree["ExperienceRegenTick"] = new TagNodeInt(_experienceRegenTick ?? 0); + if (_experienceRegenRate != null) + tree["ExperienceRegenRate"] = new TagNodeInt(_experienceRegenRate ?? 0); + if (_experienceRegenAmount != null) + tree["ExperienceRegenAmount"] = new TagNodeInt(_experienceRegenAmount ?? 0); + + if (_spawnData != null && _spawnData.Count > 0) + tree["SpawnData"] = _spawnData; + + return tree; + } + + public override bool ValidateTree (TagNode tree) + { + return new NbtVerifier(tree, MobSpawnerSchema).Verify(); + } + + #endregion + } +} diff --git a/SubstrateCS/Source/TileEntities/TileEntityMusic.cs b/Substrate.Entities/TileEntities/TileEntityMusic.cs similarity index 92% rename from SubstrateCS/Source/TileEntities/TileEntityMusic.cs rename to Substrate.Entities/TileEntities/TileEntityMusic.cs index 51130964..c2f7d03a 100644 --- a/SubstrateCS/Source/TileEntities/TileEntityMusic.cs +++ b/Substrate.Entities/TileEntities/TileEntityMusic.cs @@ -1,89 +1,89 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Substrate.TileEntities -{ - using Substrate.Nbt; - - public class TileEntityMusic : TileEntity - { - public static readonly SchemaNodeCompound MusicSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") - { - new SchemaNodeString("id", TypeId), - new SchemaNodeScaler("note", TagType.TAG_BYTE), - }); - - public static string TypeId - { - get { return "Music"; } - } - - private byte _note; - - public int Note - { - get { return _note; } - set { _note = (byte)value; } - } - - protected TileEntityMusic (string id) - : base(id) - { - } - - public TileEntityMusic () - : this(TypeId) - { - } - - public TileEntityMusic (TileEntity te) - : base(te) - { - TileEntityMusic tes = te as TileEntityMusic; - if (tes != null) { - _note = tes._note; - } - } - - - #region ICopyable Members - - public override TileEntity Copy () - { - return new TileEntityMusic(this); - } - - #endregion - - - #region INBTObject Members - - public override TileEntity LoadTree (TagNode tree) - { - TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null || base.LoadTree(tree) == null) { - return null; - } - - _note = ctree["note"].ToTagByte(); - - return this; - } - - public override TagNode BuildTree () - { - TagNodeCompound tree = base.BuildTree() as TagNodeCompound; - tree["note"] = new TagNodeByte(_note); - - return tree; - } - - public override bool ValidateTree (TagNode tree) - { - return new NbtVerifier(tree, MusicSchema).Verify(); - } - - #endregion - } -} +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.TileEntities +{ + using Substrate.Nbt; + + public class TileEntityMusic : TileEntity + { + public static readonly SchemaNodeCompound MusicSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") + { + new SchemaNodeString("id", TypeId), + new SchemaNodeScalar("note", TagType.TAG_BYTE), + }); + + public static string TypeId + { + get { return "Music"; } + } + + private byte _note; + + public int Note + { + get { return _note; } + set { _note = (byte)value; } + } + + protected TileEntityMusic (string id) + : base(id) + { + } + + public TileEntityMusic () + : this(TypeId) + { + } + + public TileEntityMusic (TileEntity te) + : base(te) + { + TileEntityMusic tes = te as TileEntityMusic; + if (tes != null) { + _note = tes._note; + } + } + + + #region ICopyable Members + + public override TileEntity Copy () + { + return new TileEntityMusic(this); + } + + #endregion + + + #region INBTObject Members + + public override TileEntity LoadTree (TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null || base.LoadTree(tree) == null) { + return null; + } + + _note = ctree["note"].ToTagByte(); + + return this; + } + + public override TagNode BuildTree () + { + TagNodeCompound tree = base.BuildTree() as TagNodeCompound; + tree["note"] = new TagNodeByte(_note); + + return tree; + } + + public override bool ValidateTree (TagNode tree) + { + return new NbtVerifier(tree, MusicSchema).Verify(); + } + + #endregion + } +} diff --git a/SubstrateCS/Source/TileEntities/TileEntityPiston.cs b/Substrate.Entities/TileEntities/TileEntityPiston.cs similarity index 88% rename from SubstrateCS/Source/TileEntities/TileEntityPiston.cs rename to Substrate.Entities/TileEntities/TileEntityPiston.cs index 153e5dc4..c0946f43 100644 --- a/SubstrateCS/Source/TileEntities/TileEntityPiston.cs +++ b/Substrate.Entities/TileEntities/TileEntityPiston.cs @@ -1,138 +1,138 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Substrate.TileEntities -{ - using Substrate.Nbt; - - public class TileEntityPiston : TileEntity - { - public static readonly SchemaNodeCompound PistonSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") - { - new SchemaNodeString("id", TypeId), - new SchemaNodeScaler("blockId", TagType.TAG_INT), - new SchemaNodeScaler("blockData", TagType.TAG_INT), - new SchemaNodeScaler("facing", TagType.TAG_INT), - new SchemaNodeScaler("progress", TagType.TAG_FLOAT), - new SchemaNodeScaler("extending", TagType.TAG_BYTE), - }); - - public static string TypeId - { - get { return "Piston"; } - } - - private int? _record = null; - - private byte _extending; - private int _blockId; - private int _blockData; - private int _facing; - private float _progress; - - public bool Extending - { - get { return _extending != 0; } - set { _extending = (byte)(value ? 1 : 0); } - } - - public int BlockId - { - get { return _blockId; } - set { _blockId = value; } - } - - public int BlockData - { - get { return _blockData; } - set { _blockData = value; } - } - - public int Facing - { - get { return _facing; } - set { _facing = value; } - } - - public float Progress - { - get { return _progress; } - set { _progress = value; } - } - - protected TileEntityPiston (string id) - : base(id) - { - } - - public TileEntityPiston () - : this(TypeId) - { - } - - public TileEntityPiston (TileEntity te) - : base(te) - { - TileEntityPiston tes = te as TileEntityPiston; - if (tes != null) { - _blockId = tes._blockId; - _blockData = tes._blockData; - _facing = tes._facing; - _progress = tes._progress; - _extending = tes._extending; - } - } - - - #region ICopyable Members - - public override TileEntity Copy () - { - return new TileEntityPiston(this); - } - - #endregion - - - #region INBTObject Members - - public override TileEntity LoadTree (TagNode tree) - { - TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null || base.LoadTree(tree) == null) { - return null; - } - - _blockId = ctree["blockId"].ToTagInt(); - _blockData = ctree["blockData"].ToTagInt(); - _facing = ctree["facing"].ToTagInt(); - _progress = ctree["progress"].ToTagFloat(); - _extending = ctree["extending"].ToTagByte(); - - return this; - } - - public override TagNode BuildTree () - { - TagNodeCompound tree = base.BuildTree() as TagNodeCompound; - - if (_record != null) { - tree["blockId"] = new TagNodeInt(_blockId); - tree["blockData"] = new TagNodeInt(_blockData); - tree["facing"] = new TagNodeInt(_facing); - tree["progress"] = new TagNodeFloat(_progress); - tree["extending"] = new TagNodeByte(_extending); - } - - return tree; - } - - public override bool ValidateTree (TagNode tree) - { - return new NbtVerifier(tree, PistonSchema).Verify(); - } - - #endregion - } +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.TileEntities +{ + using Substrate.Nbt; + + public class TileEntityPiston : TileEntity + { + public static readonly SchemaNodeCompound PistonSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") + { + new SchemaNodeString("id", TypeId), + new SchemaNodeScalar("blockId", TagType.TAG_INT), + new SchemaNodeScalar("blockData", TagType.TAG_INT), + new SchemaNodeScalar("facing", TagType.TAG_INT), + new SchemaNodeScalar("progress", TagType.TAG_FLOAT), + new SchemaNodeScalar("extending", TagType.TAG_BYTE), + }); + + public static string TypeId + { + get { return "Piston"; } + } + + private int? _record = null; + + private byte _extending; + private int _blockId; + private int _blockData; + private int _facing; + private float _progress; + + public bool Extending + { + get { return _extending != 0; } + set { _extending = (byte)(value ? 1 : 0); } + } + + public int BlockId + { + get { return _blockId; } + set { _blockId = value; } + } + + public int BlockData + { + get { return _blockData; } + set { _blockData = value; } + } + + public int Facing + { + get { return _facing; } + set { _facing = value; } + } + + public float Progress + { + get { return _progress; } + set { _progress = value; } + } + + protected TileEntityPiston (string id) + : base(id) + { + } + + public TileEntityPiston () + : this(TypeId) + { + } + + public TileEntityPiston (TileEntity te) + : base(te) + { + TileEntityPiston tes = te as TileEntityPiston; + if (tes != null) { + _blockId = tes._blockId; + _blockData = tes._blockData; + _facing = tes._facing; + _progress = tes._progress; + _extending = tes._extending; + } + } + + + #region ICopyable Members + + public override TileEntity Copy () + { + return new TileEntityPiston(this); + } + + #endregion + + + #region INBTObject Members + + public override TileEntity LoadTree (TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null || base.LoadTree(tree) == null) { + return null; + } + + _blockId = ctree["blockId"].ToTagInt(); + _blockData = ctree["blockData"].ToTagInt(); + _facing = ctree["facing"].ToTagInt(); + _progress = ctree["progress"].ToTagFloat(); + _extending = ctree["extending"].ToTagByte(); + + return this; + } + + public override TagNode BuildTree () + { + TagNodeCompound tree = base.BuildTree() as TagNodeCompound; + + if (_record != null) { + tree["blockId"] = new TagNodeInt(_blockId); + tree["blockData"] = new TagNodeInt(_blockData); + tree["facing"] = new TagNodeInt(_facing); + tree["progress"] = new TagNodeFloat(_progress); + tree["extending"] = new TagNodeByte(_extending); + } + + return tree; + } + + public override bool ValidateTree (TagNode tree) + { + return new NbtVerifier(tree, PistonSchema).Verify(); + } + + #endregion + } } \ No newline at end of file diff --git a/SubstrateCS/Source/TileEntities/TileEntityRecordPlayer.cs b/Substrate.Entities/TileEntities/TileEntityRecordPlayer.cs similarity index 93% rename from SubstrateCS/Source/TileEntities/TileEntityRecordPlayer.cs rename to Substrate.Entities/TileEntities/TileEntityRecordPlayer.cs index 8bb51f3a..b8635e96 100644 --- a/SubstrateCS/Source/TileEntities/TileEntityRecordPlayer.cs +++ b/Substrate.Entities/TileEntities/TileEntityRecordPlayer.cs @@ -1,94 +1,94 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Substrate.TileEntities -{ - using Substrate.Nbt; - - public class TileEntityRecordPlayer : TileEntity - { - public static readonly SchemaNodeCompound RecordPlayerSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") - { - new SchemaNodeString("id", TypeId), - new SchemaNodeScaler("Record", TagType.TAG_INT, SchemaOptions.OPTIONAL), - }); - - public static string TypeId - { - get { return "RecordPlayer"; } - } - - private int? _record = null; - - public int? Record - { - get { return _record; } - set { _record = value; } - } - - protected TileEntityRecordPlayer (string id) - : base(id) - { - } - - public TileEntityRecordPlayer () - : this(TypeId) - { - } - - public TileEntityRecordPlayer (TileEntity te) - : base(te) - { - TileEntityRecordPlayer tes = te as TileEntityRecordPlayer; - if (tes != null) { - _record = tes._record; - } - } - - - #region ICopyable Members - - public override TileEntity Copy () - { - return new TileEntityRecordPlayer(this); - } - - #endregion - - - #region INBTObject Members - - public override TileEntity LoadTree (TagNode tree) - { - TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null || base.LoadTree(tree) == null) { - return null; - } - - if (ctree.ContainsKey("Record")) { - _record = ctree["Record"].ToTagInt(); - } - - return this; - } - - public override TagNode BuildTree () - { - TagNodeCompound tree = base.BuildTree() as TagNodeCompound; - - if (_record != null) { - tree["Record"] = new TagNodeInt((int)_record); - } - - return tree; - } - - public override bool ValidateTree (TagNode tree) - { - return new NbtVerifier(tree, RecordPlayerSchema).Verify(); - } - - #endregion - } -} +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.TileEntities +{ + using Substrate.Nbt; + + public class TileEntityRecordPlayer : TileEntity + { + public static readonly SchemaNodeCompound RecordPlayerSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") + { + new SchemaNodeString("id", TypeId), + new SchemaNodeScalar("Record", TagType.TAG_INT, SchemaOptions.OPTIONAL), + }); + + public static string TypeId + { + get { return "RecordPlayer"; } + } + + private int? _record = null; + + public int? Record + { + get { return _record; } + set { _record = value; } + } + + protected TileEntityRecordPlayer (string id) + : base(id) + { + } + + public TileEntityRecordPlayer () + : this(TypeId) + { + } + + public TileEntityRecordPlayer (TileEntity te) + : base(te) + { + TileEntityRecordPlayer tes = te as TileEntityRecordPlayer; + if (tes != null) { + _record = tes._record; + } + } + + + #region ICopyable Members + + public override TileEntity Copy () + { + return new TileEntityRecordPlayer(this); + } + + #endregion + + + #region INBTObject Members + + public override TileEntity LoadTree (TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null || base.LoadTree(tree) == null) { + return null; + } + + if (ctree.ContainsKey("Record")) { + _record = ctree["Record"].ToTagInt(); + } + + return this; + } + + public override TagNode BuildTree () + { + TagNodeCompound tree = base.BuildTree() as TagNodeCompound; + + if (_record != null) { + tree["Record"] = new TagNodeInt((int)_record); + } + + return tree; + } + + public override bool ValidateTree (TagNode tree) + { + return new NbtVerifier(tree, RecordPlayerSchema).Verify(); + } + + #endregion + } +} diff --git a/SubstrateCS/Source/TileEntities/TileEntitySign.cs b/Substrate.Entities/TileEntities/TileEntitySign.cs similarity index 89% rename from SubstrateCS/Source/TileEntities/TileEntitySign.cs rename to Substrate.Entities/TileEntities/TileEntitySign.cs index 1c0c72bf..5f35ad3d 100644 --- a/SubstrateCS/Source/TileEntities/TileEntitySign.cs +++ b/Substrate.Entities/TileEntities/TileEntitySign.cs @@ -1,122 +1,122 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Substrate.TileEntities -{ - using Substrate.Nbt; - - public class TileEntitySign : TileEntity - { - public static readonly SchemaNodeCompound SignSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") - { - new SchemaNodeString("id", TypeId), - new SchemaNodeScaler("Text1", TagType.TAG_STRING), - new SchemaNodeScaler("Text2", TagType.TAG_STRING), - new SchemaNodeScaler("Text3", TagType.TAG_STRING), - new SchemaNodeScaler("Text4", TagType.TAG_STRING), - }); - - public static string TypeId - { - get { return "Sign"; } - } - - private string _text1 = ""; - private string _text2 = ""; - private string _text3 = ""; - private string _text4 = ""; - - public string Text1 - { - get { return _text1; } - set { _text1 = value.Length > 14 ? value.Substring(0, 14) : value; } - } - - public string Text2 - { - get { return _text2; } - set { _text2 = value.Length > 14 ? value.Substring(0, 14) : value; } - } - - public string Text3 - { - get { return _text3; } - set { _text3 = value.Length > 14 ? value.Substring(0, 14) : value; } - } - - public string Text4 - { - get { return _text4; } - set { _text4 = value.Length > 14 ? value.Substring(0, 14) : value; } - } - - protected TileEntitySign (string id) - : base(id) - { - } - - public TileEntitySign () - : this(TypeId) - { - } - - public TileEntitySign (TileEntity te) - : base(te) - { - TileEntitySign tes = te as TileEntitySign; - if (tes != null) { - _text1 = tes._text1; - _text2 = tes._text2; - _text3 = tes._text3; - _text4 = tes._text4; - } - } - - - #region ICopyable Members - - public override TileEntity Copy () - { - return new TileEntitySign(this); - } - - #endregion - - - #region INBTObject Members - - public override TileEntity LoadTree (TagNode tree) - { - TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null || base.LoadTree(tree) == null) { - return null; - } - - _text1 = ctree["Text1"].ToTagString(); - _text2 = ctree["Text2"].ToTagString(); - _text3 = ctree["Text3"].ToTagString(); - _text4 = ctree["Text4"].ToTagString(); - - return this; - } - - public override TagNode BuildTree () - { - TagNodeCompound tree = base.BuildTree() as TagNodeCompound; - tree["Text1"] = new TagNodeString(_text1); - tree["Text2"] = new TagNodeString(_text2); - tree["Text3"] = new TagNodeString(_text3); - tree["Text4"] = new TagNodeString(_text4); - - return tree; - } - - public override bool ValidateTree (TagNode tree) - { - return new NbtVerifier(tree, SignSchema).Verify(); - } - - #endregion - } -} +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.TileEntities +{ + using Substrate.Nbt; + + public class TileEntitySign : TileEntity + { + public static readonly SchemaNodeCompound SignSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") + { + new SchemaNodeString("id", TypeId), + new SchemaNodeScalar("Text1", TagType.TAG_STRING), + new SchemaNodeScalar("Text2", TagType.TAG_STRING), + new SchemaNodeScalar("Text3", TagType.TAG_STRING), + new SchemaNodeScalar("Text4", TagType.TAG_STRING), + }); + + public static string TypeId + { + get { return "Sign"; } + } + + private string _text1 = ""; + private string _text2 = ""; + private string _text3 = ""; + private string _text4 = ""; + + public string Text1 + { + get { return _text1; } + set { _text1 = value.Length > 14 ? value.Substring(0, 14) : value; } + } + + public string Text2 + { + get { return _text2; } + set { _text2 = value.Length > 14 ? value.Substring(0, 14) : value; } + } + + public string Text3 + { + get { return _text3; } + set { _text3 = value.Length > 14 ? value.Substring(0, 14) : value; } + } + + public string Text4 + { + get { return _text4; } + set { _text4 = value.Length > 14 ? value.Substring(0, 14) : value; } + } + + protected TileEntitySign (string id) + : base(id) + { + } + + public TileEntitySign () + : this(TypeId) + { + } + + public TileEntitySign (TileEntity te) + : base(te) + { + TileEntitySign tes = te as TileEntitySign; + if (tes != null) { + _text1 = tes._text1; + _text2 = tes._text2; + _text3 = tes._text3; + _text4 = tes._text4; + } + } + + + #region ICopyable Members + + public override TileEntity Copy () + { + return new TileEntitySign(this); + } + + #endregion + + + #region INBTObject Members + + public override TileEntity LoadTree (TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null || base.LoadTree(tree) == null) { + return null; + } + + _text1 = ctree["Text1"].ToTagString(); + _text2 = ctree["Text2"].ToTagString(); + _text3 = ctree["Text3"].ToTagString(); + _text4 = ctree["Text4"].ToTagString(); + + return this; + } + + public override TagNode BuildTree () + { + TagNodeCompound tree = base.BuildTree() as TagNodeCompound; + tree["Text1"] = new TagNodeString(_text1); + tree["Text2"] = new TagNodeString(_text2); + tree["Text3"] = new TagNodeString(_text3); + tree["Text4"] = new TagNodeString(_text4); + + return tree; + } + + public override bool ValidateTree (TagNode tree) + { + return new NbtVerifier(tree, SignSchema).Verify(); + } + + #endregion + } +} diff --git a/SubstrateCS/Source/TileEntities/TileEntityTrap.cs b/Substrate.Entities/TileEntities/TileEntityTrap.cs similarity index 95% rename from SubstrateCS/Source/TileEntities/TileEntityTrap.cs rename to Substrate.Entities/TileEntities/TileEntityTrap.cs index 69637ae5..67492581 100644 --- a/SubstrateCS/Source/TileEntities/TileEntityTrap.cs +++ b/Substrate.Entities/TileEntities/TileEntityTrap.cs @@ -1,99 +1,99 @@ -using System; -using System.Collections.Generic; -using Substrate.Core; -using Substrate.Nbt; - -namespace Substrate.TileEntities -{ - public class TileEntityTrap : TileEntity, IItemContainer - { - public static readonly SchemaNodeCompound TrapSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") - { - new SchemaNodeString("id", TypeId), - new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.Schema), - }); - - public static string TypeId - { - get { return "Trap"; } - } - - private const int _CAPACITY = 8; - - private ItemCollection _items; - - protected TileEntityTrap (string id) - : base(id) - { - _items = new ItemCollection(_CAPACITY); - } - - public TileEntityTrap () - : this(TypeId) - { - } - - public TileEntityTrap (TileEntity te) - : base(te) - { - TileEntityTrap tec = te as TileEntityTrap; - if (tec != null) { - _items = tec._items.Copy(); - } - else { - _items = new ItemCollection(_CAPACITY); - } - } - - - #region ICopyable Members - - public override TileEntity Copy () - { - return new TileEntityTrap(this); - } - - #endregion - - - #region IItemContainer Members - - public ItemCollection Items - { - get { return _items; } - } - - #endregion - - - #region INBTObject Members - - public override TileEntity LoadTree (TagNode tree) - { - TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null || base.LoadTree(tree) == null) { - return null; - } - - TagNodeList items = ctree["Items"].ToTagList(); - _items = new ItemCollection(_CAPACITY).LoadTree(items); - - return this; - } - - public override TagNode BuildTree () - { - TagNodeCompound tree = base.BuildTree() as TagNodeCompound; - tree["Items"] = _items.BuildTree(); - - return tree; - } - - public override bool ValidateTree (TagNode tree) - { - return new NbtVerifier(tree, TrapSchema).Verify(); - } - - #endregion - } -} +using System; +using System.Collections.Generic; +using Substrate.Core; +using Substrate.Nbt; + +namespace Substrate.TileEntities +{ + public class TileEntityTrap : TileEntity, IItemContainer + { + public static readonly SchemaNodeCompound TrapSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") + { + new SchemaNodeString("id", TypeId), + new SchemaNodeList("Items", TagType.TAG_COMPOUND, ItemCollection.ItemSchema), + }); + + public static string TypeId + { + get { return "Trap"; } + } + + private const int _CAPACITY = 8; + + private ItemCollection _items; + + protected TileEntityTrap (string id) + : base(id) + { + _items = new ItemCollection(_CAPACITY); + } + + public TileEntityTrap () + : this(TypeId) + { + } + + public TileEntityTrap (TileEntity te) + : base(te) + { + TileEntityTrap tec = te as TileEntityTrap; + if (tec != null) { + _items = tec._items.Copy(); + } + else { + _items = new ItemCollection(_CAPACITY); + } + } + + + #region ICopyable Members + + public override TileEntity Copy () + { + return new TileEntityTrap(this); + } + + #endregion + + + #region IItemContainer Members + + public ItemCollection Items + { + get { return _items; } + } + + #endregion + + + #region INBTObject Members + + public override TileEntity LoadTree (TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null || base.LoadTree(tree) == null) { + return null; + } + + TagNodeList items = ctree["Items"].ToTagList(); + _items = new ItemCollection(_CAPACITY).LoadTree(items); + + return this; + } + + public override TagNode BuildTree () + { + TagNodeCompound tree = base.BuildTree() as TagNodeCompound; + tree["Items"] = _items.BuildTree(); + + return tree; + } + + public override bool ValidateTree (TagNode tree) + { + return new NbtVerifier(tree, TrapSchema).Verify(); + } + + #endregion + } +} diff --git a/Substrate.Tests/BlockTests.cs b/Substrate.Tests/BlockTests.cs index 2743a7a3..68bd3580 100644 --- a/Substrate.Tests/BlockTests.cs +++ b/Substrate.Tests/BlockTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Text; using Substrate; @@ -17,7 +17,7 @@ static class DebugWorld public const int MinZ = 1; public const int MaxZ = 180; } - + [TestMethod] public void BlockTest_1_8_3_debug() { @@ -42,6 +42,7 @@ public void BlockTest_1_8_3_debug() [TestMethod] public void BlockTest_1_9_2_debug() { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_9_2-debug\"); Assert.IsNotNull(world); @@ -64,6 +65,44 @@ public void BlockTest_1_9_2_debug() } } } + + Assert.IsFalse(dataError); + } + + [TestMethod] + public void BlockTest_1_12_2_debug() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_12_2-debug\"); + Assert.IsNotNull(world); + + var sb = new StringBuilder(); + + for (int x = DebugWorld.MinX; x < DebugWorld.MaxX; x += 2) + { + for (int z = DebugWorld.MinZ; z < DebugWorld.MaxZ; z += 2) + { + var blockRef = world.GetBlockManager().GetBlockRef(x, DebugWorld.Y, z); + var blockInfo = BlockInfo.BlockTable[blockRef.ID]; + + Debug.WriteLine(string.Format("ID:{0} ({1}), Data:{2}", blockRef.ID, blockInfo.Name, blockRef.Data)); + + if (!blockInfo.Registered) + { + sb.AppendFormat("Block ID {0} has not been registered", blockRef.ID); + sb.AppendLine(); + } + + if (!blockInfo.TestData(blockRef.Data)) + { + sb.AppendFormat("Data value '0x{0:X4}' not recognised for block '{1}' at {2},{3}", blockRef.Data, blockInfo.Name, x, z); + sb.AppendLine(); + } + } + } + + var errors = sb.ToString(); + + Assert.IsTrue(string.IsNullOrEmpty(errors), errors); } } } diff --git a/Substrate.Tests/Data/1_12_2-debug/data/villages.dat b/Substrate.Tests/Data/1_12_2-debug/data/villages.dat new file mode 100644 index 00000000..138fd791 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-debug/data/villages.dat differ diff --git a/Substrate.Tests/Data/1_12_2-debug/data/villages_end.dat b/Substrate.Tests/Data/1_12_2-debug/data/villages_end.dat new file mode 100644 index 00000000..138fd791 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-debug/data/villages_end.dat differ diff --git a/Substrate.Tests/Data/1_12_2-debug/data/villages_nether.dat b/Substrate.Tests/Data/1_12_2-debug/data/villages_nether.dat new file mode 100644 index 00000000..138fd791 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-debug/data/villages_nether.dat differ diff --git a/Substrate.Tests/Data/1_12_2-debug/icon.png b/Substrate.Tests/Data/1_12_2-debug/icon.png new file mode 100644 index 00000000..2928c69f Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-debug/icon.png differ diff --git a/Substrate.Tests/Data/1_12_2-debug/level.dat b/Substrate.Tests/Data/1_12_2-debug/level.dat new file mode 100644 index 00000000..29c99148 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-debug/level.dat differ diff --git a/Substrate.Tests/Data/1_12_2-debug/level.dat_old b/Substrate.Tests/Data/1_12_2-debug/level.dat_old new file mode 100644 index 00000000..09c7d12a Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-debug/level.dat_old differ diff --git a/Substrate.Tests/Data/1_12_2-debug/region/r.-1.-1.mca b/Substrate.Tests/Data/1_12_2-debug/region/r.-1.-1.mca new file mode 100644 index 00000000..b929e5a0 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-debug/region/r.-1.-1.mca differ diff --git a/Substrate.Tests/Data/1_12_2-debug/region/r.-1.0.mca b/Substrate.Tests/Data/1_12_2-debug/region/r.-1.0.mca new file mode 100644 index 00000000..cdde9f5b Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-debug/region/r.-1.0.mca differ diff --git a/Substrate.Tests/Data/1_12_2-debug/region/r.0.-1.mca b/Substrate.Tests/Data/1_12_2-debug/region/r.0.-1.mca new file mode 100644 index 00000000..2198932b Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-debug/region/r.0.-1.mca differ diff --git a/Substrate.Tests/Data/1_12_2-debug/region/r.0.0.mca b/Substrate.Tests/Data/1_12_2-debug/region/r.0.0.mca new file mode 100644 index 00000000..a7ad9bf7 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-debug/region/r.0.0.mca differ diff --git a/Substrate.Tests/Data/1_12_2-debug/session.lock b/Substrate.Tests/Data/1_12_2-debug/session.lock new file mode 100644 index 00000000..1acc6f71 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-debug/session.lock differ diff --git a/Substrate.Tests/Data/1_12_2-survival/data/Mineshaft.dat b/Substrate.Tests/Data/1_12_2-survival/data/Mineshaft.dat new file mode 100644 index 00000000..ba9123be Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/data/Mineshaft.dat differ diff --git a/Substrate.Tests/Data/1_12_2-survival/data/Temple.dat b/Substrate.Tests/Data/1_12_2-survival/data/Temple.dat new file mode 100644 index 00000000..0584db02 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/data/Temple.dat differ diff --git a/Substrate.Tests/Data/1_12_2-survival/data/Village.dat b/Substrate.Tests/Data/1_12_2-survival/data/Village.dat new file mode 100644 index 00000000..7ab6cc4b Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/data/Village.dat differ diff --git a/Substrate.Tests/Data/1_12_2-survival/data/villages.dat b/Substrate.Tests/Data/1_12_2-survival/data/villages.dat new file mode 100644 index 00000000..ce8b06a4 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/data/villages.dat differ diff --git a/Substrate.Tests/Data/1_12_2-survival/data/villages_end.dat b/Substrate.Tests/Data/1_12_2-survival/data/villages_end.dat new file mode 100644 index 00000000..ce8b06a4 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/data/villages_end.dat differ diff --git a/Substrate.Tests/Data/1_12_2-survival/data/villages_nether.dat b/Substrate.Tests/Data/1_12_2-survival/data/villages_nether.dat new file mode 100644 index 00000000..ce8b06a4 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/data/villages_nether.dat differ diff --git a/Substrate.Tests/Data/1_12_2-survival/icon.png b/Substrate.Tests/Data/1_12_2-survival/icon.png new file mode 100644 index 00000000..6eac46ce Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/icon.png differ diff --git a/Substrate.Tests/Data/1_12_2-survival/level.dat b/Substrate.Tests/Data/1_12_2-survival/level.dat new file mode 100644 index 00000000..5365baeb Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/level.dat differ diff --git a/Substrate.Tests/Data/1_12_2-survival/level.dat_old b/Substrate.Tests/Data/1_12_2-survival/level.dat_old new file mode 100644 index 00000000..fa84173a Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/level.dat_old differ diff --git a/Substrate.Tests/Data/1_12_2-survival/region/r.-1.-1.mca b/Substrate.Tests/Data/1_12_2-survival/region/r.-1.-1.mca new file mode 100644 index 00000000..2abb4744 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/region/r.-1.-1.mca differ diff --git a/Substrate.Tests/Data/1_12_2-survival/region/r.-1.0.mca b/Substrate.Tests/Data/1_12_2-survival/region/r.-1.0.mca new file mode 100644 index 00000000..bae1e221 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/region/r.-1.0.mca differ diff --git a/Substrate.Tests/Data/1_12_2-survival/region/r.0.-1.mca b/Substrate.Tests/Data/1_12_2-survival/region/r.0.-1.mca new file mode 100644 index 00000000..bac44af2 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/region/r.0.-1.mca differ diff --git a/Substrate.Tests/Data/1_12_2-survival/region/r.0.0.mca b/Substrate.Tests/Data/1_12_2-survival/region/r.0.0.mca new file mode 100644 index 00000000..4a17b124 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/region/r.0.0.mca differ diff --git a/Substrate.Tests/Data/1_12_2-survival/session.lock b/Substrate.Tests/Data/1_12_2-survival/session.lock new file mode 100644 index 00000000..8ede2cb1 Binary files /dev/null and b/Substrate.Tests/Data/1_12_2-survival/session.lock differ diff --git a/Substrate.Tests/Data/1_9_2-survival/data/Mineshaft.dat b/Substrate.Tests/Data/1_9_2-survival/data/Mineshaft.dat new file mode 100644 index 00000000..77fab1d5 Binary files /dev/null and b/Substrate.Tests/Data/1_9_2-survival/data/Mineshaft.dat differ diff --git a/Substrate.Tests/Data/1_9_2-survival/data/villages.dat b/Substrate.Tests/Data/1_9_2-survival/data/villages.dat new file mode 100644 index 00000000..601a54a3 Binary files /dev/null and b/Substrate.Tests/Data/1_9_2-survival/data/villages.dat differ diff --git a/Substrate.Tests/Data/1_9_2-survival/data/villages_end.dat b/Substrate.Tests/Data/1_9_2-survival/data/villages_end.dat new file mode 100644 index 00000000..601a54a3 Binary files /dev/null and b/Substrate.Tests/Data/1_9_2-survival/data/villages_end.dat differ diff --git a/Substrate.Tests/Data/1_9_2-survival/data/villages_nether.dat b/Substrate.Tests/Data/1_9_2-survival/data/villages_nether.dat new file mode 100644 index 00000000..601a54a3 Binary files /dev/null and b/Substrate.Tests/Data/1_9_2-survival/data/villages_nether.dat differ diff --git a/Substrate.Tests/Data/1_9_2-survival/icon.png b/Substrate.Tests/Data/1_9_2-survival/icon.png new file mode 100644 index 00000000..eb4be9cd Binary files /dev/null and b/Substrate.Tests/Data/1_9_2-survival/icon.png differ diff --git a/Substrate.Tests/Data/1_9_2-survival/level.dat b/Substrate.Tests/Data/1_9_2-survival/level.dat new file mode 100644 index 00000000..ff48a1c4 Binary files /dev/null and b/Substrate.Tests/Data/1_9_2-survival/level.dat differ diff --git a/Substrate.Tests/Data/1_9_2-survival/level.dat_old b/Substrate.Tests/Data/1_9_2-survival/level.dat_old new file mode 100644 index 00000000..db095d85 Binary files /dev/null and b/Substrate.Tests/Data/1_9_2-survival/level.dat_old differ diff --git a/Substrate.Tests/Data/1_9_2-survival/region/r.0.0.mca b/Substrate.Tests/Data/1_9_2-survival/region/r.0.0.mca new file mode 100644 index 00000000..f75b9e67 Binary files /dev/null and b/Substrate.Tests/Data/1_9_2-survival/region/r.0.0.mca differ diff --git a/Substrate.Tests/Data/1_9_2-survival/session.lock b/Substrate.Tests/Data/1_9_2-survival/session.lock new file mode 100644 index 00000000..8a4c152a Binary files /dev/null and b/Substrate.Tests/Data/1_9_2-survival/session.lock differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.-1.mca new file mode 100644 index 00000000..64497a8d Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.-2.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.-2.mca new file mode 100644 index 00000000..70ec5aab Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.-2.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.0.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.0.mca new file mode 100644 index 00000000..b068103d Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.0.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.1.mca new file mode 100644 index 00000000..a7d8cd0c Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-1.1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-2.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-2.-1.mca new file mode 100644 index 00000000..d5c28a17 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-2.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-2.0.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-2.0.mca new file mode 100644 index 00000000..7881c4d6 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.-2.0.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.-1.mca new file mode 100644 index 00000000..9155a659 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.-2.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.-2.mca new file mode 100644 index 00000000..582ab11d Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.-2.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.0.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.0.mca new file mode 100644 index 00000000..85547b90 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.0.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.1.mca new file mode 100644 index 00000000..18e4fd6c Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.0.1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.1.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.1.-1.mca new file mode 100644 index 00000000..e296c374 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM-1/region/r.1.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.-1.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.-1.-1.mca new file mode 100644 index 00000000..aaba205b Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.-1.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.-1.0.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.-1.0.mca new file mode 100644 index 00000000..33fed9a1 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.-1.0.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.0.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.0.-1.mca new file mode 100644 index 00000000..6fbdea82 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.0.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.0.0.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.0.0.mca new file mode 100644 index 00000000..ac1645f4 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.0.0.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.1.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.1.-1.mca new file mode 100644 index 00000000..bfa4a209 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.1.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.1.0.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.1.0.mca new file mode 100644 index 00000000..f9d6d137 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.1.0.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.2.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.2.-1.mca new file mode 100644 index 00000000..bba1d124 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.2.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.2.0.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.2.0.mca new file mode 100644 index 00000000..84f67f68 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/DIM1/region/r.2.0.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/data/Fortress.dat b/Substrate.Tests/Data/Climatic Islands [ENG]/data/Fortress.dat new file mode 100644 index 00000000..fdc725ed Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/data/Fortress.dat differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/data/idcounts.dat b/Substrate.Tests/Data/Climatic Islands [ENG]/data/idcounts.dat new file mode 100644 index 00000000..4df64be7 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/data/idcounts.dat differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/data/map_0.dat b/Substrate.Tests/Data/Climatic Islands [ENG]/data/map_0.dat new file mode 100644 index 00000000..5ae27e0d Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/data/map_0.dat differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/data/villages.dat b/Substrate.Tests/Data/Climatic Islands [ENG]/data/villages.dat new file mode 100644 index 00000000..110e7680 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/data/villages.dat differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/data/villages_end.dat b/Substrate.Tests/Data/Climatic Islands [ENG]/data/villages_end.dat new file mode 100644 index 00000000..110e7680 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/data/villages_end.dat differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/data/villages_nether.dat b/Substrate.Tests/Data/Climatic Islands [ENG]/data/villages_nether.dat new file mode 100644 index 00000000..110e7680 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/data/villages_nether.dat differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/icon.png b/Substrate.Tests/Data/Climatic Islands [ENG]/icon.png new file mode 100644 index 00000000..8bc9f335 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/icon.png differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/level.dat b/Substrate.Tests/Data/Climatic Islands [ENG]/level.dat new file mode 100644 index 00000000..fcdf34df Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/level.dat differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/level.dat_old b/Substrate.Tests/Data/Climatic Islands [ENG]/level.dat_old new file mode 100644 index 00000000..613f3f81 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/level.dat_old differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/mcedit_waypoints.dat b/Substrate.Tests/Data/Climatic Islands [ENG]/mcedit_waypoints.dat new file mode 100644 index 00000000..c106a7bc Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/mcedit_waypoints.dat differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.-1.mca new file mode 100644 index 00000000..5cfbea9c Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.-2.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.-2.mca new file mode 100644 index 00000000..a813efad Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.-2.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.0.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.0.mca new file mode 100644 index 00000000..4e527e0f Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.0.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.1.mca new file mode 100644 index 00000000..47ae59c4 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-1.1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-2.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-2.-1.mca new file mode 100644 index 00000000..8d7419ad Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-2.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-2.0.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-2.0.mca new file mode 100644 index 00000000..d0a95708 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.-2.0.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.-1.mca new file mode 100644 index 00000000..289090dd Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.-2.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.-2.mca new file mode 100644 index 00000000..3a9fb291 Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.-2.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.0.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.0.mca new file mode 100644 index 00000000..638e0f3a Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.0.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.1.mca new file mode 100644 index 00000000..b757f9cd Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.0.1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.1.-1.mca b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.1.-1.mca new file mode 100644 index 00000000..3254d09e Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/region/r.1.-1.mca differ diff --git a/Substrate.Tests/Data/Climatic Islands [ENG]/session.lock b/Substrate.Tests/Data/Climatic Islands [ENG]/session.lock new file mode 100644 index 00000000..99b1d5de Binary files /dev/null and b/Substrate.Tests/Data/Climatic Islands [ENG]/session.lock differ diff --git a/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/data/villages.dat b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/data/villages.dat new file mode 100644 index 00000000..0660a2cd Binary files /dev/null and b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/data/villages.dat differ diff --git a/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/data/villages_end.dat b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/data/villages_end.dat new file mode 100644 index 00000000..0660a2cd Binary files /dev/null and b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/data/villages_end.dat differ diff --git a/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/data/villages_nether.dat b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/data/villages_nether.dat new file mode 100644 index 00000000..0660a2cd Binary files /dev/null and b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/data/villages_nether.dat differ diff --git a/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/icon.png b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/icon.png new file mode 100644 index 00000000..c53e8f23 Binary files /dev/null and b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/icon.png differ diff --git a/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/level.dat b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/level.dat new file mode 100644 index 00000000..5cbe6bef Binary files /dev/null and b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/level.dat differ diff --git a/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/level.dat_old b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/level.dat_old new file mode 100644 index 00000000..491ec3ff Binary files /dev/null and b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/level.dat_old differ diff --git a/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.-1.-1.mca b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.-1.-1.mca new file mode 100644 index 00000000..8bd77359 Binary files /dev/null and b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.-1.-1.mca differ diff --git a/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.-1.0.mca b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.-1.0.mca new file mode 100644 index 00000000..6ba6b7fb Binary files /dev/null and b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.-1.0.mca differ diff --git a/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.0.-1.mca b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.0.-1.mca new file mode 100644 index 00000000..37010484 Binary files /dev/null and b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.0.-1.mca differ diff --git a/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.0.0.mca b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.0.0.mca new file mode 100644 index 00000000..b13c83f8 Binary files /dev/null and b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/region/r.0.0.mca differ diff --git a/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/session.lock b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/session.lock new file mode 100644 index 00000000..0db1c50a Binary files /dev/null and b/Substrate.Tests/Data/Colors of the Rainbow SURVIVAL/session.lock differ diff --git a/Substrate.Tests/LevelTests.cs b/Substrate.Tests/LevelTests.cs index f773560e..874b605c 100644 --- a/Substrate.Tests/LevelTests.cs +++ b/Substrate.Tests/LevelTests.cs @@ -1,73 +1,157 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Substrate; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.IO; -using Substrate.Nbt; -using Substrate.Core; - -namespace Substrate.Tests -{ - [TestClass] - public class LevelTests - { - NbtTree LoadLevelTree(string path) - { - NBTFile nf = new NBTFile(path); - NbtTree tree = null; - - using (Stream nbtstr = nf.GetDataInputStream()) - { - if (nbtstr == null) - { - return null; - } - - tree = new NbtTree(nbtstr); - } - - return tree; - } - - [TestMethod] - public void LoadTreeTest_1_6_4_survival() - { - NbtTree levelTree = LoadLevelTree(@"..\..\Data\1_6_4-survival\level.dat"); - - Level level = new Level(null); - level = level.LoadTreeSafe(levelTree.Root); - Assert.IsNotNull(level); - } - - [TestMethod] - public void LoadTreeTest_1_7_2_survival() - { - NbtTree levelTree = LoadLevelTree(@"..\..\Data\1_7_2-survival\level.dat"); - - Level level = new Level(null); - level = level.LoadTreeSafe(levelTree.Root); - Assert.IsNotNull(level); - } - - [TestMethod] - public void LoadTreeTest_1_7_10_survival() - { - NbtTree levelTree = LoadLevelTree(@"..\..\Data\1_7_10-survival\level.dat"); - - Level level = new Level(null); - level = level.LoadTreeSafe(levelTree.Root); - Assert.IsNotNull(level); - } - - [TestMethod] - public void LoadTreeTest_1_8_3_survival() - { - NbtTree levelTree = LoadLevelTree(@"..\..\Data\1_8_3-survival\level.dat"); - - Level level = new Level(null); - level = level.LoadTreeSafe(levelTree.Root); - Assert.IsNotNull(level); - } - } -} +using System; +using System.Collections.Generic; +using System.Text; +using Substrate; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Substrate.Core; +using Substrate.Nbt; +using System.IO; +using System.Diagnostics; +using Substrate.Source.Nbt; + +namespace Substrate.Tests +{ + [TestClass] + public class LevelTests + { + [ClassInitialize()] + public static void ClassInit(TestContext context) + { + NbtVerifier.UnexpectedTag += new VerifierEventHandler((TagEventArgs e) => + { + var fullName = e.Schema.Name + "." + e.TagName; + + Trace.WriteLine($"UnexpectedTag {fullName}"); + + return TagEventCode.NEXT; + }); + } + + NbtTree LoadLevelTree(string path) + { + NBTFile nf = new NBTFile(path); + NbtTree tree = null; + + using (Stream nbtstr = nf.GetDataInputStream()) + { + if (nbtstr == null) + { + return null; + } + + tree = new NbtTree(nbtstr); + } + + return tree; + } + + [TestMethod] + public void LoadTreeTest_1_6_4_survival() + { + NbtTree levelTree = LoadLevelTree(@"..\..\Data\1_6_4-survival\level.dat"); + + Level level = new Level(null); + level = level.LoadTreeSafe(levelTree.Root); + Assert.IsNotNull(level); + } + + [TestMethod] + public void LoadTreeTest_1_7_2_survival() + { + NbtTree levelTree = LoadLevelTree(@"..\..\Data\1_7_2-survival\level.dat"); + + Level level = new Level(null); + level = level.LoadTreeSafe(levelTree.Root); + Assert.IsNotNull(level); + } + + [TestMethod] + public void LoadTreeTest_1_7_10_survival() + { + NbtTree levelTree = LoadLevelTree(@"..\..\Data\1_7_10-survival\level.dat"); + + Level level = new Level(null); + level = level.LoadTreeSafe(levelTree.Root); + Assert.IsNotNull(level); + } + + [TestMethod] + public void LoadTreeTest_1_8_3_survival() + { + NbtTree levelTree = LoadLevelTree(@"..\..\Data\1_8_3-survival\level.dat"); + + Level level = new Level(null); + level = level.LoadTreeSafe(levelTree.Root); + Assert.IsNotNull(level); + } + + [TestMethod] + public void LoadTreeTest_1_9_2_survival() + { + NbtTree levelTree = LoadLevelTree(@"..\..\Data\1_9_2-survival\level.dat"); + + Level level = new Level(null); + level = level.LoadTreeSafe(levelTree.Root); + Assert.IsNotNull(level); + } + + [TestMethod] + public void LoadTreeTest_1_12_2_survival() + { + NbtTree levelTree = LoadLevelTree(@"..\..\Data\1_12_2-survival\level.dat"); + + Level level = new Level(null); + level = level.LoadTreeSafe(levelTree.Root); + Assert.IsNotNull(level); + + + NbtTree mineshaftTree = LoadLevelTree(@"..\..\Data\1_12_2-survival\data\Mineshaft.dat"); + //Assert.IsTrue(new NbtVerifier(mineshaftTree.Root, _schema).Verify()); + + NbtTree templeTree = LoadLevelTree(@"..\..\Data\1_12_2-survival\data\Temple.dat"); + + NbtTree villageTree = LoadLevelTree(@"..\..\Data\1_12_2-survival\data\Village.dat"); + + NbtTree villagesTree = LoadLevelTree(@"..\..\Data\1_12_2-survival\data\villages.dat"); + Assert.IsTrue(new NbtVerifier(villagesTree.Root, Villages.Schema).Verify()); + + NbtTree villagesEndTree = LoadLevelTree(@"..\..\Data\1_12_2-survival\data\villages_end.dat"); + Assert.IsTrue(new NbtVerifier(villagesEndTree.Root, Villages.Schema).Verify()); + + NbtTree villagesNetherTree = LoadLevelTree(@"..\..\Data\1_12_2-survival\data\villages_nether.dat"); + Assert.IsTrue(new NbtVerifier(villagesNetherTree.Root, Villages.Schema).Verify()); + } + + [TestMethod] + public void LoadTreeTest_1_12_2_survival_SchemaBuilderLoader() + { + NbtTree levelTree = LoadLevelTree(@"..\..\Data\1_12_2-survival\level.dat"); + Assert.IsTrue(new NbtVerifier(levelTree.Root, Level.Schema).Verify()); + + var level = new Level(null); + var level2 = new Level(null); + + SchemaBuilder.LoadCompound(level, levelTree.Root, Level.Schema); + + level2.LoadTree(levelTree.Root); + + Assert.IsNotNull(level); + Assert.IsNotNull(level2); + } + + [TestMethod] + public void LoadTreeTest_Climatic_Islands_survival() + { + if (!Directory.Exists(@"..\..\Data\Climatic Islands [ENG]\")) + { + Assert.Inconclusive("Level not found, skipping test"); + } + + NbtWorld world = NbtWorld.Open(@"..\..\Data\Climatic Islands [ENG]\"); + Assert.IsNotNull(world); + + NbtTree villagesNetherTree = LoadLevelTree(@"..\..\Data\Climatic Islands [ENG]\level.dat"); + Assert.IsTrue(new NbtVerifier(villagesNetherTree.Root, Level.Schema).Verify()); + } + } +} diff --git a/Substrate.Tests/Nbt/SchemaBuilderTests.cs b/Substrate.Tests/Nbt/SchemaBuilderTests.cs new file mode 100644 index 00000000..5a8e2e45 --- /dev/null +++ b/Substrate.Tests/Nbt/SchemaBuilderTests.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using Substrate.Source.Nbt; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Diagnostics; +using System.IO; + +namespace Substrate.Nbt.Tests +{ + [TestClass] + public class SchemaBuilderTests + { + [TestMethod] + public void ItemTest() + { + SchemaNodeCompound _schemaManual = Item.Schema; + + SchemaNodeCompound _schemaBuilt = SchemaBuilder.FromClass(typeof(Item)); + + string formattedManual = SchemaBuilder.FormatTree(_schemaManual); + + string formattedBuilt = SchemaBuilder.FormatTree(_schemaBuilt); + + Debug.WriteLine("Manual:"); + Debug.WriteLine(formattedManual); + Debug.WriteLine("Built:"); + Debug.WriteLine(formattedBuilt); + + Assert.AreEqual(formattedManual, formattedBuilt); + } + + [TestMethod] + public void PlayerTest() + { + SchemaNodeCompound _schemaManual = Player.Schema; + + SchemaNodeCompound _schemaBuilt = SchemaBuilder.FromClass(typeof(Player)); + + string formattedManual = SchemaBuilder.FormatTree(_schemaManual); + + string formattedBuilt = SchemaBuilder.FormatTree(_schemaBuilt); + + Debug.WriteLine("Manual:"); + Debug.WriteLine(formattedManual); + Debug.WriteLine("Built:"); + Debug.WriteLine(formattedBuilt); + + Assert.AreEqual(formattedManual, formattedBuilt); + + //File.WriteAllText("Player.Manual.txt", formattedManual); + //File.WriteAllText("Player.Built.txt", formattedBuilt); + } + } +} diff --git a/Substrate.Tests/Properties/AssemblyInfo.cs b/Substrate.Tests/Properties/AssemblyInfo.cs index 08497a8f..0b0220e0 100644 --- a/Substrate.Tests/Properties/AssemblyInfo.cs +++ b/Substrate.Tests/Properties/AssemblyInfo.cs @@ -1,36 +1,36 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Substrate.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Substrate.Tests")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("76bab255-3775-4a8f-a18a-8485a417833c")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.0")] +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Substrate.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Substrate.Tests")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("76bab255-3775-4a8f-a18a-8485a417833c")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.0.0")] diff --git a/Substrate.Tests/Substrate.Tests.csproj b/Substrate.Tests/Substrate.Tests.csproj index c909dc4b..d382f6f8 100644 --- a/Substrate.Tests/Substrate.Tests.csproj +++ b/Substrate.Tests/Substrate.Tests.csproj @@ -1,143 +1,71 @@ - - - - Debug - AnyCPU - {5D875E2D-AD97-43DB-9180-DBA3F26DC569} - Library - Properties - Substrate.Tests - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - - - Substrate.Tests.net40-client - v4.0 - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - Substrate.Tests.net40-client - v4.0 - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - Substrate.Tests.net20 - v2.0 - bin\Release\ - TRACE - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - Substrate.Tests.net20 - v2.0 - true - bin\Debug\ - DEBUG;TRACE - full - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - Substrate.Tests.net35 - v3.5 - true - bin\Debug\ - DEBUG;TRACE - full - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - Substrate.Tests.net35 - v3.5 - bin\Release\ - TRACE - true - pdbonly - AnyCPU - prompt - MinimumRecommendedRules.ruleset - false - - - - - - - - - - - - - - - - - - - - - - {7264a1c4-ab4a-4437-b252-7379b98b5509} - Substrate %28NET4%29 - - - - - - - False - - - False - - - False - - - False - - - - - - - + + + + Debug + AnyCPU + {5D875E2D-AD97-43DB-9180-DBA3F26DC569} + Library + Properties + Substrate.Tests + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + Substrate.Tests.net40-client + v4.0 + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + Substrate.Tests.net40-client + v4.0 + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + {2d269ae0-c025-4647-ba9c-1db2b84a4e55} + Substrate.Entities + + + {7264A1C4-AB4A-4437-B252-7379B98B5509} + Substrate + + + + + \ No newline at end of file diff --git a/Substrate.Tests/WorldTests.cs b/Substrate.Tests/WorldTests.cs index fbc87d4f..986bdce9 100644 --- a/Substrate.Tests/WorldTests.cs +++ b/Substrate.Tests/WorldTests.cs @@ -1,67 +1,115 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Substrate; -using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Substrate.Tests -{ - [TestClass] - public class WorldTests - { - [TestMethod] - public void OpenTest_1_6_4_survival() - { - NbtWorld world = NbtWorld.Open(@"..\..\Data\1_6_4-survival\"); - Assert.IsNotNull(world); - } - - [TestMethod] - public void OpenTest_1_7_2_survival() - { - NbtWorld world = NbtWorld.Open(@"..\..\Data\1_7_2-survival\"); - Assert.IsNotNull(world); - } - - [TestMethod] - public void OpenTest_1_7_10_survival() - { - NbtWorld world = NbtWorld.Open(@"..\..\Data\1_7_10-survival\"); - Assert.IsNotNull(world); - } - - [TestMethod] - public void OpenTest_1_8_3_survival() - { - NbtWorld world = NbtWorld.Open(@"..\..\Data\1_8_3-survival\"); - Assert.IsNotNull(world); - } - - [TestMethod] - public void OpenTest_1_8_3_debug() - { - NbtWorld world = NbtWorld.Open(@"..\..\Data\1_8_3-debug\"); - Assert.IsNotNull(world); - } - - [TestMethod] - public void OpenTest_1_8_7_debug() - { - NbtWorld world = NbtWorld.Open(@"..\..\Data\1_8_7-debug\"); - Assert.IsNotNull(world); - } - - [TestMethod] - public void OpenTest_1_8_7_survival() - { - NbtWorld world = NbtWorld.Open(@"..\..\Data\1_8_7-survival\"); - Assert.IsNotNull(world); - } - - [TestMethod] - public void OpenTest_1_9_2_debug() - { - NbtWorld world = NbtWorld.Open(@"..\..\Data\1_9_2-debug\"); - Assert.IsNotNull(world); - } - } -} +using System; +using System.Collections.Generic; +using System.Text; +using Substrate; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Substrate.Nbt; +using System.IO; + +namespace Substrate.Tests +{ + [TestClass] + public class WorldTests + { + [TestMethod] + public void OpenTest_1_6_4_survival() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_6_4-survival\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_1_7_2_survival() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_7_2-survival\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_1_7_10_survival() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_7_10-survival\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_1_8_3_survival() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_8_3-survival\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_1_8_3_debug() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_8_3-debug\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_1_8_7_debug() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_8_7-debug\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_1_8_7_survival() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_8_7-survival\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_1_9_2_debug() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_9_2-debug\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_1_9_2_survival() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_9_2-survival\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_1_12_2_debug() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_12_2-debug\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_1_12_2_survival() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\1_12_2-survival\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_Colors_survival() + { + if (!Directory.Exists(@"..\..\Data\Colors of the Rainbow SURVIVAL\")) + { + Assert.Inconclusive("Level not found, skipping test"); + } + + NbtWorld world = NbtWorld.Open(@"..\..\Data\Colors of the Rainbow SURVIVAL\"); + Assert.IsNotNull(world); + } + + [TestMethod] + public void OpenTest_Climatic_Islands_survival() + { + if (!Directory.Exists(@"..\..\Data\Climatic Islands [ENG]\")) + { + Assert.Inconclusive("Level not found, skipping test"); + } + + NbtWorld world = NbtWorld.Open(@"..\..\Data\Climatic Islands [ENG]\"); + Assert.IsNotNull(world); + } + } +} diff --git a/SubstrateCS/Substrate.sln b/Substrate.sln similarity index 52% rename from SubstrateCS/Substrate.sln rename to Substrate.sln index 4dbbf15f..6cebaa01 100644 --- a/SubstrateCS/Substrate.sln +++ b/Substrate.sln @@ -1,15 +1,22 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29806.167 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Substrate (NET2)", "Substrate (NET2).csproj", "{AFE30E14-3F2F-4461-9F7D-147AB4DCA4C3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Substrate.Entities", "Substrate.Entities\Substrate.Entities.csproj", "{2D269AE0-C025-4647-BA9C-1DB2B84A4E55}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Substrate (NET4)", "Substrate (NET4).csproj", "{7264A1C4-AB4A-4437-B252-7379B98B5509}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Substrate", "Substrate\Substrate.csproj", "{7264A1C4-AB4A-4437-B252-7379B98B5509}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3E89D2F4-E9AF-4DBC-AB0B-8BED3C607012}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Substrate.Tests", "Substrate.Tests\Substrate.Tests.csproj", "{5D875E2D-AD97-43DB-9180-DBA3F26DC569}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Substrate.Tests", "..\Substrate.Tests\Substrate.Tests.csproj", "{5D875E2D-AD97-43DB-9180-DBA3F26DC569}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Files", "Files", "{D7504FC4-BC1A-449D-9BDE-1EA742E1FF16}" + ProjectSection(SolutionItems) = preProject + .gitignore = .gitignore + Directory.Build.props = Directory.Build.props + LICENSE.md = LICENSE.md + README.md = README.md + VERSION.md = VERSION.md + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -17,10 +24,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {AFE30E14-3F2F-4461-9F7D-147AB4DCA4C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AFE30E14-3F2F-4461-9F7D-147AB4DCA4C3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AFE30E14-3F2F-4461-9F7D-147AB4DCA4C3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AFE30E14-3F2F-4461-9F7D-147AB4DCA4C3}.Release|Any CPU.Build.0 = Release|Any CPU + {2D269AE0-C025-4647-BA9C-1DB2B84A4E55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2D269AE0-C025-4647-BA9C-1DB2B84A4E55}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2D269AE0-C025-4647-BA9C-1DB2B84A4E55}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2D269AE0-C025-4647-BA9C-1DB2B84A4E55}.Release|Any CPU.Build.0 = Release|Any CPU {7264A1C4-AB4A-4437-B252-7379B98B5509}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7264A1C4-AB4A-4437-B252-7379B98B5509}.Debug|Any CPU.Build.0 = Debug|Any CPU {7264A1C4-AB4A-4437-B252-7379B98B5509}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -33,4 +40,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {ED67AB82-79E7-4381-8969-679D3CF97E5A} + EndGlobalSection EndGlobal diff --git a/SubstrateCS/Help/Substrate.shfbproj b/Substrate/Help/Substrate.shfbproj similarity index 100% rename from SubstrateCS/Help/Substrate.shfbproj rename to Substrate/Help/Substrate.shfbproj diff --git a/Substrate/Properties/AssemblyInfo.cs b/Substrate/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..4e4d0308 --- /dev/null +++ b/Substrate/Properties/AssemblyInfo.cs @@ -0,0 +1,15 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("0e6cc672-bcea-401f-a5f3-30e8ef39c673")] + +// This library is compatible with all CLS-compliant .NET programming languages. +[assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/SubstrateCS/Source/AlphaBlock.cs b/Substrate/Source/AlphaBlock.cs similarity index 84% rename from SubstrateCS/Source/AlphaBlock.cs rename to Substrate/Source/AlphaBlock.cs index 97244778..5a1561cf 100644 --- a/SubstrateCS/Source/AlphaBlock.cs +++ b/Substrate/Source/AlphaBlock.cs @@ -27,7 +27,7 @@ public class AlphaBlock : IDataBlock, IPropertyBlock, IActiveBlock, ICopyableThe id (type) of the block. /// If the specified block type requires a Tile Entity as part of its definition, a default /// of the appropriate type will automatically be created. - public AlphaBlock (int id) + public AlphaBlock(int id) { _id = id; UpdateTileEntity(0, id); @@ -40,7 +40,7 @@ public AlphaBlock (int id) /// The block's supplementary data value, currently limited to the range [0-15]. /// If the specified block type requires a Tile Entity as part of its definition, a default /// of the appropriate type will automatically be created. - public AlphaBlock (int id, int data) + public AlphaBlock(int id, int data) { _id = id; _data = data; @@ -54,13 +54,14 @@ public AlphaBlock (int id, int data) /// The local X-coordinate of a block within the collection. /// The local Y-coordinate of a block within the collection. /// The local Z-coordinate of a block within the collection. - public AlphaBlock (AlphaBlockCollection chunk, int lx, int ly, int lz) + public AlphaBlock(AlphaBlockCollection chunk, int lx, int ly, int lz) { _id = chunk.GetID(lx, ly, lz); _data = chunk.GetData(lx, ly, lz); TileEntity te = chunk.GetTileEntity(lx, ly, lz); - if (te != null) { + if (te != null) + { _tileEntity = te.Copy(); } } @@ -122,7 +123,7 @@ public int Data /// Gets the Tile Entity record of the block if it has one. /// /// The attached to this block, or null if the block type does not require a Tile Entity. - public TileEntity GetTileEntity () + public TileEntity GetTileEntity() { return _tileEntity; } @@ -133,14 +134,16 @@ public TileEntity GetTileEntity () /// A Tile Entity record compatible with the block's type. /// Thrown when an incompatible is added to a block. /// Thrown when a is added to a block that does not use tile entities. - public void SetTileEntity (TileEntity te) + public void SetTileEntity(TileEntity te) { - BlockInfoEx info = BlockInfo.BlockTable[_id] as BlockInfoEx; - if (info == null) { + BlockInfo info = BlockInfo.BlockTable[_id]; + if (info.TileEntityName == null) + { throw new InvalidOperationException("The current block type does not accept a Tile Entity"); } - if (te.GetType() != TileEntityFactory.Lookup(info.TileEntityName)) { + if (te.GetType() != TileEntityFactory.Lookup(info.TileEntityName)) + { throw new ArgumentException("The current block type is not compatible with the given Tile Entity", "te"); } @@ -150,15 +153,17 @@ public void SetTileEntity (TileEntity te) /// /// Creates a default Tile Entity record appropriate for the block. /// - public void CreateTileEntity () + public void CreateTileEntity() { - BlockInfoEx info = BlockInfo.BlockTable[_id] as BlockInfoEx; - if (info == null) { + BlockInfo info = BlockInfo.BlockTable[_id]; + if (info.TileEntityName == null) + { throw new InvalidOperationException("The given block is of a type that does not support TileEntities."); } TileEntity te = TileEntityFactory.Create(info.TileEntityName); - if (te == null) { + if (te == null) + { throw new UnknownTileEntityException("The TileEntity type '" + info.TileEntityName + "' has not been registered with the TileEntityFactory."); } @@ -168,7 +173,7 @@ public void CreateTileEntity () /// /// Removes any Tile Entity currently attached to the block. /// - public void ClearTileEntity () + public void ClearTileEntity() { _tileEntity = null; } @@ -199,7 +204,7 @@ public int TileTickValue /// Gets the record of the block if it has one. /// /// The attached to this block, or null if the block type does not require a Tile Entity. - public TileTick GetTileTick () + public TileTick GetTileTick() { return _tileTick; } @@ -208,7 +213,7 @@ public TileTick GetTileTick () /// Sets a new record for the block. /// /// A record compatible with the block's type. - public void SetTileTick (TileTick tt) + public void SetTileTick(TileTick tt) { _tileTick = tt; } @@ -216,7 +221,7 @@ public void SetTileTick (TileTick tt) /// /// Creates a default record appropriate for the block. /// - public void CreateTileTick () + public void CreateTileTick() { _tileTick = new TileTick() { @@ -227,7 +232,7 @@ public void CreateTileTick () /// /// Removes any currently attached to the block. /// - public void ClearTileTick () + public void ClearTileTick() { _tileTick = null; } @@ -241,10 +246,11 @@ public void ClearTileTick () /// Creates a deep copy of the . /// /// A new representing the same data. - public AlphaBlock Copy () + public AlphaBlock Copy() { AlphaBlock block = new AlphaBlock(_id, _data); - if (_tileEntity != null) { + if (_tileEntity != null) + { block._tileEntity = _tileEntity.Copy(); } @@ -253,17 +259,20 @@ public AlphaBlock Copy () #endregion - private void UpdateTileEntity (int old, int value) + private void UpdateTileEntity(int old, int value) { - BlockInfoEx info1 = BlockInfo.BlockTable[old] as BlockInfoEx; - BlockInfoEx info2 = BlockInfo.BlockTable[value] as BlockInfoEx; + BlockInfo info1 = BlockInfo.BlockTable[old]; + BlockInfo info2 = BlockInfo.BlockTable[value]; - if (info1 != info2) { - if (info1 != null) { + if (info1 != info2) + { + if (info1.TileEntityName != null) + { _tileEntity = null; } - if (info2 != null) { + if (info2.TileEntityName != null) + { _tileEntity = TileEntityFactory.Create(info2.TileEntityName); } } diff --git a/SubstrateCS/Source/AlphaBlockCollection.cs b/Substrate/Source/AlphaBlockCollection.cs similarity index 78% rename from SubstrateCS/Source/AlphaBlockCollection.cs rename to Substrate/Source/AlphaBlockCollection.cs index 80ee4b32..adfd62d3 100644 --- a/SubstrateCS/Source/AlphaBlockCollection.cs +++ b/Substrate/Source/AlphaBlockCollection.cs @@ -37,7 +37,7 @@ public class AlphaBlockCollection : IBoundedAlphaBlockCollection, IBoundedActive private bool _autoFluid = false; private bool _autoTick = false; - public delegate AlphaBlockCollection NeighborLookupHandler (int relx, int rely, int relz); + public delegate AlphaBlockCollection NeighborLookupHandler(int relx, int rely, int relz); /// /// Creates a new of a given dimension. @@ -46,7 +46,7 @@ public class AlphaBlockCollection : IBoundedAlphaBlockCollection, IBoundedActive /// The length of the Y-dimension of the collection. /// The length of the Z-dimension of the collection. [Obsolete] - public AlphaBlockCollection (int xdim, int ydim, int zdim) + public AlphaBlockCollection(int xdim, int ydim, int zdim) { _blocks = new XZYByteArray(xdim, ydim, zdim); _data = new XZYNibbleArray(xdim, ydim, zdim); @@ -72,7 +72,7 @@ public AlphaBlockCollection (int xdim, int ydim, int zdim) /// An array of sky light nibbles. /// An array of height map values. /// A list of tile entities corresponding to blocks in this collection. - public AlphaBlockCollection ( + public AlphaBlockCollection( IDataArray3 blocks, IDataArray3 data, IDataArray3 blockLight, @@ -93,7 +93,7 @@ public AlphaBlockCollection ( /// An array of height map values. /// A list of tile entities corresponding to blocks in this collection. /// A list of tile ticks corresponding to blocks in this collection. - public AlphaBlockCollection ( + public AlphaBlockCollection( IDataArray3 blocks, IDataArray3 data, IDataArray3 blockLight, @@ -123,7 +123,7 @@ public AlphaBlockCollection ( /// /// Updates internal managers if underlying data, such as TileEntities, have been modified outside of the container. /// - public void Refresh () + public void Refresh() { _lightManager = new BlockLight(this); _fluidManager = new BlockFluid(this); @@ -140,10 +140,11 @@ internal TagNodeList TileTicks public event NeighborLookupHandler ResolveNeighbor { - add + add { - _lightManager.ResolveNeighbor += delegate(int relx, int rely, int relz) { - return value(relx, rely, relz); + _lightManager.ResolveNeighbor += delegate(int relx, int rely, int relz) + { + return value(relx, rely, relz); }; _fluidManager.ResolveNeighbor += delegate(int relx, int rely, int relz) { @@ -208,7 +209,7 @@ public bool IsDirty set { _dirty = value; } } - + /// /// Returns a new object from local coordinates relative to this collection. @@ -219,7 +220,7 @@ public bool IsDirty /// A new object representing context-independent data of a single block. /// Context-independent data excludes data such as lighting. object actually contain a copy /// of the data they represent, so changes to the will not affect this container, and vice-versa. - public AlphaBlock GetBlock (int x, int y, int z) + public AlphaBlock GetBlock(int x, int y, int z) { return new AlphaBlock(this, x, y, z); } @@ -234,7 +235,7 @@ public AlphaBlock GetBlock (int x, int y, int z) /// Context-depdendent data includes all data associated with this block. Since a represents /// a view of a block within this container, any updates to data in the container will be reflected in the , /// and vice-versa for updates to the . - public AlphaBlockRef GetBlockRef (int x, int y, int z) + public AlphaBlockRef GetBlockRef(int x, int y, int z) { return new AlphaBlockRef(this, _blocks.GetIndex(x, y, z)); } @@ -246,18 +247,20 @@ public AlphaBlockRef GetBlockRef (int x, int y, int z) /// Local Y-coordinate of a block. /// Local Z-coordinate of a block. /// A object to copy block data from. - public void SetBlock (int x, int y, int z, AlphaBlock block) + public void SetBlock(int x, int y, int z, AlphaBlock block) { SetID(x, y, z, block.ID); SetData(x, y, z, block.Data); TileEntity te = block.GetTileEntity(); - if (te != null) { + if (te != null) + { SetTileEntity(x, y, z, te.Copy()); } TileTick tt = block.GetTileTick(); - if (tt != null) { + if (tt != null) + { SetTileTick(x, y, z, tt.Copy()); } } @@ -282,40 +285,40 @@ public int ZDim get { return _zdim; } } - IBlock IBoundedBlockCollection.GetBlock (int x, int y, int z) + IBlock IBoundedBlockCollection.GetBlock(int x, int y, int z) { return GetBlock(x, y, z); } - IBlock IBoundedBlockCollection.GetBlockRef (int x, int y, int z) + IBlock IBoundedBlockCollection.GetBlockRef(int x, int y, int z) { return GetBlockRef(x, y, z); } /// - public void SetBlock (int x, int y, int z, IBlock block) + public void SetBlock(int x, int y, int z, IBlock block) { SetID(x, y, z, block.ID); } /// - public BlockInfo GetInfo (int x, int y, int z) + public BlockInfo GetInfo(int x, int y, int z) { return BlockInfo.BlockTable[_blocks[x, y, z]]; } - internal BlockInfo GetInfo (int index) + internal BlockInfo GetInfo(int index) { return BlockInfo.BlockTable[_blocks[index]]; } /// - public int GetID (int x, int y, int z) + public int GetID(int x, int y, int z) { return _blocks[x, y, z]; } - internal int GetID (int index) + internal int GetID(int index) { return _blocks[index]; } @@ -326,10 +329,11 @@ internal int GetID (int index) /// for the affected block and possibly many other indirectly-affected blocks in the collection or neighboring /// collections. If many SetID calls are expected to be made, some of this auto-reconciliation behavior should /// be disabled, and the data should be rebuilt at the -level at the end. - public void SetID (int x, int y, int z, int id) + public void SetID(int x, int y, int z, int id) { int oldid = _blocks[x, y, z]; - if (oldid == id) { + if (oldid == id) + { return; } @@ -342,49 +346,58 @@ public void SetID (int x, int y, int z, int id) BlockInfo info1 = BlockInfo.BlockTable[oldid]; BlockInfo info2 = BlockInfo.BlockTable[id]; - BlockInfoEx einfo1 = info1 as BlockInfoEx; - BlockInfoEx einfo2 = info2 as BlockInfoEx; - - if (einfo1 != einfo2) { - if (einfo1 != null || !info1.Registered) { + if (info1 != info2) + { + if (info1.TileEntityName != null || !info1.Registered) + { ClearTileEntity(x, y, z); } - if (einfo2 != null) { + if (info2.TileEntityName != null) + { CreateTileEntity(x, y, z); } } // Light consistency - if (_autoLight) { - if (info1.ObscuresLight != info2.ObscuresLight) { + if (_autoLight) + { + if (info1.ObscuresLight != info2.ObscuresLight) + { _lightManager.UpdateHeightMap(x, y, z); } - if (info1.Luminance != info2.Luminance || info1.Opacity != info2.Opacity || info1.TransmitsLight != info2.TransmitsLight) { + if (info1.Luminance != info2.Luminance || info1.Opacity != info2.Opacity || info1.TransmitsLight != info2.TransmitsLight) + { UpdateBlockLight(x, y, z); } - if (info1.Opacity != info2.Opacity || info1.TransmitsLight != info2.TransmitsLight) { + if (info1.Opacity != info2.Opacity || info1.TransmitsLight != info2.TransmitsLight) + { UpdateSkyLight(x, y, z); } } // Fluid consistency - if (_autoFluid) { - if (info1.State == BlockState.FLUID || info2.State == BlockState.FLUID) { + if (_autoFluid) + { + if (info1.State == BlockState.FLUID || info2.State == BlockState.FLUID) + { UpdateFluid(x, y, z); } } // TileTick consistency - if (_autoTick) { - if (info1.ID != info2.ID) { + if (_autoTick) + { + if (info1.ID != info2.ID) + { ClearTileTick(x, y, z); - if (info2.Tick > 0) { + if (info2.Tick > 0) + { SetTileTickValue(x, y, z, info2.Tick); } } @@ -393,7 +406,7 @@ public void SetID (int x, int y, int z, int id) _dirty = true; } - internal void SetID (int index, int id) + internal void SetID(int index, int id) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); @@ -402,11 +415,13 @@ internal void SetID (int index, int id) } /// - public int CountByID (int id) + public int CountByID(int id) { int c = 0; - for (int i = 0; i < _blocks.Length; i++) { - if (_blocks[i] == id) { + for (int i = 0; i < _blocks.Length; i++) + { + if (_blocks[i] == id) + { c++; } } @@ -419,38 +434,39 @@ public int CountByID (int id) #region IBoundedDataBlockContainer Members - IDataBlock IBoundedDataBlockCollection.GetBlock (int x, int y, int z) + IDataBlock IBoundedDataBlockCollection.GetBlock(int x, int y, int z) { return GetBlock(x, y, z); } - IDataBlock IBoundedDataBlockCollection.GetBlockRef (int x, int y, int z) + IDataBlock IBoundedDataBlockCollection.GetBlockRef(int x, int y, int z) { return GetBlockRef(x, y, z); } /// - public void SetBlock (int x, int y, int z, IDataBlock block) + public void SetBlock(int x, int y, int z, IDataBlock block) { SetID(x, y, z, block.ID); SetData(x, y, z, block.Data); } /// - public int GetData (int x, int y, int z) + public int GetData(int x, int y, int z) { return _data[x, y, z]; } - internal int GetData (int index) + internal int GetData(int index) { return _data[index]; } /// - public void SetData (int x, int y, int z, int data) + public void SetData(int x, int y, int z, int data) { - if (_data[x, y, z] != data) { + if (_data[x, y, z] != data) + { _data[x, y, z] = (byte)data; _dirty = true; } @@ -462,20 +478,23 @@ public void SetData (int x, int y, int z, int data) }*/ } - internal void SetData (int index, int data) + internal void SetData(int index, int data) { - if (_data[index] != data) { + if (_data[index] != data) + { _data[index] = (byte)data; _dirty = true; } } /// - public int CountByData (int id, int data) + public int CountByData(int id, int data) { int c = 0; - for (int i = 0; i < _blocks.Length; i++) { - if (_blocks[i] == id && _data[i] == data) { + for (int i = 0; i < _blocks.Length; i++) + { + if (_blocks[i] == id && _data[i] == data) + { c++; } } @@ -488,18 +507,18 @@ public int CountByData (int id, int data) #region IBoundedLitBlockCollection Members - ILitBlock IBoundedLitBlockCollection.GetBlock (int x, int y, int z) + ILitBlock IBoundedLitBlockCollection.GetBlock(int x, int y, int z) { throw new NotImplementedException(); } - ILitBlock IBoundedLitBlockCollection.GetBlockRef (int x, int y, int z) + ILitBlock IBoundedLitBlockCollection.GetBlockRef(int x, int y, int z) { return GetBlockRef(x, y, z); } /// - public void SetBlock (int x, int y, int z, ILitBlock block) + public void SetBlock(int x, int y, int z, ILitBlock block) { SetID(x, y, z, block.ID); SetBlockLight(x, y, z, block.BlockLight); @@ -507,145 +526,149 @@ public void SetBlock (int x, int y, int z, ILitBlock block) } /// - public int GetBlockLight (int x, int y, int z) + public int GetBlockLight(int x, int y, int z) { return _blockLight[x, y, z]; } - internal int GetBlockLight (int index) + internal int GetBlockLight(int index) { return _blockLight[index]; } /// - public int GetSkyLight (int x, int y, int z) + public int GetSkyLight(int x, int y, int z) { return _skyLight[x, y, z]; } - internal int GetSkyLight (int index) + internal int GetSkyLight(int index) { return _skyLight[index]; } /// - public void SetBlockLight (int x, int y, int z, int light) + public void SetBlockLight(int x, int y, int z, int light) { - if (_blockLight[x, y, z] != light) { + if (_blockLight[x, y, z] != light) + { _blockLight[x, y, z] = (byte)light; _dirty = true; } } - internal void SetBlockLight (int index, int light) + internal void SetBlockLight(int index, int light) { - if (_blockLight[index] != light) { + if (_blockLight[index] != light) + { _blockLight[index] = (byte)light; _dirty = true; } } /// - public void SetSkyLight (int x, int y, int z, int light) + public void SetSkyLight(int x, int y, int z, int light) { - if (_skyLight[x, y, z] != light) { + if (_skyLight[x, y, z] != light) + { _skyLight[x, y, z] = (byte)light; _dirty = true; } } - internal void SetSkyLight (int index, int light) + internal void SetSkyLight(int index, int light) { - if (_skyLight[index] != light) { + if (_skyLight[index] != light) + { _skyLight[index] = (byte)light; _dirty = true; } } /// - public int GetHeight (int x, int z) + public int GetHeight(int x, int z) { return _heightMap[x, z]; } /// - public void SetHeight (int x, int z, int height) + public void SetHeight(int x, int z, int height) { _heightMap[x, z] = (byte)height; } /// - public void UpdateBlockLight (int x, int y, int z) + public void UpdateBlockLight(int x, int y, int z) { _lightManager.UpdateBlockLight(x, y, z); _dirty = true; } /// - public void UpdateSkyLight (int x, int y, int z) + public void UpdateSkyLight(int x, int y, int z) { _lightManager.UpdateBlockSkyLight(x, y, z); _dirty = true; } /// - public void ResetBlockLight () + public void ResetBlockLight() { _blockLight.Clear(); _dirty = true; } /// - public void ResetSkyLight () + public void ResetSkyLight() { _skyLight.Clear(); _dirty = true; } /// - public void RebuildBlockLight () + public void RebuildBlockLight() { _lightManager.RebuildBlockLight(); _dirty = true; } /// - public void RebuildSkyLight () + public void RebuildSkyLight() { _lightManager.RebuildBlockSkyLight(); _dirty = true; } /// - public void RebuildHeightMap () + public void RebuildHeightMap() { _lightManager.RebuildHeightMap(); _dirty = true; } /// - public void StitchBlockLight () + public void StitchBlockLight() { _lightManager.StitchBlockLight(); _dirty = true; } /// - public void StitchSkyLight () + public void StitchSkyLight() { _lightManager.StitchBlockSkyLight(); _dirty = true; } /// - public void StitchBlockLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge) + public void StitchBlockLight(IBoundedLitBlockCollection blockset, BlockCollectionEdge edge) { _lightManager.StitchBlockLight(blockset, edge); _dirty = true; } /// - public void StitchSkyLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge) + public void StitchSkyLight(IBoundedLitBlockCollection blockset, BlockCollectionEdge edge) { _lightManager.StitchBlockSkyLight(blockset, edge); _dirty = true; @@ -656,30 +679,30 @@ public void StitchSkyLight (IBoundedLitBlockCollection blockset, BlockCollection #region IBoundedPropertyBlockCollection Members - IPropertyBlock IBoundedPropertyBlockCollection.GetBlock (int x, int y, int z) + IPropertyBlock IBoundedPropertyBlockCollection.GetBlock(int x, int y, int z) { return GetBlock(x, y, z); } - IPropertyBlock IBoundedPropertyBlockCollection.GetBlockRef (int x, int y, int z) + IPropertyBlock IBoundedPropertyBlockCollection.GetBlockRef(int x, int y, int z) { return GetBlockRef(x, y, z); } /// - public void SetBlock (int x, int y, int z, IPropertyBlock block) + public void SetBlock(int x, int y, int z, IPropertyBlock block) { SetID(x, y, z, block.ID); SetTileEntity(x, y, z, block.GetTileEntity().Copy()); } /// - public TileEntity GetTileEntity (int x, int y, int z) + public TileEntity GetTileEntity(int x, int y, int z) { return _tileEntityManager.GetTileEntity(x, y, z); } - internal TileEntity GetTileEntity (int index) + internal TileEntity GetTileEntity(int index) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); @@ -688,13 +711,13 @@ internal TileEntity GetTileEntity (int index) } /// - public void SetTileEntity (int x, int y, int z, TileEntity te) + public void SetTileEntity(int x, int y, int z, TileEntity te) { _tileEntityManager.SetTileEntity(x, y, z, te); _dirty = true; } - internal void SetTileEntity (int index, TileEntity te) + internal void SetTileEntity(int index, TileEntity te) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); @@ -704,13 +727,13 @@ internal void SetTileEntity (int index, TileEntity te) } /// - public void CreateTileEntity (int x, int y, int z) + public void CreateTileEntity(int x, int y, int z) { _tileEntityManager.CreateTileEntity(x, y, z); _dirty = true; } - internal void CreateTileEntity (int index) + internal void CreateTileEntity(int index) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); @@ -720,13 +743,13 @@ internal void CreateTileEntity (int index) } /// - public void ClearTileEntity (int x, int y, int z) + public void ClearTileEntity(int x, int y, int z) { _tileEntityManager.ClearTileEntity(x, y, z); _dirty = true; } - internal void ClearTileEntity (int index) + internal void ClearTileEntity(int index) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); @@ -740,30 +763,30 @@ internal void ClearTileEntity (int index) #region IBoundedActiveBlockCollection Members - IActiveBlock IBoundedActiveBlockCollection.GetBlock (int x, int y, int z) + IActiveBlock IBoundedActiveBlockCollection.GetBlock(int x, int y, int z) { return GetBlock(x, y, z); } - IActiveBlock IBoundedActiveBlockCollection.GetBlockRef (int x, int y, int z) + IActiveBlock IBoundedActiveBlockCollection.GetBlockRef(int x, int y, int z) { return GetBlockRef(x, y, z); } /// - public void SetBlock (int x, int y, int z, IActiveBlock block) + public void SetBlock(int x, int y, int z, IActiveBlock block) { SetID(x, y, z, block.ID); SetTileTick(x, y, z, block.GetTileTick().Copy()); } /// - public int GetTileTickValue (int x, int y, int z) + public int GetTileTickValue(int x, int y, int z) { return _tileTickManager.GetTileTickValue(x, y, z); } - internal int GetTileTickValue (int index) + internal int GetTileTickValue(int index) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); @@ -772,13 +795,13 @@ internal int GetTileTickValue (int index) } /// - public void SetTileTickValue (int x, int y, int z, int tickValue) + public void SetTileTickValue(int x, int y, int z, int tickValue) { _tileTickManager.SetTileTickValue(x, y, z, tickValue); _dirty = true; } - internal void SetTileTickValue (int index, int tickValue) + internal void SetTileTickValue(int index, int tickValue) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); @@ -788,12 +811,12 @@ internal void SetTileTickValue (int index, int tickValue) } /// - public TileTick GetTileTick (int x, int y, int z) + public TileTick GetTileTick(int x, int y, int z) { return _tileTickManager.GetTileTick(x, y, z); } - internal TileTick GetTileTick (int index) + internal TileTick GetTileTick(int index) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); @@ -802,13 +825,13 @@ internal TileTick GetTileTick (int index) } /// - public void SetTileTick (int x, int y, int z, TileTick tt) + public void SetTileTick(int x, int y, int z, TileTick tt) { _tileTickManager.SetTileTick(x, y, z, tt); _dirty = true; } - internal void SetTileTick (int index, TileTick tt) + internal void SetTileTick(int index, TileTick tt) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); @@ -818,13 +841,13 @@ internal void SetTileTick (int index, TileTick tt) } /// - public void CreateTileTick (int x, int y, int z) + public void CreateTileTick(int x, int y, int z) { _tileTickManager.CreateTileTick(x, y, z); _dirty = true; } - internal void CreateTileTick (int index) + internal void CreateTileTick(int index) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); @@ -834,13 +857,13 @@ internal void CreateTileTick (int index) } /// - public void ClearTileTick (int x, int y, int z) + public void ClearTileTick(int x, int y, int z) { _tileTickManager.ClearTileTick(x, y, z); _dirty = true; } - internal void ClearTileTick (int index) + internal void ClearTileTick(int index) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); @@ -854,7 +877,7 @@ internal void ClearTileTick (int index) /// /// Resets all fluid blocks in the collection to their inactive type. /// - public void ResetFluid () + public void ResetFluid() { _fluidManager.ResetWater(_blocks, _data); _fluidManager.ResetLava(_blocks, _data); @@ -867,7 +890,7 @@ public void ResetFluid () /// Simulation will cause inactive fluid blocks to convert into and spread active fluid blocks according /// to the fluid calculation rules in Minecraft. Fluid calculation may spill into neighboring block collections /// (and beyond). - public void RebuildFluid () + public void RebuildFluid() { _fluidManager.RebuildWater(); _fluidManager.RebuildLava(); @@ -880,18 +903,20 @@ public void RebuildFluid () /// Local X-coordinate of block. /// Local Y-coordinate of block. /// Local Z-coordiante of block. - public void UpdateFluid (int x, int y, int z) + public void UpdateFluid(int x, int y, int z) { bool autofluid = _autoFluid; _autoFluid = false; int blocktype = _blocks[x, y, z]; - if (blocktype == BlockInfo.Water.ID || blocktype == BlockInfo.StationaryWater.ID) { + if (blocktype == BlockInfo.Water.ID || blocktype == BlockInfo.StationaryWater.ID) + { _fluidManager.UpdateWater(x, y, z); _dirty = true; } - else if (blocktype == BlockInfo.Lava.ID || blocktype == BlockInfo.StationaryLava.ID) { + else if (blocktype == BlockInfo.Lava.ID || blocktype == BlockInfo.StationaryLava.ID) + { _fluidManager.UpdateLava(x, y, z); _dirty = true; } diff --git a/SubstrateCS/Source/AlphaBlockRef.cs b/Substrate/Source/AlphaBlockRef.cs similarity index 100% rename from SubstrateCS/Source/AlphaBlockRef.cs rename to Substrate/Source/AlphaBlockRef.cs diff --git a/SubstrateCS/Source/AlphaChunk.cs b/Substrate/Source/AlphaChunk.cs similarity index 96% rename from SubstrateCS/Source/AlphaChunk.cs rename to Substrate/Source/AlphaChunk.cs index fd434336..d367d7a4 100644 --- a/SubstrateCS/Source/AlphaChunk.cs +++ b/Substrate/Source/AlphaChunk.cs @@ -25,18 +25,18 @@ public class AlphaChunk : IChunk, INbtObject, ICopyable { new SchemaNodeCompound("Level") { - new SchemaNodeArray("Blocks", 32768), - new SchemaNodeArray("Data", 16384), - new SchemaNodeArray("SkyLight", 16384), - new SchemaNodeArray("BlockLight", 16384), - new SchemaNodeArray("HeightMap", 256), + new SchemaNodeByteArray("Blocks", 32768), + new SchemaNodeByteArray("Data", 16384), + new SchemaNodeByteArray("SkyLight", 16384), + new SchemaNodeByteArray("BlockLight", 16384), + new SchemaNodeByteArray("HeightMap", 256), new SchemaNodeList("Entities", TagType.TAG_COMPOUND, SchemaOptions.CREATE_ON_MISSING), new SchemaNodeList("TileEntities", TagType.TAG_COMPOUND, TileEntity.Schema, SchemaOptions.CREATE_ON_MISSING), new SchemaNodeList("TileTicks", TagType.TAG_COMPOUND, TileTick.Schema, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("LastUpdate", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), - new SchemaNodeScaler("xPos", TagType.TAG_INT), - new SchemaNodeScaler("zPos", TagType.TAG_INT), - new SchemaNodeScaler("TerrainPopulated", TagType.TAG_BYTE, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeScalar("LastUpdate", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeScalar("xPos", TagType.TAG_INT), + new SchemaNodeScalar("zPos", TagType.TAG_INT), + new SchemaNodeScalar("TerrainPopulated", TagType.TAG_BYTE, SchemaOptions.CREATE_ON_MISSING), }, }; diff --git a/SubstrateCS/Source/AlphaChunkManager.cs b/Substrate/Source/AlphaChunkManager.cs similarity index 100% rename from SubstrateCS/Source/AlphaChunkManager.cs rename to Substrate/Source/AlphaChunkManager.cs diff --git a/SubstrateCS/Source/AlphaWorld.cs b/Substrate/Source/AlphaWorld.cs similarity index 100% rename from SubstrateCS/Source/AlphaWorld.cs rename to Substrate/Source/AlphaWorld.cs diff --git a/SubstrateCS/Source/AnvilBiomeCollection.cs b/Substrate/Source/AnvilBiomeCollection.cs similarity index 100% rename from SubstrateCS/Source/AnvilBiomeCollection.cs rename to Substrate/Source/AnvilBiomeCollection.cs diff --git a/SubstrateCS/Source/AnvilChunk.cs b/Substrate/Source/AnvilChunk.cs similarity index 95% rename from SubstrateCS/Source/AnvilChunk.cs rename to Substrate/Source/AnvilChunk.cs index 7ec2e358..0d29ff76 100644 --- a/SubstrateCS/Source/AnvilChunk.cs +++ b/Substrate/Source/AnvilChunk.cs @@ -14,22 +14,22 @@ public class AnvilChunk : IChunk, INbtObject, ICopyable new SchemaNodeCompound("Level") { new SchemaNodeList("Sections", TagType.TAG_COMPOUND, new SchemaNodeCompound() { - new SchemaNodeArray("Blocks", 4096), - new SchemaNodeArray("Data", 2048), - new SchemaNodeArray("SkyLight", 2048), - new SchemaNodeArray("BlockLight", 2048), - new SchemaNodeScaler("Y", TagType.TAG_BYTE), - new SchemaNodeArray("Add", 2048, SchemaOptions.OPTIONAL), + new SchemaNodeByteArray("Blocks", 4096), + new SchemaNodeByteArray("Data", 2048), + new SchemaNodeByteArray("SkyLight", 2048), + new SchemaNodeByteArray("BlockLight", 2048), + new SchemaNodeScalar("Y", TagType.TAG_BYTE), + new SchemaNodeByteArray("Add", 2048, SchemaOptions.OPTIONAL), }), - new SchemaNodeArray("Biomes", 256, SchemaOptions.OPTIONAL), + new SchemaNodeByteArray("Biomes", 256, SchemaOptions.OPTIONAL), new SchemaNodeIntArray("HeightMap", 256), new SchemaNodeList("Entities", TagType.TAG_COMPOUND, SchemaOptions.CREATE_ON_MISSING), new SchemaNodeList("TileEntities", TagType.TAG_COMPOUND, TileEntity.Schema, SchemaOptions.CREATE_ON_MISSING), new SchemaNodeList("TileTicks", TagType.TAG_COMPOUND, TileTick.Schema, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("LastUpdate", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), - new SchemaNodeScaler("xPos", TagType.TAG_INT), - new SchemaNodeScaler("zPos", TagType.TAG_INT), - new SchemaNodeScaler("TerrainPopulated", TagType.TAG_BYTE, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeScalar("LastUpdate", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeScalar("xPos", TagType.TAG_INT), + new SchemaNodeScalar("zPos", TagType.TAG_INT), + new SchemaNodeScalar("TerrainPopulated", TagType.TAG_BYTE, SchemaOptions.CREATE_ON_MISSING), }, }; diff --git a/SubstrateCS/Source/AnvilRegion.cs b/Substrate/Source/AnvilRegion.cs similarity index 94% rename from SubstrateCS/Source/AnvilRegion.cs rename to Substrate/Source/AnvilRegion.cs index 343aade7..f96ebf9e 100644 --- a/SubstrateCS/Source/AnvilRegion.cs +++ b/Substrate/Source/AnvilRegion.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text.RegularExpressions; using Substrate.Core; using Substrate.Nbt; @@ -17,14 +17,14 @@ public AnvilRegion (AnvilRegionManager rm, ChunkCache cache, int rx, int rz) /// public override string GetFileName () { - return "r." + _rx + "." + _rz + ".mca"; + return "r." + X + "." + Z + ".mca"; } /// public override string GetFilePath () { - return System.IO.Path.Combine(_regionMan.GetRegionPath(), GetFileName()); + return System.IO.Path.Combine(RegionMan.GetRegionPath(), GetFileName()); } /// diff --git a/SubstrateCS/Source/AnvilRegionManager.cs b/Substrate/Source/AnvilRegionManager.cs similarity index 88% rename from SubstrateCS/Source/AnvilRegionManager.cs rename to Substrate/Source/AnvilRegionManager.cs index 6db9f291..77c1fde3 100644 --- a/SubstrateCS/Source/AnvilRegionManager.cs +++ b/Substrate/Source/AnvilRegionManager.cs @@ -13,13 +13,13 @@ public AnvilRegionManager (string regionDir, ChunkCache cache) protected override IRegion CreateRegionCore (int rx, int rz) { - return new AnvilRegion(this, _chunkCache, rx, rz); + return new AnvilRegion(this, ChunkCache_, rx, rz); } protected override RegionFile CreateRegionFileCore (int rx, int rz) { string fp = "r." + rx + "." + rz + ".mca"; - return new RegionFile(Path.Combine(_regionPath, fp)); + return new RegionFile(Path.Combine(GetRegionPath(), fp)); } protected override void DeleteRegionCore (IRegion region) diff --git a/SubstrateCS/Source/AnvilSection.cs b/Substrate/Source/AnvilSection.cs similarity index 94% rename from SubstrateCS/Source/AnvilSection.cs rename to Substrate/Source/AnvilSection.cs index c8d14380..04d0b6ee 100644 --- a/SubstrateCS/Source/AnvilSection.cs +++ b/Substrate/Source/AnvilSection.cs @@ -10,12 +10,12 @@ public class AnvilSection : INbtObject, ICopyable { public static SchemaNodeCompound SectionSchema = new SchemaNodeCompound() { - new SchemaNodeArray("Blocks", 4096), - new SchemaNodeArray("Data", 2048), - new SchemaNodeArray("SkyLight", 2048), - new SchemaNodeArray("BlockLight", 2048), - new SchemaNodeScaler("Y", TagType.TAG_BYTE), - new SchemaNodeArray("Add", 2048, SchemaOptions.OPTIONAL), + new SchemaNodeByteArray("Blocks", 4096), + new SchemaNodeByteArray("Data", 2048), + new SchemaNodeByteArray("SkyLight", 2048), + new SchemaNodeByteArray("BlockLight", 2048), + new SchemaNodeScalar("Y", TagType.TAG_BYTE), + new SchemaNodeByteArray("Add", 2048, SchemaOptions.OPTIONAL), }; private const int XDIM = 16; diff --git a/SubstrateCS/Source/AnvilWorld.cs b/Substrate/Source/AnvilWorld.cs similarity index 96% rename from SubstrateCS/Source/AnvilWorld.cs rename to Substrate/Source/AnvilWorld.cs index a99a7177..4bdcc30b 100644 --- a/SubstrateCS/Source/AnvilWorld.cs +++ b/Substrate/Source/AnvilWorld.cs @@ -1,433 +1,436 @@ -using System; -using System.Collections.Generic; -using System.IO; -using Substrate.Core; -using Substrate.Nbt; -using Substrate.Data; - -//TODO: Exceptions (+ Alpha) - -namespace Substrate -{ - using IO = System.IO; - - /// - /// Represents an Anvil-compatible (Release 1.2 or higher) Minecraft world. - /// - public class AnvilWorld : NbtWorld - { - private const string _REGION_DIR = "region"; - private const string _PLAYER_DIR = "players"; - private string _levelFile = "level.dat"; - - private Level _level; - - private Dictionary _regionMgrs; - private Dictionary _chunkMgrs; - private Dictionary _blockMgrs; - - private Dictionary _caches; - - private PlayerManager _playerMan; - private BetaDataManager _dataMan; - - private int _prefCacheSize = 256; - - private AnvilWorld () - { - _regionMgrs = new Dictionary(); - _chunkMgrs = new Dictionary(); - _blockMgrs = new Dictionary(); - - _caches = new Dictionary(); - } - - /// - /// Gets a reference to this world's object. - /// - public override Level Level - { - get { return _level; } - } - - /// - /// Gets a for the default dimension. - /// - /// A tied to the default dimension in this world. - /// Get a if you need to manage blocks as a global, unbounded matrix. This abstracts away - /// any higher-level organizational divisions. If your task is going to be heavily performance-bound, consider getting a - /// instead and working with blocks on a chunk-local level. - public new BlockManager GetBlockManager () - { - return GetBlockManagerVirt(Dimension.DEFAULT) as BlockManager; - } - - /// - /// Gets a for the given dimension. - /// - /// The id of the dimension to look up. - /// A tied to the given dimension in this world. - /// Get a if you need to manage blocks as a global, unbounded matrix. This abstracts away - /// any higher-level organizational divisions. If your task is going to be heavily performance-bound, consider getting a - /// instead and working with blocks on a chunk-local level. - public new BlockManager GetBlockManager (int dim) - { - return GetBlockManagerVirt(dim) as BlockManager; - } - - public new BlockManager GetBlockManager (string dim) - { - return GetBlockManagerVirt(dim) as BlockManager; - } - - /// - /// Gets a for the default dimension. - /// - /// A tied to the default dimension in this world. - /// Get a if you you need to work with easily-digestible, bounded chunks of blocks. - public new RegionChunkManager GetChunkManager () - { - return GetChunkManagerVirt(Dimension.DEFAULT) as RegionChunkManager; - } - - /// - /// Gets a for the given dimension. - /// - /// The id of the dimension to look up. - /// A tied to the given dimension in this world. - /// Get a if you you need to work with easily-digestible, bounded chunks of blocks. - public new RegionChunkManager GetChunkManager (int dim) - { - return GetChunkManagerVirt(dim) as RegionChunkManager; - } - - public new RegionChunkManager GetChunkManager (string dim) - { - return GetChunkManagerVirt(dim) as RegionChunkManager; - } - - /// - /// Gets a for the default dimension. - /// - /// A tied to the defaul dimension in this world. - /// Regions are a higher-level unit of organization for blocks unique to worlds created in Beta 1.3 and beyond. - /// Consider using the if you are interested in working with blocks. - public AnvilRegionManager GetRegionManager () - { - return GetRegionManager(Dimension.DEFAULT); - } - - /// - /// Gets a for the given dimension. - /// - /// The id of the dimension to look up. - /// A tied to the given dimension in this world. - /// Regions are a higher-level unit of organization for blocks unique to worlds created in Beta 1.3 and beyond. - /// Consider using the if you are interested in working with blocks. - public AnvilRegionManager GetRegionManager (int dim) - { - return GetRegionManager(DimensionFromInt(dim)); - } - - public AnvilRegionManager GetRegionManager (string dim) - { - AnvilRegionManager rm; - if (_regionMgrs.TryGetValue(dim, out rm)) { - return rm; - } - - OpenDimension(dim); - return _regionMgrs[dim]; - } - - /// - /// Gets a for maanging players on multiplayer worlds. - /// - /// A for this world. - /// To manage the player of a single-player world, get a object for the world instead. - public new PlayerManager GetPlayerManager () - { - return GetPlayerManagerVirt() as PlayerManager; - } - - /// - /// Gets a for managing data resources, such as maps. - /// - /// A for this world. - public new BetaDataManager GetDataManager () - { - return GetDataManagerVirt() as BetaDataManager; - } - - /// - public override void Save () - { - _level.Save(); - - foreach (KeyValuePair cm in _chunkMgrs) { - cm.Value.Save(); - } - } - - /// - /// Gets the currently managing chunks in the default dimension. - /// - /// The for the default dimension, or null if the dimension was not found. - public ChunkCache GetChunkCache () - { - return GetChunkCache(Dimension.DEFAULT); - } - - /// - /// Gets the currently managing chunks in the given dimension. - /// - /// The id of a dimension to look up. - /// The for the given dimension, or null if the dimension was not found. - public ChunkCache GetChunkCache (int dim) - { - return GetChunkCache(DimensionFromInt(dim)); - } - - public ChunkCache GetChunkCache (string dim) - { - if (_caches.ContainsKey(dim)) { - return _caches[dim]; - } - return null; - } - - /// - /// Opens an existing Beta-compatible Minecraft world and returns a new to represent it. - /// - /// The path to the directory containing the world's level.dat, or the path to level.dat itself. - /// A new object representing an existing world on disk. - public static new AnvilWorld Open (string path) - { - return new AnvilWorld().OpenWorld(path) as AnvilWorld; - } - - /// - /// Opens an existing Beta-compatible Minecraft world and returns a new to represent it. - /// - /// The path to the directory containing the world's level.dat, or the path to level.dat itself. - /// The preferred cache size in chunks for each opened dimension in this world. - /// A new object representing an existing world on disk. - public static AnvilWorld Open (string path, int cacheSize) - { - AnvilWorld world = new AnvilWorld().OpenWorld(path); - world._prefCacheSize = cacheSize; - - return world; - } - - /// - /// Creates a new Beta-compatible Minecraft world and returns a new to represent it. - /// - /// The path to the directory where the new world should be stored. - /// A new object representing a new world. - /// This method will attempt to create the specified directory immediately if it does not exist, but will not - /// write out any world data unless it is explicitly saved at a later time. - public static AnvilWorld Create (string path) - { - return new AnvilWorld().CreateWorld(path) as AnvilWorld; - } - - /// - /// Creates a new Beta-compatible Minecraft world and returns a new to represent it. - /// - /// The path to the directory where the new world should be stored. - /// The preferred cache size in chunks for each opened dimension in this world. - /// A new object representing a new world. - /// This method will attempt to create the specified directory immediately if it does not exist, but will not - /// write out any world data unless it is explicitly saved at a later time. - public static AnvilWorld Create (string path, int cacheSize) - { - AnvilWorld world = new AnvilWorld().CreateWorld(path); - world._prefCacheSize = cacheSize; - - return world; - } - - /// - protected override IBlockManager GetBlockManagerVirt (int dim) - { - return GetBlockManagerVirt(DimensionFromInt(dim)); - } - - protected override IBlockManager GetBlockManagerVirt(string dim) - { - BlockManager rm; - if (_blockMgrs.TryGetValue(dim, out rm)) { - return rm; - } - - OpenDimension(dim); - return _blockMgrs[dim]; - } - - /// - protected override IChunkManager GetChunkManagerVirt (int dim) - { - return GetChunkManagerVirt(DimensionFromInt(dim)); - } - - protected override IChunkManager GetChunkManagerVirt (string dim) - { - RegionChunkManager rm; - if (_chunkMgrs.TryGetValue(dim, out rm)) { - return rm; - } - - OpenDimension(dim); - return _chunkMgrs[dim]; - } - - /// - protected override IPlayerManager GetPlayerManagerVirt () - { - if (_playerMan != null) { - return _playerMan; - } - - string path = IO.Path.Combine(Path, _PLAYER_DIR); - - _playerMan = new PlayerManager(path); - return _playerMan; - } - - /// - protected override Data.DataManager GetDataManagerVirt () - { - if (_dataMan != null) { - return _dataMan; - } - - _dataMan = new BetaDataManager(this); - return _dataMan; - } - - private string DimensionFromInt (int dim) - { - if (dim == Dimension.DEFAULT) - return ""; - else - return "DIM" + dim; - } - - private void OpenDimension (string dim) - { - string path = Path; - if (String.IsNullOrEmpty(dim)) { - path = IO.Path.Combine(path, _REGION_DIR); - } - else { - path = IO.Path.Combine(path, dim); - path = IO.Path.Combine(path, _REGION_DIR); - } - - if (!Directory.Exists(path)) { - Directory.CreateDirectory(path); - } - - ChunkCache cc = new ChunkCache(_prefCacheSize); - - AnvilRegionManager rm = new AnvilRegionManager(path, cc); - RegionChunkManager cm = new RegionChunkManager(rm, cc); - BlockManager bm = new AnvilBlockManager(cm); - - _regionMgrs[dim] = rm; - _chunkMgrs[dim] = cm; - _blockMgrs[dim] = bm; - - _caches[dim] = cc; - } - - private AnvilWorld OpenWorld (string path) - { - if (!Directory.Exists(path)) { - if (File.Exists(path)) { - _levelFile = IO.Path.GetFileName(path); - path = IO.Path.GetDirectoryName(path); - } - else { - throw new DirectoryNotFoundException("Directory '" + path + "' not found"); - } - } - - Path = path; - - string ldat = IO.Path.Combine(path, _levelFile); - if (!File.Exists(ldat)) { - throw new FileNotFoundException("Data file '" + _levelFile + "' not found in '" + path + "'", ldat); - } - - if (!LoadLevel()) { - throw new Exception("Failed to load '" + _levelFile + "'"); - } - - return this; - } - - private AnvilWorld CreateWorld (string path) - { - if (!Directory.Exists(path)) { - Directory.CreateDirectory(path); - } - - string regpath = IO.Path.Combine(path, _REGION_DIR); - if (!Directory.Exists(regpath)) { - Directory.CreateDirectory(regpath); - } - - Path = path; - _level = new Level(this); - - return this; - } - - private bool LoadLevel () - { - NBTFile nf = new NBTFile(IO.Path.Combine(Path, _levelFile)); - NbtTree tree; - - using (Stream nbtstr = nf.GetDataInputStream()) - { - if (nbtstr == null) - { - return false; - } - - tree = new NbtTree(nbtstr); - } - - _level = new Level(this); - _level = _level.LoadTreeSafe(tree.Root); - - return _level != null; - } - - internal static void OnResolveOpen (object sender, OpenWorldEventArgs e) - { - try { - AnvilWorld world = new AnvilWorld().OpenWorld(e.Path); - if (world == null) { - return; - } - - string regPath = IO.Path.Combine(e.Path, _REGION_DIR); - if (!Directory.Exists(regPath)) { - return; - } - - if (world.Level.Version < 19133) { - return; - } - - e.AddHandler(Open); - } - catch (Exception) { - return; - } - } - } -} +using System; +using System.Collections.Generic; +using System.IO; +using Substrate.Core; +using Substrate.Nbt; +using Substrate.Data; + +//TODO: Exceptions (+ Alpha) + +namespace Substrate +{ + using IO = System.IO; + + /// + /// Represents an Anvil-compatible (Release 1.2 or higher) Minecraft world. + /// + public class AnvilWorld : NbtWorld + { + private const string _REGION_DIR = "region"; + private const string _PLAYER_DIR = "players"; + private const string _PLAYERDATA_DIR = "playerdata"; + private const string _STATS_DIR = "stats"; + private const string _DATA_DIR = "players"; + private string _levelFile = "level.dat"; + + private Level _level; + + private Dictionary _regionMgrs; + private Dictionary _chunkMgrs; + private Dictionary _blockMgrs; + + private Dictionary _caches; + + private PlayerManager _playerMan; + private BetaDataManager _dataMan; + + private int _prefCacheSize = 256; + + private AnvilWorld () + { + _regionMgrs = new Dictionary(); + _chunkMgrs = new Dictionary(); + _blockMgrs = new Dictionary(); + + _caches = new Dictionary(); + } + + /// + /// Gets a reference to this world's object. + /// + public override Level Level + { + get { return _level; } + } + + /// + /// Gets a for the default dimension. + /// + /// A tied to the default dimension in this world. + /// Get a if you need to manage blocks as a global, unbounded matrix. This abstracts away + /// any higher-level organizational divisions. If your task is going to be heavily performance-bound, consider getting a + /// instead and working with blocks on a chunk-local level. + public new BlockManager GetBlockManager () + { + return GetBlockManagerVirt(Dimension.DEFAULT) as BlockManager; + } + + /// + /// Gets a for the given dimension. + /// + /// The id of the dimension to look up. + /// A tied to the given dimension in this world. + /// Get a if you need to manage blocks as a global, unbounded matrix. This abstracts away + /// any higher-level organizational divisions. If your task is going to be heavily performance-bound, consider getting a + /// instead and working with blocks on a chunk-local level. + public new BlockManager GetBlockManager (int dim) + { + return GetBlockManagerVirt(dim) as BlockManager; + } + + public new BlockManager GetBlockManager (string dim) + { + return GetBlockManagerVirt(dim) as BlockManager; + } + + /// + /// Gets a for the default dimension. + /// + /// A tied to the default dimension in this world. + /// Get a if you you need to work with easily-digestible, bounded chunks of blocks. + public new RegionChunkManager GetChunkManager () + { + return GetChunkManagerVirt(Dimension.DEFAULT) as RegionChunkManager; + } + + /// + /// Gets a for the given dimension. + /// + /// The id of the dimension to look up. + /// A tied to the given dimension in this world. + /// Get a if you you need to work with easily-digestible, bounded chunks of blocks. + public new RegionChunkManager GetChunkManager (int dim) + { + return GetChunkManagerVirt(dim) as RegionChunkManager; + } + + public new RegionChunkManager GetChunkManager (string dim) + { + return GetChunkManagerVirt(dim) as RegionChunkManager; + } + + /// + /// Gets a for the default dimension. + /// + /// A tied to the defaul dimension in this world. + /// Regions are a higher-level unit of organization for blocks unique to worlds created in Beta 1.3 and beyond. + /// Consider using the if you are interested in working with blocks. + public AnvilRegionManager GetRegionManager () + { + return GetRegionManager(Dimension.DEFAULT); + } + + /// + /// Gets a for the given dimension. + /// + /// The id of the dimension to look up. + /// A tied to the given dimension in this world. + /// Regions are a higher-level unit of organization for blocks unique to worlds created in Beta 1.3 and beyond. + /// Consider using the if you are interested in working with blocks. + public AnvilRegionManager GetRegionManager (int dim) + { + return GetRegionManager(DimensionFromInt(dim)); + } + + public AnvilRegionManager GetRegionManager (string dim) + { + AnvilRegionManager rm; + if (_regionMgrs.TryGetValue(dim, out rm)) { + return rm; + } + + OpenDimension(dim); + return _regionMgrs[dim]; + } + + /// + /// Gets a for maanging players on multiplayer worlds. + /// + /// A for this world. + /// To manage the player of a single-player world, get a object for the world instead. + public new PlayerManager GetPlayerManager () + { + return GetPlayerManagerVirt() as PlayerManager; + } + + /// + /// Gets a for managing data resources, such as maps. + /// + /// A for this world. + public new BetaDataManager GetDataManager () + { + return GetDataManagerVirt() as BetaDataManager; + } + + /// + public override void Save () + { + _level.Save(); + + foreach (KeyValuePair cm in _chunkMgrs) { + cm.Value.Save(); + } + } + + /// + /// Gets the currently managing chunks in the default dimension. + /// + /// The for the default dimension, or null if the dimension was not found. + public ChunkCache GetChunkCache () + { + return GetChunkCache(Dimension.DEFAULT); + } + + /// + /// Gets the currently managing chunks in the given dimension. + /// + /// The id of a dimension to look up. + /// The for the given dimension, or null if the dimension was not found. + public ChunkCache GetChunkCache (int dim) + { + return GetChunkCache(DimensionFromInt(dim)); + } + + public ChunkCache GetChunkCache (string dim) + { + if (_caches.ContainsKey(dim)) { + return _caches[dim]; + } + return null; + } + + /// + /// Opens an existing Beta-compatible Minecraft world and returns a new to represent it. + /// + /// The path to the directory containing the world's level.dat, or the path to level.dat itself. + /// A new object representing an existing world on disk. + public static new AnvilWorld Open (string path) + { + return new AnvilWorld().OpenWorld(path) as AnvilWorld; + } + + /// + /// Opens an existing Beta-compatible Minecraft world and returns a new to represent it. + /// + /// The path to the directory containing the world's level.dat, or the path to level.dat itself. + /// The preferred cache size in chunks for each opened dimension in this world. + /// A new object representing an existing world on disk. + public static AnvilWorld Open (string path, int cacheSize) + { + AnvilWorld world = new AnvilWorld().OpenWorld(path); + world._prefCacheSize = cacheSize; + + return world; + } + + /// + /// Creates a new Beta-compatible Minecraft world and returns a new to represent it. + /// + /// The path to the directory where the new world should be stored. + /// A new object representing a new world. + /// This method will attempt to create the specified directory immediately if it does not exist, but will not + /// write out any world data unless it is explicitly saved at a later time. + public static AnvilWorld Create (string path) + { + return new AnvilWorld().CreateWorld(path) as AnvilWorld; + } + + /// + /// Creates a new Beta-compatible Minecraft world and returns a new to represent it. + /// + /// The path to the directory where the new world should be stored. + /// The preferred cache size in chunks for each opened dimension in this world. + /// A new object representing a new world. + /// This method will attempt to create the specified directory immediately if it does not exist, but will not + /// write out any world data unless it is explicitly saved at a later time. + public static AnvilWorld Create (string path, int cacheSize) + { + AnvilWorld world = new AnvilWorld().CreateWorld(path); + world._prefCacheSize = cacheSize; + + return world; + } + + /// + protected override IBlockManager GetBlockManagerVirt (int dim) + { + return GetBlockManagerVirt(DimensionFromInt(dim)); + } + + protected override IBlockManager GetBlockManagerVirt(string dim) + { + BlockManager rm; + if (_blockMgrs.TryGetValue(dim, out rm)) { + return rm; + } + + OpenDimension(dim); + return _blockMgrs[dim]; + } + + /// + protected override IChunkManager GetChunkManagerVirt (int dim) + { + return GetChunkManagerVirt(DimensionFromInt(dim)); + } + + protected override IChunkManager GetChunkManagerVirt (string dim) + { + RegionChunkManager rm; + if (_chunkMgrs.TryGetValue(dim, out rm)) { + return rm; + } + + OpenDimension(dim); + return _chunkMgrs[dim]; + } + + /// + protected override IPlayerManager GetPlayerManagerVirt () + { + if (_playerMan != null) { + return _playerMan; + } + + string path = IO.Path.Combine(Path, _PLAYER_DIR); + + _playerMan = new PlayerManager(path); + return _playerMan; + } + + /// + protected override Data.DataManager GetDataManagerVirt () + { + if (_dataMan != null) { + return _dataMan; + } + + _dataMan = new BetaDataManager(this); + return _dataMan; + } + + private string DimensionFromInt (int dim) + { + if (dim == Dimension.DEFAULT) + return ""; + else + return "DIM" + dim; + } + + private void OpenDimension (string dim) + { + string path = Path; + if (String.IsNullOrEmpty(dim)) { + path = IO.Path.Combine(path, _REGION_DIR); + } + else { + path = IO.Path.Combine(path, dim); + path = IO.Path.Combine(path, _REGION_DIR); + } + + if (!Directory.Exists(path)) { + Directory.CreateDirectory(path); + } + + ChunkCache cc = new ChunkCache(_prefCacheSize); + + AnvilRegionManager rm = new AnvilRegionManager(path, cc); + RegionChunkManager cm = new RegionChunkManager(rm, cc); + BlockManager bm = new AnvilBlockManager(cm); + + _regionMgrs[dim] = rm; + _chunkMgrs[dim] = cm; + _blockMgrs[dim] = bm; + + _caches[dim] = cc; + } + + private AnvilWorld OpenWorld (string path) + { + if (!Directory.Exists(path)) { + if (File.Exists(path)) { + _levelFile = IO.Path.GetFileName(path); + path = IO.Path.GetDirectoryName(path); + } + else { + throw new DirectoryNotFoundException("Directory '" + path + "' not found"); + } + } + + Path = path; + + string ldat = IO.Path.Combine(path, _levelFile); + if (!File.Exists(ldat)) { + throw new FileNotFoundException("Data file '" + _levelFile + "' not found in '" + path + "'", ldat); + } + + if (!LoadLevel()) { + throw new Exception("Failed to load '" + _levelFile + "'"); + } + + return this; + } + + private AnvilWorld CreateWorld (string path) + { + if (!Directory.Exists(path)) { + Directory.CreateDirectory(path); + } + + string regpath = IO.Path.Combine(path, _REGION_DIR); + if (!Directory.Exists(regpath)) { + Directory.CreateDirectory(regpath); + } + + Path = path; + _level = new Level(this); + + return this; + } + + private bool LoadLevel () + { + NBTFile nf = new NBTFile(IO.Path.Combine(Path, _levelFile)); + NbtTree tree; + + using (Stream nbtstr = nf.GetDataInputStream()) + { + if (nbtstr == null) + { + return false; + } + + tree = new NbtTree(nbtstr); + } + + _level = new Level(this); + _level = _level.LoadTreeSafe(tree.Root); + + return _level != null; + } + + internal static void OnResolveOpen (object sender, OpenWorldEventArgs e) + { + try { + AnvilWorld world = new AnvilWorld().OpenWorld(e.Path); + if (world == null) { + return; + } + + string regPath = IO.Path.Combine(e.Path, _REGION_DIR); + if (!Directory.Exists(regPath)) { + return; + } + + if (world.Level.Version < 19133) { + return; + } + + e.AddHandler(Open); + } + catch (Exception) { + return; + } + } + } +} diff --git a/SubstrateCS/Source/BetaRegion.cs b/Substrate/Source/BetaRegion.cs similarity index 94% rename from SubstrateCS/Source/BetaRegion.cs rename to Substrate/Source/BetaRegion.cs index cee4afa7..b7f58d13 100644 --- a/SubstrateCS/Source/BetaRegion.cs +++ b/Substrate/Source/BetaRegion.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text.RegularExpressions; using Substrate.Core; using Substrate.Nbt; @@ -17,14 +17,14 @@ public BetaRegion (BetaRegionManager rm, ChunkCache cache, int rx, int rz) /// public override string GetFileName () { - return "r." + _rx + "." + _rz + ".mcr"; + return "r." + X + "." + Z + ".mcr"; } /// public override string GetFilePath () { - return System.IO.Path.Combine(_regionMan.GetRegionPath(), GetFileName()); + return System.IO.Path.Combine(this.RegionMan.GetRegionPath(), GetFileName()); } /// diff --git a/SubstrateCS/Source/BetaRegionManager.cs b/Substrate/Source/BetaRegionManager.cs similarity index 88% rename from SubstrateCS/Source/BetaRegionManager.cs rename to Substrate/Source/BetaRegionManager.cs index d76ee939..7b75a6f0 100644 --- a/SubstrateCS/Source/BetaRegionManager.cs +++ b/Substrate/Source/BetaRegionManager.cs @@ -13,13 +13,13 @@ public BetaRegionManager (string regionDir, ChunkCache cache) protected override IRegion CreateRegionCore (int rx, int rz) { - return new BetaRegion(this, _chunkCache, rx, rz); + return new BetaRegion(this, ChunkCache_, rx, rz); } protected override RegionFile CreateRegionFileCore (int rx, int rz) { - string fp = "r." + rx + "." + rz + ".mcr"; - return new RegionFile(Path.Combine(_regionPath, fp)); + string fp = "r." + rx + "." + rz + ".mcr"; + return new RegionFile(Path.Combine(GetRegionPath(), fp)); } protected override void DeleteRegionCore (IRegion region) diff --git a/SubstrateCS/Source/BetaWorld.cs b/Substrate/Source/BetaWorld.cs similarity index 100% rename from SubstrateCS/Source/BetaWorld.cs rename to Substrate/Source/BetaWorld.cs diff --git a/Substrate/Source/BiomeInfo.cs b/Substrate/Source/BiomeInfo.cs new file mode 100644 index 00000000..835f1722 --- /dev/null +++ b/Substrate/Source/BiomeInfo.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate +{ + public class BiomeType + { + public const int Uncalculated = -1; + + public const int Ocean = 0; + public const int Plains = 1; + public const int Desert = 2; + public const int ExtremeHills = 3; + public const int Forest = 4; + public const int Taiga = 5; + public const int Swampland = 6; + public const int River = 7; + public const int Hell = 8; + public const int Sky = 9; + public const int FrozenOcean = 10; + public const int FrozenRiver = 11; + public const int IcePlains = 12; + public const int IceMountains = 13; + public const int MushroomIsland = 14; + public const int MushroomIslandShore = 15; + public const int Beach = 16; + public const int DesertHills = 17; + public const int ForestHills = 18; + public const int TaigaHills = 19; + public const int ExtremeHillsEdge = 20; + public const int Jungle = 21; + public const int JungleHills = 22; + public const int JungleEdge = 23; + public const int DeepOcean = 24; + public const int StoneBeach = 25; + public const int ColdBeach = 26; + public const int BirchForest = 27; + public const int BirchForestHills = 28; + public const int RoofedForest = 29; + public const int ColdTaiga = 30; + public const int ColdTaigaHills = 31; + public const int MegaTaiga = 32; + public const int MegaTaigaHills = 33; + public const int ExtremeHillsPlus = 34; // Extreme Hills+ + public const int Savanna = 35; + public const int SavannaPlateau = 36; + public const int Mesa = 37; + public const int MesaPlateauF = 38; + public const int MesaPlateau = 39; + public const int SunflowerPlains = 129; + public const int DesertM = 130; + public const int ExtremeHillsM = 131; + public const int FlowerForest = 132; + public const int TaigaM = 133; + public const int SwamplandM = 134; + public const int IcePlainsSpikes = 140; + public const int JungleM = 149; + public const int JungleEdgeM = 151; + public const int BirchForestM = 155; + public const int BirchForestHillsM = 156; + public const int RoofedForestM = 157; + public const int ColdTaigaM = 158; + public const int MegaSpruceTaiga = 160; + public const int RedwoodTaigaHillsM = 161; + public const int ExtremeHillsPlusM = 162; // Extreme Hills+ M + public const int SavannaM = 163; + public const int SavannaPlateauM = 164; + public const int MesaBryce = 165; // Mesa (Bryce) + public const int MesaPlateauFM = 166; + public const int MesaPlateauM = 167; + + public const int Default = 255; + } +} diff --git a/Substrate/Source/BlockInfo.cs b/Substrate/Source/BlockInfo.cs new file mode 100644 index 00000000..8ac234ee --- /dev/null +++ b/Substrate/Source/BlockInfo.cs @@ -0,0 +1,1090 @@ +using System; +using System.Collections.Generic; +using Substrate.Nbt; +using System.Collections; + +namespace Substrate +{ + /// + /// Provides named id values for known block types. + /// + /// The preferred method to lookup + /// Minecraft block IDs is to access the ID field of the corresponding static BlockInfo + /// object in the BlockInfo class. + /// The static BlockInfo objects can be re-bound to new BlockInfo objects, allowing + /// the named object to be bound to a new block ID. This gives the developer more flexibility + /// in supporting nonstandard worlds, and the ability to future-proof their application against + /// changes to Block IDs, by implementing functionality to import block/ID mappings from an + /// external source and rebinding the objects in BlockInfo. + public static class BlockType + { + public const int AIR = 0; + public const int STONE = 1; + public const int GRASS = 2; + public const int DIRT = 3; + public const int COBBLESTONE = 4; + public const int WOOD_PLANK = 5; + public const int SAPLING = 6; + public const int BEDROCK = 7; + public const int WATER = 8; + public const int STATIONARY_WATER = 9; + public const int LAVA = 10; + public const int STATIONARY_LAVA = 11; + public const int SAND = 12; + public const int GRAVEL = 13; + public const int GOLD_ORE = 14; + public const int IRON_ORE = 15; + public const int COAL_ORE = 16; + public const int WOOD = 17; + public const int LEAVES = 18; + public const int SPONGE = 19; + public const int GLASS = 20; + public const int LAPIS_ORE = 21; + public const int LAPIS_BLOCK = 22; + public const int DISPENSER = 23; + public const int SANDSTONE = 24; + public const int NOTE_BLOCK = 25; + public const int BED = 26; + public const int POWERED_RAIL = 27; + public const int DETECTOR_RAIL = 28; + public const int STICKY_PISTON = 29; + public const int COBWEB = 30; + public const int TALL_GRASS = 31; + public const int DEAD_SHRUB = 32; + public const int PISTON = 33; + public const int PISTON_HEAD = 34; + public const int WOOL = 35; + public const int PISTON_MOVING = 36; + public const int YELLOW_FLOWER = 37; + public const int RED_ROSE = 38; + public const int BROWN_MUSHROOM = 39; + public const int RED_MUSHROOM = 40; + public const int GOLD_BLOCK = 41; + public const int IRON_BLOCK = 42; + public const int DOUBLE_STONE_SLAB = 43; + public const int STONE_SLAB = 44; + public const int BRICK_BLOCK = 45; + public const int TNT = 46; + public const int BOOKSHELF = 47; + public const int MOSS_STONE = 48; + public const int OBSIDIAN = 49; + public const int TORCH = 50; + public const int FIRE = 51; + public const int MONSTER_SPAWNER = 52; + public const int WOOD_STAIRS = 53; + public const int CHEST = 54; + public const int REDSTONE_WIRE = 55; + public const int DIAMOND_ORE = 56; + public const int DIAMOND_BLOCK = 57; + public const int CRAFTING_TABLE = 58; + public const int CROPS = 59; + public const int FARMLAND = 60; + public const int FURNACE = 61; + public const int BURNING_FURNACE = 62; + public const int SIGN_POST = 63; + public const int WOOD_DOOR = 64; + public const int LADDER = 65; + public const int RAILS = 66; + public const int COBBLESTONE_STAIRS = 67; + public const int WALL_SIGN = 68; + public const int LEVER = 69; + public const int STONE_PLATE = 70; + public const int IRON_DOOR = 71; + public const int WOOD_PLATE = 72; + public const int REDSTONE_ORE = 73; + public const int GLOWING_REDSTONE_ORE = 74; + public const int REDSTONE_TORCH_OFF = 75; + public const int REDSTONE_TORCH_ON = 76; + public const int STONE_BUTTON = 77; + public const int SNOW = 78; + public const int ICE = 79; + public const int SNOW_BLOCK = 80; + public const int CACTUS = 81; + public const int CLAY_BLOCK = 82; + public const int SUGAR_CANE = 83; + public const int JUKEBOX = 84; + public const int FENCE = 85; + public const int PUMPKIN = 86; + public const int NETHERRACK = 87; + public const int SOUL_SAND = 88; + public const int GLOWSTONE_BLOCK = 89; + public const int PORTAL = 90; + public const int JACK_O_LANTERN = 91; + public const int CAKE_BLOCK = 92; + public const int REDSTONE_REPEATER_OFF = 93; + public const int REDSTONE_REPEATER_ON = 94; + public const int LOCKED_CHEST = 95; + public const int STAINED_GLASS = 95; + public const int TRAPDOOR = 96; + public const int SILVERFISH_STONE = 97; + public const int STONE_BRICK = 98; + public const int HUGE_RED_MUSHROOM = 99; + public const int HUGE_BROWN_MUSHROOM = 100; + public const int IRON_BARS = 101; + public const int GLASS_PANE = 102; + public const int MELON = 103; + public const int PUMPKIN_STEM = 104; + public const int MELON_STEM = 105; + public const int VINES = 106; + public const int FENCE_GATE = 107; + public const int BRICK_STAIRS = 108; + public const int STONE_BRICK_STAIRS = 109; + public const int MYCELIUM = 110; + public const int LILLY_PAD = 111; + public const int NETHER_BRICK = 112; + public const int NETHER_BRICK_FENCE = 113; + public const int NETHER_BRICK_STAIRS = 114; + public const int NETHER_WART = 115; + public const int ENCHANTMENT_TABLE = 116; + public const int BREWING_STAND = 117; + public const int CAULDRON = 118; + public const int END_PORTAL = 119; + public const int END_PORTAL_FRAME = 120; + public const int END_STONE = 121; + public const int DRAGON_EGG = 122; + public const int REDSTONE_LAMP_OFF = 123; + public const int REDSTONE_LAMP_ON = 124; + public const int DOUBLE_WOOD_SLAB = 125; + public const int WOOD_SLAB = 126; + public const int COCOA_PLANT = 127; + public const int SANDSTONE_STAIRS = 128; + public const int EMERALD_ORE = 129; + public const int ENDER_CHEST = 130; + public const int TRIPWIRE_HOOK = 131; + public const int TRIPWIRE = 132; + public const int EMERALD_BLOCK = 133; + public const int SPRUCE_WOOD_STAIRS = 134; + public const int BIRCH_WOOD_STAIRS = 135; + public const int JUNGLE_WOOD_STAIRS = 136; + public const int COMMAND_BLOCK = 137; + public const int BEACON_BLOCK = 138; + public const int COBBLESTONE_WALL = 139; + public const int FLOWER_POT = 140; + public const int CARROTS = 141; + public const int POTATOES = 142; + public const int WOOD_BUTTON = 143; + public const int HEADS = 144; + public const int ANVIL = 145; + public const int TRAPPED_CHEST = 146; + public const int WEIGHTED_PRESSURE_PLATE_LIGHT = 147; + public const int WEIGHTED_PRESSURE_PLATE_HEAVY = 148; + public const int REDSTONE_COMPARATOR_INACTIVE = 149; + public const int REDSTONE_COMPARATOR_ACTIVE = 150; + public const int DAYLIGHT_SENSOR = 151; + public const int REDSTONE_BLOCK = 152; + public const int NETHER_QUARTZ_ORE = 153; + public const int HOPPER = 154; + public const int QUARTZ_BLOCK = 155; + public const int QUARTZ_STAIRS = 156; + public const int ACTIVATOR_RAIL = 157; + public const int DROPPER = 158; + public const int STAINED_CLAY = 159; + public const int STAINED_GLASS_PANE = 160; + public const int HAY_BLOCK = 170; + public const int CARPET = 171; + public const int HARDENED_CLAY = 172; + public const int COAL_BLOCK = 173; + } + + /// + /// Represents the physical state of a block, such as solid or fluid. + /// + public enum BlockState + { + /// + /// A solid state that stops movement. + /// + SOLID, + + /// + /// A nonsolid state that can be passed through. + /// + NONSOLID, + + /// + /// A fluid state that flows and impedes movement. + /// + FLUID + } + + /// + /// Provides information on a specific type of block. + /// + /// By default, all known MC block types are already defined and registered, assuming Substrate + /// is up to date with the current MC version. All unknown blocks are given a default type and unregistered status. + /// New block types may be created and used at runtime, and will automatically populate various static lookup tables + /// in the class. + public class BlockInfo + { + /// + /// The maximum number of sequential blocks starting at 0 that can be registered. + /// + public const int MAX_BLOCKS = 4096; + + /// + /// The maximum opacity value that can be assigned to a block (fully opaque). + /// + public const int MAX_OPACITY = 15; + + /// + /// The minimum opacity value that can be assigned to a block (fully transparent). + /// + public const int MIN_OPACITY = 0; + + /// + /// The maximum luminance value that can be assigned to a block. + /// + public const int MAX_LUMINANCE = 15; + + /// + /// The minimum luminance value that can be assigned to a block. + /// + public const int MIN_LUMINANCE = 0; + + private static readonly BlockInfo[] _blockTable; + private static readonly Dictionary _nameIdLookup; + private static readonly int[] _opacityTable; + private static readonly int[] _luminanceTable; + + private class CacheTableArray : ICacheTable + { + private T[] _cache; + + public T this[int index] + { + get { return _cache[index]; } + } + + public CacheTableArray(T[] cache) + { + _cache = cache; + } + + public IEnumerator GetEnumerator() + { + for (int i = 0; i < _cache.Length; i++) + { + if (_cache[i] != null) + yield return _cache[i]; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + public class BlockDataLimits + { + public int Low { get; private set; } + + public int High { get; private set; } + + public int Bitmask { get; private set; } + + public BlockDataLimits(int low, int high, int bitmask = 0) + { + Low = low; + High = high; + Bitmask = bitmask; + } + + public bool Test(int data) + { + int rdata = data & ~Bitmask; + return rdata >= Low && rdata <= High; + } + } + + private int _id = 0; + private string _name = ""; + private string _nameId = ""; + private int _tick = 0; + private int _opacity = MAX_OPACITY; + private int _luminance = MIN_LUMINANCE; + private bool _transmitLight = false; + private bool _blocksFluid = true; + private bool _registered = false; + private string _tileEntityName = null; + + private BlockState _state = BlockState.SOLID; + + private BlockDataLimits _dataLimits; + + private static readonly CacheTableArray _blockTableCache; + private static readonly CacheTableArray _opacityTableCache; + private static readonly CacheTableArray _luminanceTableCache; + + /// + /// Gets the lookup table for id-to-info values. + /// + public static ICacheTable BlockTable + { + get { return _blockTableCache; } + } + + public static BlockInfo GetBlockByNameId(string nameId) + { + BlockInfo bi; + if (_nameIdLookup.TryGetValue(nameId, out bi)) + { + return bi; + } + + return null; + } + + /// + /// Gets the lookup table for id-to-opacity values. + /// + public static ICacheTable OpacityTable + { + get { return _opacityTableCache; } + } + + /// + /// Gets the lookup table for id-to-luminance values. + /// + public static ICacheTable LuminanceTable + { + get { return _luminanceTableCache; } + } + + /// + /// Get's the block's Id. + /// + public int ID + { + get { return _id; } + } + + /// + /// Get's the name ID of the block type. + /// + public string NameID + { + get { return _nameId; } + } + + /// + /// Get's the name of the block type. + /// + public string Name + { + get { return _name; } + } + + /// + /// Gets the block's opacity value. An opacity of 0 is fully transparent to light. + /// May change the value in TransmitsLight. + /// + public int Opacity + { + get { return _opacity; } + set + { + if (value < MIN_OPACITY || value > MAX_OPACITY) + { + throw new InvalidOperationException("Invalid opacity"); + } + + _opacity = value; + _opacityTable[_id] = _opacity; + + _transmitLight = (_opacity != MAX_OPACITY); + } + } + + /// + /// Gets the block's luminance value. + /// + /// Blocks with luminance act as light sources and transmit light to other blocks. + /// + public int Luminance + { + get { return _luminance; } + set + { + _luminance = value; + _luminanceTable[_id] = _luminance; + } + } + + /// + /// Checks whether the block transmits light to neighboring blocks. + /// + /// A block may stop the transmission of light, but still be illuminated. + public bool TransmitsLight + { + get { return _transmitLight; } + set { _transmitLight = value; } + } + + /// + /// Checks whether the block partially or fully blocks the transmission of light. + /// + public bool ObscuresLight + { + get { return (_opacity > MIN_OPACITY) || !_transmitLight; } + } + + /// + /// Checks whether the block stops fluid from passing through it. + /// + /// A block that does not block fluids will be destroyed by fluid. + /// + public bool BlocksFluid + { + get { return _blocksFluid; } + set { _blocksFluid = value; } + } + + /// + /// Gets the block's physical state type. + /// May change BlocksFluid + /// + public BlockState State + { + get { return _state; } + set + { + _state = value; + + if (_state == BlockState.SOLID) + { + _blocksFluid = true; + } + else + { + _blocksFluid = false; + } + } + } + + /// + /// Checks whether this block type has been registered as a known type. + /// + public bool Registered + { + get { return _registered; } + } + + + /// + /// Sets the default tick rate/delay used for updating this block. + /// The tick rate in frames between scheduled updates on this block. + /// + /// Set to 0 to indicate that this block is not processed by tick updates. + /// + public int Tick + { + get { return _tick; } + set { _tick = value; } + } + + + /// + /// Gets the name of the registered type associated with this block type. + /// Sets the name of the registered type associated with this block type. + /// + /// + public string TileEntityName + { + get { return _tileEntityName; } + set { _tileEntityName = value; } + } + + public BlockDataLimits DataLimits + { + get { return _dataLimits; } + set { _dataLimits = value; } + } + + internal BlockInfo(int id) + { + _id = id; + _name = "Unknown Block"; + _blockTable[_id] = this; + } + + /// + /// Constructs a new record for a given block id and name. + /// + /// The id of the block. + /// The name ID of the block. + /// The name of the block. + /// All user-constructed objects are registered automatically. + public BlockInfo(int id, string nameId, string name) + { + _id = id; + _nameId = nameId; + _name = name; + _blockTable[_id] = this; + _nameIdLookup.Add(_nameId, this); + _registered = true; + } + + + /// + /// Tests if the given data value is valid for this block type. + /// + /// A data value to test. + /// True if the data value is valid, false otherwise. + /// This method uses internal information set by . + public bool TestData(int data) + { + if (_dataLimits == null) + { + return data == 0; + } + return _dataLimits.Test(data); + } + + public readonly static BlockInfo Air; + public readonly static BlockInfo Stone; + public readonly static BlockInfo Grass; + public readonly static BlockInfo Dirt; + public readonly static BlockInfo Cobblestone; + public readonly static BlockInfo WoodPlank; + public readonly static BlockInfo Sapling; + public readonly static BlockInfo Bedrock; + public readonly static BlockInfo Water; + public readonly static BlockInfo StationaryWater; + public readonly static BlockInfo Lava; + public readonly static BlockInfo StationaryLava; + public readonly static BlockInfo Sand; + public readonly static BlockInfo Gravel; + public readonly static BlockInfo GoldOre; + public readonly static BlockInfo IronOre; + public readonly static BlockInfo CoalOre; + public readonly static BlockInfo Wood; + public readonly static BlockInfo Leaves; + public readonly static BlockInfo Sponge; + public readonly static BlockInfo Glass; + public readonly static BlockInfo LapisOre; + public readonly static BlockInfo LapisBlock; + public readonly static BlockInfo Dispenser; + public readonly static BlockInfo Sandstone; + public readonly static BlockInfo NoteBlock; + public readonly static BlockInfo Bed; + public readonly static BlockInfo PoweredRail; + public readonly static BlockInfo DetectorRail; + public readonly static BlockInfo StickyPiston; + public readonly static BlockInfo Cobweb; + public readonly static BlockInfo TallGrass; + public readonly static BlockInfo DeadShrub; + public readonly static BlockInfo Piston; + public readonly static BlockInfo PistonHead; + public readonly static BlockInfo Wool; + public readonly static BlockInfo PistonExtension; + public readonly static BlockInfo YellowFlower; + public readonly static BlockInfo RedRose; + public readonly static BlockInfo BrownMushroom; + public readonly static BlockInfo RedMushroom; + public readonly static BlockInfo GoldBlock; + public readonly static BlockInfo IronBlock; + public readonly static BlockInfo DoubleStoneSlab; + public readonly static BlockInfo StoneSlab; + public readonly static BlockInfo BrickBlock; + public readonly static BlockInfo TNT; + public readonly static BlockInfo Bookshelf; + public readonly static BlockInfo MossStone; + public readonly static BlockInfo Obsidian; + public readonly static BlockInfo Torch; + public readonly static BlockInfo Fire; + public readonly static BlockInfo MonsterSpawner; + public readonly static BlockInfo WoodStairs; + public readonly static BlockInfo Chest; + public readonly static BlockInfo RedstoneWire; + public readonly static BlockInfo DiamondOre; + public readonly static BlockInfo DiamondBlock; + public readonly static BlockInfo CraftTable; + public readonly static BlockInfo Crops; + public readonly static BlockInfo Farmland; + public readonly static BlockInfo Furnace; + public readonly static BlockInfo BurningFurnace; + public readonly static BlockInfo SignPost; + public readonly static BlockInfo WoodDoor; + public readonly static BlockInfo Ladder; + public readonly static BlockInfo Rails; + public readonly static BlockInfo CobbleStairs; + public readonly static BlockInfo WallSign; + public readonly static BlockInfo Lever; + public readonly static BlockInfo StonePlate; + public readonly static BlockInfo IronDoor; + public readonly static BlockInfo WoodPlate; + public readonly static BlockInfo RedstoneOre; + public readonly static BlockInfo GlowRedstoneOre; + public readonly static BlockInfo RedstoneTorch; + public readonly static BlockInfo RedstoneTorchOn; + public readonly static BlockInfo StoneButton; + public readonly static BlockInfo Snow; + public readonly static BlockInfo Ice; + public readonly static BlockInfo SnowBlock; + public readonly static BlockInfo Cactus; + public readonly static BlockInfo ClayBlock; + public readonly static BlockInfo SugarCane; + public readonly static BlockInfo Jukebox; + public readonly static BlockInfo Fence; + public readonly static BlockInfo Pumpkin; + public readonly static BlockInfo Netherrack; + public readonly static BlockInfo SoulSand; + public readonly static BlockInfo Glowstone; + public readonly static BlockInfo Portal; + public readonly static BlockInfo JackOLantern; + public readonly static BlockInfo CakeBlock; + public readonly static BlockInfo RedstoneRepeater; + public readonly static BlockInfo RedstoneRepeaterOn; + public readonly static BlockInfo LockedChest; + public readonly static BlockInfo StainedGlass; + public readonly static BlockInfo Trapdoor; + public readonly static BlockInfo SilverfishStone; + public readonly static BlockInfo StoneBrick; + public readonly static BlockInfo HugeRedMushroom; + public readonly static BlockInfo HugeBrownMushroom; + public readonly static BlockInfo IronBars; + public readonly static BlockInfo GlassPane; + public readonly static BlockInfo Melon; + public readonly static BlockInfo PumpkinStem; + public readonly static BlockInfo MelonStem; + public readonly static BlockInfo Vines; + public readonly static BlockInfo FenceGate; + public readonly static BlockInfo BrickStairs; + public readonly static BlockInfo StoneBrickStairs; + public readonly static BlockInfo Mycelium; + public readonly static BlockInfo LillyPad; + public readonly static BlockInfo NetherBrick; + public readonly static BlockInfo NetherBrickFence; + public readonly static BlockInfo NetherBrickStairs; + public readonly static BlockInfo NetherWart; + public readonly static BlockInfo EnchantmentTable; + public readonly static BlockInfo BrewingStand; + public readonly static BlockInfo Cauldron; + public readonly static BlockInfo EndPortal; + public readonly static BlockInfo EndPortalFrame; + public readonly static BlockInfo EndStone; + public readonly static BlockInfo DragonEgg; + public readonly static BlockInfo RedstoneLampOff; + public readonly static BlockInfo RedstoneLampOn; + public readonly static BlockInfo DoubleWoodSlab; + public readonly static BlockInfo WoodSlab; + public readonly static BlockInfo CocoaPlant; + public readonly static BlockInfo SandstoneStairs; + public readonly static BlockInfo EmeraldOre; + public readonly static BlockInfo EnderChest; + public readonly static BlockInfo TripwireHook; + public readonly static BlockInfo Tripwire; + public readonly static BlockInfo EmeraldBlock; + public readonly static BlockInfo SpruceWoodStairs; + public readonly static BlockInfo BirchWoodStairs; + public readonly static BlockInfo JungleWoodStairs; + public readonly static BlockInfo CommandBlock; + public readonly static BlockInfo BeaconBlock; + public readonly static BlockInfo CobblestoneWall; + public readonly static BlockInfo FlowerPot; + public readonly static BlockInfo Carrots; + public readonly static BlockInfo Potatoes; + public readonly static BlockInfo WoodButton; + public readonly static BlockInfo Heads; + public readonly static BlockInfo Anvil; + public readonly static BlockInfo TrappedChest; + public readonly static BlockInfo WeightedPressurePlateLight; + public readonly static BlockInfo WeightedPressurePlateHeavy; + public readonly static BlockInfo RedstoneComparatorInactive; + public readonly static BlockInfo RedstoneComparatorActive; + public readonly static BlockInfo DaylightSensor; + public readonly static BlockInfo RedstoneBlock; + public readonly static BlockInfo NetherQuartzOre; + public readonly static BlockInfo Hopper; + public readonly static BlockInfo QuartzBlock; + public readonly static BlockInfo QuartzStairs; + public readonly static BlockInfo ActivatorRail; + public readonly static BlockInfo Dropper; + public readonly static BlockInfo StainedClay; + public readonly static BlockInfo StainedGlassPane; + public readonly static BlockInfo Leaves2; + public readonly static BlockInfo Wood2; + public readonly static BlockInfo AcaciaWoodStairs; + public readonly static BlockInfo DarkOakWoodStairs; + public readonly static BlockInfo SlimeBlock; + public readonly static BlockInfo Barrier; + public readonly static BlockInfo IronTrapdoor; + public readonly static BlockInfo Prismarine; + public readonly static BlockInfo SeaLantern; + public readonly static BlockInfo HayBlock; + public readonly static BlockInfo Carpet; + public readonly static BlockInfo HardenedClay; + public readonly static BlockInfo CoalBlock; + public readonly static BlockInfo PackedIce; + public readonly static BlockInfo LargeFlowers; + public readonly static BlockInfo StandingBanner; + public readonly static BlockInfo WallBanner; + public readonly static BlockInfo InvertedDaylightSensor; + public readonly static BlockInfo RedSandstone; + public readonly static BlockInfo RedSandstoneStairs; + public readonly static BlockInfo DoubleRedSandstoneSlab; + public readonly static BlockInfo RedSandstoneSlab; + public readonly static BlockInfo SpruceFenceGate; + public readonly static BlockInfo BirchFenceGate; + public readonly static BlockInfo JungleFenceGate; + public readonly static BlockInfo DarkOakFenceGate; + public readonly static BlockInfo AcaciaFenceGate; + public readonly static BlockInfo SpruceFence; + public readonly static BlockInfo BirchFence; + public readonly static BlockInfo JungleFence; + public readonly static BlockInfo DarkOakFence; + public readonly static BlockInfo AcaciaFence; + public readonly static BlockInfo SpruceDoor; + public readonly static BlockInfo BirchDoor; + public readonly static BlockInfo JungleDoor; + public readonly static BlockInfo AcaciaDoor; + public readonly static BlockInfo DarkOakDoor; + public readonly static BlockInfo EndRod; + public readonly static BlockInfo ChorusPlant; + public readonly static BlockInfo ChorusFlower; + public readonly static BlockInfo PurpurBlock; + public readonly static BlockInfo PurpurPillar; + public readonly static BlockInfo PurpurStairs; + public readonly static BlockInfo PurpurDoubleSlab; + public readonly static BlockInfo PurpurSlab; + public readonly static BlockInfo EndStoneBricks; + public readonly static BlockInfo BeetrootSeeds; + public readonly static BlockInfo GrassPath; + public readonly static BlockInfo EndGateway; + public readonly static BlockInfo RepeatingCommandBlock; + public readonly static BlockInfo ChainCommandBlock; + public readonly static BlockInfo FrostedIce; + public readonly static BlockInfo MagmaBlock; + public readonly static BlockInfo NetherWartBlock; + public readonly static BlockInfo RedNetherBrick; + public readonly static BlockInfo BoneBlock; + public readonly static BlockInfo StructureVoid; + public readonly static BlockInfo Observer; + public readonly static BlockInfo WhiteShulkerBox; + public readonly static BlockInfo OrangeShulkerBox; + public readonly static BlockInfo MagentaShulkerBox; + public readonly static BlockInfo LightBlueShulkerBox; + public readonly static BlockInfo YellowShulkerBox; + public readonly static BlockInfo LimeShulkerBox; + public readonly static BlockInfo PinkShulkerBox; + public readonly static BlockInfo GrayShulkerBox; + public readonly static BlockInfo LightGrayShulkerBox; + public readonly static BlockInfo CyanShulkerBox; + public readonly static BlockInfo PurpleShulkerBox; + public readonly static BlockInfo BlueShulkerBox; + public readonly static BlockInfo BrownShulkerBox; + public readonly static BlockInfo GreenShulkerBox; + public readonly static BlockInfo RedShulkerBox; + public readonly static BlockInfo BlackShulkerBox; + public readonly static BlockInfo WhiteGlazedTerracotta; + public readonly static BlockInfo OrangeGlazedTerracotta; + public readonly static BlockInfo MagentaGlazedTerracotta; + public readonly static BlockInfo LightBlueGlazedTerracotta; + public readonly static BlockInfo YellowGlazedTerracotta; + public readonly static BlockInfo LimeGlazedTerracotta; + public readonly static BlockInfo PinkGlazedTerracotta; + public readonly static BlockInfo GrayGlazedTerracotta; + public readonly static BlockInfo LightGrayGlazedTerracotta; + public readonly static BlockInfo CyanGlazedTerracotta; + public readonly static BlockInfo PurpleGlazedTerracotta; + public readonly static BlockInfo BlueGlazedTerracotta; + public readonly static BlockInfo BrownGlazedTerracotta; + public readonly static BlockInfo GreenGlazedTerracotta; + public readonly static BlockInfo RedGlazedTerracotta; + public readonly static BlockInfo BlackGlazedTerracotta; + public readonly static BlockInfo Concrete; + public readonly static BlockInfo ConcretePowder; + public readonly static BlockInfo StructureBlock; + + static BlockInfo() + { + _blockTable = new BlockInfo[MAX_BLOCKS]; + _nameIdLookup = new Dictionary(); + _opacityTable = new int[MAX_BLOCKS]; + _luminanceTable = new int[MAX_BLOCKS]; + + _blockTableCache = new CacheTableArray(_blockTable); + _opacityTableCache = new CacheTableArray(_opacityTable); + _luminanceTableCache = new CacheTableArray(_luminanceTable); + + Air = new BlockInfo(0, "minecraft:air", "Air") { Opacity = 0, State = BlockState.NONSOLID }; + Stone = new BlockInfo(1, "minecraft:stone", "Stone") { DataLimits = new BlockDataLimits(0, 6) }; + Grass = new BlockInfo(2, "minecraft:grass", "Grass") { Tick = 10, DataLimits = new BlockDataLimits(0, 2) }; + Dirt = new BlockInfo(3, "minecraft:dirt", "Dirt") { DataLimits = new BlockDataLimits(0, 2) }; + Cobblestone = new BlockInfo(4, "minecraft:cobblestone", "Cobblestone"); + WoodPlank = new BlockInfo(5, "minecraft:planks", "Wooden Plank") { DataLimits = new BlockDataLimits(0, 5) }; + Sapling = new BlockInfo(6, "minecraft:sapling", "Sapling") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 5, 0x8) }; + Bedrock = new BlockInfo(7, "minecraft:bedrock", "Bedrock"); + Water = new BlockInfo(8, "minecraft:flowing_water", "Water") { Opacity = 3, State = BlockState.FLUID, Tick = 5, DataLimits = new BlockDataLimits(0, 7, 0x8) }; + StationaryWater = new BlockInfo(9, "minecraft:water", "Stationary Water") { Opacity = 3, State = BlockState.FLUID, DataLimits = new BlockDataLimits(0, 15) }; + Lava = new BlockInfo(10, "minecraft:flowing_lava", "Lava") { Opacity = 0, Luminance = MAX_LUMINANCE, State = BlockState.FLUID, Tick = 30, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 7, 0x8) }; + StationaryLava = new BlockInfo(11, "minecraft:lava", "Stationary Lava") { Opacity = 0, Luminance = MAX_LUMINANCE, State = BlockState.FLUID, DataLimits = new BlockDataLimits(0, 15), Tick = 10, TransmitsLight = false }; + Sand = new BlockInfo(12, "minecraft:sand", "Sand") { Tick = 3, DataLimits = new BlockDataLimits(0, 1) }; + Gravel = new BlockInfo(13, "minecraft:gravel", "Gravel") { Tick = 3 }; + GoldOre = new BlockInfo(14, "minecraft:gold_ore", "Gold Ore"); + IronOre = new BlockInfo(15, "minecraft:iron_ore", "Iron Ore"); + CoalOre = new BlockInfo(16, "minecraft:coal_ore", "Coal Ore"); + Wood = new BlockInfo(17, "minecraft:log", "Wood") { DataLimits = new BlockDataLimits(0, 15) }; + Leaves = new BlockInfo(18, "minecraft:leaves", "Leaves") { Opacity = 1, Tick = 10, DataLimits = new BlockDataLimits(0, 3, 0xC) }; + Sponge = new BlockInfo(19, "minecraft:sponge", "Sponge") { DataLimits = new BlockDataLimits(0, 1) }; + Glass = new BlockInfo(20, "minecraft:glass", "Glass") { Opacity = 0 }; + LapisOre = new BlockInfo(21, "minecraft:lapis_ore", "Lapis Lazuli Ore"); + LapisBlock = new BlockInfo(22, "minecraft:lapis_block", "Lapis Lazuli Block"); + Dispenser = new BlockInfo(23, "minecraft:dispenser", "Dispenser") { Tick = 4, TileEntityName = "Trap", DataLimits = new BlockDataLimits(0, 5, 0x8) }; + Sandstone = new BlockInfo(24, "minecraft:sandstone", "Sandstone") { DataLimits = new BlockDataLimits(0, 2) }; + NoteBlock = new BlockInfo(25, "minecraft:noteblock", "Note Block") { TileEntityName = "Music" }; + Bed = new BlockInfo(26, "minecraft:bed", "Bed") { Opacity = 0, DataLimits = new BlockDataLimits(0, 3, 0xC) }; + PoweredRail = new BlockInfo(27, "minecraft:golden_rail", "Powered Rail") { Opacity = 0, State = BlockState.NONSOLID, DataLimits = new BlockDataLimits(0, 5, 0x8) }; + DetectorRail = new BlockInfo(28, "minecraft:detector_rail", "Detector Rail") { Opacity = 0, State = BlockState.NONSOLID, Tick = 20, DataLimits = new BlockDataLimits(0, 5, 0x8) }; + StickyPiston = new BlockInfo(29, "minecraft:sticky_piston", "Sticky Piston") { Opacity = 0, DataLimits = new BlockDataLimits(0, 5, 0x8) }; + Cobweb = new BlockInfo(30, "minecraft:web", "Cobweb") { Opacity = 0, State = BlockState.NONSOLID }; + TallGrass = new BlockInfo(31, "minecraft:tallgrass", "Tall Grass") { Opacity = 0, State = BlockState.NONSOLID, DataLimits = new BlockDataLimits(0, 2, 0) }; + DeadShrub = new BlockInfo(32, "minecraft:deadbush", "Dead Shrub") { Opacity = 0, State = BlockState.NONSOLID }; + Piston = new BlockInfo(33, "minecraft:piston", "Piston") { Opacity = 0, DataLimits = new BlockDataLimits(0, 5, 0x8) }; + PistonHead = new BlockInfo(34, "minecraft:piston_head", "Piston Head") { Opacity = 0, DataLimits = new BlockDataLimits(0, 5, 0x8) }; + Wool = new BlockInfo(35, "minecraft:wool", "Wool") { DataLimits = new BlockDataLimits(0, 15) }; + PistonExtension = new BlockInfo(36, "minecraft:piston_extension", "Piston Extension") { Opacity = 0, TileEntityName = "Piston", DataLimits = new BlockDataLimits(0, 19) }; + YellowFlower = new BlockInfo(37, "minecraft:yellow_flower", "Yellow Flower") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 0) }; + RedRose = new BlockInfo(38, "minecraft:red_flower", "Red Rose") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 8) }; + BrownMushroom = new BlockInfo(39, "minecraft:brown_mushroom", "Brown Mushroom") { Opacity = 0, Luminance = 1, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 15) }; + RedMushroom = new BlockInfo(40, "minecraft:red_mushroom", "Red Mushroom") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 15) }; + GoldBlock = new BlockInfo(41, "minecraft:gold_block", "Gold Block"); + IronBlock = new BlockInfo(42, "minecraft:iron_block", "Iron Block"); + DoubleStoneSlab = new BlockInfo(43, "minecraft:double_stone_slab", "Double Slab") { DataLimits = new BlockDataLimits(0, 9, 0x8) }; + StoneSlab = new BlockInfo(44, "minecraft:stone_slab", "Slab") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 9, 0x8) }; + BrickBlock = new BlockInfo(45, "minecraft:brick_block", "Brick Block"); + TNT = new BlockInfo(46, "minecraft:tnt", "TNT") { DataLimits = new BlockDataLimits(0, 1) }; + Bookshelf = new BlockInfo(47, "minecraft:bookshelf", "Bookshelf"); + MossStone = new BlockInfo(48, "minecraft:mossy_cobblestone", "Moss Stone"); + Obsidian = new BlockInfo(49, "minecraft:obsidian", "Obsidian"); + Torch = new BlockInfo(50, "minecraft:torch", "Torch") { Opacity = 0, Luminance = MAX_LUMINANCE - 1, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(1, 5) }; + Fire = new BlockInfo(51, "minecraft:fire", "Fire") { Opacity = 0, Luminance = MAX_LUMINANCE, State = BlockState.NONSOLID, Tick = 40, DataLimits = new BlockDataLimits(0, 15) }; + MonsterSpawner = new BlockInfo(52, "minecraft:mob_spawner", "Monster Spawner") { Opacity = 0, TileEntityName = "MobSpawner" }; + WoodStairs = new BlockInfo(53, "minecraft:oak_stairs", "Wooden Stairs") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 3, 0x4) }; + Chest = new BlockInfo(54, "minecraft:chest", "Chest") { Opacity = 0, TileEntityName = "Chest", DataLimits = new BlockDataLimits(2, 5) }; + RedstoneWire = new BlockInfo(55, "minecraft:redstone_wire", "Redstone Wire") { Opacity = 0, State = BlockState.NONSOLID, DataLimits = new BlockDataLimits(0, 15) }; + DiamondOre = new BlockInfo(56, "minecraft:diamond_ore", "Diamond Ore"); + DiamondBlock = new BlockInfo(57, "minecraft:diamond_block", "Diamond Block"); + CraftTable = new BlockInfo(58, "minecraft:crafting_table", "Crafting Table"); + Crops = new BlockInfo(59, "minecraft:wheat", "Crops") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 7) }; + Farmland = new BlockInfo(60, "minecraft:farmland", "Farmland") { Opacity = 0, Tick = 10, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 7) }; + Furnace = new BlockInfo(61, "minecraft:furnace", "Furnace") { TileEntityName = "Furnace", DataLimits = new BlockDataLimits(2, 5, 0) }; + BurningFurnace = new BlockInfo(62, "minecraft:lit_furnace", "Burning Furnace") { Luminance = MAX_LUMINANCE - 1, TileEntityName = "Furnace", DataLimits = new BlockDataLimits(2, 5, 0) }; + SignPost = new BlockInfo(63, "minecraft:standing_sign", "Sign Post") { Opacity = 0, State = BlockState.NONSOLID, BlocksFluid = true, TileEntityName = "Sign", DataLimits = new BlockDataLimits(0, 15) }; + WoodDoor = new BlockInfo(64, "minecraft:wooden_door", "Wooden Door") { Opacity = 0, DataLimits = new BlockDataLimits(0, 0, 0xF) }; + Ladder = new BlockInfo(65, "minecraft:ladder", "Ladder") { Opacity = 0, DataLimits = new BlockDataLimits(2, 5, 0) }; + Rails = new BlockInfo(66, "minecraft:rail", "Rails") { Opacity = 0, State = BlockState.NONSOLID, DataLimits = new BlockDataLimits(0, 9, 0) }; + CobbleStairs = new BlockInfo(67, "minecraft:stone_stairs", "Cobblestone Stairs") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 3, 0x4) }; + WallSign = new BlockInfo(68, "minecraft:wall_sign", "Wall Sign") { Opacity = 0, State = BlockState.NONSOLID, BlocksFluid = true, TileEntityName = "Sign", DataLimits = new BlockDataLimits(2, 5) }; + Lever = new BlockInfo(69, "minecraft:lever", "Lever") { Opacity = 0, State = BlockState.NONSOLID, DataLimits = new BlockDataLimits(0, 7, 0x8) }; + StonePlate = new BlockInfo(70, "minecraft:stone_pressure_plate", "Stone Pressure Plate") { Opacity = 0, State = BlockState.NONSOLID, Tick = 20, DataLimits = new BlockDataLimits(0, 0, 0x1) }; + IronDoor = new BlockInfo(71, "minecraft:iron_door", "Iron Door") { Opacity = 0, DataLimits = new BlockDataLimits(0, 0, 0xF) }; + WoodPlate = new BlockInfo(72, "minecraft:wooden_pressure_plate", "Wooden Pressure Plate") { Opacity = 0, State = BlockState.NONSOLID, Tick = 20, DataLimits = new BlockDataLimits(0, 0, 0x1) }; + RedstoneOre = new BlockInfo(73, "minecraft:redstone_ore", "Redstone Ore") { Tick = 30 }; + GlowRedstoneOre = new BlockInfo(74, "minecraft:lit_redstone_ore", "Glowing Redstone Ore") { Luminance = 9, Tick = 30 }; + RedstoneTorch = new BlockInfo(75, "minecraft:unlit_redstone_torch", "Redstone Torch (Off)") { Opacity = 0, State = BlockState.NONSOLID, Tick = 2, DataLimits = new BlockDataLimits(1, 5) }; + RedstoneTorchOn = new BlockInfo(76, "minecraft:redstone_torch", "Redstone Torch (On)") { Opacity = 0, Luminance = 7, State = BlockState.NONSOLID, Tick = 2, DataLimits = new BlockDataLimits(1, 5) }; + StoneButton = new BlockInfo(77, "minecraft:stone_button", "Stone Button") { Opacity = 0, State = BlockState.NONSOLID, DataLimits = new BlockDataLimits(0, 5, 0x8) }; + Snow = new BlockInfo(78, "minecraft:snow_layer", "Snow") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 7, 0) }; + Ice = new BlockInfo(79, "minecraft:ice", "Ice") { Opacity = 3, Tick = 10 }; + SnowBlock = new BlockInfo(80, "minecraft:snow", "Snow Block") { Tick = 10 }; + Cactus = new BlockInfo(81, "minecraft:cactus", "Cactus") { Opacity = 0, Tick = 10, BlocksFluid = true, DataLimits = new BlockDataLimits(0, 15) }; + ClayBlock = new BlockInfo(82, "minecraft:clay", "Clay Block"); + SugarCane = new BlockInfo(83, "minecraft:reeds", "Sugar Cane") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 15) }; + Jukebox = new BlockInfo(84, "minecraft:jukebox", "Jukebox") { DataLimits = new BlockDataLimits(0, 1) }; + Fence = new BlockInfo(85, "minecraft:fence", "Fence") { Opacity = 0 }; + Pumpkin = new BlockInfo(86, "minecraft:pumpkin", "Pumpkin") { DataLimits = new BlockDataLimits(0, 3, 0x4) }; + Netherrack = new BlockInfo(87, "minecraft:netherrack", "Netherrack"); + SoulSand = new BlockInfo(88, "minecraft:soul_sand", "Soul Sand"); + Glowstone = new BlockInfo(89, "minecraft:glowstone", "Glowstone Block") { Luminance = MAX_LUMINANCE }; + Portal = new BlockInfo(90, "minecraft:portal", "Portal") { Opacity = 0, Luminance = 11, State = BlockState.NONSOLID, DataLimits = new BlockDataLimits(0, 2) }; + JackOLantern = new BlockInfo(91, "minecraft:lit_pumpkin", "Jack-O-Lantern") { Luminance = MAX_LUMINANCE, DataLimits = new BlockDataLimits(0, 3, 0x4) }; + CakeBlock = new BlockInfo(92, "minecraft:cake", "Cake Block") { Opacity = 0, DataLimits = new BlockDataLimits(0, 6) }; + RedstoneRepeater = new BlockInfo(93, "minecraft:unpowered_repeater", "Redstone Repeater (Off)") { Opacity = 0, Tick = 10, DataLimits = new BlockDataLimits(0, 0, 0xF) }; + RedstoneRepeaterOn = new BlockInfo(94, "minecraft:powered_repeater", "Redstone Repeater (On)") { Opacity = 0, Luminance = 7, Tick = 10, DataLimits = new BlockDataLimits(0, 0, 0xF) }; + //LockedChest = new BlockInfo(95, "minecraft:chest_locked_aprilfools_super_old_legacy_we_should_not_even_have_this", "Locked Chest") { Luminance = MAX_LUMINANCE, Tick = 10 }; + StainedGlass = new BlockInfo(95, "minecraft:stained_glass", "Stained Glass") { Opacity = 0, DataLimits = new BlockDataLimits(0, 15) }; + Trapdoor = new BlockInfo(96, "minecraft:trapdoor", "Trapdoor") { Opacity = 0, DataLimits = new BlockDataLimits(0, 3, 0xC) }; + SilverfishStone = new BlockInfo(97, "minecraft:monster_egg", "Stone with Silverfish") { DataLimits = new BlockDataLimits(0, 5) }; + StoneBrick = new BlockInfo(98, "minecraft:stonebrick", "Stone Brick") { DataLimits = new BlockDataLimits(0, 3) }; + HugeRedMushroom = new BlockInfo(99, "minecraft:brown_mushroom_block", "Huge Red Mushroom") { DataLimits = new BlockDataLimits(0, 15) }; // VERIFYME data values + HugeBrownMushroom = new BlockInfo(100, "minecraft:red_mushroom_block", "Huge Brown Mushroom") { DataLimits = new BlockDataLimits(0, 15) }; // VERIFYME data values + IronBars = new BlockInfo(101, "minecraft:iron_bars", "Iron Bars") { Opacity = 0 }; + GlassPane = new BlockInfo(102, "minecraft:glass_pane", "Glass Pane") { Opacity = 0 }; + Melon = new BlockInfo(103, "minecraft:melon_block", "Melon"); + PumpkinStem = new BlockInfo(104, "minecraft:pumpkin_stem", "Pumpkin Stem") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 7) }; + MelonStem = new BlockInfo(105, "minecraft:melon_stem", "Melon Stem") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 7) }; + Vines = new BlockInfo(106, "minecraft:vine", "Vines") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 0, 0xF) }; + FenceGate = new BlockInfo(107, "minecraft:fence_gate", "Fence Gate") { Opacity = 0, DataLimits = new BlockDataLimits(0, 3, 0xC) }; // VERIFYME data values + BrickStairs = new BlockInfo(108, "minecraft:brick_stairs", "Brick Stairs") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 3, 0x4) }; + StoneBrickStairs = new BlockInfo(109, "minecraft:stone_brick_stairs", "Stone Brick Stairs") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 3, 0x4) }; + Mycelium = new BlockInfo(110, "minecraft:mycelium", "Mycelium") { Tick = 10 }; + LillyPad = new BlockInfo(111, "minecraft:waterlily", "Lilly Pad") { Opacity = 0, State = BlockState.NONSOLID }; + NetherBrick = new BlockInfo(112, "minecraft:nether_brick", "Nether Brick"); + NetherBrickFence = new BlockInfo(113, "minecraft:nether_brick_fence", "Nether Brick Fence") { Opacity = 0 }; + NetherBrickStairs = new BlockInfo(114, "minecraft:nether_brick_stairs", "Nether Brick Stairs") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 3, 0x4) }; + NetherWart = new BlockInfo(115, "minecraft:nether_wart", "Nether Wart") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 3) }; + EnchantmentTable = new BlockInfo(116, "minecraft:enchanting_table", "Enchantment Table") { Opacity = 0, TileEntityName = "EnchantTable" }; + BrewingStand = new BlockInfo(117, "minecraft:brewing_stand", "Brewing Stand") { Opacity = 0, TileEntityName = "Cauldron", DataLimits = new BlockDataLimits(0, 0, 0x7) }; + Cauldron = new BlockInfo(118, "minecraft:cauldron", "Cauldron") { Opacity = 0, DataLimits = new BlockDataLimits(0, 3, 0) }; + EndPortal = new BlockInfo(119, "minecraft:end_portal", "End Portal") { Opacity = 0, Luminance = MAX_LUMINANCE, State = BlockState.NONSOLID, TileEntityName = "Airportal", DataLimits = new BlockDataLimits(0, 3, 0x4) }; + EndPortalFrame = new BlockInfo(120, "minecraft:end_portal_frame", "End Portal Frame") { Luminance = MAX_LUMINANCE, DataLimits = new BlockDataLimits(0, 0, 0x7) }; + EndStone = new BlockInfo(121, "minecraft:end_stone", "End Stone"); + DragonEgg = new BlockInfo(122, "minecraft:dragon_egg", "Dragon Egg") { Opacity = 0, Luminance = 1, Tick = 3 }; + RedstoneLampOff = new BlockInfo(123, "minecraft:redstone_lamp", "Redstone Lamp (Off)") { Tick = 2 }; + RedstoneLampOn = new BlockInfo(124, "minecraft:lit_redstone_lamp", "Redstone Lamp (On)") { Luminance = 15, Tick = 2 }; + DoubleWoodSlab = new BlockInfo(125, "minecraft:double_wooden_slab", "Double Wood Slab") { DataLimits = new BlockDataLimits(0, 5) }; + WoodSlab = new BlockInfo(126, "minecraft:wooden_slab", "Wood Slab") { TransmitsLight = false, DataLimits = new BlockDataLimits(0, 5, 0x8) }; + CocoaPlant = new BlockInfo(127, "minecraft:cocoa", "Cocoa Plant") { Luminance = 2, Opacity = 0, DataLimits = new BlockDataLimits(0, 3, 0xC) }; + SandstoneStairs = new BlockInfo(128, "minecraft:sandstone_stairs", "Sandstone Stairs") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 3, 0x4) }; + EmeraldOre = new BlockInfo(129, "minecraft:emerald_ore", "Emerald Ore"); + EnderChest = new BlockInfo(130, "minecraft:ender_chest", "Ender Chest") { Luminance = 7, Opacity = 0, TileEntityName = "EnderChest", DataLimits = new BlockDataLimits(2, 5) }; + TripwireHook = new BlockInfo(131, "minecraft:tripwire_hook", "Tripwire Hook") { Opacity = 0, State = BlockState.NONSOLID, DataLimits = new BlockDataLimits(0, 3, 0xC) }; + Tripwire = new BlockInfo(132, "minecraft:tripwire", "Tripwire") { Opacity = 0, State = BlockState.NONSOLID, DataLimits = new BlockDataLimits(0, 0, 0xF) }; + EmeraldBlock = new BlockInfo(133, "minecraft:emerald_block", "Emerald Block"); + SpruceWoodStairs = new BlockInfo(134, "minecraft:spruce_stairs", "Sprice Wood Stairs") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 3, 0x4) }; + BirchWoodStairs = new BlockInfo(135, "minecraft:birch_stairs", "Birch Wood Stairs") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 3, 0x4) }; + JungleWoodStairs = new BlockInfo(136, "minecraft:jungle_stairs", "Jungle Wood Stairs") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 3, 0x4) }; + CommandBlock = new BlockInfo(137, "minecraft:command_block", "Command Block") { TileEntityName = "Control", DataLimits = new BlockDataLimits(0, 13) }; + BeaconBlock = new BlockInfo(138, "minecraft:beacon", "Beacon Block") { Opacity = 0, Luminance = MAX_LUMINANCE, TileEntityName = "Beacon" }; + CobblestoneWall = new BlockInfo(139, "minecraft:cobblestone_wall", "Cobblestone Wall") { Opacity = 0, DataLimits = new BlockDataLimits(0, 1) }; + FlowerPot = new BlockInfo(140, "minecraft:flower_pot", "Flower Pot") { Opacity = 0, DataLimits = new BlockDataLimits(0, 15) }; // VERIFYME data values + Carrots = new BlockInfo(141, "minecraft:carrots", "Carrots") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 7) }; + Potatoes = new BlockInfo(142, "minecraft:potatoes", "Potatoes") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 7) }; + WoodButton = new BlockInfo(143, "minecraft:wooden_button", "Wooden Button") { Opacity = 0, State = BlockState.NONSOLID, DataLimits = new BlockDataLimits(0, 5, 0x8) }; + Heads = new BlockInfo(144, "minecraft:skull", "Heads") { Opacity = 0, DataLimits = new BlockDataLimits(0, 5, 0x8) }; // VERIFYME data values + Anvil = new BlockInfo(145, "minecraft:anvil", "Anvil") { Opacity = 0, DataLimits = new BlockDataLimits(0, 3, 0xC) }; + TrappedChest = new BlockInfo(146, "minecraft:trapped_chest", "Trapped Chest") { Opacity = 0, Tick = 10, TileEntityName = "Chest", DataLimits = new BlockDataLimits(2, 5) }; + WeightedPressurePlateLight = new BlockInfo(147, "minecraft:light_weighted_pressure_plate", "Weighted Pressure Plate (Light)") { Opacity = 0, State = BlockState.NONSOLID, Tick = 20, DataLimits = new BlockDataLimits(0, 15) }; + WeightedPressurePlateHeavy = new BlockInfo(148, "minecraft:heavy_weighted_pressure_plate", "Weighted Pressure Plate (Heavy)") { Opacity = 0, State = BlockState.NONSOLID, Tick = 20, DataLimits = new BlockDataLimits(0, 15) }; + RedstoneComparatorInactive = new BlockInfo(149, "minecraft:unpowered_comparator", "Redstone Comparator (Inactive)") { Opacity = 0, Tick = 10, DataLimits = new BlockDataLimits(0, 3, 0xC) }; + RedstoneComparatorActive = new BlockInfo(150, "minecraft:powered_comparator", "Redstone Comparator (Active)") { Opacity = 0, Luminance = 9, Tick = 10, DataLimits = new BlockDataLimits(0, 3, 0xC) }; + DaylightSensor = new BlockInfo(151, "minecraft:daylight_detector", "Daylight Sensor") { Opacity = 0, Tick = 10, DataLimits = new BlockDataLimits(0, 15) }; + RedstoneBlock = new BlockInfo(152, "minecraft:redstone_block", "Block of Redstone") { Tick = 10 }; + NetherQuartzOre = new BlockInfo(153, "minecraft:quartz_ore", "Neither Quartz Ore"); + Hopper = new BlockInfo(154, "minecraft:hopper", "Hopper") { Opacity = 0, Tick = 10, TileEntityName = "Hopper", DataLimits = new BlockDataLimits(0, 5, 0x8) }; + QuartzBlock = new BlockInfo(155, "minecraft:quartz_block", "Block of Quartz") { DataLimits = new BlockDataLimits(0, 4, 0) }; + QuartzStairs = new BlockInfo(156, "minecraft:quartz_stairs", "Quartz Stairs") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 3, 0x4) }; + ActivatorRail = new BlockInfo(157, "minecraft:activator_rail", "Activator Rail") { Opacity = 0, State = BlockState.NONSOLID, Tick = 10, DataLimits = new BlockDataLimits(0, 5, 0x8) }; + Dropper = new BlockInfo(158, "minecraft:dropper", "Dropper") { Tick = 10, TileEntityName = "Dropper", DataLimits = new BlockDataLimits(0, 5, 0x8) }; + StainedClay = new BlockInfo(159, "minecraft:stained_hardened_clay", "Stained Clay") { DataLimits = new BlockDataLimits(0, 15) }; + StainedGlassPane = new BlockInfo(160, "minecraft:stained_glass_pane", "Stained Glass Pane") { Opacity = 0, DataLimits = new BlockDataLimits(0, 15) }; + + // TODO fill in details + Leaves2 = new BlockInfo(161, "minecraft:leaves2", "Leaves (Acacia/Dark Oak)") { DataLimits = new BlockDataLimits(0, 1, 0xC) }; + Wood2 = new BlockInfo(162, "minecraft:log2", "Wood (Acacia/Dark Oak)") { DataLimits = new BlockDataLimits(0, 13) }; + AcaciaWoodStairs = new BlockInfo(163, "minecraft:acacia_stairs", "Acacia Wood Stairs") { DataLimits = new BlockDataLimits(0, 3, 0x4) }; + DarkOakWoodStairs = new BlockInfo(164, "minecraft:dark_oak_stairs", "Dark Oak Wood Stairs") { DataLimits = new BlockDataLimits(0, 3, 0x4) }; + SlimeBlock = new BlockInfo(165, "minecraft:slime", "Slime Block"); + Barrier = new BlockInfo(166, "minecraft:barrier", "Barrier"); + IronTrapdoor = new BlockInfo(167, "minecraft:iron_trapdoor", "Iron Trapdoor") { DataLimits = new BlockDataLimits(0, 15) }; + Prismarine = new BlockInfo(168, "minecraft:prismarine", "Prismarine") { DataLimits = new BlockDataLimits(0, 2) }; + SeaLantern = new BlockInfo(169, "minecraft:sea_lantern", "Sea Lantern"); + + HayBlock = new BlockInfo(170, "minecraft:hay_block", "Hay Block") { DataLimits = new BlockDataLimits(0, 8) }; + Carpet = new BlockInfo(171, "minecraft:carpet", "Carpet") { Opacity = 0, TransmitsLight = false, DataLimits = new BlockDataLimits(0, 15) }; + HardenedClay = new BlockInfo(172, "minecraft:hardened_clay", "Hardened Clay"); + CoalBlock = new BlockInfo(173, "minecraft:coal_block", "Block of Coal") { DataLimits = new BlockDataLimits(0, 1) }; + + // TODO fill in details + PackedIce = new BlockInfo(174, "minecraft:packed_ice", "Packed Ice"); + LargeFlowers = new BlockInfo(175, "minecraft:double_plant", "Large Flowers") { DataLimits = new BlockDataLimits(0, 5, 0x8) }; + StandingBanner = new BlockInfo(176, "minecraft:standing_banner", "Standing Banner") { DataLimits = new BlockDataLimits(0, 15) }; + WallBanner = new BlockInfo(177, "minecraft:wall_banner", "Wall Banner") { DataLimits = new BlockDataLimits(2, 5) }; + InvertedDaylightSensor = new BlockInfo(178, "minecraft:daylight_detector_inverted", "Inverted Daylight Sensor") { DataLimits = new BlockDataLimits(0, 15) }; + RedSandstone = new BlockInfo(179, "minecraft:red_sandstone", "Red Sandstone") { DataLimits = new BlockDataLimits(0, 2) }; + RedSandstoneStairs = new BlockInfo(180, "minecraft:red_sandstone_stairs", "Red Sandstone Stairs") { DataLimits = new BlockDataLimits(0, 3, 0x4) }; + DoubleRedSandstoneSlab = new BlockInfo(181, "minecraft:double_stone_slab2", "Double Red Sandstone Slab") { DataLimits = new BlockDataLimits(0, 0, 0x8) }; + RedSandstoneSlab = new BlockInfo(182, "minecraft:stone_slab2", "Red Sandstone Slab") { DataLimits = new BlockDataLimits(0, 0, 0x8) }; + SpruceFenceGate = new BlockInfo(183, "minecraft:spruce_fence_gate", "Spruce Fence Gate") { DataLimits = new BlockDataLimits(0, 3, 0xC) }; // VERIFYME data values + BirchFenceGate = new BlockInfo(184, "minecraft:birch_fence_gate", "Birch Fence Gate") { DataLimits = new BlockDataLimits(0, 3, 0xC) }; // VERIFYME data values + JungleFenceGate = new BlockInfo(185, "minecraft:jungle_fence_gate", "Jungle Fence Gate") { DataLimits = new BlockDataLimits(0, 3, 0xC) }; // VERIFYME data values + DarkOakFenceGate = new BlockInfo(186, "minecraft:dark_oak_fence_gate", "Dark Oak Fence Gate") { DataLimits = new BlockDataLimits(0, 3, 0xC) }; // VERIFYME data values + AcaciaFenceGate = new BlockInfo(187, "minecraft:acacia_fence_gate", "Acacia Fence Gate") { DataLimits = new BlockDataLimits(0, 3, 0xC) }; // VERIFYME data values + SpruceFence = new BlockInfo(188, "minecraft:spruce_fence", "Spruce Fence"); + BirchFence = new BlockInfo(189, "minecraft:birch_fence", "Birch Fence"); + JungleFence = new BlockInfo(190, "minecraft:jungle_fence", "Jungle Fence"); + DarkOakFence = new BlockInfo(191, "minecraft:dark_oak_fence", "Dark Oak Fence"); + AcaciaFence = new BlockInfo(192, "minecraft:acacia_fence", "Acacia Fence"); + SpruceDoor = new BlockInfo(193, "minecraft:spruce_door", "Spruce Door") { DataLimits = new BlockDataLimits(0, 0, 0xF) }; + BirchDoor = new BlockInfo(194, "minecraft:birch_door", "Birch Door") { DataLimits = new BlockDataLimits(0, 0, 0xF) }; + JungleDoor = new BlockInfo(195, "minecraft:jungle_door", "Jungle Door") { DataLimits = new BlockDataLimits(0, 0, 0xF) }; + AcaciaDoor = new BlockInfo(196, "minecraft:acacia_door", "Acacia Door") { DataLimits = new BlockDataLimits(0, 0, 0xF) }; + DarkOakDoor = new BlockInfo(197, "minecraft:dark_oak_door", "Dark Oak Door") { DataLimits = new BlockDataLimits(0, 0, 0xF) }; + + // TODO details + EndRod = new BlockInfo(198, "minecraft:end_rod", "End Rod") { DataLimits = new BlockDataLimits(0, 5) }; + ChorusPlant = new BlockInfo(199, "minecraft:chorus_plant", "Chorus Plant"); + ChorusFlower = new BlockInfo(200, "minecraft:chorus_flower", "Chorus Flower") { DataLimits = new BlockDataLimits(0, 5) }; + PurpurBlock = new BlockInfo(201, "minecraft:purpur_block", "Purpur Block"); + PurpurPillar = new BlockInfo(202, "minecraft:purpur_pillar", "Purpur Pillar") { DataLimits = new BlockDataLimits(0, 8) }; + PurpurStairs = new BlockInfo(203, "minecraft:purpur_stairs", "Purpur Stairs") { DataLimits = new BlockDataLimits(0, 7) }; + PurpurDoubleSlab = new BlockInfo(204, "minecraft:purpur_double_slab", "Purpur Double Slab"); + PurpurSlab = new BlockInfo(205, "minecraft:purpur_slab", "Purpur Slab") { DataLimits = new BlockDataLimits(0, 8) }; + EndStoneBricks = new BlockInfo(206, "minecraft:end_bricks", "End Stone Bricks"); + BeetrootSeeds = new BlockInfo(207, "minecraft:beetroots", "Beetroot Seeds") { DataLimits = new BlockDataLimits(0, 3) }; + GrassPath = new BlockInfo(208, "minecraft:grass_path", "Grass Path"); + EndGateway = new BlockInfo(209, "minecraft:end_gateway", "End Gateway"); + + RepeatingCommandBlock = new BlockInfo(210, "minecraft:repeating_command_block", "Repeating Command Block") { DataLimits = new BlockDataLimits(0, 13) }; + ChainCommandBlock = new BlockInfo(211, "minecraft:chain_command_block", "Chain Command Block") { DataLimits = new BlockDataLimits(0, 13) }; + FrostedIce = new BlockInfo(212, "minecraft:frosted_ice", "Frosted Ice") { DataLimits = new BlockDataLimits(0, 3) }; + MagmaBlock = new BlockInfo(213, "minecraft:magma", "Magma Block"); + NetherWartBlock = new BlockInfo(214, "minecraft:nether_wart_block", "Nether Wart Block"); + RedNetherBrick = new BlockInfo(215, "minecraft:red_nether_brick", "Red Nether Brick"); + BoneBlock = new BlockInfo(216, "minecraft:bone_block", "Bone Block") { DataLimits = new BlockDataLimits(0, 8) }; + StructureVoid = new BlockInfo(217, "minecraft:structure_void", "Structure Void"); + Observer = new BlockInfo(218, "minecraft:observer", "Observer") { DataLimits = new BlockDataLimits(0, 13) }; + WhiteShulkerBox = new BlockInfo(219, "minecraft:white_shulker_box", "White Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + + OrangeShulkerBox = new BlockInfo(220, "minecraft:orange_shulker_box", "Orange Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + MagentaShulkerBox = new BlockInfo(221, "minecraft:magenta_shulker_box", "Magenta Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + LightBlueShulkerBox = new BlockInfo(222, "minecraft:light_blue_shulker_box", "Light Blue Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + YellowShulkerBox = new BlockInfo(223, "minecraft:yellow_shulker_box", "Yellow Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + LimeShulkerBox = new BlockInfo(224, "minecraft:lime_shulker_box", "Lime Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + PinkShulkerBox = new BlockInfo(225, "minecraft:pink_shulker_box", "Pink Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + GrayShulkerBox = new BlockInfo(226, "minecraft:gray_shulker_box", "Gray Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + LightGrayShulkerBox = new BlockInfo(227, "minecraft:silver_shulker_box", "Light Gray Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + CyanShulkerBox = new BlockInfo(228, "minecraft:cyan_shulker_box", "Cyan Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + PurpleShulkerBox = new BlockInfo(229, "minecraft:purple_shulker_box", "Purple Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + + BlueShulkerBox = new BlockInfo(230, "minecraft:blue_shulker_box", "Blue Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + BrownShulkerBox = new BlockInfo(231, "minecraft:brown_shulker_box", "Brown Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + GreenShulkerBox = new BlockInfo(232, "minecraft:green_shulker_box", "Green Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + RedShulkerBox = new BlockInfo(233, "minecraft:red_shulker_box", "Red Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + BlackShulkerBox = new BlockInfo(234, "minecraft:black_shulker_box", "Black Shulker Box") { DataLimits = new BlockDataLimits(0, 5) }; + WhiteGlazedTerracotta = new BlockInfo(235, "minecraft:white_glazed_terracotta", "White Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + OrangeGlazedTerracotta = new BlockInfo(236, "minecraft:orange_glazed_terracotta", "Orange Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + MagentaGlazedTerracotta = new BlockInfo(237, "minecraft:magenta_glazed_terracotta", "Magenta Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + LightBlueGlazedTerracotta = new BlockInfo(238, "minecraft:light_blue_glazed_terracotta", "Light Blue Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + YellowGlazedTerracotta = new BlockInfo(239, "minecraft:yellow_glazed_terracotta", "Yellow Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + + LimeGlazedTerracotta = new BlockInfo(240, "minecraft:lime_glazed_terracotta", "Lime Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + PinkGlazedTerracotta = new BlockInfo(241, "minecraft:pink_glazed_terracotta", "Pink Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + GrayGlazedTerracotta = new BlockInfo(242, "minecraft:gray_glazed_terracotta", "Gray Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + LightGrayGlazedTerracotta = new BlockInfo(243, "minecraft:silver_glazed_terracotta", "Light Gray Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + CyanGlazedTerracotta = new BlockInfo(244, "minecraft:cyan_glazed_terracotta", "Cyan Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + PurpleGlazedTerracotta = new BlockInfo(245, "minecraft:purple_glazed_terracotta", "Purple Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + BlueGlazedTerracotta = new BlockInfo(246, "minecraft:blue_glazed_terracotta", "Blue Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + BrownGlazedTerracotta = new BlockInfo(247, "minecraft:brown_glazed_terracotta", "Brown Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + GreenGlazedTerracotta = new BlockInfo(248, "minecraft:green_glazed_terracotta", "Green Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + RedGlazedTerracotta = new BlockInfo(249, "minecraft:red_glazed_terracotta", "Red Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + + BlackGlazedTerracotta = new BlockInfo(250, "minecraft:minecraft:black_glazed_terracotta", "Black Glazed Terracotta") { DataLimits = new BlockDataLimits(0, 3) }; + Concrete = new BlockInfo(251, "minecraft:concrete", "Concrete") { DataLimits = new BlockDataLimits(0, 15) }; + ConcretePowder = new BlockInfo(252, "minecraft:concrete_powder", "Concrete Powder") { DataLimits = new BlockDataLimits(0, 15) }; + // Unused253 = new BlockInfo(253, "minecraft:", ""); + // Unused254 = new BlockInfo(254, "minecraft:", ""); + StructureBlock = new BlockInfo(255, "minecraft:structure_block", "Structure Block") { DataLimits = new BlockDataLimits(0, 3) }; + + for (int i = 0; i < MAX_BLOCKS; i++) + { + if (_blockTable[i] == null) + { + _blockTable[i] = new BlockInfo(i); + } + } + } + } +} diff --git a/SubstrateCS/Source/BlockManager.cs b/Substrate/Source/BlockManager.cs similarity index 100% rename from SubstrateCS/Source/BlockManager.cs rename to Substrate/Source/BlockManager.cs diff --git a/SubstrateCS/Source/CacheTable.cs b/Substrate/Source/CacheTable.cs similarity index 100% rename from SubstrateCS/Source/CacheTable.cs rename to Substrate/Source/CacheTable.cs diff --git a/SubstrateCS/Source/ChunkRef.cs b/Substrate/Source/ChunkRef.cs similarity index 94% rename from SubstrateCS/Source/ChunkRef.cs rename to Substrate/Source/ChunkRef.cs index bb19bdc6..7a035d5d 100644 --- a/SubstrateCS/Source/ChunkRef.cs +++ b/Substrate/Source/ChunkRef.cs @@ -232,15 +232,6 @@ public ChunkRef GetWestNeighbor () return _container.GetChunkRef(_cx, _cz + 1); } - /// - /// Returns a deep copy of the physical chunk underlying the ChunkRef. - /// - /// A copy of the physical Chunk object. - /*public Chunk GetChunkCopy () - { - return GetChunk().Copy(); - }*/ - /// /// Returns the reference of the physical chunk underlying the ChunkRef, and releases the reference from itself. /// diff --git a/SubstrateCS/Source/Core/Base.cs b/Substrate/Source/Core/Base.cs similarity index 70% rename from SubstrateCS/Source/Core/Base.cs rename to Substrate/Source/Core/Base.cs index 995ea963..c5825c7c 100644 --- a/SubstrateCS/Source/Core/Base.cs +++ b/Substrate/Source/Core/Base.cs @@ -8,39 +8,45 @@ internal static class Base36 { private const string _alphabet = "0123456789abcdefghijklmnopqrstuvwxyz"; - public static string Encode (long input) + public static string Encode(long input) { - if (input == 0) { + if (input == 0) + { return "0"; } bool neg = (input < 0); - if (neg) { + if (neg) + { input *= -1; } Stack result = new Stack(); - while (input != 0) { + while (input != 0) + { result.Push(_alphabet[(int)(input % 36)]); input /= 36; } string ret = new string(result.ToArray()); - if (neg) { + if (neg) + { ret = '-' + ret; } return ret; } - public static long Decode (string input) + public static long Decode(string input) { - if (input.Length == 0) { + if (input.Length == 0) + { throw new ArgumentOutOfRangeException("input", input); } bool neg = false; - if (input[0] == '-') { + if (input[0] == '-') + { neg = true; input = input.Substring(1); } @@ -49,12 +55,14 @@ public static long Decode (string input) long result = 0; int pos = 0; - for (int i = input.Length - 1; i >= 0; i--) { + for (int i = input.Length - 1; i >= 0; i--) + { result += _alphabet.IndexOf(input[i]) * (long)Math.Pow(36, pos); pos++; } - if (neg) { + if (neg) + { result *= -1; } return result; @@ -65,21 +73,24 @@ internal static class Base16 { private const string _alphabet = "0123456789abcdef"; - public static string Encode (byte[] input, int stride = 0, char strideChar = ' ') + public static string Encode(byte[] input, int stride = 0, char strideChar = ' ') { List result = new List(); - for (int i = 0; i < input.Length; i++) { + for (int i = 0; i < input.Length; i++) + { int hi = (input[i] >> 4) & 0xF; int lo = input[i] & 0xF; result.Add(_alphabet[hi]); - if (stride > 0 && (((i + 1) * 2 - 1) % stride) == 0) { + if (stride > 0 && (((i + 1) * 2 - 1) % stride) == 0) + { result.Add(strideChar); } result.Add(_alphabet[lo]); - if (stride > 0 && (((i + 1) * 2) % stride) == 0) { + if (stride > 0 && (((i + 1) * 2) % stride) == 0) + { result.Add(strideChar); } } diff --git a/SubstrateCS/Source/Core/BlockFluid.cs b/Substrate/Source/Core/BlockFluid.cs similarity index 70% rename from SubstrateCS/Source/Core/BlockFluid.cs rename to Substrate/Source/Core/BlockFluid.cs index 8e3108a1..461b8c89 100644 --- a/SubstrateCS/Source/Core/BlockFluid.cs +++ b/Substrate/Source/Core/BlockFluid.cs @@ -20,7 +20,7 @@ public class BlockFluid private Dictionary _chunks; - public delegate IBoundedDataBlockCollection NeighborLookupHandler (int relx, int rely, int relz); + public delegate IBoundedDataBlockCollection NeighborLookupHandler(int relx, int rely, int relz); public event NeighborLookupHandler ResolveNeighbor; @@ -31,7 +31,7 @@ internal class BlockCoord internal int ly; internal int lz; - internal BlockCoord (IBoundedDataBlockCollection _chunk, int _lx, int _ly, int _lz) + internal BlockCoord(IBoundedDataBlockCollection _chunk, int _lx, int _ly, int _lz) { chunk = _chunk; lx = _lx; @@ -40,7 +40,7 @@ internal BlockCoord (IBoundedDataBlockCollection _chunk, int _lx, int _ly, int _ } } - public BlockFluid (IBoundedDataBlockCollection blockset) + public BlockFluid(IBoundedDataBlockCollection blockset) { _blockset = blockset; @@ -48,10 +48,10 @@ public BlockFluid (IBoundedDataBlockCollection blockset) _ydim = _blockset.YDim; _zdim = _blockset.ZDim; - _chunks = new Dictionary(); + _chunks = new Dictionary(); } - public BlockFluid (BlockFluid bl) + public BlockFluid(BlockFluid bl) { _blockset = bl._blockset; @@ -62,45 +62,51 @@ public BlockFluid (BlockFluid bl) _chunks = new Dictionary(); } - public void ResetWater (IDataArray blocks, IDataArray data) + public void ResetWater(IDataArray blocks, IDataArray data) { - for (int i = 0; i < blocks.Length; i++) { - if ((blocks[i] == BlockInfo.StationaryWater.ID || blocks[i] == BlockInfo.Water.ID) && data[i] != 0) { + for (int i = 0; i < blocks.Length; i++) + { + if ((blocks[i] == BlockInfo.StationaryWater.ID || blocks[i] == BlockInfo.Water.ID) && data[i] != 0) + { blocks[i] = (byte)BlockInfo.Air.ID; data[i] = 0; } - else if (blocks[i] == BlockInfo.Water.ID) { + else if (blocks[i] == BlockInfo.Water.ID) + { blocks[i] = (byte)BlockInfo.StationaryWater.ID; } } } - public void ResetLava (IDataArray blocks, IDataArray data) + public void ResetLava(IDataArray blocks, IDataArray data) { - for (int i = 0; i < blocks.Length; i++) { - if ((blocks[i] == BlockInfo.StationaryLava.ID || blocks[i] == BlockInfo.Lava.ID) && data[i] != 0) { + for (int i = 0; i < blocks.Length; i++) + { + if ((blocks[i] == BlockInfo.StationaryLava.ID || blocks[i] == BlockInfo.Lava.ID) && data[i] != 0) + { blocks[i] = (byte)BlockInfo.Air.ID; data[i] = 0; } - else if (blocks[i] == BlockInfo.Lava.ID) { + else if (blocks[i] == BlockInfo.Lava.ID) + { blocks[i] = (byte)BlockInfo.StationaryLava.ID; } } } - public void UpdateWater (int x, int y, int z) + public void UpdateWater(int x, int y, int z) { DoWater(x, y, z); _chunks.Clear(); } - public void UpdateLava (int x, int y, int z) + public void UpdateLava(int x, int y, int z) { DoLava(x, y, z); _chunks.Clear(); } - public void RebuildWater () + public void RebuildWater() { int xdim = _xdim; int ydim = _ydim; @@ -108,25 +114,30 @@ public void RebuildWater () List buildQueue = new List(); - for (int x = 0; x < xdim; x++) { - for (int z = 0; z < zdim; z++) { - for (int y = 0; y < ydim; y++) { + for (int x = 0; x < xdim; x++) + { + for (int z = 0; z < zdim; z++) + { + for (int y = 0; y < ydim; y++) + { BlockInfo info = _blockset.GetInfo(x, y, z); - if (info.ID == BlockInfo.StationaryWater.ID && _blockset.GetData(x, y, z) == 0) { + if (info.ID == BlockInfo.StationaryWater.ID && _blockset.GetData(x, y, z) == 0) + { buildQueue.Add(new BlockKey(x, y, z)); } } } } - foreach (BlockKey key in buildQueue) { + foreach (BlockKey key in buildQueue) + { DoWater(key.x, key.y, key.z); } _chunks.Clear(); } - public void RebuildLava () + public void RebuildLava() { int xdim = _xdim; int ydim = _ydim; @@ -134,25 +145,30 @@ public void RebuildLava () List buildQueue = new List(); - for (int x = 0; x < xdim; x++) { - for (int z = 0; z < zdim; z++) { - for (int y = 0; y < ydim; y++) { + for (int x = 0; x < xdim; x++) + { + for (int z = 0; z < zdim; z++) + { + for (int y = 0; y < ydim; y++) + { BlockInfo info = _blockset.GetInfo(x, y, z); - if (info.ID == BlockInfo.StationaryLava.ID && _blockset.GetData(x, y, z) == 0) { + if (info.ID == BlockInfo.StationaryLava.ID && _blockset.GetData(x, y, z) == 0) + { buildQueue.Add(new BlockKey(x, y, z)); } } } } - foreach (BlockKey key in buildQueue) { + foreach (BlockKey key in buildQueue) + { DoLava(key.x, key.y, key.z); } _chunks.Clear(); } - private BlockCoord TranslateCoord (int x, int y, int z) + private BlockCoord TranslateCoord(int x, int y, int z) { IBoundedDataBlockCollection chunk = GetChunk(x, z); @@ -162,7 +178,7 @@ private BlockCoord TranslateCoord (int x, int y, int z) return new BlockCoord(chunk, lx, y, lz); } - private IBoundedDataBlockCollection GetChunk (int x, int z) + private IBoundedDataBlockCollection GetChunk(int x, int z) { int cx = x / _xdim + (x >> 31); int cz = z / _zdim + (z >> 31); @@ -170,7 +186,8 @@ private IBoundedDataBlockCollection GetChunk (int x, int z) ChunkKey key = new ChunkKey(cx, cz); IBoundedDataBlockCollection chunk; - if (!_chunks.TryGetValue(key, out chunk)) { + if (!_chunks.TryGetValue(key, out chunk)) + { chunk = OnResolveNeighbor(cx, 0, cz); _chunks[key] = chunk; } @@ -178,19 +195,22 @@ private IBoundedDataBlockCollection GetChunk (int x, int z) return chunk; } - private IBoundedDataBlockCollection OnResolveNeighbor (int relX, int relY, int relZ) + private IBoundedDataBlockCollection OnResolveNeighbor(int relX, int relY, int relZ) { - if (ResolveNeighbor != null) { + if (ResolveNeighbor != null) + { IBoundedDataBlockCollection n = ResolveNeighbor(relX, relY, relZ); - if (n == null) { + if (n == null) + { return null; } if (n.XDim != _xdim || n.YDim != _ydim || - n.ZDim != _zdim) { - throw new InvalidOperationException("Subscriber returned incompatible IDataBlockCollection"); + n.ZDim != _zdim) + { + throw new InvalidOperationException("Subscriber returned incompatible IDataBlockCollection"); } return n; @@ -201,37 +221,42 @@ private IBoundedDataBlockCollection OnResolveNeighbor (int relX, int relY, int r // ----- - private List TileOutflow (BlockKey key, int reach = 5) + private List TileOutflow(BlockKey key, int reach = 5) { Queue searchQueue = new Queue(); Queue> traceQueue = new Queue>(); - Dictionary markTable = new Dictionary(); + Dictionary markTable = new Dictionary(); searchQueue.Enqueue(key); markTable.Add(key, 0); // Identify sinks - while (searchQueue.Count > 0) { + while (searchQueue.Count > 0) + { BlockKey branch = searchQueue.Dequeue(); int distance = markTable[branch]; // Ignore blocks out of range - if (distance > reach) { + if (distance > reach) + { continue; } // Ignore invalid blocks BlockCoord branchHigh = TranslateCoord(branch.x, branch.y, branch.z); - if (branchHigh.chunk == null || branch.y == 0) { + if (branchHigh.chunk == null || branch.y == 0) + { markTable.Remove(branch); continue; } // If we're not the magical source block... - if (distance > 0) { + if (distance > 0) + { // Ignore blocks that block fluid (and thus could not become a fluid) BlockInfo branchHighInfo = branchHigh.chunk.GetInfo(branchHigh.lx, branchHigh.ly, branchHigh.lz); - if (branchHighInfo.BlocksFluid) { + if (branchHighInfo.BlocksFluid) + { markTable.Remove(branch); continue; } @@ -240,9 +265,11 @@ private List TileOutflow (BlockKey key, int reach = 5) // If we found a hole, add as a sink, mark the sink distance. BlockCoord branchLow = TranslateCoord(branch.x, branch.y - 1, branch.z); BlockInfo branchLowInfo = branchLow.chunk.GetInfo(branchLow.lx, branchLow.ly, branchLow.lz); - if (!branchLowInfo.BlocksFluid) { + if (!branchLowInfo.BlocksFluid) + { // If we are our own sink, return the only legal outflow - if (key == branch) { + if (key == branch) + { List ret = new List(); ret.Add(new BlockKey(branch.x, branch.y - 1, branch.z)); return ret; @@ -254,7 +281,8 @@ private List TileOutflow (BlockKey key, int reach = 5) } // Expand to neighbors - if (distance < reach) { + if (distance < reach) + { BlockKey[] keys = { new BlockKey(branch.x - 1, branch.y, branch.z), new BlockKey(branch.x + 1, branch.y, branch.z), @@ -262,8 +290,10 @@ private List TileOutflow (BlockKey key, int reach = 5) new BlockKey(branch.x, branch.y, branch.z + 1), }; - for (int i = 0; i < 4; i++) { - if (!markTable.ContainsKey(keys[i])) { + for (int i = 0; i < 4; i++) + { + if (!markTable.ContainsKey(keys[i])) + { searchQueue.Enqueue(keys[i]); markTable.Add(keys[i], distance + 1); } @@ -280,19 +310,23 @@ private List TileOutflow (BlockKey key, int reach = 5) }; List outflow = new List(); - foreach (BlockKey n in neighbors) { - if (markTable.ContainsKey(n)) { + foreach (BlockKey n in neighbors) + { + if (markTable.ContainsKey(n)) + { outflow.Add(n); } } // If there's no sinks, all neighbors are valid outflows - if (traceQueue.Count == 0) { + if (traceQueue.Count == 0) + { return outflow; } // Trace back from each sink eliminating shortest path marks - while (traceQueue.Count > 0) { + while (traceQueue.Count > 0) + { KeyValuePair tilekv = traceQueue.Dequeue(); BlockKey tile = tilekv.Key; @@ -307,13 +341,16 @@ private List TileOutflow (BlockKey key, int reach = 5) new BlockKey(tile.x, tile.y, tile.z + 1), }; - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) + { int nval; - if (!markTable.TryGetValue(keys[i], out nval)) { + if (!markTable.TryGetValue(keys[i], out nval)) + { continue; } - if (nval < distance) { + if (nval < distance) + { markTable.Remove(keys[i]); traceQueue.Enqueue(new KeyValuePair(keys[i], nval)); } @@ -321,8 +358,10 @@ private List TileOutflow (BlockKey key, int reach = 5) } // Remove any candidates that are still marked - foreach (BlockKey n in neighbors) { - if (markTable.ContainsKey(n)) { + foreach (BlockKey n in neighbors) + { + if (markTable.ContainsKey(n)) + { outflow.Remove(n); } } @@ -330,14 +369,16 @@ private List TileOutflow (BlockKey key, int reach = 5) return outflow; } - private int TileInflow (BlockKey key) + private int TileInflow(BlockKey key) { // Check if water is falling on us - if (key.y < _ydim - 1) { + if (key.y < _ydim - 1) + { BlockCoord up = TranslateCoord(key.x, key.y + 1, key.z); BlockInfo upInfo = up.chunk.GetInfo(up.lx, up.ly, up.lz); - if (upInfo.State == BlockState.FLUID) { + if (upInfo.State == BlockState.FLUID) + { return up.chunk.GetData(up.lx, up.ly, up.lz) | (int)LiquidState.FALLING; } } @@ -353,32 +394,39 @@ private int TileInflow (BlockKey key) int minFlow = 16; // XXX: Might have different neighboring fluids - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) + { BlockCoord neighbor = TranslateCoord(keys[i].x, keys[i].y, keys[i].z); - if (neighbor.chunk == null) { + if (neighbor.chunk == null) + { continue; } BlockInfo neighborInfo = neighbor.chunk.GetInfo(neighbor.lx, neighbor.ly, neighbor.lz); - if (neighborInfo.State == BlockState.FLUID) { + if (neighborInfo.State == BlockState.FLUID) + { int flow = neighbor.chunk.GetData(neighbor.lx, neighbor.ly, neighbor.lz); bool flowFall = (flow & (int)LiquidState.FALLING) != 0; - if (flowFall) { - if (keys[i].y == 0) { + if (flowFall) + { + if (keys[i].y == 0) + { continue; } BlockCoord low = TranslateCoord(keys[i].x, keys[i].y - 1, keys[i].z); BlockInfo lowinfo = low.chunk.GetInfo(low.lx, low.ly, low.lz); - if (lowinfo.BlocksFluid) { + if (lowinfo.BlocksFluid) + { return 0; } continue; } - if (flow < minFlow) { + if (flow < minFlow) + { minFlow = flow; } } @@ -387,7 +435,7 @@ private int TileInflow (BlockKey key) return minFlow; } - private void DoWater (int x, int y, int z) + private void DoWater(int x, int y, int z) { Queue flowQueue = new Queue(); @@ -395,11 +443,13 @@ private void DoWater (int x, int y, int z) flowQueue.Enqueue(prikey); List outflow = TileOutflow(prikey); - foreach (BlockKey outkey in outflow) { + foreach (BlockKey outkey in outflow) + { flowQueue.Enqueue(outkey); } - while (flowQueue.Count > 0) { + while (flowQueue.Count > 0) + { BlockKey key = flowQueue.Dequeue(); int curflow = 16; @@ -407,10 +457,12 @@ private void DoWater (int x, int y, int z) BlockCoord tile = TranslateCoord(key.x, key.y, key.z); BlockInfo tileInfo = tile.chunk.GetInfo(tile.lx, tile.ly, tile.lz); - if (tileInfo.ID == BlockInfo.StationaryWater.ID || tileInfo.ID == BlockInfo.Water.ID) { + if (tileInfo.ID == BlockInfo.StationaryWater.ID || tileInfo.ID == BlockInfo.Water.ID) + { curflow = tile.chunk.GetData(tile.lx, tile.ly, tile.lz); } - else if (tileInfo.BlocksFluid) { + else if (tileInfo.BlocksFluid) + { continue; } @@ -418,38 +470,48 @@ private void DoWater (int x, int y, int z) bool inFall = (inflow & (int)LiquidState.FALLING) != 0; // We won't update from the following states - if (curflow == 0 || curflow == inflow || curFall) { + if (curflow == 0 || curflow == inflow || curFall) + { continue; } int newflow = curflow; // Update from inflow if necessary - if (inFall) { + if (inFall) + { newflow = inflow; } - else if (inflow >= 7) { + else if (inflow >= 7) + { newflow = 16; } - else { + else + { newflow = inflow + 1; } // If we haven't changed the flow, don't propagate - if (newflow == curflow) { + if (newflow == curflow) + { continue; } // Update flow, add or remove water tile as necessary - if (newflow < 16 && curflow == 16) { + if (newflow < 16 && curflow == 16) + { // If we're overwriting lava, replace with appropriate stone type and abort propagation - if (tileInfo.ID == BlockInfo.StationaryLava.ID || tileInfo.ID == BlockInfo.Lava.ID) { - if ((newflow & (int)LiquidState.FALLING) != 0) { + if (tileInfo.ID == BlockInfo.StationaryLava.ID || tileInfo.ID == BlockInfo.Lava.ID) + { + if ((newflow & (int)LiquidState.FALLING) != 0) + { int odata = tile.chunk.GetData(tile.lx, tile.ly, tile.lz); - if (odata == 0) { + if (odata == 0) + { tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockInfo.Obsidian.ID); } - else { + else + { tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockInfo.Cobblestone.ID); } tile.chunk.SetData(tile.lx, tile.ly, tile.lz, 0); @@ -461,24 +523,27 @@ private void DoWater (int x, int y, int z) tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockInfo.StationaryWater.ID); tile.chunk.SetData(tile.lx, tile.ly, tile.lz, newflow); } - else if (newflow == 16) { + else if (newflow == 16) + { tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockInfo.Air.ID); tile.chunk.SetData(tile.lx, tile.ly, tile.lz, 0); } - else { + else + { tile.chunk.SetData(tile.lx, tile.ly, tile.lz, newflow); } // Process outflows outflow = TileOutflow(key); - foreach (BlockKey nkey in outflow) { + foreach (BlockKey nkey in outflow) + { flowQueue.Enqueue(nkey); } } } - private void DoLava (int x, int y, int z) + private void DoLava(int x, int y, int z) { Queue flowQueue = new Queue(); @@ -486,11 +551,13 @@ private void DoLava (int x, int y, int z) flowQueue.Enqueue(prikey); List outflow = TileOutflow(prikey); - foreach (BlockKey outkey in outflow) { + foreach (BlockKey outkey in outflow) + { flowQueue.Enqueue(outkey); } - while (flowQueue.Count > 0) { + while (flowQueue.Count > 0) + { BlockKey key = flowQueue.Dequeue(); int curflow = 16; @@ -498,10 +565,12 @@ private void DoLava (int x, int y, int z) BlockCoord tile = TranslateCoord(key.x, key.y, key.z); BlockInfo tileInfo = tile.chunk.GetInfo(tile.lx, tile.ly, tile.lz); - if (tileInfo.ID == BlockInfo.StationaryLava.ID || tileInfo.ID == BlockInfo.Lava.ID) { + if (tileInfo.ID == BlockInfo.StationaryLava.ID || tileInfo.ID == BlockInfo.Lava.ID) + { curflow = tile.chunk.GetData(tile.lx, tile.ly, tile.lz); } - else if (tileInfo.BlocksFluid) { + else if (tileInfo.BlocksFluid) + { continue; } @@ -509,33 +578,41 @@ private void DoLava (int x, int y, int z) bool inFall = (inflow & (int)LiquidState.FALLING) != 0; // We won't update from the following states - if (curflow == 0 || curflow == inflow || curFall) { + if (curflow == 0 || curflow == inflow || curFall) + { continue; } int newflow = curflow; // Update from inflow if necessary - if (inFall) { + if (inFall) + { newflow = inflow; } - else if (inflow >= 6) { + else if (inflow >= 6) + { newflow = 16; } - else { + else + { newflow = inflow + 2; } // If we haven't changed the flow, don't propagate - if (newflow == curflow) { + if (newflow == curflow) + { continue; } // Update flow, add or remove lava tile as necessary - if (newflow < 16 && curflow == 16) { + if (newflow < 16 && curflow == 16) + { // If we're overwriting water, replace with appropriate stone type and abort propagation - if (tileInfo.ID == BlockInfo.StationaryWater.ID || tileInfo.ID == BlockInfo.Water.ID) { - if ((newflow & (int)LiquidState.FALLING) == 0) { + if (tileInfo.ID == BlockInfo.StationaryWater.ID || tileInfo.ID == BlockInfo.Water.ID) + { + if ((newflow & (int)LiquidState.FALLING) == 0) + { tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockInfo.Cobblestone.ID); tile.chunk.SetData(tile.lx, tile.ly, tile.lz, 0); continue; @@ -545,18 +622,21 @@ private void DoLava (int x, int y, int z) tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockInfo.StationaryLava.ID); tile.chunk.SetData(tile.lx, tile.ly, tile.lz, newflow); } - else if (newflow == 16) { + else if (newflow == 16) + { tile.chunk.SetID(tile.lx, tile.ly, tile.lz, BlockInfo.Air.ID); tile.chunk.SetData(tile.lx, tile.ly, tile.lz, 0); } - else { + else + { tile.chunk.SetData(tile.lx, tile.ly, tile.lz, newflow); } // Process outflows outflow = TileOutflow(key); - foreach (BlockKey nkey in outflow) { + foreach (BlockKey nkey in outflow) + { flowQueue.Enqueue(nkey); } } diff --git a/SubstrateCS/Source/Core/BlockInterface.cs b/Substrate/Source/Core/BlockInterface.cs similarity index 92% rename from SubstrateCS/Source/Core/BlockInterface.cs rename to Substrate/Source/Core/BlockInterface.cs index 399f24d5..5fe478a4 100644 --- a/SubstrateCS/Source/Core/BlockInterface.cs +++ b/Substrate/Source/Core/BlockInterface.cs @@ -80,7 +80,7 @@ public interface IPropertyBlock : IBlock /// Gets a tile entity attached to this block. /// /// A for this block, or null if this block type does not support a tile entity. - TileEntity GetTileEntity (); + TileEntity GetTileEntity(); /// /// Sets the tile entity attached to this block. @@ -88,7 +88,7 @@ public interface IPropertyBlock : IBlock /// A supported by this block type. /// Thrown when the being passed is of the wrong type for the given block. /// Thrown when the given block is of a type that does not support a record. - void SetTileEntity (TileEntity te); + void SetTileEntity(TileEntity te); /// /// Creates a default tile entity for this block consistent with its type. @@ -96,12 +96,12 @@ public interface IPropertyBlock : IBlock /// This method will overwrite any existing attached to the block. /// Thrown when the given block is of a type that does not support a record. /// Thrown when the block type requests a that has not been registered with the . - void CreateTileEntity (); + void CreateTileEntity(); /// /// Deletes the tile entity attached to this block if one exists. /// - void ClearTileEntity (); + void ClearTileEntity(); } /// @@ -113,24 +113,24 @@ public interface IActiveBlock : IBlock /// Gets a entry attached to this block. /// /// A for this block, or null if one has not been created yet. - TileTick GetTileTick (); + TileTick GetTileTick(); /// /// Sets the attached to this block. /// /// A representing the delay until this block is next processed in-game. - void SetTileTick (TileTick tt); + void SetTileTick(TileTick tt); /// /// Creates a default entry for this block. /// /// This method will overwrite any existing attached to the block. - void CreateTileTick (); + void CreateTileTick(); /// /// Deletes the entry attached to this block, if one exists. /// - void ClearTileTick (); + void ClearTileTick(); /// /// Gets or sets the the actual tick delay associated with this block. @@ -175,7 +175,7 @@ public interface IVersion10BlockRef : IAlphaBlockRef, IActiveBlock /// Provides a common interface for block containers that provide global management. /// public interface IBlockManager : IAlphaBlockCollection - { + { } /// diff --git a/SubstrateCS/Source/Core/BlockKey.cs b/Substrate/Source/Core/BlockKey.cs similarity index 66% rename from SubstrateCS/Source/Core/BlockKey.cs rename to Substrate/Source/Core/BlockKey.cs index 4e4f044d..64453a8e 100644 --- a/SubstrateCS/Source/Core/BlockKey.cs +++ b/Substrate/Source/Core/BlockKey.cs @@ -8,29 +8,31 @@ public struct BlockKey : IEquatable public readonly int y; public readonly int z; - public BlockKey (int _x, int _y, int _z) + public BlockKey(int _x, int _y, int _z) { x = _x; y = _y; z = _z; } - public bool Equals (BlockKey bk) + public bool Equals(BlockKey bk) { return this.x == bk.x && this.y == bk.y && this.z == bk.z; } - public override bool Equals (Object o) + public override bool Equals(Object o) { - try { + try + { return this == (BlockKey)o; } - catch { + catch + { return false; } } - public override int GetHashCode () + public override int GetHashCode() { int hash = 23; hash = hash * 37 + x; @@ -39,17 +41,17 @@ public override int GetHashCode () return hash; } - public static bool operator == (BlockKey k1, BlockKey k2) + public static bool operator ==(BlockKey k1, BlockKey k2) { return k1.x == k2.x && k1.y == k2.y && k1.z == k2.z; } - public static bool operator != (BlockKey k1, BlockKey k2) + public static bool operator !=(BlockKey k1, BlockKey k2) { return k1.x != k2.x || k1.y != k2.y || k1.z != k2.z; } - public override string ToString () + public override string ToString() { return "(" + x + ", " + y + ", " + z + ")"; } diff --git a/SubstrateCS/Source/Core/BlockLight.cs b/Substrate/Source/Core/BlockLight.cs similarity index 64% rename from SubstrateCS/Source/Core/BlockLight.cs rename to Substrate/Source/Core/BlockLight.cs index 89c78b26..f6ab7e64 100644 --- a/SubstrateCS/Source/Core/BlockLight.cs +++ b/Substrate/Source/Core/BlockLight.cs @@ -13,7 +13,7 @@ private struct LightRecord public int z; public int str; - public LightRecord (int _x, int _y, int _z, int s) + public LightRecord(int _x, int _y, int _z, int s) { x = _x; y = _y; @@ -32,11 +32,11 @@ public LightRecord (int _x, int _y, int _z, int s) private BitArray _lightbit; private Queue _update; - public delegate IBoundedLitBlockCollection NeighborLookupHandler (int relx, int rely, int relz); + public delegate IBoundedLitBlockCollection NeighborLookupHandler(int relx, int rely, int relz); public event NeighborLookupHandler ResolveNeighbor; - public BlockLight (IBoundedLitBlockCollection blockset) + public BlockLight(IBoundedLitBlockCollection blockset) { _blockset = blockset; @@ -48,7 +48,7 @@ public BlockLight (IBoundedLitBlockCollection blockset) _update = new Queue(); } - public BlockLight (BlockLight bl) + public BlockLight(BlockLight bl) { _blockset = bl._blockset; @@ -60,7 +60,7 @@ public BlockLight (BlockLight bl) _update = new Queue(); } - public void UpdateBlockLight (int lx, int ly, int lz) + public void UpdateBlockLight(int lx, int ly, int lz) { BlockKey primary = new BlockKey(lx, ly, lz); _update.Enqueue(primary); @@ -68,10 +68,12 @@ public void UpdateBlockLight (int lx, int ly, int lz) //BlockInfo info = _blockset.GetInfo(lx, ly, lz); //if (info.Luminance > BlockInfo.MIN_LUMINANCE || info.TransmitsLight) { - if (ly > 0) { + if (ly > 0) + { QueueRelight(new BlockKey(lx, ly - 1, lz)); } - if (ly < _ydim - 1) { + if (ly < _ydim - 1) + { QueueRelight(new BlockKey(lx, ly + 1, lz)); } @@ -84,7 +86,7 @@ public void UpdateBlockLight (int lx, int ly, int lz) UpdateBlockLight(); } - public void UpdateBlockSkyLight (int lx, int ly, int lz) + public void UpdateBlockSkyLight(int lx, int ly, int lz) { BlockKey primary = new BlockKey(lx, ly, lz); _update.Enqueue(primary); @@ -92,34 +94,39 @@ public void UpdateBlockSkyLight (int lx, int ly, int lz) UpdateBlockSkyLight(); } - public void UpdateHeightMap (int lx, int ly, int lz) + public void UpdateHeightMap(int lx, int ly, int lz) { BlockInfo info = _blockset.GetInfo(lx, ly, lz); int h = Math.Min(ly + 1, _ydim - 1); int height = _blockset.GetHeight(lx, lz); - if (h < height) { + if (h < height) + { return; } - if (h == height && !info.ObscuresLight) { - for (int i = ly - 1; i >= 0; i--) { + if (h == height && !info.ObscuresLight) + { + for (int i = ly - 1; i >= 0; i--) + { BlockInfo info2 = _blockset.GetInfo(lx, i, lz); - if (info2.ObscuresLight) { + if (info2.ObscuresLight) + { _blockset.SetHeight(lx, lz, Math.Min(i + 1, _ydim - 1)); break; } } UpdateBlockSkyLight(lx, h, lz); } - else if (h > height && info.ObscuresLight) { + else if (h > height && info.ObscuresLight) + { _blockset.SetHeight(lx, lz, h); UpdateBlockSkyLight(lx, h, lz); } } - public void RebuildBlockLight () + public void RebuildBlockLight() { IBoundedLitBlockCollection[,] chunkMap = LocalBlockLightMap(); @@ -128,11 +135,15 @@ public void RebuildBlockLight () int ydim = _ydim; int zdim = _zdim; - for (int x = 0; x < xdim; x++) { - for (int z = 0; z < zdim; z++) { - for (int y = 0; y < ydim; y++) { + for (int x = 0; x < xdim; x++) + { + for (int z = 0; z < zdim; z++) + { + for (int y = 0; y < ydim; y++) + { BlockInfo info = _blockset.GetInfo(x, y, z); - if (info.Luminance > 0) { + if (info.Luminance > 0) + { SpreadBlockLight(chunkMap, x, y, z); } } @@ -140,7 +151,7 @@ public void RebuildBlockLight () } } - public void RebuildBlockSkyLight () + public void RebuildBlockSkyLight() { IBoundedLitBlockCollection[,] chunkMap = LocalBlockLightMap(); int[,] heightMap = LocalHeightMap(chunkMap); @@ -150,8 +161,10 @@ public void RebuildBlockSkyLight () int zdim = _zdim; // Optimization - only need to queue at level of highest neighbor's height - for (int x = 0; x < xdim; x++) { - for (int z = 0; z < zdim; z++) { + for (int x = 0; x < xdim; x++) + { + for (int z = 0; z < zdim; z++) + { int xi = x + xdim; int zi = z + zdim; @@ -161,7 +174,8 @@ public void RebuildBlockSkyLight () h = Math.Max(h, heightMap[xi + 1, zi]); h = Math.Max(h, heightMap[xi, zi + 1]); - for (int y = h + 1; y < ydim; y++) { + for (int y = h + 1; y < ydim; y++) + { _blockset.SetSkyLight(x, y, z, BlockInfo.MAX_LUMINANCE); } @@ -171,17 +185,21 @@ public void RebuildBlockSkyLight () } } - public void RebuildHeightMap () + public void RebuildHeightMap() { int xdim = _xdim; int ydim = _ydim; int zdim = _zdim; - for (int x = 0; x < xdim; x++) { - for (int z = 0; z < zdim; z++) { - for (int y = ydim - 1; y >= 0; y--) { + for (int x = 0; x < xdim; x++) + { + for (int z = 0; z < zdim; z++) + { + for (int y = ydim - 1; y >= 0; y--) + { BlockInfo info = _blockset.GetInfo(x, y, z); - if (info.ObscuresLight) { + if (info.ObscuresLight) + { _blockset.SetHeight(x, z, Math.Min(y + 1, ydim - 1)); break; } @@ -191,26 +209,30 @@ public void RebuildHeightMap () } - public void StitchBlockLight () + public void StitchBlockLight() { IBoundedLitBlockCollection[,] map = LocalBlockLightMap(); - if (map[1, 0] != null) { + if (map[1, 0] != null) + { StitchBlockLight(map[1, 0], BlockCollectionEdge.EAST); } - if (map[0, 1] != null) { + if (map[0, 1] != null) + { StitchBlockLight(map[0, 1], BlockCollectionEdge.NORTH); } - if (map[1, 2] != null) { + if (map[1, 2] != null) + { StitchBlockLight(map[1, 2], BlockCollectionEdge.WEST); } - if (map[2, 1] != null) { + if (map[2, 1] != null) + { StitchBlockLight(map[2, 1], BlockCollectionEdge.SOUTH); } } // TODO: Revise to cache the specified chunk into local map - public void StitchBlockLight (IBoundedLitBlockCollection chunk, BlockCollectionEdge edge) + public void StitchBlockLight(IBoundedLitBlockCollection chunk, BlockCollectionEdge edge) { int xdim = _xdim; int ydim = _ydim; @@ -218,66 +240,80 @@ public void StitchBlockLight (IBoundedLitBlockCollection chunk, BlockCollectionE if (chunk.XDim != xdim || chunk.YDim != ydim || - chunk.ZDim != zdim) { - throw new InvalidOperationException("BlockLight must have same dimensions to be stitched"); + chunk.ZDim != zdim) + { + throw new InvalidOperationException("BlockLight must have same dimensions to be stitched"); } - switch (edge) { - case BlockCollectionEdge.EAST: - for (int x = 0; x < xdim; x++) { - for (int y = 0; y < ydim; y++) { - TestBlockLight(chunk, x, y, 0, x, y, zdim - 1); - } + switch (edge) + { + case BlockCollectionEdge.EAST: + for (int x = 0; x < xdim; x++) + { + for (int y = 0; y < ydim; y++) + { + TestBlockLight(chunk, x, y, 0, x, y, zdim - 1); } - break; - - case BlockCollectionEdge.NORTH: - for (int z = 0; z < zdim; z++) { - for (int y = 0; y < ydim; y++) { - TestBlockLight(chunk, 0, y, z, xdim - 1, y, z); - } + } + break; + + case BlockCollectionEdge.NORTH: + for (int z = 0; z < zdim; z++) + { + for (int y = 0; y < ydim; y++) + { + TestBlockLight(chunk, 0, y, z, xdim - 1, y, z); } - break; - - case BlockCollectionEdge.WEST: - for (int x = 0; x < xdim; x++) { - for (int y = 0; y < ydim; y++) { - TestBlockLight(chunk, x, y, zdim - 1, x, y, 0); - } + } + break; + + case BlockCollectionEdge.WEST: + for (int x = 0; x < xdim; x++) + { + for (int y = 0; y < ydim; y++) + { + TestBlockLight(chunk, x, y, zdim - 1, x, y, 0); } - break; - - case BlockCollectionEdge.SOUTH: - for (int z = 0; z < zdim; z++) { - for (int y = 0; y < ydim; y++) { - TestBlockLight(chunk, xdim - 1, y, z, 0, y, z); - } + } + break; + + case BlockCollectionEdge.SOUTH: + for (int z = 0; z < zdim; z++) + { + for (int y = 0; y < ydim; y++) + { + TestBlockLight(chunk, xdim - 1, y, z, 0, y, z); } - break; + } + break; } UpdateBlockLight(); } - public void StitchBlockSkyLight () + public void StitchBlockSkyLight() { IBoundedLitBlockCollection[,] map = LocalBlockLightMap(); - if (map[1, 0] != null) { + if (map[1, 0] != null) + { StitchBlockSkyLight(map[1, 0], BlockCollectionEdge.EAST); } - if (map[0, 1] != null) { + if (map[0, 1] != null) + { StitchBlockSkyLight(map[0, 1], BlockCollectionEdge.NORTH); } - if (map[1, 2] != null) { + if (map[1, 2] != null) + { StitchBlockSkyLight(map[1, 2], BlockCollectionEdge.WEST); } - if (map[2, 1] != null) { + if (map[2, 1] != null) + { StitchBlockSkyLight(map[2, 1], BlockCollectionEdge.SOUTH); } } - public void StitchBlockSkyLight (IBoundedLitBlockCollection chunk, BlockCollectionEdge edge) + public void StitchBlockSkyLight(IBoundedLitBlockCollection chunk, BlockCollectionEdge edge) { int xdim = _xdim; int ydim = _ydim; @@ -285,49 +321,59 @@ public void StitchBlockSkyLight (IBoundedLitBlockCollection chunk, BlockCollecti if (chunk.XDim != xdim || chunk.YDim != ydim || - chunk.ZDim != zdim) { + chunk.ZDim != zdim) + { throw new InvalidOperationException("BlockLight must have same dimensions to be stitched"); } - switch (edge) { - case BlockCollectionEdge.EAST: - for (int x = 0; x < xdim; x++) { - for (int y = 0; y < ydim; y++) { - TestSkyLight(chunk, x, y, 0, x, y, zdim - 1); - } + switch (edge) + { + case BlockCollectionEdge.EAST: + for (int x = 0; x < xdim; x++) + { + for (int y = 0; y < ydim; y++) + { + TestSkyLight(chunk, x, y, 0, x, y, zdim - 1); } - break; - - case BlockCollectionEdge.NORTH: - for (int z = 0; z < zdim; z++) { - for (int y = 0; y < ydim; y++) { - TestSkyLight(chunk, 0, y, z, xdim - 1, y, z); - } + } + break; + + case BlockCollectionEdge.NORTH: + for (int z = 0; z < zdim; z++) + { + for (int y = 0; y < ydim; y++) + { + TestSkyLight(chunk, 0, y, z, xdim - 1, y, z); } - break; - - case BlockCollectionEdge.WEST: - for (int x = 0; x < xdim; x++) { - for (int y = 0; y < ydim; y++) { - TestSkyLight(chunk, x, y, zdim - 1, x, y, 0); - } + } + break; + + case BlockCollectionEdge.WEST: + for (int x = 0; x < xdim; x++) + { + for (int y = 0; y < ydim; y++) + { + TestSkyLight(chunk, x, y, zdim - 1, x, y, 0); } - break; - - case BlockCollectionEdge.SOUTH: - for (int z = 0; z < zdim; z++) { - for (int y = 0; y < ydim; y++) { - TestSkyLight(chunk, xdim - 1, y, z, 0, y, z); - } + } + break; + + case BlockCollectionEdge.SOUTH: + for (int z = 0; z < zdim; z++) + { + for (int y = 0; y < ydim; y++) + { + TestSkyLight(chunk, xdim - 1, y, z, 0, y, z); } - break; + } + break; } UpdateBlockSkyLight(); } - private void UpdateBlockLight () + private void UpdateBlockLight() { IBoundedLitBlockCollection[,] chunkMap = LocalBlockLightMap(); @@ -335,7 +381,8 @@ private void UpdateBlockLight () int ydim = _ydim; int zdim = _zdim; - while (_update.Count > 0) { + while (_update.Count > 0) + { BlockKey k = _update.Dequeue(); int index = LightBitmapIndex(k); _lightbit[index] = false; @@ -344,7 +391,8 @@ private void UpdateBlockLight () int zi = k.z + zdim; IBoundedLitBlockCollection cc = chunkMap[xi / xdim, zi / zdim]; - if (cc == null) { + if (cc == null) + { continue; } @@ -372,16 +420,20 @@ private void UpdateBlockLight () light = Math.Max(light - info.Opacity, 0); - if (light != lightval) { + if (light != lightval) + { //Console.WriteLine("Block Light: ({0},{1},{2}) " + lightval + " -> " + light, k.x, k.y, k.z); cc.SetBlockLight(x, y, z, light); - if (info.TransmitsLight) { - if (k.y > 0) { + if (info.TransmitsLight) + { + if (k.y > 0) + { QueueRelight(new BlockKey(k.x, k.y - 1, k.z)); } - if (k.y < ydim - 1) { + if (k.y < ydim - 1) + { QueueRelight(new BlockKey(k.x, k.y + 1, k.z)); } @@ -394,7 +446,7 @@ private void UpdateBlockLight () } } - private void UpdateBlockSkyLight () + private void UpdateBlockSkyLight() { IBoundedLitBlockCollection[,] chunkMap = LocalBlockLightMap(); @@ -402,7 +454,8 @@ private void UpdateBlockSkyLight () int ydim = _ydim; int zdim = _zdim; - while (_update.Count > 0) { + while (_update.Count > 0) + { BlockKey k = _update.Dequeue(); int index = LightBitmapIndex(k); _lightbit[index] = false; @@ -411,7 +464,8 @@ private void UpdateBlockSkyLight () int zi = k.z + zdim; IBoundedLitBlockCollection cc = chunkMap[xi / xdim, zi / zdim]; - if (cc == null) { + if (cc == null) + { continue; } @@ -424,10 +478,12 @@ private void UpdateBlockSkyLight () int light = BlockInfo.MIN_LUMINANCE; - if (cc.GetHeight(x, z) <= y) { + if (cc.GetHeight(x, z) <= y) + { light = BlockInfo.MAX_LUMINANCE; } - else { + else + { int lle = NeighborSkyLight(chunkMap, k.x, k.y, k.z - 1); int lln = NeighborSkyLight(chunkMap, k.x - 1, k.y, k.z); int lls = NeighborSkyLight(chunkMap, k.x, k.y, k.z + 1); @@ -445,16 +501,20 @@ private void UpdateBlockSkyLight () light = Math.Max(light - info.Opacity, 0); - if (light != lightval) { + if (light != lightval) + { //Console.WriteLine("Block SkyLight: ({0},{1},{2}) " + lightval + " -> " + light, k.x, k.y, k.z); cc.SetSkyLight(x, y, z, light); - if (info.TransmitsLight) { - if (k.y > 0) { + if (info.TransmitsLight) + { + if (k.y > 0) + { QueueRelight(new BlockKey(k.x, k.y - 1, k.z)); } - if (k.y < ydim - 1) { + if (k.y < ydim - 1) + { QueueRelight(new BlockKey(k.x, k.y + 1, k.z)); } @@ -467,17 +527,19 @@ private void UpdateBlockSkyLight () } } - private void SpreadBlockLight (IBoundedLitBlockCollection[,] chunkMap, int lx, int ly, int lz) + private void SpreadBlockLight(IBoundedLitBlockCollection[,] chunkMap, int lx, int ly, int lz) { BlockInfo primary = _blockset.GetInfo(lx, ly, lz); int primaryLight = _blockset.GetBlockLight(lx, ly, lz); int priLum = Math.Max(primary.Luminance - primary.Opacity, 0); - if (primaryLight < priLum) { - _blockset.SetBlockLight(lx, ly, lz, priLum); + if (primaryLight < priLum) + { + _blockset.SetBlockLight(lx, ly, lz, priLum); } - if (primaryLight > primary.Luminance - 1 && !primary.TransmitsLight) { + if (primaryLight > primary.Luminance - 1 && !primary.TransmitsLight) + { return; } @@ -486,10 +548,12 @@ private void SpreadBlockLight (IBoundedLitBlockCollection[,] chunkMap, int lx, i int zdim = _zdim; Queue spread = new Queue(); - if (ly > 0) { + if (ly > 0) + { spread.Enqueue(new LightRecord(lx, ly - 1, lz, primary.Luminance - 1)); } - if (ly < ydim - 1) { + if (ly < ydim - 1) + { spread.Enqueue(new LightRecord(lx, ly + 1, lz, primary.Luminance - 1)); } @@ -498,14 +562,16 @@ private void SpreadBlockLight (IBoundedLitBlockCollection[,] chunkMap, int lx, i spread.Enqueue(new LightRecord(lx, ly, lz - 1, primary.Luminance - 1)); spread.Enqueue(new LightRecord(lx, ly, lz + 1, primary.Luminance - 1)); - while (spread.Count > 0) { + while (spread.Count > 0) + { LightRecord rec = spread.Dequeue(); int xi = rec.x + xdim; int zi = rec.z + zdim; IBoundedLitBlockCollection cc = chunkMap[xi / xdim, zi / zdim]; - if (cc == null) { + if (cc == null) + { continue; } @@ -518,16 +584,20 @@ private void SpreadBlockLight (IBoundedLitBlockCollection[,] chunkMap, int lx, i int dimStr = Math.Max(rec.str - info.Opacity, 0); - if (dimStr > light) { + if (dimStr > light) + { cc.SetBlockLight(x, y, z, dimStr); - if (info.TransmitsLight) { + if (info.TransmitsLight) + { int strength = (info.Opacity > 0) ? dimStr : dimStr - 1; - if (rec.y > 0) { + if (rec.y > 0) + { spread.Enqueue(new LightRecord(rec.x, rec.y - 1, rec.z, strength)); } - if (rec.y < ydim - 1) { + if (rec.y < ydim - 1) + { spread.Enqueue(new LightRecord(rec.x, rec.y + 1, rec.z, strength)); } @@ -540,17 +610,19 @@ private void SpreadBlockLight (IBoundedLitBlockCollection[,] chunkMap, int lx, i } } - private void SpreadSkyLight (IBoundedLitBlockCollection[,] chunkMap, int[,] heightMap, int lx, int ly, int lz) + private void SpreadSkyLight(IBoundedLitBlockCollection[,] chunkMap, int[,] heightMap, int lx, int ly, int lz) { BlockInfo primary = _blockset.GetInfo(lx, ly, lz); int primaryLight = _blockset.GetSkyLight(lx, ly, lz); int priLum = Math.Max(BlockInfo.MAX_LUMINANCE - primary.Opacity, 0); - if (primaryLight < priLum) { + if (primaryLight < priLum) + { _blockset.SetSkyLight(lx, ly, lz, priLum); } - if (primaryLight > BlockInfo.MAX_LUMINANCE - 1 || !primary.TransmitsLight) { + if (primaryLight > BlockInfo.MAX_LUMINANCE - 1 || !primary.TransmitsLight) + { return; } @@ -565,42 +637,53 @@ private void SpreadSkyLight (IBoundedLitBlockCollection[,] chunkMap, int[,] heig int strength = (primary.Opacity > 0) ? priLum : priLum - 1; - if (ly > 0) { - if (heightMap[lxi, lzi] > ly - 1) { + if (ly > 0) + { + if (heightMap[lxi, lzi] > ly - 1) + { spread.Enqueue(new LightRecord(lx, ly - 1, lz, strength)); } - else { + else + { spread.Enqueue(new LightRecord(lx, ly - 1, lz, priLum)); } } - if (ly < ydim - 1) { - if (heightMap[lxi, lzi] > ly + 1) { + if (ly < ydim - 1) + { + if (heightMap[lxi, lzi] > ly + 1) + { spread.Enqueue(new LightRecord(lx, ly + 1, lz, strength)); } } - if (heightMap[lxi - 1, lzi] > ly) { + if (heightMap[lxi - 1, lzi] > ly) + { spread.Enqueue(new LightRecord(lx - 1, ly, lz, strength)); } - if (heightMap[lxi + 1, lzi] > ly) { + if (heightMap[lxi + 1, lzi] > ly) + { spread.Enqueue(new LightRecord(lx + 1, ly, lz, strength)); } - if (heightMap[lxi, lzi - 1] > ly) { + if (heightMap[lxi, lzi - 1] > ly) + { spread.Enqueue(new LightRecord(lx, ly, lz - 1, strength)); } - if (heightMap[lxi, lzi + 1] > ly) { + if (heightMap[lxi, lzi + 1] > ly) + { spread.Enqueue(new LightRecord(lx, ly, lz + 1, strength)); } - while (spread.Count > 0) { + while (spread.Count > 0) + { LightRecord rec = spread.Dequeue(); int xi = rec.x + xdim; int zi = rec.z + zdim; IBoundedLitBlockCollection cc = chunkMap[xi / xdim, zi / zdim]; - if (cc == null) { + if (cc == null) + { continue; } @@ -613,37 +696,48 @@ private void SpreadSkyLight (IBoundedLitBlockCollection[,] chunkMap, int[,] heig int dimStr = Math.Max(rec.str - info.Opacity, 0); - if (dimStr > light) { + if (dimStr > light) + { cc.SetSkyLight(x, y, z, dimStr); - if (info.TransmitsLight) { + if (info.TransmitsLight) + { strength = (info.Opacity > 0) ? dimStr : dimStr - 1; - if (rec.y > 0) { - if (heightMap[xi, zi] > rec.y - 1) { + if (rec.y > 0) + { + if (heightMap[xi, zi] > rec.y - 1) + { spread.Enqueue(new LightRecord(rec.x, rec.y - 1, rec.z, strength)); } - else { + else + { spread.Enqueue(new LightRecord(rec.x, rec.y - 1, rec.z, dimStr)); } } - if (rec.y < ydim - 1) { - if (heightMap[xi, zi] > rec.y + 1) { + if (rec.y < ydim - 1) + { + if (heightMap[xi, zi] > rec.y + 1) + { spread.Enqueue(new LightRecord(rec.x, rec.y + 1, rec.z, strength)); } } - if (heightMap[xi - 1, zi] > rec.y) { + if (heightMap[xi - 1, zi] > rec.y) + { spread.Enqueue(new LightRecord(rec.x - 1, rec.y, rec.z, strength)); } - if (heightMap[xi + 1, zi] > rec.y) { + if (heightMap[xi + 1, zi] > rec.y) + { spread.Enqueue(new LightRecord(rec.x + 1, rec.y, rec.z, strength)); } - if (heightMap[xi, zi - 1] > rec.y) { + if (heightMap[xi, zi - 1] > rec.y) + { spread.Enqueue(new LightRecord(rec.x, rec.y, rec.z - 1, strength)); } - if (heightMap[xi, zi + 1] > rec.y) { + if (heightMap[xi, zi + 1] > rec.y) + { spread.Enqueue(new LightRecord(rec.x, rec.y, rec.z + 1, strength)); } } @@ -652,7 +746,7 @@ private void SpreadSkyLight (IBoundedLitBlockCollection[,] chunkMap, int[,] heig } - private int LightBitmapIndex (BlockKey key) + private int LightBitmapIndex(BlockKey key) { int x = key.x + _xdim; int y = key.y; @@ -664,59 +758,72 @@ private int LightBitmapIndex (BlockKey key) return (x * xstride) + (z * zstride) + y; } - private void QueueRelight (BlockKey key) + private void QueueRelight(BlockKey key) { - if (key.x < -15 || key.x >= 31 || key.z < -15 || key.z >= 31) { + if (key.x < -15 || key.x >= 31 || key.z < -15 || key.z >= 31) + { return; } int index = LightBitmapIndex(key); - if (!_lightbit[index]) { + if (!_lightbit[index]) + { _lightbit[index] = true; _update.Enqueue(key); } } - private IBoundedLitBlockCollection LocalChunk (int lx, int ly, int lz) + private IBoundedLitBlockCollection LocalChunk(int lx, int ly, int lz) { - if (ly < 0 || ly >= _ydim) { + if (ly < 0 || ly >= _ydim) + { return null; } - if (lx < 0) { - if (lz < 0) { + if (lx < 0) + { + if (lz < 0) + { return OnResolveNeighbor(-1, 0, -1); } - else if (lz >= _zdim) { + else if (lz >= _zdim) + { return OnResolveNeighbor(-1, 0, 1); } return OnResolveNeighbor(-1, 0, 0); } - else if (lx >= _xdim) { - if (lz < 0) { + else if (lx >= _xdim) + { + if (lz < 0) + { return OnResolveNeighbor(1, 0, -1); } - else if (lz >= _zdim) { + else if (lz >= _zdim) + { return OnResolveNeighbor(1, 0, 1); } return OnResolveNeighbor(1, 0, 0); } - else { - if (lz < 0) { + else + { + if (lz < 0) + { return OnResolveNeighbor(0, 0, -1); } - else if (lz >= _zdim) { + else if (lz >= _zdim) + { return OnResolveNeighbor(0, 0, 1); } return _blockset; } } - private int NeighborLight (IBoundedLitBlockCollection[,] chunkMap, int x, int y, int z) + private int NeighborLight(IBoundedLitBlockCollection[,] chunkMap, int x, int y, int z) { - if (y < 0 || y >= _ydim) { + if (y < 0 || y >= _ydim) + { return 0; } @@ -727,7 +834,8 @@ private int NeighborLight (IBoundedLitBlockCollection[,] chunkMap, int x, int y, int zi = z + zdim; IBoundedLitBlockCollection src = chunkMap[xi / xdim, zi / zdim]; - if (src == null) { + if (src == null) + { return 0; } @@ -735,7 +843,8 @@ private int NeighborLight (IBoundedLitBlockCollection[,] chunkMap, int x, int y, z = zi % zdim; BlockInfo info = src.GetInfo(x, y, z); - if (!info.TransmitsLight) { + if (!info.TransmitsLight) + { return info.Luminance; } @@ -744,9 +853,10 @@ private int NeighborLight (IBoundedLitBlockCollection[,] chunkMap, int x, int y, return Math.Max((info.Opacity > 0) ? light : light - 1, info.Luminance - 1); } - private int NeighborSkyLight (IBoundedLitBlockCollection[,] chunkMap, int x, int y, int z) + private int NeighborSkyLight(IBoundedLitBlockCollection[,] chunkMap, int x, int y, int z) { - if (y < 0 || y >= _ydim) { + if (y < 0 || y >= _ydim) + { return 0; } @@ -757,7 +867,8 @@ private int NeighborSkyLight (IBoundedLitBlockCollection[,] chunkMap, int x, int int zi = z + zdim; IBoundedLitBlockCollection src = chunkMap[xi / xdim, zi / zdim]; - if (src == null) { + if (src == null) + { return 0; } @@ -765,7 +876,8 @@ private int NeighborSkyLight (IBoundedLitBlockCollection[,] chunkMap, int x, int z = zi % zdim; BlockInfo info = src.GetInfo(x, y, z); - if (!info.TransmitsLight) { + if (!info.TransmitsLight) + { return BlockInfo.MIN_LUMINANCE; } @@ -774,10 +886,11 @@ private int NeighborSkyLight (IBoundedLitBlockCollection[,] chunkMap, int x, int return (info.Opacity > 0) ? light : light - 1; } - private int NeighborHeight (int x, int z) + private int NeighborHeight(int x, int z) { IBoundedLitBlockCollection src = LocalChunk(x, 0, z); - if (src == null) { + if (src == null) + { return _ydim - 1; } @@ -788,7 +901,7 @@ private int NeighborHeight (int x, int z) } - private void TestBlockLight (IBoundedLitBlockCollection chunk, int x1, int y1, int z1, int x2, int y2, int z2) + private void TestBlockLight(IBoundedLitBlockCollection chunk, int x1, int y1, int z1, int x2, int y2, int z2) { int light1 = _blockset.GetBlockLight(x1, y1, z1); int light2 = chunk.GetBlockLight(x2, y2, z2); @@ -797,23 +910,25 @@ private void TestBlockLight (IBoundedLitBlockCollection chunk, int x1, int y1, i int v1 = Math.Max(light1, lum1); int v2 = Math.Max(light2, lum2); - if (Math.Abs(v1 - v2) > 1) { + if (Math.Abs(v1 - v2) > 1) + { QueueRelight(new BlockKey(x1, y1, z1)); } } - private void TestSkyLight (IBoundedLitBlockCollection chunk, int x1, int y1, int z1, int x2, int y2, int z2) + private void TestSkyLight(IBoundedLitBlockCollection chunk, int x1, int y1, int z1, int x2, int y2, int z2) { int light1 = _blockset.GetSkyLight(x1, y1, z1); int light2 = chunk.GetSkyLight(x2, y2, z2); - if (Math.Abs(light1 - light2) > 1) { + if (Math.Abs(light1 - light2) > 1) + { QueueRelight(new BlockKey(x1, y1, z1)); } } - private IBoundedLitBlockCollection[,] LocalBlockLightMap () + private IBoundedLitBlockCollection[,] LocalBlockLightMap() { IBoundedLitBlockCollection[,] map = new IBoundedLitBlockCollection[3, 3]; @@ -830,24 +945,29 @@ private void TestSkyLight (IBoundedLitBlockCollection chunk, int x1, int y1, int return map; } - private int[,] LocalHeightMap (IBoundedLitBlockCollection[,] chunkMap) + private int[,] LocalHeightMap(IBoundedLitBlockCollection[,] chunkMap) { int xdim = _xdim; int zdim = _zdim; int[,] map = new int[3 * xdim, 3 * zdim]; - for (int xi = 0; xi < 3; xi++) { + for (int xi = 0; xi < 3; xi++) + { int xoff = xi * xdim; - for (int zi = 0; zi < 3; zi++) { + for (int zi = 0; zi < 3; zi++) + { int zoff = zi * zdim; - if (chunkMap[xi, zi] == null) { + if (chunkMap[xi, zi] == null) + { continue; } - for (int x = 0; x < xdim; x++) { + for (int x = 0; x < xdim; x++) + { int xx = xoff + x; - for (int z = 0; z < zdim; z++) { + for (int z = 0; z < zdim; z++) + { int zz = zoff + z; map[xx, zz] = chunkMap[xi, zi].GetHeight(x, z); } @@ -859,19 +979,22 @@ private void TestSkyLight (IBoundedLitBlockCollection chunk, int x1, int y1, int } - private IBoundedLitBlockCollection OnResolveNeighbor (int relX, int relY, int relZ) + private IBoundedLitBlockCollection OnResolveNeighbor(int relX, int relY, int relZ) { - if (ResolveNeighbor != null) { + if (ResolveNeighbor != null) + { IBoundedLitBlockCollection n = ResolveNeighbor(relX, relY, relZ); - if (n == null) { + if (n == null) + { return null; } if (n.XDim != _xdim || n.YDim != _ydim || - n.ZDim != _zdim) { - throw new InvalidOperationException("Subscriber returned incompatible ILitBlockCollection"); + n.ZDim != _zdim) + { + throw new InvalidOperationException("Subscriber returned incompatible ILitBlockCollection"); } return n; @@ -880,6 +1003,6 @@ private IBoundedLitBlockCollection OnResolveNeighbor (int relX, int relY, int re return null; } - + } } diff --git a/SubstrateCS/Source/Core/BlockTileEntities.cs b/Substrate/Source/Core/BlockTileEntities.cs similarity index 70% rename from SubstrateCS/Source/Core/BlockTileEntities.cs rename to Substrate/Source/Core/BlockTileEntities.cs index 8b655328..ba3fcf7d 100644 --- a/SubstrateCS/Source/Core/BlockTileEntities.cs +++ b/Substrate/Source/Core/BlockTileEntities.cs @@ -4,7 +4,7 @@ namespace Substrate.Core { - public delegate BlockKey BlockCoordinateHandler (int lx, int ly, int lz); + public delegate BlockKey BlockCoordinateHandler(int lx, int ly, int lz); public class BlockTileEntities { @@ -15,7 +15,7 @@ public class BlockTileEntities public event BlockCoordinateHandler TranslateCoordinates; - public BlockTileEntities (IDataArray3 blocks, TagNodeList tileEntities) + public BlockTileEntities(IDataArray3 blocks, TagNodeList tileEntities) { _blocks = blocks; _tileEntities = tileEntities; @@ -23,7 +23,7 @@ public BlockTileEntities (IDataArray3 blocks, TagNodeList tileEntities) BuildTileEntityCache(); } - public BlockTileEntities (BlockTileEntities bte) + public BlockTileEntities(BlockTileEntities bte) { _blocks = bte._blocks; _tileEntities = bte._tileEntities; @@ -31,7 +31,7 @@ public BlockTileEntities (BlockTileEntities bte) BuildTileEntityCache(); } - public TileEntity GetTileEntity (int x, int y, int z) + public TileEntity GetTileEntity(int x, int y, int z) { BlockKey key = (TranslateCoordinates != null) ? TranslateCoordinates(x, y, z) @@ -39,17 +39,19 @@ public TileEntity GetTileEntity (int x, int y, int z) TagNodeCompound te; - if (!_tileEntityTable.TryGetValue(key, out te)) { + if (!_tileEntityTable.TryGetValue(key, out te)) + { return null; } return TileEntityFactory.CreateGeneric(te); } - public void SetTileEntity (int x, int y, int z, TileEntity te) + public void SetTileEntity(int x, int y, int z, TileEntity te) { - BlockInfoEx info = BlockInfo.BlockTable[_blocks[x, y, z]] as BlockInfoEx; - if (info != null) { + BlockInfo info = BlockInfo.BlockTable[_blocks[x, y, z]]; + if (info.TileEntityName != null) + { if (te.GetType() != TileEntityFactory.Lookup(info.TileEntityName)) throw new ArgumentException("The TileEntity type is not valid for this block.", "te"); } @@ -60,7 +62,8 @@ public void SetTileEntity (int x, int y, int z, TileEntity te) TagNodeCompound oldte; - if (_tileEntityTable.TryGetValue(key, out oldte)) { + if (_tileEntityTable.TryGetValue(key, out oldte)) + { _tileEntities.Remove(oldte); } @@ -74,15 +77,17 @@ public void SetTileEntity (int x, int y, int z, TileEntity te) _tileEntityTable[key] = tree; } - public void CreateTileEntity (int x, int y, int z) + public void CreateTileEntity(int x, int y, int z) { - BlockInfoEx info = BlockInfo.BlockTable[_blocks[x, y, z]] as BlockInfoEx; - if (info == null) { + BlockInfo info = BlockInfo.BlockTable[_blocks[x, y, z]]; + if (info.TileEntityName == null) + { throw new InvalidOperationException("The given block is of a type that does not support TileEntities."); } TileEntity te = TileEntityFactory.Create(info.TileEntityName); - if (te == null) { + if (te == null) + { throw new UnknownTileEntityException("The TileEntity type '" + info.TileEntityName + "' has not been registered with the TileEntityFactory."); } @@ -92,7 +97,8 @@ public void CreateTileEntity (int x, int y, int z) TagNodeCompound oldte; - if (_tileEntityTable.TryGetValue(key, out oldte)) { + if (_tileEntityTable.TryGetValue(key, out oldte)) + { _tileEntities.Remove(oldte); } @@ -106,7 +112,7 @@ public void CreateTileEntity (int x, int y, int z) _tileEntityTable[key] = tree; } - public void ClearTileEntity (int x, int y, int z) + public void ClearTileEntity(int x, int y, int z) { BlockKey key = (TranslateCoordinates != null) ? TranslateCoordinates(x, y, z) @@ -114,7 +120,8 @@ public void ClearTileEntity (int x, int y, int z) TagNodeCompound te; - if (!_tileEntityTable.TryGetValue(key, out te)) { + if (!_tileEntityTable.TryGetValue(key, out te)) + { return; } @@ -122,11 +129,12 @@ public void ClearTileEntity (int x, int y, int z) _tileEntityTable.Remove(key); } - private void BuildTileEntityCache () + private void BuildTileEntityCache() { _tileEntityTable = new Dictionary(); - foreach (TagNodeCompound te in _tileEntities) { + foreach (TagNodeCompound te in _tileEntities) + { int tex = te["x"].ToTagInt(); int tey = te["y"].ToTagInt(); int tez = te["z"].ToTagInt(); diff --git a/SubstrateCS/Source/Core/BlockTileTicks.cs b/Substrate/Source/Core/BlockTileTicks.cs similarity index 76% rename from SubstrateCS/Source/Core/BlockTileTicks.cs rename to Substrate/Source/Core/BlockTileTicks.cs index 7102c625..d6bc3c12 100644 --- a/SubstrateCS/Source/Core/BlockTileTicks.cs +++ b/Substrate/Source/Core/BlockTileTicks.cs @@ -13,7 +13,7 @@ public class BlockTileTicks public event BlockCoordinateHandler TranslateCoordinates; - public BlockTileTicks (IDataArray3 blocks, TagNodeList tileTicks) + public BlockTileTicks(IDataArray3 blocks, TagNodeList tileTicks) { _blocks = blocks; _tileTicks = tileTicks; @@ -21,7 +21,7 @@ public BlockTileTicks (IDataArray3 blocks, TagNodeList tileTicks) BuildTileTickCache(); } - public BlockTileTicks (BlockTileTicks bte) + public BlockTileTicks(BlockTileTicks bte) { _blocks = bte._blocks; _tileTicks = bte._tileTicks; @@ -29,7 +29,7 @@ public BlockTileTicks (BlockTileTicks bte) BuildTileTickCache(); } - public int GetTileTickValue (int x, int y, int z) + public int GetTileTickValue(int x, int y, int z) { BlockKey key = (TranslateCoordinates != null) ? TranslateCoordinates(x, y, z) @@ -37,7 +37,8 @@ public int GetTileTickValue (int x, int y, int z) TagNodeCompound te; - if (!_tileTickTable.TryGetValue(key, out te)) { + if (!_tileTickTable.TryGetValue(key, out te)) + { return 0; } @@ -47,7 +48,7 @@ public int GetTileTickValue (int x, int y, int z) return te["t"].ToTagInt().Data; } - public void SetTileTickValue (int x, int y, int z, int tickValue) + public void SetTileTickValue(int x, int y, int z, int tickValue) { BlockKey key = (TranslateCoordinates != null) ? TranslateCoordinates(x, y, z) @@ -55,7 +56,8 @@ public void SetTileTickValue (int x, int y, int z, int tickValue) TagNodeCompound te; - if (!_tileTickTable.TryGetValue(key, out te)) { + if (!_tileTickTable.TryGetValue(key, out te)) + { TileTick tt = new TileTick() { ID = _blocks[x, y, z], @@ -69,12 +71,13 @@ public void SetTileTickValue (int x, int y, int z, int tickValue) _tileTicks.Add(te); _tileTickTable[key] = te; } - else { + else + { te["t"].ToTagInt().Data = tickValue; } } - public TileTick GetTileTick (int x, int y, int z) + public TileTick GetTileTick(int x, int y, int z) { BlockKey key = (TranslateCoordinates != null) ? TranslateCoordinates(x, y, z) @@ -82,20 +85,23 @@ public TileTick GetTileTick (int x, int y, int z) TagNodeCompound te; - if (!_tileTickTable.TryGetValue(key, out te)) { + if (!_tileTickTable.TryGetValue(key, out te)) + { return null; } - if (!te.ContainsKey("i")) { + if (!te.ContainsKey("i")) + { return null; } return TileTick.FromTreeSafe(te); } - public void SetTileTick (int x, int y, int z, TileTick te) + public void SetTileTick(int x, int y, int z, TileTick te) { - if (te.ID != _blocks[x, y, z]) { + if (te.ID != _blocks[x, y, z]) + { throw new ArgumentException("The TileTick type is not valid for this block.", "te"); } @@ -105,7 +111,8 @@ public void SetTileTick (int x, int y, int z, TileTick te) TagNodeCompound oldte; - if (_tileTickTable.TryGetValue(key, out oldte)) { + if (_tileTickTable.TryGetValue(key, out oldte)) + { _tileTicks.Remove(oldte); } @@ -119,7 +126,7 @@ public void SetTileTick (int x, int y, int z, TileTick te) _tileTickTable[key] = tree; } - public void CreateTileTick (int x, int y, int z) + public void CreateTileTick(int x, int y, int z) { TileTick te = new TileTick() { @@ -132,7 +139,8 @@ public void CreateTileTick (int x, int y, int z) TagNodeCompound oldte; - if (_tileTickTable.TryGetValue(key, out oldte)) { + if (_tileTickTable.TryGetValue(key, out oldte)) + { _tileTicks.Remove(oldte); } @@ -146,7 +154,7 @@ public void CreateTileTick (int x, int y, int z) _tileTickTable[key] = tree; } - public void ClearTileTick (int x, int y, int z) + public void ClearTileTick(int x, int y, int z) { BlockKey key = (TranslateCoordinates != null) ? TranslateCoordinates(x, y, z) @@ -154,7 +162,8 @@ public void ClearTileTick (int x, int y, int z) TagNodeCompound te; - if (!_tileTickTable.TryGetValue(key, out te)) { + if (!_tileTickTable.TryGetValue(key, out te)) + { return; } @@ -162,11 +171,12 @@ public void ClearTileTick (int x, int y, int z) _tileTickTable.Remove(key); } - private void BuildTileTickCache () + private void BuildTileTickCache() { _tileTickTable = new Dictionary(); - foreach (TagNodeCompound te in _tileTicks) { + foreach (TagNodeCompound te in _tileTicks) + { int tex = te["x"].ToTagInt(); int tey = te["y"].ToTagInt(); int tez = te["z"].ToTagInt(); diff --git a/SubstrateCS/Source/Core/BoundedBlockInterface.cs b/Substrate/Source/Core/BoundedBlockInterface.cs similarity index 90% rename from SubstrateCS/Source/Core/BoundedBlockInterface.cs rename to Substrate/Source/Core/BoundedBlockInterface.cs index b1cb6e10..b9a1aec2 100644 --- a/SubstrateCS/Source/Core/BoundedBlockInterface.cs +++ b/Substrate/Source/Core/BoundedBlockInterface.cs @@ -29,7 +29,7 @@ public interface IBoundedBlockCollection /// /// The id (type) of the block to count. /// The count of blocks in the container matching the given id (type). - int CountByID (int id); + int CountByID(int id); /// /// Gets a basic block from a bounded block container. @@ -38,7 +38,7 @@ public interface IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// A basic from the collection at the given coordinates. - IBlock GetBlock (int x, int y, int z); + IBlock GetBlock(int x, int y, int z); /// /// Gets a reference object to a basic within a bounded block container. @@ -47,7 +47,7 @@ public interface IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// A basic acting as a reference directly into the container at the given coordinates. - IBlock GetBlockRef (int x, int y, int z); + IBlock GetBlockRef(int x, int y, int z); /// /// Updates a block in a bounded block container with data from an existing object. @@ -56,7 +56,7 @@ public interface IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The to copy basic data from. - void SetBlock (int x, int y, int z, IBlock block); + void SetBlock(int x, int y, int z, IBlock block); /// /// Gets a block's id (type) from a bounded block container. @@ -65,7 +65,7 @@ public interface IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The block id (type) from the block container at the given coordinates. - int GetID (int x, int y, int z); + int GetID(int x, int y, int z); /// /// Sets a block's id (type) within a bounded block container. @@ -74,7 +74,7 @@ public interface IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The id (type) to assign to a block at the given coordinates. - void SetID (int x, int y, int z, int id); + void SetID(int x, int y, int z, int id); /// /// Gets info and attributes on a block's type within a bounded block container. @@ -83,7 +83,7 @@ public interface IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// A instance for the block's type. - BlockInfo GetInfo (int x, int y, int z); + BlockInfo GetInfo(int x, int y, int z); } /// @@ -99,7 +99,7 @@ public interface IBoundedDataBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// An from the collection at the given coordinates. - new IDataBlock GetBlock (int x, int y, int z); + new IDataBlock GetBlock(int x, int y, int z); /// /// Gets a reference object to a block with data field within a bounded block container. @@ -108,7 +108,7 @@ public interface IBoundedDataBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// An acting as a reference directly into the container at the given coordinates. - new IDataBlock GetBlockRef (int x, int y, int z); + new IDataBlock GetBlockRef(int x, int y, int z); /// /// Updates a block in a bounded block container with data from an existing object. @@ -117,7 +117,7 @@ public interface IBoundedDataBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The to copy data from. - void SetBlock (int x, int y, int z, IDataBlock block); + void SetBlock(int x, int y, int z, IDataBlock block); /// /// Gets a block's data field from a bounded block container. @@ -126,7 +126,7 @@ public interface IBoundedDataBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The data field of a block at the given coordinates. - int GetData (int x, int y, int z); + int GetData(int x, int y, int z); /// /// Sets a block's data field within a bounded block container. @@ -135,7 +135,7 @@ public interface IBoundedDataBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The data field to assign to a block at the given coordinates. - void SetData (int x, int y, int z, int data); + void SetData(int x, int y, int z, int data); /// /// Counts all blocks within a bounded container set to a given id (type) and data value. @@ -143,7 +143,7 @@ public interface IBoundedDataBlockCollection : IBoundedBlockCollection /// The id (type) of blocks to match. /// The data value of blocks to match. /// A count of all blocks in the container matching both conditions. - int CountByData (int id, int data); + int CountByData(int id, int data); } /// @@ -159,7 +159,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// An from the collection at the given coordinates. - new ILitBlock GetBlock (int x, int y, int z); + new ILitBlock GetBlock(int x, int y, int z); /// /// Gets a reference object to a block with lighting information within a bounded block container. @@ -168,7 +168,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// An acting as a reference directly into the container at the given coordinates. - new ILitBlock GetBlockRef (int x, int y, int z); + new ILitBlock GetBlockRef(int x, int y, int z); /// /// Updates a block in a bounded block container with data from an existing object. @@ -177,7 +177,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The to copy data from. - void SetBlock (int x, int y, int z, ILitBlock block); + void SetBlock(int x, int y, int z, ILitBlock block); /// /// Gets a block's block-source light value from a bounded block container. @@ -186,7 +186,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The block-source light value of a block at the given coordinates. - int GetBlockLight (int x, int y, int z); + int GetBlockLight(int x, int y, int z); /// /// Gets a block's sky-source light value from a bounded block container. @@ -195,7 +195,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The sky-source light value of a block at the given coordinates. - int GetSkyLight (int x, int y, int z); + int GetSkyLight(int x, int y, int z); /// /// Sets a block's block-source light value within a bounded block container. @@ -204,7 +204,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The block-source light value to assign to a block at the given coordinates. - void SetBlockLight (int x, int y, int z, int light); + void SetBlockLight(int x, int y, int z, int light); /// /// Sets a block's sky-source light value within a bounded block container. @@ -213,7 +213,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The sky-source light value to assign to a block at the given coordinates. - void SetSkyLight (int x, int y, int z, int light); + void SetSkyLight(int x, int y, int z, int light); /// /// Gets the Y-coordinate of the lowest block with unobstructed view of the sky at the given coordinates within a bounded block container. @@ -223,7 +223,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// The height value of an X-Z coordinate pair in the block container. /// The height value represents the lowest block with an unobstructed view of the sky. This is the lowest block with /// a maximum-value sky-light value. Fully transparent blocks, like glass, do not count as an obstruction. - int GetHeight (int x, int z); + int GetHeight(int x, int z); /// /// Sets the Y-coordinate of the lowest block with unobstructed view of the sky at the given coordinates within a bounded block container. @@ -233,7 +233,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// The height value of an X-Z coordinate pair in the block container. /// Minecraft lighting algorithms rely heavily on this value being correct. Setting this value too low may result in /// rooms that can never get dark, for example. - void SetHeight (int x, int z, int height); + void SetHeight(int x, int z, int height); /// /// Recalculates the block-source light value of a single block within a bounded block container. @@ -247,7 +247,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// This function assumes that the entire and neighboring s /// already have consistent lighting, with the exception of the block being updated. If this assumption is violated, /// lighting may fail to converge correctly. - void UpdateBlockLight (int x, int y, int z); + void UpdateBlockLight(int x, int y, int z); /// /// Recalculates the sky-source light value of a single block within a bounded block container. @@ -261,17 +261,17 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// This function assumes that the entire and neighboring s /// already have consistent lighting, with the exception of the block being updated. If this assumption is violated, /// lighting may fail to converge correctly. - void UpdateSkyLight (int x, int y, int z); + void UpdateSkyLight(int x, int y, int z); /// /// Resets the block-source light value to 0 for all blocks within a bounded block container. /// - void ResetBlockLight (); + void ResetBlockLight(); /// /// Resets the sky-source light value to 0 for all blocks within a bounded block container. /// - void ResetSkyLight (); + void ResetSkyLight(); /// /// Reconstructs the block-source lighting for all blocks within a bounded block container. @@ -283,7 +283,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// be preferable to avoid explicit or implicit calls to and call this function once when /// modifications are complete. /// - void RebuildBlockLight (); + void RebuildBlockLight(); /// /// Reconstructs the sky-source lighting for all blocks within a bounded block container. @@ -295,12 +295,12 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// be preferable to avoid explicit or implicit calls to and call this function once when /// modifications are complete. /// - void RebuildSkyLight (); + void RebuildSkyLight(); /// /// Reconstructs the height-map for a bounded block container. /// - void RebuildHeightMap (); + void RebuildHeightMap(); /// /// Reconciles any block-source lighting inconsistencies between this and any of its neighbors. @@ -309,7 +309,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// some of its neighbors are not. A rebuilt will spill lighting updates into its neighbors, /// but will not see lighting that should be propagated back from its neighbors. /// - void StitchBlockLight (); + void StitchBlockLight(); /// /// Reconciles any sky-source lighting inconsistencies between this and any of its neighbors. @@ -318,7 +318,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// some of its neighbors are not. A rebuilt will spill lighting updates into its neighbors, /// but will not see lighting that should be propagated back from its neighbors. /// - void StitchSkyLight (); + void StitchSkyLight(); /// /// Reconciles any block-source lighting inconsistencies between this and another on a given edge. @@ -329,7 +329,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// some of its neighbors are not. A rebuilt will spill lighting updates into its neighbors, /// but will not see lighting that should be propagated back from its neighbors. /// - void StitchBlockLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge); + void StitchBlockLight(IBoundedLitBlockCollection blockset, BlockCollectionEdge edge); /// /// Reconciles any sky-source lighting inconsistencies between this and another on a given edge. @@ -340,7 +340,7 @@ public interface IBoundedLitBlockCollection : IBoundedBlockCollection /// some of its neighbors are not. A rebuilt will spill lighting updates into its neighbors, /// but will not see lighting that should be propagated back from its neighbors. /// - void StitchSkyLight (IBoundedLitBlockCollection blockset, BlockCollectionEdge edge); + void StitchSkyLight(IBoundedLitBlockCollection blockset, BlockCollectionEdge edge); } /// @@ -356,7 +356,7 @@ public interface IBoundedPropertyBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// An from the collection at the given coordinates. - new IPropertyBlock GetBlock (int x, int y, int z); + new IPropertyBlock GetBlock(int x, int y, int z); /// /// Gets a reference object to a block supporting extra properties within a bounded block container. @@ -365,7 +365,7 @@ public interface IBoundedPropertyBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// An acting as a reference directly into the container at the given coordinates. - new IPropertyBlock GetBlockRef (int x, int y, int z); + new IPropertyBlock GetBlockRef(int x, int y, int z); /// /// Updates a block in a bounded block container with data from an existing object. @@ -374,7 +374,7 @@ public interface IBoundedPropertyBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The to copy data from. - void SetBlock (int x, int y, int z, IPropertyBlock block); + void SetBlock(int x, int y, int z, IPropertyBlock block); /// /// Gets the record of a block within a bounded block container. @@ -383,7 +383,7 @@ public interface IBoundedPropertyBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// A record attached to a block at the given coordinates, or null if no tile entity is set. - TileEntity GetTileEntity (int x, int y, int z); + TileEntity GetTileEntity(int x, int y, int z); /// /// Sets a record to a block within a bounded block container. @@ -394,7 +394,7 @@ public interface IBoundedPropertyBlockCollection : IBoundedBlockCollection /// The record to assign to the given block. /// Thrown when an incompatible is added to a block. /// Thrown when a is added to a block that does not use tile entities. - void SetTileEntity (int x, int y, int z, TileEntity te); + void SetTileEntity(int x, int y, int z, TileEntity te); /// /// Creates a new default record for a block within a bounded block container. @@ -404,7 +404,7 @@ public interface IBoundedPropertyBlockCollection : IBoundedBlockCollection /// The container-local Z-coordinate of a block. /// Thrown when a is created for a block that does not use tile entities. /// Thrown when the tile entity type associated with the given block has not been registered with . - void CreateTileEntity (int x, int y, int z); + void CreateTileEntity(int x, int y, int z); /// /// Deletes a record associated with a block within a bounded block container, if it exists. @@ -412,7 +412,7 @@ public interface IBoundedPropertyBlockCollection : IBoundedBlockCollection /// The container-local X-coordinate of a block. /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. - void ClearTileEntity (int x, int y, int z); + void ClearTileEntity(int x, int y, int z); } /// @@ -428,7 +428,7 @@ public interface IBoundedActiveBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// An from the collection at the given coordinates. - new IActiveBlock GetBlock (int x, int y, int z); + new IActiveBlock GetBlock(int x, int y, int z); /// /// Gets a reference object to a block supporting active processing properties within a bounded block container. @@ -437,7 +437,7 @@ public interface IBoundedActiveBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// An acting as a reference directly into the container at the given coordinates. - new IActiveBlock GetBlockRef (int x, int y, int z); + new IActiveBlock GetBlockRef(int x, int y, int z); /// /// Updates a block in a bounded block container with data from an existing object. @@ -446,7 +446,7 @@ public interface IBoundedActiveBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The to copy data from. - void SetBlock (int x, int y, int z, IActiveBlock block); + void SetBlock(int x, int y, int z, IActiveBlock block); /// /// Gets the record of a block within a bounded block container. @@ -455,7 +455,7 @@ public interface IBoundedActiveBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// A record attached to a block at the given coordinates, or null if no tile entity is set. - TileTick GetTileTick (int x, int y, int z); + TileTick GetTileTick(int x, int y, int z); /// /// Sets a record to a block within a bounded block container. @@ -464,7 +464,7 @@ public interface IBoundedActiveBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The record to assign to the given block. - void SetTileTick (int x, int y, int z, TileTick tt); + void SetTileTick(int x, int y, int z, TileTick tt); /// /// Creates a new default record for a block within a bounded block container. @@ -472,7 +472,7 @@ public interface IBoundedActiveBlockCollection : IBoundedBlockCollection /// The container-local X-coordinate of a block. /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. - void CreateTileTick (int x, int y, int z); + void CreateTileTick(int x, int y, int z); /// /// Deletes a record associated with a block within a bounded block container, if it exists. @@ -480,7 +480,7 @@ public interface IBoundedActiveBlockCollection : IBoundedBlockCollection /// The container-local X-coordinate of a block. /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. - void ClearTileTick (int x, int y, int z); + void ClearTileTick(int x, int y, int z); /// /// Gets the tick delay specified in a block's entry, if it exists. @@ -489,7 +489,7 @@ public interface IBoundedActiveBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The tick delay in a block's entry, or 0 if no entry exists. - int GetTileTickValue (int x, int y, int z); + int GetTileTickValue(int x, int y, int z); /// /// Sets the tick delay in a block's entry. @@ -498,7 +498,7 @@ public interface IBoundedActiveBlockCollection : IBoundedBlockCollection /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The tick delay that specifies when this block should next be processed for update. - void SetTileTickValue (int x, int y, int z, int tickValue); + void SetTileTickValue(int x, int y, int z, int tickValue); } /// @@ -514,7 +514,7 @@ public interface IBoundedAlphaBlockCollection : IBoundedDataBlockCollection, IBo /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// An from the collection at the given coordinates. - new AlphaBlock GetBlock (int x, int y, int z); + new AlphaBlock GetBlock(int x, int y, int z); /// /// Gets a reference object to a context-sensitive Alpha-compatible block within a bounded block container. @@ -523,7 +523,7 @@ public interface IBoundedAlphaBlockCollection : IBoundedDataBlockCollection, IBo /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// An acting as a reference directly into the container at the given coordinates. - new AlphaBlockRef GetBlockRef (int x, int y, int z); + new AlphaBlockRef GetBlockRef(int x, int y, int z); /// /// Updates a block in a bounded block container with data from an existing object. @@ -532,6 +532,6 @@ public interface IBoundedAlphaBlockCollection : IBoundedDataBlockCollection, IBo /// The container-local Y-coordinate of a block. /// The container-local Z-coordinate of a block. /// The to copy data from. - void SetBlock (int x, int y, int z, AlphaBlock block); + void SetBlock(int x, int y, int z, AlphaBlock block); } } diff --git a/SubstrateCS/Source/Core/ByteArray.cs b/Substrate/Source/Core/ByteArray.cs similarity index 80% rename from SubstrateCS/Source/Core/ByteArray.cs rename to Substrate/Source/Core/ByteArray.cs index 75aa93e5..0e7d83a8 100644 --- a/SubstrateCS/Source/Core/ByteArray.cs +++ b/Substrate/Source/Core/ByteArray.cs @@ -10,7 +10,7 @@ public interface IDataArray int Length { get; } int DataWidth { get; } - void Clear (); + void Clear(); } public interface IDataArray2 : IDataArray @@ -29,20 +29,20 @@ public interface IDataArray3 : IDataArray int YDim { get; } int ZDim { get; } - int GetIndex (int x, int y, int z); - void GetMultiIndex (int index, out int x, out int y, out int z); + int GetIndex(int x, int y, int z); + void GetMultiIndex(int index, out int x, out int y, out int z); } public class ByteArray : IDataArray, ICopyable { protected readonly byte[] dataArray; - public ByteArray (int length) + public ByteArray(int length) { dataArray = new byte[length]; } - public ByteArray (byte[] data) + public ByteArray(byte[] data) { dataArray = data; } @@ -63,7 +63,7 @@ public int DataWidth get { return 8; } } - public void Clear () + public void Clear() { for (int i = 0; i < dataArray.Length; i++) { @@ -73,7 +73,7 @@ public void Clear () #region ICopyable Members - public virtual ByteArray Copy () + public virtual ByteArray Copy() { byte[] data = new byte[dataArray.Length]; dataArray.CopyTo(data, 0); @@ -90,7 +90,7 @@ public sealed class XZYByteArray : ByteArray, IDataArray3 private readonly int _ydim; private readonly int _zdim; - public XZYByteArray (int xdim, int ydim, int zdim) + public XZYByteArray(int xdim, int ydim, int zdim) : base(xdim * ydim * zdim) { _xdim = xdim; @@ -98,7 +98,7 @@ public XZYByteArray (int xdim, int ydim, int zdim) _zdim = zdim; } - public XZYByteArray (int xdim, int ydim, int zdim, byte[] data) + public XZYByteArray(int xdim, int ydim, int zdim, byte[] data) : base(data) { _xdim = xdim; @@ -141,12 +141,12 @@ public int ZDim get { return _zdim; } } - public int GetIndex (int x, int y, int z) + public int GetIndex(int x, int y, int z) { return _ydim * (x * _zdim + z) + y; } - public void GetMultiIndex (int index, out int x, out int y, out int z) + public void GetMultiIndex(int index, out int x, out int y, out int z) { int yzdim = _ydim * _zdim; x = index / yzdim; @@ -158,7 +158,7 @@ public void GetMultiIndex (int index, out int x, out int y, out int z) #region ICopyable Members - public override ByteArray Copy () + public override ByteArray Copy() { byte[] data = new byte[dataArray.Length]; dataArray.CopyTo(data, 0); @@ -175,7 +175,7 @@ public sealed class YZXByteArray : ByteArray, IDataArray3 private readonly int _ydim; private readonly int _zdim; - public YZXByteArray (int xdim, int ydim, int zdim) + public YZXByteArray(int xdim, int ydim, int zdim) : base(xdim * ydim * zdim) { _xdim = xdim; @@ -183,14 +183,15 @@ public YZXByteArray (int xdim, int ydim, int zdim) _zdim = zdim; } - public YZXByteArray (int xdim, int ydim, int zdim, byte[] data) + public YZXByteArray(int xdim, int ydim, int zdim, byte[] data) : base(data) { _xdim = xdim; _ydim = ydim; _zdim = zdim; - if (xdim * ydim * zdim != data.Length) { + if (xdim * ydim * zdim != data.Length) + { throw new ArgumentException("Product of dimensions must equal length of data"); } } @@ -225,12 +226,12 @@ public int ZDim get { return _zdim; } } - public int GetIndex (int x, int y, int z) + public int GetIndex(int x, int y, int z) { return _xdim * (y * _zdim + z) + x; } - public void GetMultiIndex (int index, out int x, out int y, out int z) + public void GetMultiIndex(int index, out int x, out int y, out int z) { int xzdim = _xdim * _zdim; y = index / xzdim; @@ -242,7 +243,7 @@ public void GetMultiIndex (int index, out int x, out int y, out int z) #region ICopyable Members - public override ByteArray Copy () + public override ByteArray Copy() { byte[] data = new byte[dataArray.Length]; dataArray.CopyTo(data, 0); @@ -258,14 +259,14 @@ public sealed class ZXByteArray : ByteArray, IDataArray2 private readonly int _xdim; private readonly int _zdim; - public ZXByteArray (int xdim, int zdim) + public ZXByteArray(int xdim, int zdim) : base(xdim * zdim) { _xdim = xdim; _zdim = zdim; } - public ZXByteArray (int xdim, int zdim, byte[] data) + public ZXByteArray(int xdim, int zdim, byte[] data) : base(data) { _xdim = xdim; @@ -304,7 +305,7 @@ public int ZDim #region ICopyable Members - public override ByteArray Copy () + public override ByteArray Copy() { byte[] data = new byte[dataArray.Length]; dataArray.CopyTo(data, 0); @@ -319,12 +320,12 @@ public class IntArray : IDataArray, ICopyable { protected readonly int[] dataArray; - public IntArray (int length) + public IntArray(int length) { dataArray = new int[length]; } - public IntArray (int[] data) + public IntArray(int[] data) { dataArray = data; } @@ -345,16 +346,17 @@ public int DataWidth get { return 32; } } - public void Clear () + public void Clear() { - for (int i = 0; i < dataArray.Length; i++) { + for (int i = 0; i < dataArray.Length; i++) + { dataArray[i] = 0; } } #region ICopyable Members - public virtual IntArray Copy () + public virtual IntArray Copy() { int[] data = new int[dataArray.Length]; dataArray.CopyTo(data, 0); @@ -370,20 +372,21 @@ public sealed class ZXIntArray : IntArray, IDataArray2 private readonly int _xdim; private readonly int _zdim; - public ZXIntArray (int xdim, int zdim) + public ZXIntArray(int xdim, int zdim) : base(xdim * zdim) { _xdim = xdim; _zdim = zdim; } - public ZXIntArray (int xdim, int zdim, int[] data) + public ZXIntArray(int xdim, int zdim, int[] data) : base(data) { _xdim = xdim; _zdim = zdim; - if (xdim * zdim != data.Length) { + if (xdim * zdim != data.Length) + { throw new ArgumentException("Product of dimensions must equal length of data"); } } @@ -415,7 +418,7 @@ public int ZDim #region ICopyable Members - public override IntArray Copy () + public override IntArray Copy() { int[] data = new int[dataArray.Length]; dataArray.CopyTo(data, 0); diff --git a/SubstrateCS/Source/Core/ChunkCache.cs b/Substrate/Source/Core/ChunkCache.cs similarity index 83% rename from SubstrateCS/Source/Core/ChunkCache.cs rename to Substrate/Source/Core/ChunkCache.cs index 7404e67f..10c7cc1c 100644 --- a/SubstrateCS/Source/Core/ChunkCache.cs +++ b/Substrate/Source/Core/ChunkCache.cs @@ -17,7 +17,7 @@ public class ChunkCache /// /// Creates a new with the default capacity of 256 chunks. /// - public ChunkCache () + public ChunkCache() : this(256) { } @@ -26,7 +26,7 @@ public ChunkCache () /// Creates a new with the given chunk capacity. /// /// The capacity of the LRU-portion of the cache. - public ChunkCache (int cacheSize) + public ChunkCache(int cacheSize) { _cache = new LRUCache(cacheSize); _dirty = new Dictionary(); @@ -43,14 +43,15 @@ public ChunkCache (int cacheSize) /// True if the chunk did not already exist in the cache, false otherwise. /// If the chunk does not already exist and the list is full, then the least-recently used chunk in the cache will be evicted /// to make room for the new chunk. If the chunk is present in the dirty list, it will be removed. - public bool Insert (ChunkRef chunk) + public bool Insert(ChunkRef chunk) { ChunkKey key = new ChunkKey(chunk.X, chunk.Z); _dirty.Remove(key); ChunkRef c; - if (!_cache.TryGetValue(key, out c)) { + if (!_cache.TryGetValue(key, out c)) + { _cache[key] = chunk; return true; } @@ -64,7 +65,7 @@ public bool Insert (ChunkRef chunk) /// The key identifying which to try and remove. /// True if the chunk was in the LRU-portion of the cache and removed, False otherwise. /// The chunk will also be removed from the dirty list, if it is currently in it. - public bool Remove (ChunkKey key) + public bool Remove(ChunkKey key) { _dirty.Remove(key); return _cache.Remove(key); @@ -77,14 +78,16 @@ public bool Remove (ChunkKey key) /// The cached if it was found anywhere in the cache, or null if it was not found. /// If the is found in the LRU-portion of the cache, it will be moved to the front of the /// LRU list, making future eviction less likely. - public ChunkRef Fetch (ChunkKey key) + public ChunkRef Fetch(ChunkKey key) { ChunkRef c; - if (_dirty.TryGetValue(key, out c)) { + if (_dirty.TryGetValue(key, out c)) + { return c; } - if (_cache.TryGetValue(key, out c)) { + if (_cache.TryGetValue(key, out c)) + { return c; } @@ -95,7 +98,7 @@ public ChunkRef Fetch (ChunkKey key) /// Gets an enumerator to iterate over all of the objects currently in the dirty list. /// /// An enumerator over all of the dirty objects. - public IEnumerator GetDirtyEnumerator () + public IEnumerator GetDirtyEnumerator() { return _dirty.Values.GetEnumerator(); } @@ -106,7 +109,7 @@ public IEnumerator GetDirtyEnumerator () /// This method will clear all chunks from the LRU-portion of the cache, including any chunks that are /// dirty but have not yet been discovered and added to the dirty list. Chunks already in the dirty list will /// not be affected. To clear dirty chunks as well, see . - public void Clear () + public void Clear() { _cache.Clear(); } @@ -114,7 +117,7 @@ public void Clear () /// /// Clears all chunks from the dirty list. /// - public void ClearDirty () + public void ClearDirty() { _dirty.Clear(); } @@ -122,19 +125,22 @@ public void ClearDirty () /// /// Scans the LRU list for any dirty chunks, and adds them to the dirty list. /// - public void SyncDirty () + public void SyncDirty() { - foreach (KeyValuePair e in _cache) { - if (e.Value.IsDirty) { + foreach (KeyValuePair e in _cache) + { + if (e.Value.IsDirty) + { _dirty[e.Key] = e.Value; } } } - private void EvictionHandler (object sender, LRUCache.CacheValueArgs e) + private void EvictionHandler(object sender, LRUCache.CacheValueArgs e) { - if (e.Value.IsDirty) { + if (e.Value.IsDirty) + { _dirty[e.Key] = e.Value; } } diff --git a/SubstrateCS/Source/Core/ChunkFile.cs b/Substrate/Source/Core/ChunkFile.cs similarity index 72% rename from SubstrateCS/Source/Core/ChunkFile.cs rename to Substrate/Source/Core/ChunkFile.cs index 06997dc8..b0a02979 100644 --- a/SubstrateCS/Source/Core/ChunkFile.cs +++ b/Substrate/Source/Core/ChunkFile.cs @@ -8,22 +8,24 @@ namespace Substrate.Core { public class ChunkFile : NBTFile { - public ChunkFile (string path) + public ChunkFile(string path) : base(path) { } - public ChunkFile (string path, int cx, int cz) + public ChunkFile(string path, int cx, int cz) : base("") { string cx64 = Base36.Encode(cx); string cz64 = Base36.Encode(cz); string file = "c." + cx64 + "." + cz64 + ".dat"; - while (cx < 0) { + while (cx < 0) + { cx += (64 * 64); } - while (cz < 0) { + while (cz < 0) + { cz += (64 * 64); } @@ -31,12 +33,14 @@ public ChunkFile (string path, int cx, int cz) string dir2 = Base36.Encode(cz % 64); FileName = Path.Combine(path, dir1); - if (!Directory.Exists(FileName)) { + if (!Directory.Exists(FileName)) + { Directory.CreateDirectory(FileName); } FileName = Path.Combine(FileName, dir2); - if (!Directory.Exists(FileName)) { + if (!Directory.Exists(FileName)) + { Directory.CreateDirectory(FileName); } diff --git a/SubstrateCS/Source/Core/ChunkInterface.cs b/Substrate/Source/Core/ChunkInterface.cs similarity index 92% rename from SubstrateCS/Source/Core/ChunkInterface.cs rename to Substrate/Source/Core/ChunkInterface.cs index fab7ee91..ce2dd094 100644 --- a/SubstrateCS/Source/Core/ChunkInterface.cs +++ b/Substrate/Source/Core/ChunkInterface.cs @@ -41,14 +41,14 @@ public interface IChunk /// Terrain features include ores, water and lava sources, dungeons, trees, flowers, etc. bool IsTerrainPopulated { get; set; } - void SetLocation (int x, int z); + void SetLocation(int x, int z); /// /// Writes out the chunk's data to an output stream. /// /// A valid, open output stream. /// True if the chunk could be saved; false otherwise. - bool Save (Stream outStream); + bool Save(Stream outStream); } /// @@ -64,7 +64,7 @@ public interface IChunkContainer /// This is largely intended for internal use. If an is assigned coordinates by an /// , the interpretation of those coordinates is ambiguous. This method ensures the coordinate /// returned is interpreted as a global coordinate. - int ChunkGlobalX (int cx); + int ChunkGlobalX(int cx); /// /// Returns a global chunk Z-coordinate, given a container-defined Z-coordinate. @@ -74,7 +74,7 @@ public interface IChunkContainer /// This is largely intended for internal use. If an is assigned coordinates by an /// , the interpretation of those coordinates is ambiguous. This method ensures the coordinate /// returned is interpreted as a global coordinate. - int ChunkGlobalZ (int cz); + int ChunkGlobalZ(int cz); /// /// Returns a local chunk X-coordinate, given a container-defined X-coordinate. @@ -84,7 +84,7 @@ public interface IChunkContainer /// This is largely intended for internal use. If an is assigned coordinates by an /// , the interpretation of those coordinates is ambiguous. This method ensures the coordinate /// returned is interpreted as a local coordinate. - int ChunkLocalX (int cx); + int ChunkLocalX(int cx); /// /// Returns a local chunk Z-coordinate, given a container-defined Z-coordinate. @@ -94,7 +94,7 @@ public interface IChunkContainer /// This is largely intended for internal use. If an is assigned coordinates by an /// , the interpretation of those coordinates is ambiguous. This method ensures the coordinate /// returned is interpreted as a local coordinate. - int ChunkLocalZ (int cz); + int ChunkLocalZ(int cz); /// /// Gets an unwrapped object for the given container-local coordinates. @@ -102,7 +102,7 @@ public interface IChunkContainer /// The container-local X-coordinate of a chunk. /// The container-local Z-coordinate of a chunk. /// A for the given coordinates, or null if no chunk exists at those coordinates. - IChunk GetChunk (int cx, int cz); + IChunk GetChunk(int cx, int cz); /// /// Gets a binding a chunk to this container for the given container-local coordinates. @@ -111,7 +111,7 @@ public interface IChunkContainer /// The container-local Z-coordinate of a chunk. /// A for the given coordinates binding a to this container, or null if /// no chunk exists at the given coordinates. - ChunkRef GetChunkRef (int cx, int cz); + ChunkRef GetChunkRef(int cx, int cz); /// /// Creates an empty chunk at the given coordinates, if no chunk previously exists. @@ -121,7 +121,7 @@ public interface IChunkContainer /// A for the newly created chunk if no previous chunk existed; a /// to the existing chunk otherwise. /// This method ensures that an empty/default chunk is written out to the underlying data store before returning. - ChunkRef CreateChunk (int cx, int cz); + ChunkRef CreateChunk(int cx, int cz); /// /// Saves an unwrapped to the container at the given container-local coordinates. @@ -136,7 +136,7 @@ public interface IChunkContainer /// other is written to the underlying data store with invalid coordinates. /// The specification is designed to avoid this situation from occuring, but /// class hierarchy extensions could violate these safeguards. - ChunkRef SetChunk (int cx, int cz, IChunk chunk); + ChunkRef SetChunk(int cx, int cz, IChunk chunk); /// /// Checks if a chunk exists at the given container-local coordinates. @@ -144,7 +144,7 @@ public interface IChunkContainer /// The container-local X-coordinate of a chunk. /// The container-local Z-coordinate of a chunk. /// True if a chunk exists at the given coordinates; false otherwise. - bool ChunkExists (int cx, int cz); + bool ChunkExists(int cx, int cz); /// /// Deletes a chunk at the given container-local coordinates if it exists. @@ -152,7 +152,7 @@ public interface IChunkContainer /// The container-local X-coordinate of a chunk. /// The container-local Z-coordinate of a chunk. /// True if a chunk existed and was deleted; false otherwise. - bool DeleteChunk (int cx, int cz); + bool DeleteChunk(int cx, int cz); /// /// Saves any chunks in the container that currently have unsaved changes. @@ -162,11 +162,11 @@ public interface IChunkContainer /// modified by an action on this container that was delegated to another container will not be saved. The foreign /// containers must be individually saved, but are guaranteed to know about the unsaved changes originating from /// an action in another container. - int Save (); + int Save(); // TODO: Check that this doesn't violate borders /// - bool SaveChunk (IChunk chunk); + bool SaveChunk(IChunk chunk); /// /// Checks if this container supports delegating an action on out-of-bounds coordinates to another container. diff --git a/SubstrateCS/Source/Core/ChunkKey.cs b/Substrate/Source/Core/ChunkKey.cs similarity index 64% rename from SubstrateCS/Source/Core/ChunkKey.cs rename to Substrate/Source/Core/ChunkKey.cs index d617a5c2..0f1a3225 100644 --- a/SubstrateCS/Source/Core/ChunkKey.cs +++ b/Substrate/Source/Core/ChunkKey.cs @@ -9,28 +9,30 @@ public struct ChunkKey : IEquatable public readonly int cx; public readonly int cz; - public ChunkKey (int _cx, int _cz) + public ChunkKey(int _cx, int _cz) { cx = _cx; cz = _cz; } - public bool Equals (ChunkKey ck) + public bool Equals(ChunkKey ck) { return this.cx == ck.cx && this.cz == ck.cz; } - public override bool Equals (Object o) + public override bool Equals(Object o) { - try { + try + { return this == (ChunkKey)o; } - catch { + catch + { return false; } } - public override int GetHashCode () + public override int GetHashCode() { int hash = 23; hash = hash * 37 + cx; @@ -38,17 +40,17 @@ public override int GetHashCode () return hash; } - public static bool operator == (ChunkKey k1, ChunkKey k2) + public static bool operator ==(ChunkKey k1, ChunkKey k2) { return k1.cx == k2.cx && k1.cz == k2.cz; } - public static bool operator != (ChunkKey k1, ChunkKey k2) + public static bool operator !=(ChunkKey k1, ChunkKey k2) { return k1.cx != k2.cx || k1.cz != k2.cz; } - public override string ToString () + public override string ToString() { return "(" + cx + ", " + cz + ")"; } diff --git a/SubstrateCS/Source/Core/CompositeDataArray.cs b/Substrate/Source/Core/CompositeDataArray.cs similarity index 91% rename from SubstrateCS/Source/Core/CompositeDataArray.cs rename to Substrate/Source/Core/CompositeDataArray.cs index 8bf99250..544c18bf 100644 --- a/SubstrateCS/Source/Core/CompositeDataArray.cs +++ b/Substrate/Source/Core/CompositeDataArray.cs @@ -8,13 +8,14 @@ public class CompositeDataArray3 : IDataArray3 { private IDataArray3[] _sections; - public CompositeDataArray3 (IDataArray3[] sections) + public CompositeDataArray3(IDataArray3[] sections) { for (int i = 0; i < sections.Length; i++) if (sections[i] == null) throw new ArgumentException("sections argument cannot have null entries."); - for (int i = 0; i < sections.Length; i++) { + for (int i = 0; i < sections.Length; i++) + { if (sections[i].Length != sections[0].Length || sections[i].XDim != sections[0].XDim || sections[i].YDim != sections[0].YDim @@ -59,14 +60,14 @@ public int ZDim get { return _sections[0].ZDim; } } - public int GetIndex (int x, int y, int z) + public int GetIndex(int x, int y, int z) { int ydiv = y / _sections[0].YDim; int yrem = y - (ydiv * _sections[0].YDim); return (ydiv * _sections[0].Length) + _sections[ydiv].GetIndex(x, yrem, z); } - public void GetMultiIndex (int index, out int x, out int y, out int z) + public void GetMultiIndex(int index, out int x, out int y, out int z) { int idiv = index / _sections[0].Length; int irem = index - (idiv * _sections[0].Length); @@ -104,7 +105,7 @@ public int DataWidth get { return _sections[0].DataWidth; } } - public void Clear () + public void Clear() { for (int i = 0; i < _sections.Length; i++) _sections[i].Clear(); diff --git a/SubstrateCS/Source/Core/FusedDataArray.cs b/Substrate/Source/Core/FusedDataArray.cs similarity index 89% rename from SubstrateCS/Source/Core/FusedDataArray.cs rename to Substrate/Source/Core/FusedDataArray.cs index 80211b1b..16980dc8 100644 --- a/SubstrateCS/Source/Core/FusedDataArray.cs +++ b/Substrate/Source/Core/FusedDataArray.cs @@ -11,7 +11,7 @@ public class FusedDataArray3 : IDataArray3 private int _mask1; - public FusedDataArray3 (IDataArray3 array0, IDataArray3 array1) + public FusedDataArray3(IDataArray3 array0, IDataArray3 array1) { if (array0 == null || array1 == null) throw new ArgumentException("arguments cannot be null"); @@ -50,12 +50,12 @@ public int ZDim get { return _array1.ZDim; } } - public int GetIndex (int x, int y, int z) + public int GetIndex(int x, int y, int z) { return _array1.GetIndex(x, y, z); } - public void GetMultiIndex (int index, out int x, out int y, out int z) + public void GetMultiIndex(int index, out int x, out int y, out int z) { _array1.GetMultiIndex(index, out x, out y, out z); } @@ -80,7 +80,7 @@ public int DataWidth get { return _array0.DataWidth + _array1.DataWidth; } } - public void Clear () + public void Clear() { _array0.Clear(); _array1.Clear(); diff --git a/SubstrateCS/Source/Core/IndexedLinkedList.cs b/Substrate/Source/Core/IndexedLinkedList.cs similarity index 78% rename from SubstrateCS/Source/Core/IndexedLinkedList.cs rename to Substrate/Source/Core/IndexedLinkedList.cs index 09a377b9..4187c33d 100644 --- a/SubstrateCS/Source/Core/IndexedLinkedList.cs +++ b/Substrate/Source/Core/IndexedLinkedList.cs @@ -19,31 +19,31 @@ public T Last get { return _list.Last.Value; } } - public IndexedLinkedList () + public IndexedLinkedList() { _list = new LinkedList(); _index = new Dictionary>(); } - public void AddFirst (T value) + public void AddFirst(T value) { LinkedListNode node = _list.AddFirst(value); _index.Add(value, node); } - public void AddLast (T value) + public void AddLast(T value) { LinkedListNode node = _list.AddLast(value); _index.Add(value, node); } - public void RemoveFirst () + public void RemoveFirst() { _index.Remove(_list.First.Value); _list.RemoveFirst(); } - public void RemoveLast () + public void RemoveLast() { _index.Remove(_list.First.Value); _list.RemoveLast(); @@ -51,23 +51,23 @@ public void RemoveLast () #region ICollection Members - public void Add (T item) + public void Add(T item) { AddLast(item); } - public void Clear () + public void Clear() { _index.Clear(); _list.Clear(); } - public bool Contains (T item) + public bool Contains(T item) { return _index.ContainsKey(item); } - public void CopyTo (T[] array, int arrayIndex) + public void CopyTo(T[] array, int arrayIndex) { _list.CopyTo(array, arrayIndex); } @@ -77,7 +77,7 @@ public bool IsReadOnly get { return false; } } - public bool Remove (T value) + public bool Remove(T value) { LinkedListNode node; if (_index.TryGetValue(value, out node)) @@ -94,7 +94,7 @@ public bool Remove (T value) #region ICollection Members - void ICollection.CopyTo (Array array, int index) + void ICollection.CopyTo(Array array, int index) { (_list as ICollection).CopyTo(array, index); } @@ -118,7 +118,7 @@ object ICollection.SyncRoot #region IEnumerable Members - public IEnumerator GetEnumerator () + public IEnumerator GetEnumerator() { return _list.GetEnumerator(); } @@ -127,7 +127,7 @@ public IEnumerator GetEnumerator () #region IEnumerable Members - IEnumerator IEnumerable.GetEnumerator () + IEnumerator IEnumerable.GetEnumerator() { return _list.GetEnumerator(); } diff --git a/SubstrateCS/Source/Core/Interface.cs b/Substrate/Source/Core/Interface.cs similarity index 85% rename from SubstrateCS/Source/Core/Interface.cs rename to Substrate/Source/Core/Interface.cs index b40647f7..cfe5d619 100644 --- a/SubstrateCS/Source/Core/Interface.cs +++ b/Substrate/Source/Core/Interface.cs @@ -8,12 +8,12 @@ namespace Substrate.Core /// Provides a virtual deep copy capability to implementors. /// /// - public interface ICopyable + public interface ICopyable { /// /// Performs a virtual deep copy of the object instance. /// /// An independent copy of the object instance. - T Copy (); + T Copy(); } } diff --git a/SubstrateCS/Source/Core/ItemInterface.cs b/Substrate/Source/Core/ItemInterface.cs similarity index 100% rename from SubstrateCS/Source/Core/ItemInterface.cs rename to Substrate/Source/Core/ItemInterface.cs diff --git a/SubstrateCS/Source/Core/LRUCache.cs b/Substrate/Source/Core/LRUCache.cs similarity index 82% rename from SubstrateCS/Source/Core/LRUCache.cs rename to Substrate/Source/Core/LRUCache.cs index 1ab66831..d6da4e67 100644 --- a/SubstrateCS/Source/Core/LRUCache.cs +++ b/Substrate/Source/Core/LRUCache.cs @@ -22,7 +22,7 @@ public TValue Value get { return _value; } } - public CacheValueArgs (TKey key, TValue value) + public CacheValueArgs(TKey key, TValue value) { _key = key; _value = value; @@ -36,7 +36,7 @@ public CacheValueArgs (TKey key, TValue value) private int _capacity; - public LRUCache (int capacity) + public LRUCache(int capacity) { if (capacity <= 0) { @@ -51,7 +51,7 @@ public LRUCache (int capacity) #region IDictionary Members - public void Add (TKey key, TValue value) + public void Add(TKey key, TValue value) { if (_data.ContainsKey(key)) { @@ -70,7 +70,7 @@ public void Add (TKey key, TValue value) } } - public bool ContainsKey (TKey key) + public bool ContainsKey(TKey key) { return _data.ContainsKey(key); } @@ -80,7 +80,7 @@ public ICollection Keys get { return _data.Keys; } } - public bool Remove (TKey key) + public bool Remove(TKey key) { if (_data.Remove(key)) { @@ -91,7 +91,7 @@ public bool Remove (TKey key) return false; } - public bool TryGetValue (TKey key, out TValue value) + public bool TryGetValue(TKey key, out TValue value) { if (!_data.TryGetValue(key, out value)) { @@ -138,23 +138,23 @@ public TValue this[TKey key] #region ICollection> Members - public void Add (KeyValuePair item) + public void Add(KeyValuePair item) { Add(item.Key, item.Value); } - public void Clear () + public void Clear() { _data.Clear(); _index.Clear(); } - public bool Contains (KeyValuePair item) + public bool Contains(KeyValuePair item) { return ((ICollection>)_data).Contains(item); } - public void CopyTo (KeyValuePair[] array, int arrayIndex) + public void CopyTo(KeyValuePair[] array, int arrayIndex) { ((ICollection>)_data).CopyTo(array, arrayIndex); } @@ -169,7 +169,7 @@ public bool IsReadOnly get { return false; } } - public bool Remove (KeyValuePair item) + public bool Remove(KeyValuePair item) { if (((ICollection>)_data).Remove(item)) { @@ -184,7 +184,7 @@ public bool Remove (KeyValuePair item) #region IEnumerable> Members - public IEnumerator> GetEnumerator () + public IEnumerator> GetEnumerator() { return _data.GetEnumerator(); } @@ -193,14 +193,14 @@ public IEnumerator> GetEnumerator () #region IEnumerable Members - IEnumerator IEnumerable.GetEnumerator () + IEnumerator IEnumerable.GetEnumerator() { return _data.GetEnumerator(); } #endregion - private void OnRemoveCacheValue (CacheValueArgs e) + private void OnRemoveCacheValue(CacheValueArgs e) { if (RemoveCacheValue != null) { diff --git a/Substrate/Source/Core/NBTFile.cs b/Substrate/Source/Core/NBTFile.cs new file mode 100644 index 00000000..eb940641 --- /dev/null +++ b/Substrate/Source/Core/NBTFile.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using Ionic.Zlib; +using Substrate.Nbt; + +namespace Substrate.Core +{ + public enum CompressionType + { + None, + Zlib, + Deflate, + GZip, + } + + public class NBTFile + { + private string _filename; + + public NBTFile(string path) + { + _filename = path; + } + + public string FileName + { + get { return _filename; } + protected set { _filename = value; } + } + + public bool Exists() + { + return File.Exists(_filename); + } + + public void Delete() + { + File.Delete(_filename); + } + + public int GetModifiedTime() + { + return Timestamp(File.GetLastWriteTime(_filename)); + } + + public Stream GetDataInputStream() + { + return GetDataInputStream(CompressionType.GZip); + } + + public virtual Stream GetDataInputStream(CompressionType compression) + { + try + { + switch (compression) + { + case CompressionType.None: + using (FileStream fstr = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + { + long length = fstr.Seek(0, SeekOrigin.End); + fstr.Seek(0, SeekOrigin.Begin); + + byte[] data = new byte[length]; + fstr.Read(data, 0, data.Length); + + return new MemoryStream(data); + } + case CompressionType.GZip: + Stream stream1 = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + return new GZipStream(stream1, CompressionMode.Decompress); + case CompressionType.Zlib: + Stream stream2 = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + return new ZlibStream(stream2, CompressionMode.Decompress); + case CompressionType.Deflate: + Stream stream3 = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + return new DeflateStream(stream3, CompressionMode.Decompress); + default: + throw new ArgumentException("Invalid CompressionType specified", "compression"); + } + } + catch (Exception ex) + { + throw new NbtIOException("Failed to open compressed NBT data stream for input.", ex); + } + } + + public Stream GetDataOutputStream() + { + return GetDataOutputStream(CompressionType.GZip); + } + + public virtual Stream GetDataOutputStream(CompressionType compression) + { + try + { + switch (compression) + { + case CompressionType.None: + return new NBTBuffer(this); + case CompressionType.GZip: + return new GZipStream(new NBTBuffer(this), CompressionMode.Compress); + case CompressionType.Zlib: + return new ZlibStream(new NBTBuffer(this), CompressionMode.Compress); + case CompressionType.Deflate: + return new DeflateStream(new NBTBuffer(this), CompressionMode.Compress); + default: + throw new ArgumentException("Invalid CompressionType specified", "compression"); + } + } + catch (Exception ex) + { + throw new NbtIOException("Failed to initialize compressed NBT data stream for output.", ex); + } + } + + class NBTBuffer : MemoryStream + { + private NBTFile file; + + public NBTBuffer(NBTFile c) + : base(8096) + { + this.file = c; + } + + public override void Close() + { + try + { + using (Stream fstr = new FileStream(file._filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) + { + try + { + fstr.Write(this.GetBuffer(), 0, (int)this.Length); + } + catch (Exception ex) + { + throw new NbtIOException("Failed to write out NBT data stream.", ex); + } + } + } + catch (NbtIOException) + { + throw; + } + catch (Exception ex) + { + throw new NbtIOException("Failed to open NBT data stream for output.", ex); + } + } + } + + private int Timestamp(DateTime time) + { + DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0); + return (int)((time - epoch).Ticks / (10000L * 1000L)); + } + } +} diff --git a/SubstrateCS/Source/Core/NibbleArray.cs b/Substrate/Source/Core/NibbleArray.cs similarity index 82% rename from SubstrateCS/Source/Core/NibbleArray.cs rename to Substrate/Source/Core/NibbleArray.cs index 88e09cd2..a00a86e7 100644 --- a/SubstrateCS/Source/Core/NibbleArray.cs +++ b/Substrate/Source/Core/NibbleArray.cs @@ -9,12 +9,12 @@ public class NibbleArray : IDataArray, ICopyable { private readonly byte[] _data = null; - public NibbleArray (int length) + public NibbleArray(int length) { _data = new byte[(int)Math.Ceiling(length / 2.0)]; } - public NibbleArray (byte[] data) + public NibbleArray(byte[] data) { _data = data; } @@ -63,7 +63,7 @@ protected byte[] Data get { return _data; } } - public void Clear () + public void Clear() { for (int i = 0; i < _data.Length; i++) { @@ -73,7 +73,7 @@ public void Clear () #region ICopyable Members - public virtual NibbleArray Copy () + public virtual NibbleArray Copy() { byte[] data = new byte[_data.Length]; _data.CopyTo(data, 0); @@ -90,7 +90,7 @@ public sealed class XZYNibbleArray : NibbleArray, IDataArray3 private readonly int _ydim; private readonly int _zdim; - public XZYNibbleArray (int xdim, int ydim, int zdim) + public XZYNibbleArray(int xdim, int ydim, int zdim) : base(xdim * ydim * zdim) { _xdim = xdim; @@ -98,7 +98,7 @@ public XZYNibbleArray (int xdim, int ydim, int zdim) _zdim = zdim; } - public XZYNibbleArray (int xdim, int ydim, int zdim, byte[] data) + public XZYNibbleArray(int xdim, int ydim, int zdim, byte[] data) : base(data) { _xdim = xdim; @@ -141,12 +141,12 @@ public int ZDim get { return _zdim; } } - public int GetIndex (int x, int y, int z) + public int GetIndex(int x, int y, int z) { return _ydim * (x * _zdim + z) + y; } - public void GetMultiIndex (int index, out int x, out int y, out int z) + public void GetMultiIndex(int index, out int x, out int y, out int z) { int yzdim = _ydim * _zdim; x = index / yzdim; @@ -158,7 +158,7 @@ public void GetMultiIndex (int index, out int x, out int y, out int z) #region ICopyable Members - public override NibbleArray Copy () + public override NibbleArray Copy() { byte[] data = new byte[Data.Length]; Data.CopyTo(data, 0); @@ -175,7 +175,7 @@ public sealed class YZXNibbleArray : NibbleArray, IDataArray3 private readonly int _ydim; private readonly int _zdim; - public YZXNibbleArray (int xdim, int ydim, int zdim) + public YZXNibbleArray(int xdim, int ydim, int zdim) : base(xdim * ydim * zdim) { _xdim = xdim; @@ -183,14 +183,15 @@ public YZXNibbleArray (int xdim, int ydim, int zdim) _zdim = zdim; } - public YZXNibbleArray (int xdim, int ydim, int zdim, byte[] data) + public YZXNibbleArray(int xdim, int ydim, int zdim, byte[] data) : base(data) { _xdim = xdim; _ydim = ydim; _zdim = zdim; - if (xdim * ydim * zdim != data.Length * 2) { + if (xdim * ydim * zdim != data.Length * 2) + { throw new ArgumentException("Product of dimensions must equal half length of raw data"); } } @@ -225,12 +226,12 @@ public int ZDim get { return _zdim; } } - public int GetIndex (int x, int y, int z) + public int GetIndex(int x, int y, int z) { return _xdim * (y * _zdim + z) + x; } - public void GetMultiIndex (int index, out int x, out int y, out int z) + public void GetMultiIndex(int index, out int x, out int y, out int z) { int xzdim = _xdim * _zdim; y = index / xzdim; @@ -242,7 +243,7 @@ public void GetMultiIndex (int index, out int x, out int y, out int z) #region ICopyable Members - public override NibbleArray Copy () + public override NibbleArray Copy() { byte[] data = new byte[Data.Length]; Data.CopyTo(data, 0); diff --git a/SubstrateCS/Source/Core/OpenWorldEvent.cs b/Substrate/Source/Core/OpenWorldEvent.cs similarity index 88% rename from SubstrateCS/Source/Core/OpenWorldEvent.cs rename to Substrate/Source/Core/OpenWorldEvent.cs index 8ac75d7b..e16fab21 100644 --- a/SubstrateCS/Source/Core/OpenWorldEvent.cs +++ b/Substrate/Source/Core/OpenWorldEvent.cs @@ -8,7 +8,7 @@ namespace Substrate.Core /// /// The path to the directory of the world to open. /// An instance of a concrete derivative of . - public delegate NbtWorld OpenWorldCallback (string path); + public delegate NbtWorld OpenWorldCallback(string path); /// /// Event arugments and response data for any handlers trying to determine if they can open a given world. @@ -22,7 +22,7 @@ public class OpenWorldEventArgs : EventArgs /// Create a new instance of event arguments. /// /// The path to the directory of a world. - public OpenWorldEventArgs (string path) + public OpenWorldEventArgs(string path) : base() { _path = path; @@ -41,7 +41,7 @@ public string Path /// Adds an delegate that can open a world and return a corresponding object. /// /// The delegate to return to the code that raised the event. - public void AddHandler (OpenWorldCallback callback) + public void AddHandler(OpenWorldCallback callback) { _handlers.Add(callback); } diff --git a/SubstrateCS/Source/Core/PlayerFile.cs b/Substrate/Source/Core/PlayerFile.cs similarity index 64% rename from SubstrateCS/Source/Core/PlayerFile.cs rename to Substrate/Source/Core/PlayerFile.cs index 6cb38c2f..4217c0bb 100644 --- a/SubstrateCS/Source/Core/PlayerFile.cs +++ b/Substrate/Source/Core/PlayerFile.cs @@ -8,15 +8,16 @@ namespace Substrate.Core { public class PlayerFile : NBTFile { - public PlayerFile (string path) + public PlayerFile(string path) : base(path) { } - public PlayerFile (string path, string name) + public PlayerFile(string path, string name) : base("") { - if (!Directory.Exists(path)) { + if (!Directory.Exists(path)) + { Directory.CreateDirectory(path); } @@ -24,9 +25,10 @@ public PlayerFile (string path, string name) FileName = Path.Combine(path, file); } - public static string NameFromFilename (string filename) + public static string NameFromFilename(string filename) { - if (filename.EndsWith(".dat")) { + if (filename.EndsWith(".dat")) + { return filename.Remove(filename.Length - 4); } diff --git a/SubstrateCS/Source/Core/PlayerManagerInterface.cs b/Substrate/Source/Core/PlayerManagerInterface.cs similarity index 86% rename from SubstrateCS/Source/Core/PlayerManagerInterface.cs rename to Substrate/Source/Core/PlayerManagerInterface.cs index 5c8d7c82..d9985022 100644 --- a/SubstrateCS/Source/Core/PlayerManagerInterface.cs +++ b/Substrate/Source/Core/PlayerManagerInterface.cs @@ -14,26 +14,26 @@ public interface IPlayerManager /// /// The name of the player to fetch. /// A object for the given player, or null if the player could not be found. - Player GetPlayer (string name); + Player GetPlayer(string name); /// /// Saves a object's data back to the underlying data store for the given player. /// /// The name of the player to write back data for. /// The object containing data to write back. - void SetPlayer (string name, Player player); + void SetPlayer(string name, Player player); /// /// Checks if a player exists in the underlying data store. /// /// The name of the player to look up. /// True if player data was found; false otherwise. - bool PlayerExists (string name); + bool PlayerExists(string name); /// /// Deletes a player with the given name from the underlying data store. /// /// The name of the player to delete. - void DeletePlayer (string name); + void DeletePlayer(string name); } } diff --git a/SubstrateCS/Source/Core/Region.cs b/Substrate/Source/Core/Region.cs similarity index 75% rename from SubstrateCS/Source/Core/Region.cs rename to Substrate/Source/Core/Region.cs index 44e6f32c..251dd975 100644 --- a/SubstrateCS/Source/Core/Region.cs +++ b/Substrate/Source/Core/Region.cs @@ -1,559 +1,576 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Text.RegularExpressions; -using System.IO; -using Substrate.Nbt; -using Substrate.Core; - -namespace Substrate.Core -{ - - - /// - /// Represents a single region containing 32x32 chunks. - /// - public abstract class Region : IDisposable, IRegion - { - protected const int XDIM = 32; - protected const int ZDIM = 32; - protected const int XMASK = XDIM - 1; - protected const int ZMASK = ZDIM - 1; - protected const int XLOG = 5; - protected const int ZLOG = 5; - - protected int _rx; - protected int _rz; - private bool _disposed = false; - - protected RegionManager _regionMan; - - private static Regex _namePattern = new Regex("r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mca$"); - - private WeakReference _regionFile; - - protected ChunkCache _cache; - - protected abstract IChunk CreateChunkCore (int cx, int cz); - - protected abstract IChunk CreateChunkVerifiedCore (NbtTree tree); - - protected abstract bool ParseFileNameCore (string filename, out int x, out int z); - - /// - public int X - { - get { return _rx; } - } - - /// - public int Z - { - get { return _rz; } - } - - /// - /// Gets the length of the X-dimension of the region in chunks. - /// - public int XDim - { - get { return XDIM; } - } - - /// - /// Gets the length of the Z-dimension of the region in chunks. - /// - public int ZDim - { - get { return ZDIM; } - } - - public abstract string GetFileName (); - - public abstract string GetFilePath (); - - /// - /// Creates an instance of a for a given set of coordinates. - /// - /// The that should be managing this region. - /// A shared cache for holding chunks. - /// The global X-coordinate of the region. - /// The global Z-coordinate of the region. - /// The constructor will not actually open or parse any region files. Given just the region coordinates, the - /// region will be able to determien the correct region file to look for based on the naming pattern for regions: - /// r.x.z.mcr, given x and z are integers representing the region's coordinates. - /// Regions require a to be provided because they do not actually store any chunks or references - /// to chunks on their own. This allows regions to easily pass off requests outside of their bounds, if necessary. - public Region (RegionManager rm, ChunkCache cache, int rx, int rz) - { - _regionMan = rm; - _cache = cache; - _regionFile = new WeakReference(null); - _rx = rx; - _rz = rz; - - if (!File.Exists(GetFilePath())) { - throw new FileNotFoundException(); - } - } - - /// - /// Creates an instance of a for the given region file. - /// - /// The that should be managing this region. - /// A shared cache for holding chunks. - /// The region file to derive the region from. - /// The constructor will not actually open or parse the region file. It will only read the file's name in order - /// to derive the region's coordinates, based on a strict naming pattern for regions: r.x.z.mcr, given x and z are integers - /// representing the region's coordinates. - /// Regions require a to be provided because they do not actually store any chunks or references - /// to chunks on their own. This allows regions to easily pass off requests outside of their bounds, if necessary. - public Region (RegionManager rm, ChunkCache cache, string filename) - { - _regionMan = rm; - _cache = cache; - _regionFile = new WeakReference(null); - - ParseFileNameCore(filename, out _rx, out _rz); - - if (!File.Exists(Path.Combine(_regionMan.GetRegionPath(), filename))) { - throw new FileNotFoundException(); - } - } - - /// - /// Region finalizer that ensures any resources are cleaned up - /// - ~Region () - { - Dispose(false); - } - - /// - /// Disposes any managed and unmanaged resources held by the region. - /// - public void Dispose () - { - Dispose(true); - System.GC.SuppressFinalize(this); - } - - /// - /// Conditionally dispose managed or unmanaged resources. - /// - /// True if the call to Dispose was explicit. - protected virtual void Dispose (bool disposing) - { - if (!_disposed) { - if (disposing) { - // Cleanup managed resources - RegionFile rf = _regionFile.Target as RegionFile; - if (rf != null) { - rf.Dispose(); - rf = null; - } - } - - // Cleanup unmanaged resources - } - _disposed = true; - } - - private RegionFile GetRegionFile () - { - RegionFile rf = _regionFile.Target as RegionFile; - if (rf == null) { - rf = new RegionFile(GetFilePath()); - _regionFile.Target = rf; - } - - return rf; - } - - /// - public NbtTree GetChunkTree (int lcx, int lcz) - { - if (!LocalBoundsCheck(lcx, lcz)) { - IRegion alt = GetForeignRegion(lcx, lcz); - return (alt == null) ? null : alt.GetChunkTree(ForeignX(lcx), ForeignZ(lcz)); - } - - RegionFile rf = GetRegionFile(); - NbtTree tree; - - using (Stream nbtstr = rf.GetChunkDataInputStream(lcx, lcz)) - { - if (nbtstr == null) - { - return null; - } - - tree = new NbtTree(nbtstr); - } - - return tree; - } - - // XXX: Exceptions - /// - public bool SaveChunkTree (int lcx, int lcz, NbtTree tree) - { - return SaveChunkTree(lcx, lcz, tree, null); - } - - /// - public bool SaveChunkTree (int lcx, int lcz, NbtTree tree, int timestamp) - { - return SaveChunkTree(lcx, lcz, tree, timestamp); - } - - private bool SaveChunkTree (int lcx, int lcz, NbtTree tree, int? timestamp) - { - if (!LocalBoundsCheck(lcx, lcz)) { - IRegion alt = GetForeignRegion(lcx, lcz); - return (alt == null) ? false : alt.SaveChunkTree(ForeignX(lcx), ForeignZ(lcz), tree); - } - - RegionFile rf = GetRegionFile(); - using (Stream zipstr = (timestamp == null) - ? rf.GetChunkDataOutputStream(lcx, lcz) - : rf.GetChunkDataOutputStream(lcx, lcz, (int)timestamp)) - { - if (zipstr == null) - { - return false; - } - - tree.WriteTo(zipstr); - } - - return true; - } - - /// - public Stream GetChunkOutStream (int lcx, int lcz) - { - if (!LocalBoundsCheck(lcx, lcz)) { - IRegion alt = GetForeignRegion(lcx, lcz); - return (alt == null) ? null : alt.GetChunkOutStream(ForeignX(lcx), ForeignZ(lcz)); - } - - RegionFile rf = GetRegionFile(); - return rf.GetChunkDataOutputStream(lcx, lcz); - } - - /// - public int ChunkCount () - { - RegionFile rf = GetRegionFile(); - - int count = 0; - for (int x = 0; x < XDIM; x++) { - for (int z = 0; z < ZDIM; z++) { - if (rf.HasChunk(x, z)) { - count++; - } - } - } - - return count; - } - - // XXX: Consider revising foreign lookup support - /// - public ChunkRef GetChunkRef (int lcx, int lcz) - { - if (!LocalBoundsCheck(lcx, lcz)) { - IRegion alt = GetForeignRegion(lcx, lcz); - return (alt == null) ? null : alt.GetChunkRef(ForeignX(lcx), ForeignZ(lcz)); - } - - int cx = lcx + _rx * XDIM; - int cz = lcz + _rz * ZDIM; - - ChunkKey k = new ChunkKey(cx, cz); - ChunkRef c = _cache.Fetch(k); - if (c != null) { - return c; - } - - c = ChunkRef.Create(this, lcx, lcz); - if (c != null) { - _cache.Insert(c); - } - - return c; - } - - /// - public ChunkRef CreateChunk (int lcx, int lcz) - { - if (!LocalBoundsCheck(lcx, lcz)) { - IRegion alt = GetForeignRegion(lcx, lcz); - return (alt == null) ? null : alt.CreateChunk(ForeignX(lcx), ForeignZ(lcz)); - } - - DeleteChunk(lcx, lcz); - - int cx = lcx + _rx * XDIM; - int cz = lcz + _rz * ZDIM; - - IChunk c = CreateChunkCore(cx, cz); - using (Stream chunkOutStream = GetChunkOutStream(lcx, lcz)) - { - c.Save(chunkOutStream); - } - - ChunkRef cr = ChunkRef.Create(this, lcx, lcz); - _cache.Insert(cr); - - return cr; - } - - - #region IChunkCollection Members - - // XXX: This also feels dirty. - /// - /// Gets the global X-coordinate of a chunk given an internal coordinate handed out by a container. - /// - /// An internal X-coordinate given to a by any instance of a container. - /// The global X-coordinate of the corresponding chunk. - public int ChunkGlobalX (int cx) - { - return _rx * XDIM + cx; - } - - /// - /// Gets the global Z-coordinate of a chunk given an internal coordinate handed out by a container. - /// - /// An internal Z-coordinate given to a by any instance of a container. - /// The global Z-coordinate of the corresponding chunk. - public int ChunkGlobalZ (int cz) - { - return _rz * ZDIM + cz; - } - - /// - /// Gets the region-local X-coordinate of a chunk given an internal coordinate handed out by a container. - /// - /// An internal X-coordinate given to a by any instance of a container. - /// The region-local X-coordinate of the corresponding chunk. - public int ChunkLocalX (int cx) - { - return cx; - } - - /// - /// Gets the region-local Z-coordinate of a chunk given an internal coordinate handed out by a container. - /// - /// An internal Z-coordinate given to a by any instance of a container. - /// The region-local Z-coordinate of the corresponding chunk. - public int ChunkLocalZ (int cz) - { - return cz; - } - - /// - /// Returns a given local coordinates relative to this region. - /// - /// The local X-coordinate of a chunk relative to this region. - /// The local Z-coordinate of a chunk relative to this region. - /// A object for the given coordinates, or null if the chunk does not exist. - /// If the local coordinates are out of bounds for this region, the action will be forwarded to the correct region - /// transparently. The returned object may either come from cache, or be regenerated from disk. - public IChunk GetChunk (int lcx, int lcz) - { - if (!LocalBoundsCheck(lcx, lcz)) { - IRegion alt = GetForeignRegion(lcx, lcz); - return (alt == null) ? null : alt.GetChunk(ForeignX(lcx), ForeignZ(lcz)); - } - - if (!ChunkExists(lcx, lcz)) { - return null; - } - - return CreateChunkVerifiedCore(GetChunkTree(lcx, lcz)); - } - - /// - /// Checks if a chunk exists at the given local coordinates relative to this region. - /// - /// The local X-coordinate of a chunk relative to this region. - /// The local Z-coordinate of a chunk relative to this region. - /// True if there is a chunk at the given coordinates; false otherwise. - /// If the local coordinates are out of bounds for this region, the action will be forwarded to the correct region - /// transparently. - public bool ChunkExists (int lcx, int lcz) - { - if (!LocalBoundsCheck(lcx, lcz)) { - IRegion alt = GetForeignRegion(lcx, lcz); - return (alt == null) ? false : alt.ChunkExists(ForeignX(lcx), ForeignZ(lcz)); - } - - RegionFile rf = GetRegionFile(); - return rf.HasChunk(lcx, lcz); - } - - /// - /// Deletes a chunk from the underlying data store at the given local coordinates relative to this region. - /// - /// The local X-coordinate of a chunk relative to this region. - /// The local Z-coordinate of a chunk relative to this region. - /// True if there is a chunk was deleted; false otherwise. - /// If the local coordinates are out of bounds for this region, the action will be forwarded to the correct region - /// transparently. - public bool DeleteChunk (int lcx, int lcz) - { - if (!LocalBoundsCheck(lcx, lcz)) { - IRegion alt = GetForeignRegion(lcx, lcz); - return (alt == null) ? false : alt.DeleteChunk(ForeignX(lcx), ForeignZ(lcz)); - } - - RegionFile rf = GetRegionFile(); - if (!rf.HasChunk(lcx, lcz)) { - return false; - } - - rf.DeleteChunk(lcx, lcz); - - ChunkKey k = new ChunkKey(ChunkGlobalX(lcx), ChunkGlobalZ(lcz)); - _cache.Remove(k); - - if (ChunkCount() == 0) { - _regionMan.DeleteRegion(X, Z); - _regionFile.Target = null; - } - - return true; - } - - /// - /// Saves an existing to the region at the given local coordinates. - /// - /// The local X-coordinate of a chunk relative to this region. - /// The local Z-coordinate of a chunk relative to this region. - /// A to save to the given location. - /// A represneting the at its new location. - /// If the local coordinates are out of bounds for this region, the action will be forwarded to the correct region - /// transparently. The 's internal global coordinates will be updated to reflect the new location. - public ChunkRef SetChunk (int lcx, int lcz, IChunk chunk) - { - if (!LocalBoundsCheck(lcx, lcz)) { - IRegion alt = GetForeignRegion(lcx, lcz); - return (alt == null) ? null : alt.CreateChunk(ForeignX(lcx), ForeignZ(lcz)); - } - - DeleteChunk(lcx, lcz); - - int cx = lcx + _rx * XDIM; - int cz = lcz + _rz * ZDIM; - - chunk.SetLocation(cx, cz); - using (Stream chunkOutStream = GetChunkOutStream(lcx, lcz)) - { - chunk.Save(chunkOutStream); - } - - ChunkRef cr = ChunkRef.Create(this, lcx, lcz); - _cache.Insert(cr); - - return cr; - } - - /// - /// Saves all chunks within this region that have been marked as dirty. - /// - /// The number of chunks that were saved. - public int Save () - { - _cache.SyncDirty(); - - int saved = 0; - IEnumerator en = _cache.GetDirtyEnumerator(); - while (en.MoveNext()) { - ChunkRef chunk = en.Current; - - if (!ChunkExists(chunk.LocalX, chunk.LocalZ)) { - throw new MissingChunkException(); - } - using (Stream chunkOutStream = GetChunkOutStream(chunk.LocalX, chunk.LocalZ)) - { - if (chunk.Save(chunkOutStream)) - { - saved++; - } - } - } - - _cache.ClearDirty(); - return saved; - } - - // XXX: Allows a chunk not part of this region to be saved to it - /// - public bool SaveChunk (IChunk chunk) - { - using (Stream chunkOutStream = GetChunkOutStream(ForeignX(chunk.X), ForeignZ(chunk.Z))) - { - //Console.WriteLine("Region[{0}, {1}].Save({2}, {3})", _rx, _rz, ForeignX(chunk.X),ForeignZ(chunk.Z)); - return chunk.Save(chunkOutStream); - } - } - - /// - /// Checks if this container supports delegating an action on out-of-bounds coordinates to another container. - /// - public bool CanDelegateCoordinates - { - get { return true; } - } - - /// - public int GetChunkTimestamp (int lcx, int lcz) - { - if (!LocalBoundsCheck(lcx, lcz)) { - IRegion alt = GetForeignRegion(lcx, lcz); - return (alt == null) ? 0 : alt.GetChunkTimestamp(ForeignX(lcx), ForeignZ(lcz)); - } - - RegionFile rf = GetRegionFile(); - return rf.GetTimestamp(lcx, lcz); - } - - /// - public void SetChunkTimestamp (int lcx, int lcz, int timestamp) - { - if (!LocalBoundsCheck(lcx, lcz)) { - IRegion alt = GetForeignRegion(lcx, lcz); - if (alt != null) - alt.SetChunkTimestamp(ForeignX(lcx), ForeignZ(lcz), timestamp); - } - - RegionFile rf = GetRegionFile(); - rf.SetTimestamp(lcx, lcz, timestamp); - } - - #endregion - - protected bool LocalBoundsCheck (int lcx, int lcz) - { - return (lcx >= 0 && lcx < XDIM && lcz >= 0 && lcz < ZDIM); - } - - protected IRegion GetForeignRegion (int lcx, int lcz) - { - return _regionMan.GetRegion(_rx + (lcx >> XLOG), _rz + (lcz >> ZLOG)); - } - - protected int ForeignX (int lcx) - { - return (lcx + XDIM * 10000) & XMASK; - } - - protected int ForeignZ (int lcz) - { - return (lcz + ZDIM * 10000) & ZMASK; - } - } -} +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; +using System.IO; +using Substrate.Nbt; +using Substrate.Core; + +namespace Substrate.Core +{ + + + /// + /// Represents a single region containing 32x32 chunks. + /// + public abstract class Region : IDisposable, IRegion + { + private const int XDIM = 32; + private const int ZDIM = 32; + private const int XMASK = XDIM - 1; + private const int ZMASK = ZDIM - 1; + private const int XLOG = 5; + private const int ZLOG = 5; + + private bool _disposed = false; + + private RegionManager regionMan; + + private static Regex _namePattern = new Regex("r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mca$"); + + private WeakReference _regionFile; + + private ChunkCache _cache; + + protected abstract IChunk CreateChunkCore(int cx, int cz); + + protected abstract IChunk CreateChunkVerifiedCore(NbtTree tree); + + protected abstract bool ParseFileNameCore(string filename, out int x, out int z); + + /// + public int X { get; private set; } + + /// + public int Z { get; private set; } + + /// + /// Gets the length of the X-dimension of the region in chunks. + /// + public int XDim { get { return XDIM; } } + + /// + /// Gets the length of the Z-dimension of the region in chunks. + /// + public int ZDim { get { return ZDIM; } } + + public abstract string GetFileName(); + + public abstract string GetFilePath(); + + /// + /// Creates an instance of a for a given set of coordinates. + /// + /// The that should be managing this region. + /// A shared cache for holding chunks. + /// The global X-coordinate of the region. + /// The global Z-coordinate of the region. + /// The constructor will not actually open or parse any region files. Given just the region coordinates, the + /// region will be able to determien the correct region file to look for based on the naming pattern for regions: + /// r.x.z.mcr, given x and z are integers representing the region's coordinates. + /// Regions require a to be provided because they do not actually store any chunks or references + /// to chunks on their own. This allows regions to easily pass off requests outside of their bounds, if necessary. + public Region(RegionManager rm, ChunkCache cache, int rx, int rz) + { + this.RegionMan = rm; + _cache = cache; + _regionFile = new WeakReference(null); + X = rx; + Z = rz; + + if (!File.Exists(GetFilePath())) + { + throw new FileNotFoundException(); + } + } + + /// + /// Creates an instance of a for the given region file. + /// + /// The that should be managing this region. + /// A shared cache for holding chunks. + /// The region file to derive the region from. + /// The constructor will not actually open or parse the region file. It will only read the file's name in order + /// to derive the region's coordinates, based on a strict naming pattern for regions: r.x.z.mcr, given x and z are integers + /// representing the region's coordinates. + /// Regions require a to be provided because they do not actually store any chunks or references + /// to chunks on their own. This allows regions to easily pass off requests outside of their bounds, if necessary. + public Region(RegionManager rm, ChunkCache cache, string filename) + { + this.RegionMan = rm; + _cache = cache; + _regionFile = new WeakReference(null); + + ParseFileNameCore(filename, out int x, out int z); + X = x; + Z = z; + + if (!File.Exists(Path.Combine(this.RegionMan.GetRegionPath(), filename))) + { + throw new FileNotFoundException(); + } + } + + /// + /// Region finalizer that ensures any resources are cleaned up + /// + ~Region() + { + Dispose(false); + } + + /// + /// Disposes any managed and unmanaged resources held by the region. + /// + public void Dispose() + { + Dispose(true); + System.GC.SuppressFinalize(this); + } + + /// + /// Conditionally dispose managed or unmanaged resources. + /// + /// True if the call to Dispose was explicit. + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + // Cleanup managed resources + RegionFile rf = _regionFile.Target as RegionFile; + if (rf != null) + { + rf.Dispose(); + rf = null; + } + } + + // Cleanup unmanaged resources + } + _disposed = true; + } + + private RegionFile GetRegionFile() + { + RegionFile rf = _regionFile.Target as RegionFile; + if (rf == null) + { + rf = new RegionFile(GetFilePath()); + _regionFile.Target = rf; + } + + return rf; + } + + /// + public NbtTree GetChunkTree(int lcx, int lcz) + { + if (!LocalBoundsCheck(lcx, lcz)) + { + IRegion alt = GetForeignRegion(lcx, lcz); + return (alt == null) ? null : alt.GetChunkTree(ForeignX(lcx), ForeignZ(lcz)); + } + + RegionFile rf = GetRegionFile(); + NbtTree tree; + + using (Stream nbtstr = rf.GetChunkDataInputStream(lcx, lcz)) + { + if (nbtstr == null) + { + return null; + } + + tree = new NbtTree(nbtstr); + } + + return tree; + } + + // XXX: Exceptions + /// + public bool SaveChunkTree(int lcx, int lcz, NbtTree tree) + { + return SaveChunkTree(lcx, lcz, tree, null); + } + + /// + public bool SaveChunkTree(int lcx, int lcz, NbtTree tree, int timestamp) + { + return SaveChunkTree(lcx, lcz, tree, timestamp); + } + + private bool SaveChunkTree(int lcx, int lcz, NbtTree tree, int? timestamp) + { + if (!LocalBoundsCheck(lcx, lcz)) + { + IRegion alt = GetForeignRegion(lcx, lcz); + return (alt == null) ? false : alt.SaveChunkTree(ForeignX(lcx), ForeignZ(lcz), tree); + } + + RegionFile rf = GetRegionFile(); + using (Stream zipstr = (timestamp == null) + ? rf.GetChunkDataOutputStream(lcx, lcz) + : rf.GetChunkDataOutputStream(lcx, lcz, (int)timestamp)) + { + if (zipstr == null) + { + return false; + } + + tree.WriteTo(zipstr); + } + + return true; + } + + /// + public Stream GetChunkOutStream(int lcx, int lcz) + { + if (!LocalBoundsCheck(lcx, lcz)) + { + IRegion alt = GetForeignRegion(lcx, lcz); + return (alt == null) ? null : alt.GetChunkOutStream(ForeignX(lcx), ForeignZ(lcz)); + } + + RegionFile rf = GetRegionFile(); + return rf.GetChunkDataOutputStream(lcx, lcz); + } + + /// + public int ChunkCount() + { + RegionFile rf = GetRegionFile(); + + int count = 0; + for (int x = 0; x < XDIM; x++) + { + for (int z = 0; z < ZDIM; z++) + { + if (rf.HasChunk(x, z)) + { + count++; + } + } + } + + return count; + } + + // XXX: Consider revising foreign lookup support + /// + public ChunkRef GetChunkRef(int lcx, int lcz) + { + if (!LocalBoundsCheck(lcx, lcz)) + { + IRegion alt = GetForeignRegion(lcx, lcz); + return (alt == null) ? null : alt.GetChunkRef(ForeignX(lcx), ForeignZ(lcz)); + } + + int cx = lcx + X * XDIM; + int cz = lcz + Z * ZDIM; + + ChunkKey k = new ChunkKey(cx, cz); + ChunkRef c = _cache.Fetch(k); + if (c != null) + { + return c; + } + + c = ChunkRef.Create(this, lcx, lcz); + if (c != null) + { + _cache.Insert(c); + } + + return c; + } + + /// + public ChunkRef CreateChunk(int lcx, int lcz) + { + if (!LocalBoundsCheck(lcx, lcz)) + { + IRegion alt = GetForeignRegion(lcx, lcz); + return (alt == null) ? null : alt.CreateChunk(ForeignX(lcx), ForeignZ(lcz)); + } + + DeleteChunk(lcx, lcz); + + int cx = lcx + X * XDIM; + int cz = lcz + Z * ZDIM; + + IChunk c = CreateChunkCore(cx, cz); + using (Stream chunkOutStream = GetChunkOutStream(lcx, lcz)) + { + c.Save(chunkOutStream); + } + + ChunkRef cr = ChunkRef.Create(this, lcx, lcz); + _cache.Insert(cr); + + return cr; + } + + + #region IChunkCollection Members + + // XXX: This also feels dirty. + /// + /// Gets the global X-coordinate of a chunk given an internal coordinate handed out by a container. + /// + /// An internal X-coordinate given to a by any instance of a container. + /// The global X-coordinate of the corresponding chunk. + public int ChunkGlobalX(int cx) + { + return X * XDIM + cx; + } + + /// + /// Gets the global Z-coordinate of a chunk given an internal coordinate handed out by a container. + /// + /// An internal Z-coordinate given to a by any instance of a container. + /// The global Z-coordinate of the corresponding chunk. + public int ChunkGlobalZ(int cz) + { + return Z * ZDIM + cz; + } + + /// + /// Gets the region-local X-coordinate of a chunk given an internal coordinate handed out by a container. + /// + /// An internal X-coordinate given to a by any instance of a container. + /// The region-local X-coordinate of the corresponding chunk. + public int ChunkLocalX(int cx) + { + return cx; + } + + /// + /// Gets the region-local Z-coordinate of a chunk given an internal coordinate handed out by a container. + /// + /// An internal Z-coordinate given to a by any instance of a container. + /// The region-local Z-coordinate of the corresponding chunk. + public int ChunkLocalZ(int cz) + { + return cz; + } + + /// + /// Returns a given local coordinates relative to this region. + /// + /// The local X-coordinate of a chunk relative to this region. + /// The local Z-coordinate of a chunk relative to this region. + /// A object for the given coordinates, or null if the chunk does not exist. + /// If the local coordinates are out of bounds for this region, the action will be forwarded to the correct region + /// transparently. The returned object may either come from cache, or be regenerated from disk. + public IChunk GetChunk(int lcx, int lcz) + { + if (!LocalBoundsCheck(lcx, lcz)) + { + IRegion alt = GetForeignRegion(lcx, lcz); + return (alt == null) ? null : alt.GetChunk(ForeignX(lcx), ForeignZ(lcz)); + } + + if (!ChunkExists(lcx, lcz)) + { + return null; + } + + return CreateChunkVerifiedCore(GetChunkTree(lcx, lcz)); + } + + /// + /// Checks if a chunk exists at the given local coordinates relative to this region. + /// + /// The local X-coordinate of a chunk relative to this region. + /// The local Z-coordinate of a chunk relative to this region. + /// True if there is a chunk at the given coordinates; false otherwise. + /// If the local coordinates are out of bounds for this region, the action will be forwarded to the correct region + /// transparently. + public bool ChunkExists(int lcx, int lcz) + { + if (!LocalBoundsCheck(lcx, lcz)) + { + IRegion alt = GetForeignRegion(lcx, lcz); + return (alt == null) ? false : alt.ChunkExists(ForeignX(lcx), ForeignZ(lcz)); + } + + RegionFile rf = GetRegionFile(); + return rf.HasChunk(lcx, lcz); + } + + /// + /// Deletes a chunk from the underlying data store at the given local coordinates relative to this region. + /// + /// The local X-coordinate of a chunk relative to this region. + /// The local Z-coordinate of a chunk relative to this region. + /// True if there is a chunk was deleted; false otherwise. + /// If the local coordinates are out of bounds for this region, the action will be forwarded to the correct region + /// transparently. + public bool DeleteChunk(int lcx, int lcz) + { + if (!LocalBoundsCheck(lcx, lcz)) + { + IRegion alt = GetForeignRegion(lcx, lcz); + return (alt == null) ? false : alt.DeleteChunk(ForeignX(lcx), ForeignZ(lcz)); + } + + RegionFile rf = GetRegionFile(); + if (!rf.HasChunk(lcx, lcz)) + { + return false; + } + + rf.DeleteChunk(lcx, lcz); + + ChunkKey k = new ChunkKey(ChunkGlobalX(lcx), ChunkGlobalZ(lcz)); + _cache.Remove(k); + + if (ChunkCount() == 0) + { + this.RegionMan.DeleteRegion(X, Z); + _regionFile.Target = null; + } + + return true; + } + + /// + /// Saves an existing to the region at the given local coordinates. + /// + /// The local X-coordinate of a chunk relative to this region. + /// The local Z-coordinate of a chunk relative to this region. + /// A to save to the given location. + /// A represneting the at its new location. + /// If the local coordinates are out of bounds for this region, the action will be forwarded to the correct region + /// transparently. The 's internal global coordinates will be updated to reflect the new location. + public ChunkRef SetChunk(int lcx, int lcz, IChunk chunk) + { + if (!LocalBoundsCheck(lcx, lcz)) + { + IRegion alt = GetForeignRegion(lcx, lcz); + return (alt == null) ? null : alt.CreateChunk(ForeignX(lcx), ForeignZ(lcz)); + } + + DeleteChunk(lcx, lcz); + + int cx = lcx + X * XDIM; + int cz = lcz + Z * ZDIM; + + chunk.SetLocation(cx, cz); + using (Stream chunkOutStream = GetChunkOutStream(lcx, lcz)) + { + chunk.Save(chunkOutStream); + } + + ChunkRef cr = ChunkRef.Create(this, lcx, lcz); + _cache.Insert(cr); + + return cr; + } + + /// + /// Saves all chunks within this region that have been marked as dirty. + /// + /// The number of chunks that were saved. + public int Save() + { + _cache.SyncDirty(); + + int saved = 0; + IEnumerator en = _cache.GetDirtyEnumerator(); + while (en.MoveNext()) + { + ChunkRef chunk = en.Current; + + if (!ChunkExists(chunk.LocalX, chunk.LocalZ)) + { + throw new MissingChunkException(); + } + using (Stream chunkOutStream = GetChunkOutStream(chunk.LocalX, chunk.LocalZ)) + { + if (chunk.Save(chunkOutStream)) + { + saved++; + } + } + } + + _cache.ClearDirty(); + return saved; + } + + // XXX: Allows a chunk not part of this region to be saved to it + /// + public bool SaveChunk(IChunk chunk) + { + using (Stream chunkOutStream = GetChunkOutStream(ForeignX(chunk.X), ForeignZ(chunk.Z))) + { + //Console.WriteLine("Region[{0}, {1}].Save({2}, {3})", _rx, _rz, ForeignX(chunk.X),ForeignZ(chunk.Z)); + return chunk.Save(chunkOutStream); + } + } + + /// + /// Checks if this container supports delegating an action on out-of-bounds coordinates to another container. + /// + public bool CanDelegateCoordinates + { + get { return true; } + } + + protected RegionManager RegionMan { get => this.regionMan; set => this.regionMan = value ; } + + /// + public int GetChunkTimestamp(int lcx, int lcz) + { + if (!LocalBoundsCheck(lcx, lcz)) + { + IRegion alt = GetForeignRegion(lcx, lcz); + return (alt == null) ? 0 : alt.GetChunkTimestamp(ForeignX(lcx), ForeignZ(lcz)); + } + + RegionFile rf = GetRegionFile(); + return rf.GetTimestamp(lcx, lcz); + } + + /// + public void SetChunkTimestamp(int lcx, int lcz, int timestamp) + { + if (!LocalBoundsCheck(lcx, lcz)) + { + IRegion alt = GetForeignRegion(lcx, lcz); + if (alt != null) + alt.SetChunkTimestamp(ForeignX(lcx), ForeignZ(lcz), timestamp); + } + + RegionFile rf = GetRegionFile(); + rf.SetTimestamp(lcx, lcz, timestamp); + } + + #endregion + + protected bool LocalBoundsCheck(int lcx, int lcz) + { + return (lcx >= 0 && lcx < XDIM && lcz >= 0 && lcz < ZDIM); + } + + protected IRegion GetForeignRegion(int lcx, int lcz) + { + return this.RegionMan.GetRegion(X + (lcx >> XLOG), Z + (lcz >> ZLOG)); + } + + protected int ForeignX(int lcx) + { + return (lcx + XDIM * 10000) & XMASK; + } + + protected int ForeignZ(int lcz) + { + return (lcz + ZDIM * 10000) & ZMASK; + } + } +} diff --git a/SubstrateCS/Source/Core/RegionFile.cs b/Substrate/Source/Core/RegionFile.cs similarity index 73% rename from SubstrateCS/Source/Core/RegionFile.cs rename to Substrate/Source/Core/RegionFile.cs index 155c7860..2632bc25 100644 --- a/SubstrateCS/Source/Core/RegionFile.cs +++ b/Substrate/Source/Core/RegionFile.cs @@ -40,7 +40,7 @@ public class RegionFile : IDisposable private bool _disposed = false; - public RegionFile (string path) + public RegionFile(string path) { offsets = new int[SectorInts]; chunkTimestamps = new int[SectorInts]; @@ -53,27 +53,31 @@ public RegionFile (string path) ReadFile(); } - ~RegionFile () + ~RegionFile() { Dispose(false); } - public void Dispose () + public void Dispose() { Dispose(true); System.GC.SuppressFinalize(this); } - protected virtual void Dispose (bool disposing) + protected virtual void Dispose(bool disposing) { - if (!_disposed) { - if (disposing) { + if (!_disposed) + { + if (disposing) + { // Cleanup managed resources } // Cleanup unmanaged resources - if (file != null) { - lock (this.fileLock) { + if (file != null) + { + lock (this.fileLock) + { file.Close(); file = null; } @@ -82,43 +86,53 @@ protected virtual void Dispose (bool disposing) _disposed = true; } - protected void ReadFile () + protected void ReadFile() { - if (_disposed) { + if (_disposed) + { throw new ObjectDisposedException("RegionFile", "Attempting to use a RegionFile after it has been disposed."); } // Get last udpate time long newModified = -1; - try { - if (File.Exists(fileName)) { + try + { + if (File.Exists(fileName)) + { newModified = Timestamp(File.GetLastWriteTime(fileName)); } } - catch (UnauthorizedAccessException e) { + catch (UnauthorizedAccessException e) + { Console.WriteLine(e.Message); return; } // If it hasn't been modified, we don't need to do anything - if (newModified == lastModified) { + if (newModified == lastModified) + { return; } - try { - lock (this.fileLock) { + try + { + lock (this.fileLock) + { file = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite); //using (file) { - if (file.Length < SectorBytes) { + if (file.Length < SectorBytes) + { byte[] int0 = BitConverter.GetBytes((int)0); /* we need to write the chunk offset table */ - for (int i = 0; i < SectorInts; ++i) { + for (int i = 0; i < SectorInts; ++i) + { file.Write(int0, 0, 4); } // write another sector for the timestamp info - for (int i = 0; i < SectorInts; ++i) { + for (int i = 0; i < SectorInts; ++i) + { file.Write(int0, 0, 4); } @@ -127,10 +141,12 @@ protected void ReadFile () sizeDelta += SectorBytes * 2; } - if ((file.Length & 0xfff) != 0) { + if ((file.Length & 0xfff) != 0) + { /* the file size is not a multiple of 4KB, grow it */ file.Seek(0, SeekOrigin.End); - for (int i = 0; i < (file.Length & 0xfff); ++i) { + for (int i = 0; i < (file.Length & 0xfff); ++i) + { file.WriteByte(0); } @@ -141,7 +157,8 @@ protected void ReadFile () int nSectors = (int)file.Length / SectorBytes; sectorFree = new List(nSectors); - for (int i = 0; i < nSectors; ++i) { + for (int i = 0; i < nSectors; ++i) + { sectorFree.Add(true); } @@ -149,27 +166,33 @@ protected void ReadFile () sectorFree[1] = false; // for the last modified info file.Seek(0, SeekOrigin.Begin); - for (int i = 0; i < SectorInts; ++i) { + for (int i = 0; i < SectorInts; ++i) + { byte[] offsetBytes = new byte[4]; file.Read(offsetBytes, 0, 4); - if (BitConverter.IsLittleEndian) { + if (BitConverter.IsLittleEndian) + { Array.Reverse(offsetBytes); } int offset = BitConverter.ToInt32(offsetBytes, 0); offsets[i] = offset; - if (offset != 0 && (offset >> 8) + (offset & 0xFF) <= sectorFree.Count) { - for (int sectorNum = 0; sectorNum < (offset & 0xFF); ++sectorNum) { + if (offset != 0 && (offset >> 8) + (offset & 0xFF) <= sectorFree.Count) + { + for (int sectorNum = 0; sectorNum < (offset & 0xFF); ++sectorNum) + { sectorFree[(offset >> 8) + sectorNum] = false; } } } - for (int i = 0; i < SectorInts; ++i) { + for (int i = 0; i < SectorInts; ++i) + { byte[] modBytes = new byte[4]; file.Read(modBytes, 0, 4); - if (BitConverter.IsLittleEndian) { + if (BitConverter.IsLittleEndian) + { Array.Reverse(modBytes); } int lastModValue = BitConverter.ToInt32(modBytes, 0); @@ -178,20 +201,21 @@ protected void ReadFile () } } } - catch (IOException e) { + catch (IOException e) + { System.Console.WriteLine(e.Message); System.Console.WriteLine(e.StackTrace); } } /* the modification date of the region file when it was first opened */ - public long LastModified () + public long LastModified() { return lastModified; } /* gets how much the region file has grown since it was last checked */ - public int GetSizeDelta () + public int GetSizeDelta() { int ret = sizeDelta; sizeDelta = 0; @@ -199,27 +223,27 @@ public int GetSizeDelta () } // various small debug printing helpers - private void Debug (String str) + private void Debug(String str) { // System.Consle.Write(str); } - private void Debugln (String str) + private void Debugln(String str) { Debug(str + "\n"); } - private void Debug (String mode, int x, int z, String str) + private void Debug(String mode, int x, int z, String str) { Debug("REGION " + mode + " " + fileName + "[" + x + "," + z + "] = " + str); } - private void Debug (String mode, int x, int z, int count, String str) + private void Debug(String mode, int x, int z, int count, String str) { Debug("REGION " + mode + " " + fileName + "[" + x + "," + z + "] " + count + "B = " + str); } - private void Debugln (String mode, int x, int z, String str) + private void Debugln(String mode, int x, int z, String str) { Debug(mode, x, z, str + "\n"); } @@ -228,20 +252,24 @@ private void Debugln (String mode, int x, int z, String str) * gets an (uncompressed) stream representing the chunk data returns null if * the chunk is not found or an error occurs */ - public Stream GetChunkDataInputStream (int x, int z) + public Stream GetChunkDataInputStream(int x, int z) { - if (_disposed) { + if (_disposed) + { throw new ObjectDisposedException("RegionFile", "Attempting to use a RegionFile after it has been disposed."); } - if (OutOfBounds(x, z)) { + if (OutOfBounds(x, z)) + { Debugln("READ", x, z, "out of bounds"); return null; } - try { + try + { int offset = GetOffset(x, z); - if (offset == 0) { + if (offset == 0) + { // Debugln("READ", x, z, "miss"); return null; } @@ -251,7 +279,8 @@ public Stream GetChunkDataInputStream (int x, int z) lock (this.fileLock) { - if (sectorNumber + numSectors > sectorFree.Count) { + if (sectorNumber + numSectors > sectorFree.Count) + { Debugln("READ", x, z, "invalid sector"); return null; } @@ -260,25 +289,29 @@ public Stream GetChunkDataInputStream (int x, int z) byte[] lengthBytes = new byte[4]; file.Read(lengthBytes, 0, 4); - if (BitConverter.IsLittleEndian) { + if (BitConverter.IsLittleEndian) + { Array.Reverse(lengthBytes); } int length = BitConverter.ToInt32(lengthBytes, 0); - if (length > SectorBytes * numSectors) { + if (length > SectorBytes * numSectors) + { Debugln("READ", x, z, "invalid length: " + length + " > 4096 * " + numSectors); return null; } byte version = (byte)file.ReadByte(); - if (version == VERSION_GZIP) { + if (version == VERSION_GZIP) + { byte[] data = new byte[length - 1]; file.Read(data, 0, data.Length); Stream ret = new GZipStream(new MemoryStream(data), CompressionMode.Decompress); return ret; } - else if (version == VERSION_DEFLATE) { + else if (version == VERSION_DEFLATE) + { byte[] data = new byte[length - 1]; file.Read(data, 0, data.Length); @@ -299,20 +332,21 @@ public Stream GetChunkDataInputStream (int x, int z) return null; } } - catch (IOException) { + catch (IOException) + { Debugln("READ", x, z, "exception"); return null; } } - public Stream GetChunkDataOutputStream (int x, int z) + public Stream GetChunkDataOutputStream(int x, int z) { if (OutOfBounds(x, z)) return null; return new ZlibStream(new ChunkBuffer(this, x, z), CompressionMode.Compress); } - public Stream GetChunkDataOutputStream (int x, int z, int timestamp) + public Stream GetChunkDataOutputStream(int x, int z, int timestamp) { if (OutOfBounds(x, z)) return null; @@ -330,7 +364,7 @@ class ChunkBuffer : MemoryStream private int? _timestamp; - public ChunkBuffer (RegionFile r, int x, int z) + public ChunkBuffer(RegionFile r, int x, int z) : base(8096) { this.region = r; @@ -338,90 +372,107 @@ public ChunkBuffer (RegionFile r, int x, int z) this.z = z; } - public ChunkBuffer (RegionFile r, int x, int z, int timestamp) + public ChunkBuffer(RegionFile r, int x, int z, int timestamp) : this(r, x, z) { _timestamp = timestamp; } - public override void Close () + public override void Close() { - if (_timestamp == null) { + if (_timestamp == null) + { region.Write(x, z, this.GetBuffer(), (int)this.Length); } - else { + else + { region.Write(x, z, this.GetBuffer(), (int)this.Length, (int)_timestamp); } } } - protected void Write (int x, int z, byte[] data, int length) + protected void Write(int x, int z, byte[] data, int length) { Write(x, z, data, length, Timestamp()); } /* write a chunk at (x,z) with length bytes of data to disk */ - protected void Write (int x, int z, byte[] data, int length, int timestamp) + protected void Write(int x, int z, byte[] data, int length, int timestamp) { - if (_disposed) { + if (_disposed) + { throw new ObjectDisposedException("RegionFile", "Attempting to use a RegionFile after it has been disposed."); } - try { + try + { int offset = GetOffset(x, z); int sectorNumber = offset >> 8; int sectorsAllocated = offset & 0xFF; int sectorsNeeded = (length + CHUNK_HEADER_SIZE) / SectorBytes + 1; // maximum chunk size is 1MB - if (sectorsNeeded >= 256) { + if (sectorsNeeded >= 256) + { return; } - if (sectorNumber != 0 && sectorsAllocated == sectorsNeeded) { + if (sectorNumber != 0 && sectorsAllocated == sectorsNeeded) + { /* we can simply overwrite the old sectors */ Debug("SAVE", x, z, length, "rewrite"); Write(sectorNumber, data, length); } - else { + else + { /* we need to allocate new sectors */ - lock (this.fileLock) { + lock (this.fileLock) + { /* mark the sectors previously used for this chunk as free */ - for (int i = 0; i < sectorsAllocated; ++i) { + for (int i = 0; i < sectorsAllocated; ++i) + { sectorFree[sectorNumber + i] = true; } /* scan for a free space large enough to store this chunk */ int runStart = sectorFree.FindIndex(b => b == true); int runLength = 0; - if (runStart != -1) { - for (int i = runStart; i < sectorFree.Count; ++i) { - if (runLength != 0) { + if (runStart != -1) + { + for (int i = runStart; i < sectorFree.Count; ++i) + { + if (runLength != 0) + { if (sectorFree[i]) runLength++; else runLength = 0; } - else if (sectorFree[i]) { + else if (sectorFree[i]) + { runStart = i; runLength = 1; } - if (runLength >= sectorsNeeded) { + if (runLength >= sectorsNeeded) + { break; } } } - if (runLength >= sectorsNeeded) { + if (runLength >= sectorsNeeded) + { /* we found a free space large enough */ Debug("SAVE", x, z, length, "reuse"); sectorNumber = runStart; SetOffset(x, z, (sectorNumber << 8) | sectorsNeeded); - for (int i = 0; i < sectorsNeeded; ++i) { + for (int i = 0; i < sectorsNeeded; ++i) + { sectorFree[sectorNumber + i] = false; } Write(sectorNumber, data, length); } - else { + else + { /* * no free space large enough found -- we need to grow the * file @@ -429,7 +480,8 @@ protected void Write (int x, int z, byte[] data, int length, int timestamp) Debug("SAVE", x, z, length, "grow"); file.Seek(0, SeekOrigin.End); sectorNumber = sectorFree.Count; - for (int i = 0; i < sectorsNeeded; ++i) { + for (int i = 0; i < sectorsNeeded; ++i) + { file.Write(emptySector, 0, emptySector.Length); sectorFree.Add(false); } @@ -442,20 +494,23 @@ protected void Write (int x, int z, byte[] data, int length, int timestamp) } SetTimestamp(x, z, timestamp); } - catch (IOException e) { + catch (IOException e) + { Console.WriteLine(e.StackTrace); } } /* write a chunk data to the region file at specified sector number */ - private void Write (int sectorNumber, byte[] data, int length) + private void Write(int sectorNumber, byte[] data, int length) { - lock (this.fileLock) { + lock (this.fileLock) + { Debugln(" " + sectorNumber); file.Seek(sectorNumber * SectorBytes, SeekOrigin.Begin); byte[] bytes = BitConverter.GetBytes(length + 1); - if (BitConverter.IsLittleEndian) { + if (BitConverter.IsLittleEndian) + { ; Array.Reverse(bytes); } @@ -465,15 +520,17 @@ private void Write (int sectorNumber, byte[] data, int length) } } - public void DeleteChunk (int x, int z) + public void DeleteChunk(int x, int z) { - lock (this.fileLock) { + lock (this.fileLock) + { int offset = GetOffset(x, z); int sectorNumber = offset >> 8; int sectorsAllocated = offset & 0xFF; file.Seek(sectorNumber * SectorBytes, SeekOrigin.Begin); - for (int i = 0; i < sectorsAllocated; i++) { + for (int i = 0; i < sectorsAllocated; i++) + { file.Write(emptySector, 0, SectorBytes); } @@ -483,29 +540,31 @@ public void DeleteChunk (int x, int z) } /* is this an invalid chunk coordinate? */ - private bool OutOfBounds (int x, int z) + private bool OutOfBounds(int x, int z) { return x < 0 || x >= 32 || z < 0 || z >= 32; } - private int GetOffset (int x, int z) + private int GetOffset(int x, int z) { return offsets[x + z * 32]; } - public bool HasChunk (int x, int z) + public bool HasChunk(int x, int z) { return GetOffset(x, z) != 0; } - private void SetOffset (int x, int z, int offset) + private void SetOffset(int x, int z, int offset) { - lock (this.fileLock) { + lock (this.fileLock) + { offsets[x + z * 32] = offset; file.Seek((x + z * 32) * 4, SeekOrigin.Begin); byte[] bytes = BitConverter.GetBytes(offset); - if (BitConverter.IsLittleEndian) { + if (BitConverter.IsLittleEndian) + { ; Array.Reverse(bytes); } @@ -514,31 +573,33 @@ private void SetOffset (int x, int z, int offset) } } - private int Timestamp () + private int Timestamp() { DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0); return (int)((DateTime.UtcNow - epoch).Ticks / (10000L * 1000L)); } - private int Timestamp (DateTime time) + private int Timestamp(DateTime time) { DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0); return (int)((time - epoch).Ticks / (10000L * 1000L)); } - public int GetTimestamp (int x, int z) + public int GetTimestamp(int x, int z) { return chunkTimestamps[x + z * 32]; } - public void SetTimestamp (int x, int z, int value) + public void SetTimestamp(int x, int z, int value) { - lock (this.fileLock) { + lock (this.fileLock) + { chunkTimestamps[x + z * 32] = value; file.Seek(SectorBytes + (x + z * 32) * 4, SeekOrigin.Begin); byte[] bytes = BitConverter.GetBytes(value); - if (BitConverter.IsLittleEndian) { + if (BitConverter.IsLittleEndian) + { ; Array.Reverse(bytes); } @@ -547,20 +608,22 @@ public void SetTimestamp (int x, int z, int value) } } - public void Close () + public void Close() { - lock (this.fileLock) { + lock (this.fileLock) + { file.Close(); } } - public virtual RegionKey parseCoordinatesFromName () + public virtual RegionKey parseCoordinatesFromName() { int x = 0; int z = 0; Match match = _namePattern.Match(fileName); - if (!match.Success) { + if (!match.Success) + { return RegionKey.InvalidRegion; } diff --git a/SubstrateCS/Source/Core/RegionInterface.cs b/Substrate/Source/Core/RegionInterface.cs similarity index 93% rename from SubstrateCS/Source/Core/RegionInterface.cs rename to Substrate/Source/Core/RegionInterface.cs index 83288a14..cd5a3eb2 100644 --- a/SubstrateCS/Source/Core/RegionInterface.cs +++ b/Substrate/Source/Core/RegionInterface.cs @@ -84,7 +84,7 @@ public interface IRegion : IChunkContainer /// as being out of bounds, the lookup will be delegated to the correct region and the lookup will be performed there /// instead. This allows any to perform a similar task to , but with a /// region-local frame of reference instead of a global frame of reference. - ChunkRef GetChunkRef (int lcx, int lcz); + new ChunkRef GetChunkRef (int lcx, int lcz); /// /// Creates a new chunk at the given local coordinates relative to this region and returns a new for it. @@ -94,7 +94,7 @@ public interface IRegion : IChunkContainer /// A for the newly created chunk. /// If the local coordinates are out of bounds for this region, the action will be forwarded to the correct region /// transparently. - ChunkRef CreateChunk (int lcx, int lcz); + new ChunkRef CreateChunk (int lcx, int lcz); /// /// Gets the timestamp of a chunk from the underlying region file. @@ -127,10 +127,11 @@ public interface IRegionContainer bool RegionExists (int rx, int rz); /// - /// Gets an for the given region filename. + /// Gets the region at the given coordinates. /// - /// The filename of the region to get. - /// A corresponding to the coordinates encoded in the filename. + /// The global X-coordinate of a region. + /// The global Z-coordinate of a region. + /// The object for the given coordinates, or null if none exists. IRegion GetRegion (int rx, int rz); /// diff --git a/SubstrateCS/Source/Core/RegionKey.cs b/Substrate/Source/Core/RegionKey.cs similarity index 100% rename from SubstrateCS/Source/Core/RegionKey.cs rename to Substrate/Source/Core/RegionKey.cs diff --git a/SubstrateCS/Source/Core/RegionManager.cs b/Substrate/Source/Core/RegionManager.cs similarity index 90% rename from SubstrateCS/Source/Core/RegionManager.cs rename to Substrate/Source/Core/RegionManager.cs index 23c801d8..09c76330 100644 --- a/SubstrateCS/Source/Core/RegionManager.cs +++ b/Substrate/Source/Core/RegionManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.IO; @@ -12,12 +12,34 @@ namespace Substrate.Core /// public abstract class RegionManager : IRegionManager { - protected string _regionPath; + private string _regionPath; - protected Dictionary _cache; + private Dictionary _cache; - protected ChunkCache _chunkCache; +/* Unmerged change from project 'Substrate (net45)' +Before: + protected ChunkCache _chCache; +After: + private ChunkCache chCache; +*/ + +/* Unmerged change from project 'Substrate (netcoreapp3.1)' +Before: + protected ChunkCache _chCache; +After: + private ChunkCache chCache; +*/ + +/* Unmerged change from project 'Substrate (net5.0)' +Before: + protected ChunkCache _chCache; +After: + private ChunkCache chCache; +*/ + private ChunkCache chCache; + + protected ChunkCache ChunkCache_ { get => this.chCache; set => this.chCache = value ; } protected abstract IRegion CreateRegionCore (int rx, int rz); @@ -35,7 +57,7 @@ public abstract class RegionManager : IRegionManager public RegionManager (string regionDir, ChunkCache cache) { _regionPath = regionDir; - _chunkCache = cache; + ChunkCache_ = cache; _cache = new Dictionary(); } diff --git a/SubstrateCS/Source/Core/UnboundedBlockInterface.cs b/Substrate/Source/Core/UnboundedBlockInterface.cs similarity index 100% rename from SubstrateCS/Source/Core/UnboundedBlockInterface.cs rename to Substrate/Source/Core/UnboundedBlockInterface.cs diff --git a/SubstrateCS/Source/Data.cs b/Substrate/Source/Data.cs similarity index 100% rename from SubstrateCS/Source/Data.cs rename to Substrate/Source/Data.cs diff --git a/SubstrateCS/Source/Data/BetaDataManager.cs b/Substrate/Source/Data/BetaDataManager.cs similarity index 98% rename from SubstrateCS/Source/Data/BetaDataManager.cs rename to Substrate/Source/Data/BetaDataManager.cs index c6cca4cb..fa40ea90 100644 --- a/SubstrateCS/Source/Data/BetaDataManager.cs +++ b/Substrate/Source/Data/BetaDataManager.cs @@ -10,7 +10,7 @@ public class BetaDataManager : DataManager, INbtObject { private static SchemaNodeCompound _schema = new SchemaNodeCompound() { - new SchemaNodeScaler("map", TagType.TAG_SHORT), + new SchemaNodeScalar("map", TagType.TAG_SHORT), }; private TagNodeCompound _source; diff --git a/SubstrateCS/Source/Data/DataExceptions.cs b/Substrate/Source/Data/DataExceptions.cs similarity index 100% rename from SubstrateCS/Source/Data/DataExceptions.cs rename to Substrate/Source/Data/DataExceptions.cs diff --git a/SubstrateCS/Source/Data/DataManager.cs b/Substrate/Source/Data/DataManager.cs similarity index 100% rename from SubstrateCS/Source/Data/DataManager.cs rename to Substrate/Source/Data/DataManager.cs diff --git a/SubstrateCS/Source/Data/Map.cs b/Substrate/Source/Data/Map.cs similarity index 96% rename from SubstrateCS/Source/Data/Map.cs rename to Substrate/Source/Data/Map.cs index 657ae55c..8205d134 100644 --- a/SubstrateCS/Source/Data/Map.cs +++ b/Substrate/Source/Data/Map.cs @@ -16,13 +16,13 @@ public class Map : INbtObject, ICopyable { new SchemaNodeCompound("data") { - new SchemaNodeScaler("scale", TagType.TAG_BYTE), - new SchemaNodeScaler("dimension", TagType.TAG_BYTE), - new SchemaNodeScaler("height", TagType.TAG_SHORT), - new SchemaNodeScaler("width", TagType.TAG_SHORT), - new SchemaNodeScaler("xCenter", TagType.TAG_INT), - new SchemaNodeScaler("zCenter", TagType.TAG_INT), - new SchemaNodeArray("colors"), + new SchemaNodeScalar("scale", TagType.TAG_BYTE), + new SchemaNodeScalar("dimension", TagType.TAG_BYTE), + new SchemaNodeScalar("height", TagType.TAG_SHORT), + new SchemaNodeScalar("width", TagType.TAG_SHORT), + new SchemaNodeScalar("xCenter", TagType.TAG_INT), + new SchemaNodeScalar("zCenter", TagType.TAG_INT), + new SchemaNodeByteArray("colors"), }, }; diff --git a/SubstrateCS/Source/Data/MapConverter.cs b/Substrate/Source/Data/MapConverter.cs similarity index 100% rename from SubstrateCS/Source/Data/MapConverter.cs rename to Substrate/Source/Data/MapConverter.cs diff --git a/SubstrateCS/Source/Data/MapFile.cs b/Substrate/Source/Data/MapFile.cs similarity index 100% rename from SubstrateCS/Source/Data/MapFile.cs rename to Substrate/Source/Data/MapFile.cs diff --git a/SubstrateCS/Source/Data/MapManager.cs b/Substrate/Source/Data/MapManager.cs similarity index 100% rename from SubstrateCS/Source/Data/MapManager.cs rename to Substrate/Source/Data/MapManager.cs diff --git a/SubstrateCS/Source/Data/MapManagerInterface.cs b/Substrate/Source/Data/MapManagerInterface.cs similarity index 100% rename from SubstrateCS/Source/Data/MapManagerInterface.cs rename to Substrate/Source/Data/MapManagerInterface.cs diff --git a/SubstrateCS/Source/Enchantment.cs b/Substrate/Source/Enchantment.cs similarity index 67% rename from SubstrateCS/Source/Enchantment.cs rename to Substrate/Source/Enchantment.cs index a5d08c1e..2d4fca02 100644 --- a/SubstrateCS/Source/Enchantment.cs +++ b/Substrate/Source/Enchantment.cs @@ -12,19 +12,16 @@ public class Enchantment : INbtObject, ICopyable { private static readonly SchemaNodeCompound _schema = new SchemaNodeCompound("") { - new SchemaNodeScaler("id", TagType.TAG_SHORT), - new SchemaNodeScaler("lvl", TagType.TAG_SHORT), + new SchemaNodeScalar("id", TagType.TAG_SHORT), + new SchemaNodeScalar("lvl", TagType.TAG_SHORT), }; private TagNodeCompound _source; - private short _id; - private short _level; - /// /// Constructs a blank . /// - public Enchantment () + public Enchantment() { } @@ -33,10 +30,10 @@ public Enchantment () /// /// The id (type) of the enchantment. /// The level of the enchantment. - public Enchantment (int id, int level) + public Enchantment(int id, int level) { - _id = (short)id; - _level = (short)level; + Id = id; + Level = level; } #region Properties @@ -46,26 +43,20 @@ public Enchantment (int id, int level) /// public EnchantmentInfo Info { - get { return EnchantmentInfo.EnchantmentTable[_id]; } + get { return EnchantmentInfo.EnchantmentTable[Id]; } } /// /// Gets or sets the current type (id) of the enchantment. /// - public int Id - { - get { return _id; } - set { _id = (short)value; } - } + [TagNode("id", TagType = TagType.TAG_SHORT)] + public int Id { get; set; } /// /// Gets or sets the level of the enchantment. /// - public int Level - { - get { return _level; } - set { _level = (short)value; } - } + [TagNode("lvl", TagType = TagType.TAG_SHORT)] + public int Level { get; set; } /// /// Gets a representing the schema of an enchantment. @@ -80,15 +71,16 @@ public static SchemaNodeCompound Schema #region INbtObject Members /// - public Enchantment LoadTree (TagNode tree) + public Enchantment LoadTree(TagNode tree) { TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null) { + if (ctree == null) + { return null; } - _id = ctree["id"].ToTagShort(); - _level = ctree["lvl"].ToTagShort(); + Id = ctree["id"].ToTagShort(); + Level = ctree["lvl"].ToTagShort(); _source = ctree.Copy() as TagNodeCompound; @@ -96,9 +88,10 @@ public Enchantment LoadTree (TagNode tree) } /// - public Enchantment LoadTreeSafe (TagNode tree) + public Enchantment LoadTreeSafe(TagNode tree) { - if (!ValidateTree(tree)) { + if (!ValidateTree(tree)) + { return null; } @@ -106,13 +99,14 @@ public Enchantment LoadTreeSafe (TagNode tree) } /// - public TagNode BuildTree () + public TagNode BuildTree() { TagNodeCompound tree = new TagNodeCompound(); - tree["id"] = new TagNodeShort(_id); - tree["lvl"] = new TagNodeShort(_level); + tree["id"] = new TagNodeShort((short)Id); + tree["lvl"] = new TagNodeShort((short)Level); - if (_source != null) { + if (_source != null) + { tree.MergeFrom(_source); } @@ -120,7 +114,7 @@ public TagNode BuildTree () } /// - public bool ValidateTree (TagNode tree) + public bool ValidateTree(TagNode tree) { return new NbtVerifier(tree, _schema).Verify(); } @@ -130,11 +124,12 @@ public bool ValidateTree (TagNode tree) #region ICopyable Members /// - public Enchantment Copy () + public Enchantment Copy() { - Enchantment ench = new Enchantment(_id, _level); + Enchantment ench = new Enchantment(Id, Level); - if (_source != null) { + if (_source != null) + { ench._source = _source.Copy() as TagNodeCompound; } diff --git a/SubstrateCS/Source/EnchantmentInfo.cs b/Substrate/Source/EnchantmentInfo.cs similarity index 100% rename from SubstrateCS/Source/EnchantmentInfo.cs rename to Substrate/Source/EnchantmentInfo.cs diff --git a/SubstrateCS/Source/Entity.cs b/Substrate/Source/Entity.cs similarity index 65% rename from SubstrateCS/Source/Entity.cs rename to Substrate/Source/Entity.cs index 6be3adf9..09862736 100644 --- a/SubstrateCS/Source/Entity.cs +++ b/Substrate/Source/Entity.cs @@ -16,85 +16,55 @@ public class Entity : INbtObject, ICopyable new SchemaNodeList("Pos", TagType.TAG_DOUBLE, 3), new SchemaNodeList("Motion", TagType.TAG_DOUBLE, 3), new SchemaNodeList("Rotation", TagType.TAG_FLOAT, 2), - new SchemaNodeScaler("FallDistance", TagType.TAG_FLOAT), - new SchemaNodeScaler("Fire", TagType.TAG_SHORT), - new SchemaNodeScaler("Air", TagType.TAG_SHORT), - new SchemaNodeScaler("OnGround", TagType.TAG_BYTE), + new SchemaNodeScalar("FallDistance", TagType.TAG_FLOAT), + new SchemaNodeScalar("Fire", TagType.TAG_SHORT), + new SchemaNodeScalar("Air", TagType.TAG_SHORT), + new SchemaNodeScalar("OnGround", TagType.TAG_BYTE), }; private TagNodeCompound _source; - private Vector3 _pos; - private Vector3 _motion; - private Orientation _rotation; - - private float _fallDistance; - private short _fire; - private short _air; - private byte _onGround; - /// /// Gets or sets the global position of the entity in fractional block coordinates. /// - public Vector3 Position - { - get { return _pos; } - set { _pos = value; } - } + [TagNode(Name = "Pos", TagType = TagType.TAG_LIST)] + public Vector3 Position { get; set; } /// /// Gets or sets the velocity of the entity. /// - public Vector3 Motion - { - get { return _motion; } - set { _motion = value; } - } + [TagNode(TagType = TagType.TAG_LIST)] + public Vector3 Motion { get; set; } /// /// Gets or sets the orientation of the entity. /// - public Orientation Rotation - { - get { return _rotation; } - set { _rotation = value; } - } + [TagNode(TagType = TagType.TAG_LIST)] + public Orientation Rotation { get; set; } /// /// Gets or sets the distance that the entity has fallen, if it is falling. /// - public double FallDistance - { - get { return _fallDistance; } - set { _fallDistance = (float)value; } - } + [TagNode] + public float FallDistance { get; set; } /// /// Gets or sets the fire counter of the entity. /// - public int Fire - { - get { return _fire; } - set { _fire = (short)value; } - } + [TagNode(TagType = TagType.TAG_SHORT)] + public int Fire { get; set; } /// /// Gets or sets the remaining air availale to the entity. /// - public int Air - { - get { return _air; } - set { _air = (short)value; } - } + [TagNode(TagType = TagType.TAG_SHORT)] + public int Air { get; set; } /// /// Gets or sets a value indicating whether the entity is currently touch the ground. /// - public bool IsOnGround - { - get { return _onGround == 1; } - set { _onGround = (byte)(value ? 1 : 0); } - } + [TagNode(Name = "OnGround")] + public bool IsOnGround { get; set; } /// /// Gets the source used to create this if it exists. @@ -107,41 +77,40 @@ public TagNodeCompound Source /// /// Constructs a new generic with default values. /// - public Entity () + public Entity() { - _pos = new Vector3(); - _motion = new Vector3(); - _rotation = new Orientation(); - - _source = new TagNodeCompound(); + Position = new Vector3(); + Motion = new Vector3(); + Rotation = new Orientation(); } /// /// Constructs a new generic by copying fields from another object. /// /// An to copy fields from. - protected Entity (Entity e) + protected Entity(Entity e) { - _pos = new Vector3(); - _pos.X = e._pos.X; - _pos.Y = e._pos.Y; - _pos.Z = e._pos.Z; - - _motion = new Vector3(); - _motion.X = e._motion.X; - _motion.Y = e._motion.Y; - _motion.Z = e._motion.Z; - - _rotation = new Orientation(); - _rotation.Pitch = e._rotation.Pitch; - _rotation.Yaw = e._rotation.Yaw; - - _fallDistance = e._fallDistance; - _fire = e._fire; - _air = e._air; - _onGround = e._onGround; - - if (e._source != null) { + Position = new Vector3(); + Position.X = e.Position.X; + Position.Y = e.Position.Y; + Position.Z = e.Position.Z; + + Motion = new Vector3(); + Motion.X = e.Motion.X; + Motion.Y = e.Motion.Y; + Motion.Z = e.Motion.Z; + + Rotation = new Orientation(); + Rotation.Pitch = e.Rotation.Pitch; + Rotation.Yaw = e.Rotation.Yaw; + + FallDistance = e.FallDistance; + Fire = e.Fire; + Air = e.Air; + IsOnGround = e.IsOnGround; + + if (e._source != null) + { _source = e._source.Copy() as TagNodeCompound; } } @@ -152,11 +121,11 @@ protected Entity (Entity e) /// The X-offset to move by, in blocks. /// The Y-offset to move by, in blocks. /// The Z-offset to move by, in blocks. - public virtual void MoveBy (int diffX, int diffY, int diffZ) + public virtual void MoveBy(int diffX, int diffY, int diffZ) { - _pos.X += diffX; - _pos.Y += diffY; - _pos.Z += diffZ; + Position.X += diffX; + Position.Y += diffY; + Position.Z += diffZ; } @@ -175,33 +144,34 @@ public static SchemaNodeCompound Schema /// /// The root node of an Entity subtree. /// The returns itself on success, or null if the tree was unparsable. - public Entity LoadTree (TagNode tree) + public Entity LoadTree(TagNode tree) { TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null) { + if (ctree == null) + { return null; } TagNodeList pos = ctree["Pos"].ToTagList(); - _pos = new Vector3(); - _pos.X = pos[0].ToTagDouble(); - _pos.Y = pos[1].ToTagDouble(); - _pos.Z = pos[2].ToTagDouble(); + Position = new Vector3(); + Position.X = pos[0].ToTagDouble(); + Position.Y = pos[1].ToTagDouble(); + Position.Z = pos[2].ToTagDouble(); TagNodeList motion = ctree["Motion"].ToTagList(); - _motion = new Vector3(); - _motion.X = motion[0].ToTagDouble(); - _motion.Y = motion[1].ToTagDouble(); - _motion.Z = motion[2].ToTagDouble(); + Motion = new Vector3(); + Motion.X = motion[0].ToTagDouble(); + Motion.Y = motion[1].ToTagDouble(); + Motion.Z = motion[2].ToTagDouble(); TagNodeList rotation = ctree["Rotation"].ToTagList(); - _rotation = new Orientation(); - _rotation.Yaw = rotation[0].ToTagFloat(); - _rotation.Pitch = rotation[1].ToTagFloat(); + Rotation = new Orientation(); + Rotation.Yaw = rotation[0].ToTagFloat(); + Rotation.Pitch = rotation[1].ToTagFloat(); - _fire = ctree["Fire"].ToTagShort(); - _air = ctree["Air"].ToTagShort(); - _onGround = ctree["OnGround"].ToTagByte(); + Fire = ctree["Fire"].ToTagShort(); + Air = ctree["Air"].ToTagShort(); + IsOnGround = ctree["OnGround"].ToTagByte() != 0; _source = ctree.Copy() as TagNodeCompound; @@ -213,9 +183,10 @@ public Entity LoadTree (TagNode tree) /// /// The root node of an Entity subtree. /// The returns itself on success, or null if the tree failed validation. - public Entity LoadTreeSafe (TagNode tree) + public Entity LoadTreeSafe(TagNode tree) { - if (!ValidateTree(tree)) { + if (!ValidateTree(tree)) + { return null; } @@ -226,33 +197,34 @@ public Entity LoadTreeSafe (TagNode tree) /// Builds an Entity subtree from the current data. /// /// The root node of an Entity subtree representing the current data. - public TagNode BuildTree () + public TagNode BuildTree() { TagNodeCompound tree = new TagNodeCompound(); TagNodeList pos = new TagNodeList(TagType.TAG_DOUBLE); - pos.Add(new TagNodeDouble(_pos.X)); - pos.Add(new TagNodeDouble(_pos.Y)); - pos.Add(new TagNodeDouble(_pos.Z)); + pos.Add(new TagNodeDouble(Position.X)); + pos.Add(new TagNodeDouble(Position.Y)); + pos.Add(new TagNodeDouble(Position.Z)); tree["Pos"] = pos; TagNodeList motion = new TagNodeList(TagType.TAG_DOUBLE); - motion.Add(new TagNodeDouble(_motion.X)); - motion.Add(new TagNodeDouble(_motion.Y)); - motion.Add(new TagNodeDouble(_motion.Z)); + motion.Add(new TagNodeDouble(Motion.X)); + motion.Add(new TagNodeDouble(Motion.Y)); + motion.Add(new TagNodeDouble(Motion.Z)); tree["Motion"] = motion; TagNodeList rotation = new TagNodeList(TagType.TAG_FLOAT); - rotation.Add(new TagNodeFloat((float)_rotation.Yaw)); - rotation.Add(new TagNodeFloat((float)_rotation.Pitch)); + rotation.Add(new TagNodeFloat((float)Rotation.Yaw)); + rotation.Add(new TagNodeFloat((float)Rotation.Pitch)); tree["Rotation"] = rotation; - tree["FallDistance"] = new TagNodeFloat(_fallDistance); - tree["Fire"] = new TagNodeShort(_fire); - tree["Air"] = new TagNodeShort(_air); - tree["OnGround"] = new TagNodeByte(_onGround); + tree["FallDistance"] = new TagNodeFloat(FallDistance); + tree["Fire"] = new TagNodeShort((short)Fire); + tree["Air"] = new TagNodeShort((short)Air); + tree["OnGround"] = new TagNodeByte(IsOnGround); - if (_source != null) { + if (_source != null) + { tree.MergeFrom(_source); } @@ -264,7 +236,7 @@ public TagNode BuildTree () /// /// The root node of an Entity subtree. /// Status indicating whether the tree was valid against the internal schema. - public bool ValidateTree (TagNode tree) + public bool ValidateTree(TagNode tree) { return new NbtVerifier(tree, _schema).Verify(); } @@ -278,7 +250,7 @@ public bool ValidateTree (TagNode tree) /// Creates a deep-copy of the . /// /// A deep-copy of the . - public Entity Copy () + public Entity Copy() { return new Entity(this); } @@ -296,7 +268,7 @@ public class TypedEntity : Entity, INbtObject, ICopyable with the given id. /// /// The id (name) of the Entity. - public TypedEntity (string id) + public TypedEntity(string id) : base() { _id = id; @@ -323,7 +295,7 @@ public TypedEntity (string id) /// Constructs a new by copying an existing one. /// /// The to copy. - protected TypedEntity (TypedEntity e) + protected TypedEntity(TypedEntity e) : base(e) { _id = e._id; @@ -345,10 +317,11 @@ protected TypedEntity (TypedEntity e) /// /// The root node of an Entity subtree. /// The returns itself on success, or null if the tree was unparsable. - public virtual new TypedEntity LoadTree (TagNode tree) + public virtual new TypedEntity LoadTree(TagNode tree) { TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null || base.LoadTree(tree) == null) { + if (ctree == null || base.LoadTree(tree) == null) + { return null; } @@ -362,9 +335,10 @@ protected TypedEntity (TypedEntity e) /// /// The root node of an Entity subtree. /// The returns itself on success, or null if the tree failed validation. - public virtual new TypedEntity LoadTreeSafe (TagNode tree) + public virtual new TypedEntity LoadTreeSafe(TagNode tree) { - if (!ValidateTree(tree)) { + if (!ValidateTree(tree)) + { return null; } @@ -375,7 +349,7 @@ protected TypedEntity (TypedEntity e) /// Builds an Entity subtree from the current data. /// /// The root node of an Entity subtree representing the current data. - public virtual new TagNode BuildTree () + public virtual new TagNode BuildTree() { TagNodeCompound tree = base.BuildTree() as TagNodeCompound; tree["id"] = new TagNodeString(_id); @@ -388,7 +362,7 @@ protected TypedEntity (TypedEntity e) /// /// The root node of an Entity subtree. /// Status indicating whether the tree was valid against the internal schema. - public virtual new bool ValidateTree (TagNode tree) + public virtual new bool ValidateTree(TagNode tree) { return new NbtVerifier(tree, _schema).Verify(); } @@ -402,7 +376,7 @@ protected TypedEntity (TypedEntity e) /// Creates a deep-copy of the . /// /// A deep-copy of the . - public virtual new TypedEntity Copy () + public virtual new TypedEntity Copy() { return new TypedEntity(this); } diff --git a/SubstrateCS/Source/EntityCollection.cs b/Substrate/Source/EntityCollection.cs similarity index 92% rename from SubstrateCS/Source/EntityCollection.cs rename to Substrate/Source/EntityCollection.cs index 8b566d8a..069f17bb 100644 --- a/SubstrateCS/Source/EntityCollection.cs +++ b/Substrate/Source/EntityCollection.cs @@ -12,16 +12,10 @@ public class EntityCollection : IEnumerable { private TagNodeList _entities; - private bool _dirty; - /// /// Gets or sets a value indicating whether this collection contains unsaved changes. /// - public bool IsDirty - { - get { return _dirty; } - set { _dirty = value; } - } + public bool IsDirty { get; set; } /// /// Creates a new around a containing Entity nodes. @@ -89,12 +83,12 @@ public List FindAll (Predicate match) /// The object to add. /// It is up to the developer to ensure that the being added to the collection has a position that /// is within acceptable range of the collection. transparently back other objects such as - /// objects, which have a well-defined position in global space. The itself has + /// objects, which have a well-defined position in global space. The itself has /// no concept of position and will not enforce constraints on the positions of objects being added. public void Add (TypedEntity ent) { _entities.Add(ent.BuildTree()); - _dirty = true; + IsDirty = true; } /// @@ -120,7 +114,7 @@ public int RemoveAll (string id) }); if (rem > 0) { - _dirty = true; + IsDirty = true; } return rem; @@ -149,7 +143,7 @@ public int RemoveAll (Predicate match) }); if (rem > 0) { - _dirty = true; + IsDirty = true; } return rem; diff --git a/SubstrateCS/Source/EntityFactory.cs b/Substrate/Source/EntityFactory.cs similarity index 60% rename from SubstrateCS/Source/EntityFactory.cs rename to Substrate/Source/EntityFactory.cs index 9d256187..75408e5f 100644 --- a/SubstrateCS/Source/EntityFactory.cs +++ b/Substrate/Source/EntityFactory.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Substrate.Entities; using Substrate.Nbt; namespace Substrate @@ -106,48 +105,5 @@ public static IEnumerable> RegisteredEntities } } } - - static EntityFactory () - { - _registry[EntityArrow.TypeId] = typeof(EntityArrow); - _registry[EntityBlaze.TypeId] = typeof(EntityBlaze); - _registry[EntityBoat.TypeId] = typeof(EntityBoat); - _registry[EntityCaveSpider.TypeId] = typeof(EntityCaveSpider); - _registry[EntityChicken.TypeId] = typeof(EntityChicken); - _registry[EntityCow.TypeId] = typeof(EntityCow); - _registry[EntityCreeper.TypeId] = typeof(EntityCreeper); - _registry[EntityEgg.TypeId] = typeof(EntityEgg); - _registry[EntityEnderDragon.TypeId] = typeof(EntityEnderDragon); - _registry[EntityEnderman.TypeId] = typeof(EntityEnderman); - _registry[EntityEnderEye.TypeId] = typeof(EntityEnderEye); - _registry[EntityFallingSand.TypeId] = typeof(EntityFallingSand); - _registry[EntityFireball.TypeId] = typeof(EntityFireball); - _registry[EntityGhast.TypeId] = typeof(EntityGhast); - _registry[EntityGiant.TypeId] = typeof(EntityGiant); - _registry[EntityItem.TypeId] = typeof(EntityItem); - _registry[EntityMagmaCube.TypeId] = typeof(EntityMagmaCube); - _registry[EntityMinecart.TypeId] = typeof(EntityMinecart); - _registry[EntityMob.TypeId] = typeof(EntityMob); - _registry[EntityMonster.TypeId] = typeof(EntityMonster); - _registry[EntityMooshroom.TypeId] = typeof(EntityMooshroom); - _registry[EntityPainting.TypeId] = typeof(EntityPainting); - _registry[EntityPig.TypeId] = typeof(EntityPig); - _registry[EntityPigZombie.TypeId] = typeof(EntityPigZombie); - _registry[EntityPrimedTnt.TypeId] = typeof(EntityPrimedTnt); - _registry[EntitySheep.TypeId] = typeof(EntitySheep); - _registry[EntitySilverfish.TypeId] = typeof(EntitySilverfish); - _registry[EntitySkeleton.TypeId] = typeof(EntitySkeleton); - _registry[EntitySlime.TypeId] = typeof(EntitySlime); - _registry[EntitySmallFireball.TypeId] = typeof(EntitySmallFireball); - _registry[EntitySnowball.TypeId] = typeof(EntitySnowball); - _registry[EntitySnowman.TypeId] = typeof(EntitySnowman); - _registry[EntitySpider.TypeId] = typeof(EntitySpider); - _registry[EntitySquid.TypeId] = typeof(EntitySquid); - _registry[EntityEnderPearl.TypeId] = typeof(EntityEnderPearl); - _registry[EntityVillager.TypeId] = typeof(EntityVillager); - _registry[EntityWolf.TypeId] = typeof(EntityWolf); - _registry[EntityXPOrb.TypeId] = typeof(EntityXPOrb); - _registry[EntityZombie.TypeId] = typeof(EntityZombie); - } } } diff --git a/SubstrateCS/Source/ImportExport/Schematic.cs b/Substrate/Source/ImportExport/Schematic.cs similarity index 82% rename from SubstrateCS/Source/ImportExport/Schematic.cs rename to Substrate/Source/ImportExport/Schematic.cs index 6093f5c9..0bde7007 100644 --- a/SubstrateCS/Source/ImportExport/Schematic.cs +++ b/Substrate/Source/ImportExport/Schematic.cs @@ -13,12 +13,12 @@ public class Schematic { private static SchemaNodeCompound _schema = new SchemaNodeCompound() { - new SchemaNodeScaler("Width", TagType.TAG_SHORT), - new SchemaNodeScaler("Length", TagType.TAG_SHORT), - new SchemaNodeScaler("Height", TagType.TAG_SHORT), + new SchemaNodeScalar("Width", TagType.TAG_SHORT), + new SchemaNodeScalar("Length", TagType.TAG_SHORT), + new SchemaNodeScalar("Height", TagType.TAG_SHORT), new SchemaNodeString("Materials", "Alpha"), - new SchemaNodeArray("Blocks"), - new SchemaNodeArray("Data"), + new SchemaNodeByteArray("Blocks"), + new SchemaNodeByteArray("Data"), new SchemaNodeList("Entities", TagType.TAG_COMPOUND, Entity.Schema), new SchemaNodeList("TileEntities", TagType.TAG_COMPOUND, TileEntity.Schema), }; @@ -35,7 +35,7 @@ public class Schematic private AlphaBlockCollection _blockset; private EntityCollection _entityset; - private Schematic () + private Schematic() { } @@ -44,7 +44,7 @@ private Schematic () /// /// An existing . /// An existing . - public Schematic (AlphaBlockCollection blocks, EntityCollection entities) + public Schematic(AlphaBlockCollection blocks, EntityCollection entities) { _blockset = blocks; _entityset = entities; @@ -56,7 +56,7 @@ public Schematic (AlphaBlockCollection blocks, EntityCollection entities) /// The length of the X-dimension in blocks. /// The length of the Y-dimension in blocks. /// The length of the Z-dimension in blocks. - public Schematic (int xdim, int ydim, int zdim) + public Schematic(int xdim, int ydim, int zdim) { _blocks = new XZYByteArray(xdim, ydim, zdim); _data = new XZYNibbleArray(xdim, ydim, zdim); @@ -98,10 +98,11 @@ public EntityCollection Entities /// /// The path to the schematic file. /// A object containing the decoded schematic file data. - public static Schematic Import (string path) + public static Schematic Import(string path) { NBTFile schematicFile = new NBTFile(path); - if (!schematicFile.Exists()) { + if (!schematicFile.Exists()) + { return null; } NbtTree tree; @@ -117,7 +118,8 @@ public static Schematic Import (string path) } NbtVerifier v = new NbtVerifier(tree.Root, _schema); - if (!v.Verify()) { + if (!v.Verify()) + { return null; } @@ -133,9 +135,12 @@ public static Schematic Import (string path) YZXByteArray schemaBlocks = new YZXByteArray(xdim, ydim, zdim, schematic["Blocks"].ToTagByteArray()); YZXByteArray schemaData = new YZXByteArray(xdim, ydim, zdim, schematic["Data"].ToTagByteArray()); - for (int x = 0; x < xdim; x++) { - for (int y = 0; y < ydim; y++) { - for (int z = 0; z < zdim; z++) { + for (int x = 0; x < xdim; x++) + { + for (int y = 0; y < ydim; y++) + { + for (int z = 0; z < zdim; z++) + { self._blocks[x, y, z] = schemaBlocks[x, y, z]; self._data[x, y, z] = schemaData[x, y, z]; } @@ -143,12 +148,14 @@ public static Schematic Import (string path) } TagNodeList entities = schematic["Entities"] as TagNodeList; - foreach (TagNode e in entities) { + foreach (TagNode e in entities) + { self._entities.Add(e); } TagNodeList tileEntities = schematic["TileEntities"] as TagNodeList; - foreach (TagNode te in tileEntities) { + foreach (TagNode te in tileEntities) + { self._tileEntities.Add(te); } @@ -161,7 +168,7 @@ public static Schematic Import (string path) /// Exports the object to a schematic file. /// /// The path to write out the schematic file to. - public void Export (string path) + public void Export(string path) { int xdim = _blockset.XDim; int ydim = _blockset.YDim; @@ -176,15 +183,19 @@ public void Export (string path) TagNodeList entities = new TagNodeList(TagType.TAG_COMPOUND); TagNodeList tileEntities = new TagNodeList(TagType.TAG_COMPOUND); - for (int x = 0; x < xdim; x++) { - for (int z = 0; z < zdim; z++) { - for (int y = 0; y < ydim; y++) { + for (int x = 0; x < xdim; x++) + { + for (int z = 0; z < zdim; z++) + { + for (int y = 0; y < ydim; y++) + { AlphaBlock block = _blockset.GetBlock(x, y, z); schemaBlocks[x, y, z] = (byte)block.ID; schemaData[x, y, z] = (byte)block.Data; TileEntity te = block.GetTileEntity(); - if (te != null) { + if (te != null) + { te.X = x; te.Y = y; te.Z = z; @@ -195,7 +206,8 @@ public void Export (string path) } } - foreach (TypedEntity e in _entityset) { + foreach (TypedEntity e in _entityset) + { entities.Add(e.BuildTree()); } diff --git a/Substrate/Source/Item.cs b/Substrate/Source/Item.cs new file mode 100644 index 00000000..4dfc4dc9 --- /dev/null +++ b/Substrate/Source/Item.cs @@ -0,0 +1,285 @@ +using System; +using System.Collections.Generic; +using Substrate.Core; +using Substrate.Nbt; + +namespace Substrate +{ + public class ItemTag : ICopyable + { + + /// + /// Gets the list of s applied to this item. + /// + [TagNode(Name = "ench", Optional = true)] + public List Enchantments { get; } = new List(); + + [TagNode(Name = "title", Optional = true)] + public string Title { get; set; } + + [TagNode(Name = "author", Optional = true)] + public string Author { get; set; } + + [TagNode(Name = "pages", Optional = true)] + public List Pages { get; } = new List(); + + + + #region ICopyable Members + + /// + public virtual ItemTag Copy() + { + ItemTag itemTag = new ItemTag(); + itemTag.Title = Title; + itemTag.Author = Author; + + foreach (var e in Enchantments) + { + itemTag.Enchantments.Add(e.Copy()); + } + + foreach (var e in Pages) + { + itemTag.Pages.Add(e); + } + + return itemTag; + } + + #endregion + + } + + /// + /// Represents an item (or item stack) within an item slot. + /// + public class Item : INbtObject, ICopyable + { + private static readonly SchemaNodeCompound _schema = new SchemaNodeCompound("") + { + new SchemaNodeString("id"), + new SchemaNodeScalar("Damage", TagType.TAG_SHORT), + new SchemaNodeScalar("Count", TagType.TAG_BYTE), + new SchemaNodeScalar("Slot", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeCompound("tag", new SchemaNodeCompound("") { + new SchemaNodeList("ench", TagType.TAG_COMPOUND, Enchantment.Schema, SchemaOptions.OPTIONAL), + new SchemaNodeString("title", SchemaOptions.OPTIONAL), + new SchemaNodeString("author", SchemaOptions.OPTIONAL), + new SchemaNodeList("pages", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + }, SchemaOptions.OPTIONAL), + }; + + private TagNodeCompound source_; + + private List _enchantments; + + /// + /// Constructs an empty instance. + /// + public Item() + { + _enchantments = new List(); + Source = new TagNodeCompound(); + } + + /// + /// Constructs an instance representing the given item id. + /// + /// An item id. + public Item(int id) + : this() + { + ID = ItemInfo.ItemTable[id].NameID; + } + + #region Properties + + ///// + ///// Gets an entry for this item's type. + ///// + //public ItemInfo Info + //{ + // get { return ItemInfo.ItemTable[ID]; } + //} + + /// + /// Gets or sets the current type (id) of the item. + /// + [TagNode("id", TagType = TagType.TAG_STRING)] + public string ID { get; set; } + + /// + /// Gets or sets the damage value of the item. + /// + /// The damage value may represent a generic data value for some items. + [TagNode(TagType = TagType.TAG_SHORT)] + public int Damage { get; set; } + + /// + /// Gets or sets the number of this item stacked together in an item slot. + /// + [TagNode(TagType = TagType.TAG_BYTE)] + public int Count { get; set; } + + [TagNode(TagType = TagType.TAG_BYTE)] + public int? Slot { get; set; } + + /// + /// Gets or sets the number of this item stacked together in an item slot. + /// + [TagNode(Name = "tag", Optional = true)] + public ItemTag Tag { get; set; } + + /// + /// Gets the list of s applied to this item. + /// + public List Enchantments + { + get { return _enchantments; } + } + + /// + /// Gets the source used to create this if it exists. + /// + public TagNodeCompound Source + { + get => this.source_; + protected set => this.source_ = value; + } + + /// + /// Gets a representing the schema of an item. + /// + public static SchemaNodeCompound Schema + { + get { return _schema; } + } + + #endregion + + #region ICopyable Members + + /// + public virtual Item Copy() + { + Item item = new Item(); + item.ID = ID; + item.Count = Count; + item.Damage = Damage; + + foreach (Enchantment e in _enchantments) + { + item._enchantments.Add(e.Copy()); + } + + if (Source != null) + { + item.Source = Source.Copy() as TagNodeCompound; + } + + return item; + } + + #endregion + + #region INBTObject Members + + /// + public Item LoadTree(TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null) + { + return null; + } + + _enchantments.Clear(); + + var id = ctree["id"]; + if (id.GetTagType() == TagType.TAG_SHORT) + { + ID = ItemInfo.ItemTable[id.ToTagShort()].NameID; + } + else + { + ID = id.ToTagString(); + } + + Count = ctree["Count"].ToTagByte(); + Damage = ctree["Damage"].ToTagShort(); + + if (ctree.ContainsKey("tag")) + { + TagNodeCompound tagtree = ctree["tag"].ToTagCompound(); + if (tagtree.ContainsKey("ench")) + { + TagNodeList enchList = tagtree["ench"].ToTagList(); + + foreach (TagNode tag in enchList) + { + _enchantments.Add(new Enchantment().LoadTree(tag)); + } + } + } + + Source = ctree.Copy() as TagNodeCompound; + + return this; + } + + /// + public Item LoadTreeSafe(TagNode tree) + { + if (!ValidateTree(tree)) + { + return null; + } + + return LoadTree(tree); + } + + /// + public TagNode BuildTree() + { + TagNodeCompound tree = new TagNodeCompound(); + tree["id"] = new TagNodeString(ID); + tree["Count"] = new TagNodeByte((byte)Count); + tree["Damage"] = new TagNodeShort((short)Damage); + + if (_enchantments.Count > 0) + { + TagNodeList enchList = new TagNodeList(TagType.TAG_COMPOUND); + foreach (Enchantment e in _enchantments) + { + enchList.Add(e.BuildTree()); + } + + TagNodeCompound tagtree = new TagNodeCompound(); + tagtree["ench"] = enchList; + + if (Source != null && Source.ContainsKey("tag")) + { + tagtree.MergeFrom(Source["tag"].ToTagCompound()); + } + + tree["tag"] = tagtree; + } + + if (Source != null) + { + tree.MergeFrom(Source); + } + + return tree; + } + + /// + public bool ValidateTree(TagNode tree) + { + return new NbtVerifier(tree, _schema).Verify(); + } + + #endregion + } +} diff --git a/SubstrateCS/Source/ItemCollection.cs b/Substrate/Source/ItemCollection.cs similarity index 68% rename from SubstrateCS/Source/ItemCollection.cs rename to Substrate/Source/ItemCollection.cs index d721b645..58633207 100644 --- a/SubstrateCS/Source/ItemCollection.cs +++ b/Substrate/Source/ItemCollection.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Substrate.Nbt; using Substrate.Core; +using Substrate.Source.Nbt; namespace Substrate { @@ -9,17 +10,14 @@ namespace Substrate /// Represents a collection of items, such as a chest or an inventory. /// /// ItemCollections have a limited number of slots that depends on where they are used. - public class ItemCollection : INbtObject, ICopyable + [TagNodeType(TagType.TAG_LIST, ListItemTagType = TagType.TAG_COMPOUND, ListItemType = typeof(Item))] + public class ItemCollection : INbtObject, INbtObject2, ICopyable { - private static readonly SchemaNodeCompound _schema = Item.Schema.MergeInto(new SchemaNodeCompound("") - { - new SchemaNodeScaler("Slot", TagType.TAG_BYTE), - }); + private static readonly SchemaNodeList _listSchema = new SchemaNodeList("", TagType.TAG_COMPOUND, Item.Schema); - private static readonly SchemaNodeList _listSchema = new SchemaNodeList("", TagType.TAG_COMPOUND, _schema); + private static readonly SchemaNodeList Schema2 = new SchemaNodeList("", TagType.TAG_COMPOUND, SchemaBuilder.FromClass(typeof(Item))); private Dictionary _items; - private int _capacity; /// /// Constructs an with at most item slots. @@ -28,29 +26,21 @@ public class ItemCollection : INbtObject, ICopyableThe parameter does not necessarily indicate the true capacity of an item collection. /// The player object, for example, contains a conventional inventory, a range of invalid slots, and then equipment. Capacity in /// this case would refer to the highest equipment slot. - public ItemCollection (int capacity) + public ItemCollection(int capacity) { - _capacity = capacity; + Capacity = capacity; _items = new Dictionary(); } - #region Properties - /// /// Gets the capacity of the item collection. /// - public int Capacity - { - get { return _capacity; } - } + public int Capacity { get; private set; } /// /// Gets the current number of item slots actually used in the collection. /// - public int Count - { - get { return _items.Count; } - } + public int Count { get { return _items.Count; } } /// /// Gets or sets an item in a given item slot. @@ -67,7 +57,8 @@ public Item this[int slot] set { - if (slot < 0 || slot >= _capacity) { + if (slot < 0 || slot >= Capacity) + { return; } _items[slot] = value; @@ -77,19 +68,17 @@ public Item this[int slot] /// /// Gets a representing the schema of an item collection. /// - public static SchemaNodeCompound Schema + public static SchemaNodeCompound ItemSchema { - get { return _schema; } + get { return Item.Schema; } } - #endregion - /// /// Checks if an item exists in the given item slot. /// /// The item slot to check. /// True if an item or stack of items exists in the given slot. - public bool ItemExists (int slot) + public bool ItemExists(int slot) { return _items.ContainsKey(slot); } @@ -99,7 +88,7 @@ public bool ItemExists (int slot) /// /// The item slot to clear. /// True if an item was removed; false otherwise. - public bool Clear (int slot) + public bool Clear(int slot) { return _items.Remove(slot); } @@ -107,7 +96,7 @@ public bool Clear (int slot) /// /// Removes all items from the item collection. /// - public void ClearAllItems () + public void ClearAllItems() { _items.Clear(); } @@ -115,10 +104,11 @@ public void ClearAllItems () #region ICopyable Members /// - public ItemCollection Copy () + public ItemCollection Copy() { - ItemCollection ic = new ItemCollection(_capacity); - foreach (KeyValuePair item in _items) { + ItemCollection ic = new ItemCollection(Capacity); + foreach (KeyValuePair item in _items) + { ic[item.Key] = item.Value.Copy(); } return ic; @@ -129,14 +119,16 @@ public ItemCollection Copy () #region INBTObject Members /// - public ItemCollection LoadTree (TagNode tree) + public ItemCollection LoadTree(TagNode tree) { TagNodeList ltree = tree as TagNodeList; - if (ltree == null) { + if (ltree == null) + { return null; } - foreach (TagNodeCompound item in ltree) { + foreach (TagNodeCompound item in ltree) + { int slot = item["Slot"].ToTagByte(); _items[slot] = new Item().LoadTree(item); } @@ -145,9 +137,10 @@ public ItemCollection LoadTree (TagNode tree) } /// - public ItemCollection LoadTreeSafe (TagNode tree) + public ItemCollection LoadTreeSafe(TagNode tree) { - if (!ValidateTree(tree)) { + if (!ValidateTree(tree)) + { return null; } @@ -155,11 +148,12 @@ public ItemCollection LoadTreeSafe (TagNode tree) } /// - public TagNode BuildTree () + public TagNode BuildTree() { TagNodeList list = new TagNodeList(TagType.TAG_COMPOUND); - foreach (KeyValuePair item in _items) { + foreach (KeyValuePair item in _items) + { TagNodeCompound itemtree = item.Value.BuildTree() as TagNodeCompound; itemtree["Slot"] = new TagNodeByte((byte)item.Key); list.Add(itemtree); @@ -169,11 +163,26 @@ public TagNode BuildTree () } /// - public bool ValidateTree (TagNode tree) + public bool ValidateTree(TagNode tree) { return new NbtVerifier(tree, _listSchema).Verify(); } #endregion + + void INbtObject2.LoadTree(TagNode tree) + { + TagNodeList ltree = tree as TagNodeList; + if (ltree == null) + { + return; + } + + foreach (TagNodeCompound item in ltree) + { + int slot = item["Slot"].ToTagByte(); + _items[slot] = new Item().LoadTree(item); + } + } } } diff --git a/Substrate/Source/ItemInfo.cs b/Substrate/Source/ItemInfo.cs new file mode 100644 index 00000000..97b3caf5 --- /dev/null +++ b/Substrate/Source/ItemInfo.cs @@ -0,0 +1,721 @@ +using System; +using System.Collections.Generic; +using Substrate.Nbt; +using System.Collections; + +namespace Substrate +{ + /// + /// Provides named id values for known item types. + /// + /// See for additional information. + public static class ItemType + { + public const int IRON_SHOVEL = 256; + public const int IRON_PICKAXE = 257; + public const int IRON_AXE = 258; + public const int FLINT_AND_STEEL = 259; + public const int APPLE = 260; + public const int BOW = 261; + public const int ARROW = 262; + public const int COAL = 263; + public const int DIAMOND = 264; + public const int IRON_INGOT = 265; + public const int GOLD_INGOT = 266; + public const int IRON_SWORD = 267; + public const int WOODEN_SWORD = 268; + public const int WOODEN_SHOVEL = 269; + public const int WOODEN_PICKAXE = 270; + public const int WOODEN_AXE = 271; + public const int STONE_SWORD = 272; + public const int STONE_SHOVEL = 273; + public const int STONE_PICKAXE = 274; + public const int STONE_AXE = 275; + public const int DIAMOND_SWORD = 276; + public const int DIAMOND_SHOVEL = 277; + public const int DIAMOND_PICKAXE = 278; + public const int DIAMOND_AXE = 279; + public const int STICK = 280; + public const int BOWL = 281; + public const int MUSHROOM_SOUP = 282; + public const int GOLD_SWORD = 283; + public const int GOLD_SHOVEL = 284; + public const int GOLD_PICKAXE = 285; + public const int GOLD_AXE = 286; + public const int STRING = 287; + public const int FEATHER = 288; + public const int GUNPOWDER = 289; + public const int WOODEN_HOE = 290; + public const int STONE_HOE = 291; + public const int IRON_HOE = 292; + public const int DIAMOND_HOE = 293; + public const int GOLD_HOE = 294; + public const int SEEDS = 295; + public const int WHEAT = 296; + public const int BREAD = 297; + public const int LEATHER_CAP = 298; + public const int LEATHER_TUNIC = 299; + public const int LEATHER_PANTS = 300; + public const int LEATHER_BOOTS = 301; + public const int CHAIN_HELMET = 302; + public const int CHAIN_CHESTPLATE = 303; + public const int CHAIN_LEGGINGS = 304; + public const int CHAIN_BOOTS = 305; + public const int IRON_HELMET = 306; + public const int IRON_CHESTPLATE = 307; + public const int IRON_LEGGINGS = 308; + public const int IRON_BOOTS = 309; + public const int DIAMOND_HELMET = 310; + public const int DIAMOND_CHESTPLATE = 311; + public const int DIAMOND_LEGGINGS = 312; + public const int DIAMOND_BOOTS = 313; + public const int GOLD_HELMET = 314; + public const int GOLD_CHESTPLATE = 315; + public const int GOLD_LEGGINGS = 316; + public const int GOLD_BOOTS = 317; + public const int FLINT = 318; + public const int RAW_PORKCHOP = 319; + public const int COOKED_PORKCHOP = 320; + public const int PAINTING = 321; + public const int GOLDEN_APPLE = 322; + public const int SIGN = 323; + public const int WOODEN_DOOR = 324; + public const int BUCKET = 325; + public const int WATER_BUCKET = 326; + public const int LAVA_BUCKET = 327; + public const int MINECART = 328; + public const int SADDLE = 329; + public const int IRON_DOOR = 330; + public const int REDSTONE_DUST = 331; + public const int SNOWBALL = 332; + public const int BOAT = 333; + public const int LEATHER = 334; + public const int MILK = 335; + public const int CLAY_BRICK = 336; + public const int CLAY = 337; + public const int SUGAR_CANE = 338; + public const int PAPER = 339; + public const int BOOK = 340; + public const int SLIMEBALL = 341; + public const int STORAGE_MINECART = 342; + public const int POWERED_MINECARD = 343; + public const int EGG = 344; + public const int COMPASS = 345; + public const int FISHING_ROD = 346; + public const int CLOCK = 347; + public const int GLOWSTONE_DUST = 348; + public const int RAW_FISH = 349; + public const int COOKED_FISH = 350; + public const int DYE = 351; + public const int BONE = 352; + public const int SUGAR = 353; + public const int CAKE = 354; + public const int BED = 355; + public const int REDSTONE_REPEATER = 356; + public const int COOKIE = 357; + public const int MAP = 358; + public const int SHEARS = 359; + public const int MELON_SLICE = 360; + public const int PUMPKIN_SEEDS = 361; + public const int MELON_SEEDS = 262; + public const int RAW_BEEF = 363; + public const int STEAK = 364; + public const int RAW_CHICKEN = 365; + public const int COOKED_CHICKEN = 366; + public const int ROTTEN_FLESH = 367; + public const int ENDER_PEARL = 368; + public const int BLAZE_ROD = 369; + public const int GHAST_TEAR = 370; + public const int GOLD_NUGGET = 371; + public const int NETHER_WART = 372; + public const int POTION = 373; + public const int GLASS_BOTTLE = 374; + public const int SPIDER_EYE = 375; + public const int FERMENTED_SPIDER_EYE = 376; + public const int BLAZE_POWDER = 377; + public const int MAGMA_CREAM = 378; + public const int BREWING_STAND = 379; + public const int CAULDRON = 380; + public const int EYE_OF_ENDER = 381; + public const int GLISTERING_MELON = 382; + public const int SPAWN_EGG = 383; + public const int BOTTLE_O_ENCHANTING = 384; + public const int FIRE_CHARGE = 385; + public const int BOOK_AND_QUILL = 386; + public const int WRITTEN_BOOK = 387; + public const int EMERALD = 388; + public const int ITEM_FRAME = 389; + public const int FLOWER_POT = 390; + public const int CARROT = 391; + public const int POTATO = 392; + public const int BAKED_POTATO = 393; + public const int POISON_POTATO = 394; + public const int EMPTY_MAP = 395; + public const int GOLDEN_CARROT = 396; + public const int MOB_HEAD = 397; + public const int CARROT_ON_A_STICK = 398; + public const int NETHER_STAR = 399; + public const int PUMPKIN_PIE = 400; + public const int FIREWORK_ROCKET = 401; + public const int FIREWORK_STAR = 402; + public const int ENCHANTED_BOOK = 403; + public const int REDSTONE_COMPARATOR = 404; + public const int NETHER_BRICK = 405; + public const int NETHER_QUARTZ = 406; + public const int TNT_MINECART = 407; + public const int HOPPER_MINECART = 408; + public const int PRISMARINE_SHARD = 409; + public const int PRISMARINE_CRYSTALS = 410; + public const int RAW_RABBIT = 411; + public const int COOKED_RABBIT = 412; + public const int RABBIT_STEW = 413; + public const int RABBITS_FOOT = 414; + public const int RABBIT_HIDE = 415; + public const int ARMOR_STAND = 416; + public const int IRON_HORSE_ARMOR = 417; + public const int GOLD_HORSE_ARMOR = 418; + public const int DIAMOND_HORSE_ARMOR = 419; + public const int LEAD = 420; + public const int NAME_TAG = 421; + public const int MINECART_WITH_COMMAND_BLOCK = 422; + public const int RAW_MUTTON = 423; + public const int COOKED_MUTTON = 424; + public const int BANNER = 425; + + public const int SPRUCE_DOOR = 427; + public const int BIRCH_DOOR = 428; + public const int JUNGLE_DOOR = 429; + public const int ACACIA_DOOR = 430; + public const int DARK_OAK_DOOR = 431; + + public const int MUSIC_DISC_13 = 2256; + public const int MUSIC_DISC_CAT = 2257; + public const int MUSIC_DISC_BLOCKS = 2258; + public const int MUSIC_DISC_CHIRP = 2259; + public const int MUSIC_DISC_FAR = 2260; + public const int MUSIC_DISC_MALL = 2261; + public const int MUSIC_DISC_MELLOHI = 2262; + public const int MUSIC_DISC_STAL = 2263; + public const int MUSIC_DISC_STRAD = 2264; + public const int MUSIC_DISC_WARD = 2265; + public const int MUSIC_DISC_11 = 2266; + public const int MUSIC_DISC_WAIT = 2267; + } + + /// + /// Provides information on a specific type of item. + /// + /// By default, all known MC item types are already defined and registered, assuming Substrate + /// is up to date with the current MC version. + /// New item types may be created and used at runtime, and will automatically populate various static lookup tables + /// in the class. + public class ItemInfo + { + private static Random _rand = new Random(); + + private class CacheTableDict : ICacheTable + { + private Dictionary _cache; + + public T this[int index] + { + get + { + T val; + if (_cache.TryGetValue(index, out val)) + { + return val; + } + return default(T); + } + } + + public CacheTableDict(Dictionary cache) + { + _cache = cache; + } + + public IEnumerator GetEnumerator() + { + foreach (T val in _cache.Values) + yield return val; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + private static readonly Dictionary _itemTable; + + private int _id = 0; + private string _name = ""; + private string _nameId = ""; + private int _stack = 1; + + private static readonly CacheTableDict _itemTableCache; + + /// + /// Gets the lookup table for id-to-info values. + /// + public static ICacheTable ItemTable + { + get { return _itemTableCache; } + } + + /// + /// Gets the id of the item type. + /// + public int ID + { + get { return _id; } + } + + /// + /// Gets the name of the item type. + /// + public string NameID + { + get { return _nameId; } + } + + /// + /// Gets the name of the item type. + /// + public string Name + { + get { return _name; } + } + + /// + /// Gets the maximum stack size allowed for this item type. + /// A stack size between 1 and 64, inclusive. + /// + public int StackSize + { + get { return _stack; } + set { _stack = value; } + } + + /// + /// Constructs a new record for the given item id. + /// + /// The id of an item type. + public ItemInfo(int id) + { + _id = id; + _itemTable[_id] = this; + } + + /// + /// Constructs a new record for the given item id and name. + /// + /// The id of an item type. + /// The name id of an item type + /// The name of an item type. + public ItemInfo(int id, string nameId, string name) + { + _id = id; + _nameId = nameId; + _name = name; + _itemTable[_id] = this; + } + + /// + /// Chooses a registered item type at random and returns it. + /// + /// + public static ItemInfo GetRandomItem() + { + List list = new List(_itemTable.Values); + return list[_rand.Next(list.Count)]; + } + + public static ItemInfo IronShovel; + public static ItemInfo IronPickaxe; + public static ItemInfo IronAxe; + public static ItemInfo FlintAndSteel; + public static ItemInfo Apple; + public static ItemInfo Bow; + public static ItemInfo Arrow; + public static ItemInfo Coal; + public static ItemInfo Diamond; + public static ItemInfo IronIngot; + public static ItemInfo GoldIngot; + public static ItemInfo IronSword; + public static ItemInfo WoodenSword; + public static ItemInfo WoodenShovel; + public static ItemInfo WoodenPickaxe; + public static ItemInfo WoodenAxe; + public static ItemInfo StoneSword; + public static ItemInfo StoneShovel; + public static ItemInfo StonePickaxe; + public static ItemInfo StoneAxe; + public static ItemInfo DiamondSword; + public static ItemInfo DiamondShovel; + public static ItemInfo DiamondPickaxe; + public static ItemInfo DiamondAxe; + public static ItemInfo Stick; + public static ItemInfo Bowl; + public static ItemInfo MushroomSoup; + public static ItemInfo GoldSword; + public static ItemInfo GoldShovel; + public static ItemInfo GoldPickaxe; + public static ItemInfo GoldAxe; + public static ItemInfo String; + public static ItemInfo Feather; + public static ItemInfo Gunpowder; + public static ItemInfo WoodenHoe; + public static ItemInfo StoneHoe; + public static ItemInfo IronHoe; + public static ItemInfo DiamondHoe; + public static ItemInfo GoldHoe; + public static ItemInfo Seeds; + public static ItemInfo Wheat; + public static ItemInfo Bread; + public static ItemInfo LeatherCap; + public static ItemInfo LeatherTunic; + public static ItemInfo LeatherPants; + public static ItemInfo LeatherBoots; + public static ItemInfo ChainHelmet; + public static ItemInfo ChainChestplate; + public static ItemInfo ChainLeggings; + public static ItemInfo ChainBoots; + public static ItemInfo IronHelmet; + public static ItemInfo IronChestplate; + public static ItemInfo IronLeggings; + public static ItemInfo IronBoots; + public static ItemInfo DiamondHelmet; + public static ItemInfo DiamondChestplate; + public static ItemInfo DiamondLeggings; + public static ItemInfo DiamondBoots; + public static ItemInfo GoldHelmet; + public static ItemInfo GoldChestplate; + public static ItemInfo GoldLeggings; + public static ItemInfo GoldBoots; + public static ItemInfo Flint; + public static ItemInfo RawPorkchop; + public static ItemInfo CookedPorkchop; + public static ItemInfo Painting; + public static ItemInfo GoldenApple; + public static ItemInfo Sign; + public static ItemInfo WoodenDoor; + public static ItemInfo Bucket; + public static ItemInfo WaterBucket; + public static ItemInfo LavaBucket; + public static ItemInfo Minecart; + public static ItemInfo Saddle; + public static ItemInfo IronDoor; + public static ItemInfo RedstoneDust; + public static ItemInfo Snowball; + public static ItemInfo Boat; + public static ItemInfo Leather; + public static ItemInfo Milk; + public static ItemInfo ClayBrick; + public static ItemInfo Clay; + public static ItemInfo SugarCane; + public static ItemInfo Paper; + public static ItemInfo Book; + public static ItemInfo Slimeball; + public static ItemInfo StorageMinecart; + public static ItemInfo PoweredMinecart; + public static ItemInfo Egg; + public static ItemInfo Compass; + public static ItemInfo FishingRod; + public static ItemInfo Clock; + public static ItemInfo GlowstoneDust; + public static ItemInfo RawFish; + public static ItemInfo CookedFish; + public static ItemInfo Dye; + public static ItemInfo Bone; + public static ItemInfo Sugar; + public static ItemInfo Cake; + public static ItemInfo Bed; + public static ItemInfo RedstoneRepeater; + public static ItemInfo Cookie; + public static ItemInfo Map; + public static ItemInfo Shears; + public static ItemInfo MelonSlice; + public static ItemInfo PumpkinSeeds; + public static ItemInfo MelonSeeds; + public static ItemInfo RawBeef; + public static ItemInfo Steak; + public static ItemInfo RawChicken; + public static ItemInfo CookedChicken; + public static ItemInfo RottenFlesh; + public static ItemInfo EnderPearl; + public static ItemInfo BlazeRod; + public static ItemInfo GhastTear; + public static ItemInfo GoldNugget; + public static ItemInfo NetherWart; + public static ItemInfo Potion; + public static ItemInfo GlassBottle; + public static ItemInfo SpiderEye; + public static ItemInfo FermentedSpiderEye; + public static ItemInfo BlazePowder; + public static ItemInfo MagmaCream; + public static ItemInfo BrewingStand; + public static ItemInfo Cauldron; + public static ItemInfo EyeOfEnder; + public static ItemInfo GlisteringMelon; + public static ItemInfo SpawnEgg; + public static ItemInfo BottleOEnchanting; + public static ItemInfo FireCharge; + public static ItemInfo BookAndQuill; + public static ItemInfo WrittenBook; + public static ItemInfo Emerald; + public static ItemInfo ItemFrame; + public static ItemInfo FlowerPot; + public static ItemInfo Carrot; + public static ItemInfo Potato; + public static ItemInfo BakedPotato; + public static ItemInfo PoisonPotato; + public static ItemInfo EmptyMap; + public static ItemInfo GoldenCarrot; + public static ItemInfo MobHead; + public static ItemInfo CarrotOnStick; + public static ItemInfo NetherStar; + public static ItemInfo PumpkinPie; + public static ItemInfo FireworkRocket; + public static ItemInfo FireworkStar; + public static ItemInfo EnchantedBook; + public static ItemInfo RedstoneComparator; + public static ItemInfo NetherBrick; + public static ItemInfo NetherQuartz; + public static ItemInfo TntMinecart; + public static ItemInfo HopperMinecart; + public static ItemInfo PrismarineShard; + public static ItemInfo PrismarineCrystals; + public static ItemInfo RawRabbit; + public static ItemInfo CookedRabbit; + public static ItemInfo RabbitStew; + public static ItemInfo RabbitsFoot; + public static ItemInfo RabbitHide; + public static ItemInfo ArmorStand; + public static ItemInfo IronHorseArmor; + public static ItemInfo GoldHorseArmor; + public static ItemInfo DiamondHorseArmor; + public static ItemInfo Lead; + public static ItemInfo NameTag; + public static ItemInfo MinecartWithCommandBlock; + public static ItemInfo RawMutton; + public static ItemInfo CookedMutton; + public static ItemInfo Banner; + public static ItemInfo SpruceDoor; + public static ItemInfo BirchDoor; + public static ItemInfo JungleDoor; + public static ItemInfo AcaciaDoor; + public static ItemInfo DarkOakDoor; + + public static ItemInfo MusicDisc13; + public static ItemInfo MusicDiscCat; + public static ItemInfo MusicDiscBlocks; + public static ItemInfo MusicDiscChirp; + public static ItemInfo MusicDiscFar; + public static ItemInfo MusicDiscMall; + public static ItemInfo MusicDiscMellohi; + public static ItemInfo MusicDiscStal; + public static ItemInfo MusicDiscStrad; + public static ItemInfo MusicDiscWard; + public static ItemInfo MusicDisc11; + public static ItemInfo MusicDiscWait; + + + static ItemInfo() + { + _itemTable = new Dictionary(); + _itemTableCache = new CacheTableDict(_itemTable); + + IronShovel = new ItemInfo(256, "minecraft:iron_shovel", "Iron Shovel"); + IronPickaxe = new ItemInfo(257, "minecraft:iron_pickaxe", "Iron Pickaxe"); + IronAxe = new ItemInfo(258, "minecraft:iron_axe", "Iron Axe"); + FlintAndSteel = new ItemInfo(259, "minecraft:flint_and_steel", "Flint and Steel"); + Apple = new ItemInfo(260, "minecraft:apple", "Apple") { StackSize = 64 }; + Bow = new ItemInfo(261, "minecraft:bow", "Bow"); + Arrow = new ItemInfo(262, "minecraft:arrow", "Arrow") { StackSize = 64 }; + Coal = new ItemInfo(263, "minecraft:coal", "Coal") { StackSize = 64 }; + Diamond = new ItemInfo(264, "minecraft:diamond", "Diamond") { StackSize = 64 }; + IronIngot = new ItemInfo(265, "minecraft:iron_ingot", "Iron Ingot") { StackSize = 64 }; + GoldIngot = new ItemInfo(266, "minecraft:gold_ingot", "Gold Ingot") { StackSize = 64 }; + IronSword = new ItemInfo(267, "minecraft:iron_sword", "Iron Sword"); + WoodenSword = new ItemInfo(268, "minecraft:wooden_sword", "Wooden Sword"); + WoodenShovel = new ItemInfo(269, "minecraft:wooden_shovel", "Wooden Shovel"); + WoodenPickaxe = new ItemInfo(270, "minecraft:wooden_pickaxe", "Wooden Pickaxe"); + WoodenAxe = new ItemInfo(271, "minecraft:wooden_axe", "Wooden Axe"); + StoneSword = new ItemInfo(272, "minecraft:stone_sword", "Stone Sword"); + StoneShovel = new ItemInfo(273, "minecraft:stone_shovel", "Stone Shovel"); + StonePickaxe = new ItemInfo(274, "minecraft:stone_pickaxe", "Stone Pickaxe"); + StoneAxe = new ItemInfo(275, "minecraft:stone_axe", "Stone Axe"); + DiamondSword = new ItemInfo(276, "minecraft:diamond_sword", "Diamond Sword"); + DiamondShovel = new ItemInfo(277, "minecraft:diamond_shovel", "Diamond Shovel"); + DiamondPickaxe = new ItemInfo(278, "minecraft:diamond_pickaxe", "Diamond Pickaxe"); + DiamondAxe = new ItemInfo(279, "minecraft:diamond_axe", "Diamond Axe"); + Stick = new ItemInfo(280, "minecraft:stick", "Stick") { StackSize = 64 }; + Bowl = new ItemInfo(281, "minecraft:bowl", "Bowl") { StackSize = 64 }; + MushroomSoup = new ItemInfo(282, "minecraft:mushroom_stew", "Mushroom Soup"); + GoldSword = new ItemInfo(283, "minecraft:golden_sword", "Gold Sword"); + GoldShovel = new ItemInfo(284, "minecraft:golden_shovel", "Gold Shovel"); + GoldPickaxe = new ItemInfo(285, "minecraft:golden_pickaxe", "Gold Pickaxe"); + GoldAxe = new ItemInfo(286, "minecraft:golden_axe", "Gold Axe"); + String = new ItemInfo(287, "minecraft:string", "String") { StackSize = 64 }; + Feather = new ItemInfo(288, "minecraft:feather", "Feather") { StackSize = 64 }; + Gunpowder = new ItemInfo(289, "minecraft:gunpowder", "Gunpowder") { StackSize = 64 }; + WoodenHoe = new ItemInfo(290, "minecraft:wooden_hoe", "Wooden Hoe"); + StoneHoe = new ItemInfo(291, "minecraft:stone_hoe", "Stone Hoe"); + IronHoe = new ItemInfo(292, "minecraft:iron_hoe", "Iron Hoe"); + DiamondHoe = new ItemInfo(293, "minecraft:diamond_hoe", "Diamond Hoe"); + GoldHoe = new ItemInfo(294, "minecraft:golden_hoe", "Gold Hoe"); + Seeds = new ItemInfo(295, "minecraft:wheat_seeds", "Seeds") { StackSize = 64 }; + Wheat = new ItemInfo(296, "minecraft:wheat", "Wheat") { StackSize = 64 }; + Bread = new ItemInfo(297, "minecraft:bread", "Bread") { StackSize = 64 }; + LeatherCap = new ItemInfo(298, "minecraft:leather_helmet", "Leather Cap"); + LeatherTunic = new ItemInfo(299, "minecraft:leather_chestplate", "Leather Tunic"); + LeatherPants = new ItemInfo(300, "minecraft:leather_leggings", "Leather Pants"); + LeatherBoots = new ItemInfo(301, "minecraft:leather_boots", "Leather Boots"); + ChainHelmet = new ItemInfo(302, "minecraft:chainmail_helmet", "Chain Helmet"); + ChainChestplate = new ItemInfo(303, "minecraft:chainmail_chestplate", "Chain Chestplate"); + ChainLeggings = new ItemInfo(304, "minecraft:chainmail_leggings", "Chain Leggings"); + ChainBoots = new ItemInfo(305, "minecraft:chainmail_boots", "Chain Boots"); + IronHelmet = new ItemInfo(306, "minecraft:iron_helmet", "Iron Helmet"); + IronChestplate = new ItemInfo(307, "minecraft:iron_chestplate", "Iron Chestplate"); + IronLeggings = new ItemInfo(308, "minecraft:iron_leggings", "Iron Leggings"); + IronBoots = new ItemInfo(309, "minecraft:iron_boots", "Iron Boots"); + DiamondHelmet = new ItemInfo(310, "minecraft:diamond_helmet", "Diamond Helmet"); + DiamondChestplate = new ItemInfo(311, "minecraft:diamond_chestplate", "Diamond Chestplate"); + DiamondLeggings = new ItemInfo(312, "minecraft:diamond_leggings", "Diamond Leggings"); + DiamondBoots = new ItemInfo(313, "minecraft:diamond_boots", "Diamond Boots"); + GoldHelmet = new ItemInfo(314, "minecraft:golden_helmet", "Gold Helmet"); + GoldChestplate = new ItemInfo(315, "minecraft:golden_chestplate", "Gold Chestplate"); + GoldLeggings = new ItemInfo(316, "minecraft:golden_leggings", "Gold Leggings"); + GoldBoots = new ItemInfo(317, "minecraft:golden_boots", "Gold Boots"); + Flint = new ItemInfo(318, "minecraft:flint", "Flint") { StackSize = 64 }; + RawPorkchop = new ItemInfo(319, "minecraft:porkchop", "Raw Porkchop") { StackSize = 64 }; + CookedPorkchop = new ItemInfo(320, "minecraft:cooked_porkchop", "Cooked Porkchop") { StackSize = 64 }; + Painting = new ItemInfo(321, "minecraft:painting", "Painting") { StackSize = 64 }; + GoldenApple = new ItemInfo(322, "minecraft:golden_apple", "Golden Apple") { StackSize = 64 }; + Sign = new ItemInfo(323, "minecraft:sign", "Sign"); + WoodenDoor = new ItemInfo(324, "minecraft:wooden_door", "Door"); + Bucket = new ItemInfo(325, "minecraft:bucket", "Bucket"); + WaterBucket = new ItemInfo(326, "minecraft:water_bucket", "Water Bucket"); + LavaBucket = new ItemInfo(327, "minecraft:lava_bucket", "Lava Bucket"); + Minecart = new ItemInfo(328, "minecraft:minecart", "Minecart"); + Saddle = new ItemInfo(329, "minecraft:saddle", "Saddle"); + IronDoor = new ItemInfo(330, "minecraft:iron_door", "Iron Door"); + RedstoneDust = new ItemInfo(331, "minecraft:redstone", "Redstone Dust") { StackSize = 64 }; + Snowball = new ItemInfo(332, "minecraft:snowball", "Snowball") { StackSize = 16 }; + Boat = new ItemInfo(333, "minecraft:boat", "Boat"); + Leather = new ItemInfo(334, "minecraft:leather", "Leather") { StackSize = 64 }; + Milk = new ItemInfo(335, "minecraft:milk_bucket", "Milk"); + ClayBrick = new ItemInfo(336, "minecraft:brick", "Clay Brick") { StackSize = 64 }; + Clay = new ItemInfo(337, "minecraft:clay_ball", "Clay") { StackSize = 64 }; + SugarCane = new ItemInfo(338, "minecraft:reeds", "Sugar Cane") { StackSize = 64 }; + Paper = new ItemInfo(339, "minecraft:paper", "Paper") { StackSize = 64 }; + Book = new ItemInfo(340, "minecraft:book", "Book") { StackSize = 64 }; + Slimeball = new ItemInfo(341, "minecraft:slime_ball", "Slimeball") { StackSize = 64 }; + StorageMinecart = new ItemInfo(342, "minecraft:chest_minecart", "Storage Minecart"); + PoweredMinecart = new ItemInfo(343, "minecraft:furnace_minecart", "Powered Minecart"); + Egg = new ItemInfo(344, "minecraft:egg", "Egg") { StackSize = 16 }; + Compass = new ItemInfo(345, "minecraft:compass", "Compass"); + FishingRod = new ItemInfo(346, "minecraft:fishing_rod", "Fishing Rod"); + Clock = new ItemInfo(347, "minecraft:clock", "Clock"); + GlowstoneDust = new ItemInfo(348, "minecraft:glowstone_dust", "Glowstone Dust") { StackSize = 64 }; + RawFish = new ItemInfo(349, "minecraft:fish", "Raw Fish") { StackSize = 64 }; + CookedFish = new ItemInfo(350, "minecraft:cooked_fish", "Cooked Fish") { StackSize = 64 }; + Dye = new ItemInfo(351, "minecraft:dye", "Dye") { StackSize = 64 }; + Bone = new ItemInfo(352, "minecraft:bone", "Bone") { StackSize = 64 }; + Sugar = new ItemInfo(353, "minecraft:sugar", "Sugar") { StackSize = 64 }; + Cake = new ItemInfo(354, "minecraft:cake", "Cake"); + Bed = new ItemInfo(355, "minecraft:bed", "Bed"); + RedstoneRepeater = new ItemInfo(356, "minecraft:repeater", "Redstone Repeater") { StackSize = 64 }; + Cookie = new ItemInfo(357, "minecraft:cookie", "Cookie") { StackSize = 8 }; + Map = new ItemInfo(358, "minecraft:filled_map", "Map"); + Shears = new ItemInfo(359, "minecraft:shears", "Shears"); + MelonSlice = new ItemInfo(360, "minecraft:melon", "Melon Slice") { StackSize = 64 }; + PumpkinSeeds = new ItemInfo(361, "minecraft:pumpkin_seeds", "Pumpkin Seeds") { StackSize = 64 }; + MelonSeeds = new ItemInfo(362, "minecraft:melon_seeds", "Melon Seeds") { StackSize = 64 }; + RawBeef = new ItemInfo(363, "minecraft:beef", "Raw Beef") { StackSize = 64 }; + Steak = new ItemInfo(364, "minecraft:cooked_beef", "Steak") { StackSize = 64 }; + RawChicken = new ItemInfo(365, "minecraft:chicken", "Raw Chicken") { StackSize = 64 }; + CookedChicken = new ItemInfo(366, "minecraft:cooked_chicken", "Cooked Chicken") { StackSize = 64 }; + RottenFlesh = new ItemInfo(367, "minecraft:rotten_flesh", "Rotten Flesh") { StackSize = 64 }; + EnderPearl = new ItemInfo(368, "minecraft:ender_pearl", "Ender Pearl") { StackSize = 64 }; + BlazeRod = new ItemInfo(369, "minecraft:blaze_rod", "Blaze Rod") { StackSize = 64 }; + GhastTear = new ItemInfo(370, "minecraft:ghast_tear", "Ghast Tear") { StackSize = 64 }; + GoldNugget = new ItemInfo(371, "minecraft:gold_nugget", "Gold Nugget") { StackSize = 64 }; + NetherWart = new ItemInfo(372, "minecraft:nether_wart", "Nether Wart") { StackSize = 64 }; + Potion = new ItemInfo(373, "minecraft:potion", "Potion"); + GlassBottle = new ItemInfo(374, "minecraft:glass_bottle", "Glass Bottle") { StackSize = 64 }; + SpiderEye = new ItemInfo(375, "minecraft:spider_eye", "Spider Eye") { StackSize = 64 }; + FermentedSpiderEye = new ItemInfo(376, "minecraft:fermented_spider_eye", "Fermented Spider Eye") { StackSize = 64 }; + BlazePowder = new ItemInfo(377, "minecraft:blaze_powder", "Blaze Powder") { StackSize = 64 }; + MagmaCream = new ItemInfo(378, "minecraft:magma_cream", "Magma Cream") { StackSize = 64 }; + BrewingStand = new ItemInfo(379, "minecraft:brewing_stand", "Brewing Stand") { StackSize = 64 }; + Cauldron = new ItemInfo(380, "minecraft:cauldron", "Cauldron"); + EyeOfEnder = new ItemInfo(381, "minecraft:ender_eye", "Eye of Ender") { StackSize = 64 }; + GlisteringMelon = new ItemInfo(382, "minecraft:speckled_melon", "Glistering Melon") { StackSize = 64 }; + SpawnEgg = new ItemInfo(383, "minecraft:spawn_egg", "Spawn Egg") { StackSize = 64 }; + BottleOEnchanting = new ItemInfo(384, "minecraft:experience_bottle", "Bottle O' Enchanting") { StackSize = 64 }; + FireCharge = new ItemInfo(385, "minecraft:fire_charge", "Fire Charge") { StackSize = 64 }; + BookAndQuill = new ItemInfo(386, "minecraft:writable_book", "Book and Quill"); + WrittenBook = new ItemInfo(387, "minecraft:written_book", "Written Book"); + Emerald = new ItemInfo(388, "minecraft:emerald", "Emerald") { StackSize = 64 }; + ItemFrame = new ItemInfo(389, "minecraft:item_frame", "Item Frame") { StackSize = 64 }; + FlowerPot = new ItemInfo(390, "minecraft:flower_pot", "Flower Pot") { StackSize = 64 }; + Carrot = new ItemInfo(391, "minecraft:carrot", "Carrot") { StackSize = 64 }; + Potato = new ItemInfo(392, "minecraft:potato", "Potato") { StackSize = 64 }; + BakedPotato = new ItemInfo(393, "minecraft:baked_potato", "Baked Potato") { StackSize = 64 }; + PoisonPotato = new ItemInfo(394, "minecraft:poisonous_potato", "Poisonous Potato") { StackSize = 64 }; + EmptyMap = new ItemInfo(395, "minecraft:map", "Empty Map") { StackSize = 64 }; + GoldenCarrot = new ItemInfo(396, "minecraft:golden_carrot", "Golden Carrot") { StackSize = 64 }; + MobHead = new ItemInfo(397, "minecraft:skull", "Mob Head") { StackSize = 64 }; + CarrotOnStick = new ItemInfo(398, "minecraft:carrot_on_a_stick", "Carrot on a Stick"); + NetherStar = new ItemInfo(399, "minecraft:nether_star", "Nether Star") { StackSize = 64 }; + PumpkinPie = new ItemInfo(400, "minecraft:pumpkin_pie", "Pumpkin Pie") { StackSize = 64 }; + FireworkRocket = new ItemInfo(401, "minecraft:fireworks", "Firework Rocket"); + FireworkStar = new ItemInfo(402, "minecraft:firework_charge", "Firework Star") { StackSize = 64 }; + EnchantedBook = new ItemInfo(403, "minecraft:enchanted_book", "Enchanted Book"); + RedstoneComparator = new ItemInfo(404, "minecraft:comparator", "Redstone Comparator") { StackSize = 64 }; + NetherBrick = new ItemInfo(405, "minecraft:netherbrick", "Nether Brick") { StackSize = 64 }; + NetherQuartz = new ItemInfo(406, "minecraft:quartz", "Nether Quartz") { StackSize = 64 }; + TntMinecart = new ItemInfo(407, "minecraft:tnt_minecart", "Minecart with TNT"); + HopperMinecart = new ItemInfo(408, "minecraft:hopper_minecart", "Minecart with Hopper"); + PrismarineShard = new ItemInfo(409, "minecraft:prismarine_shard", "Prismarine Shard"); + PrismarineCrystals = new ItemInfo(410, "minecraft:prismarine_crystals", "Prismarine Crystals"); + RawRabbit = new ItemInfo(411, "minecraft:rabbit", "Raw Rabbit"); + CookedRabbit = new ItemInfo(412, "minecraft:cooked_rabbit", "Cooked Rabbit"); + RabbitStew = new ItemInfo(413, "minecraft:rabbit_stew", "Rabbit Stew"); + RabbitsFoot = new ItemInfo(414, "minecraft:rabbit_foot", "Rabbit's Foot"); + RabbitHide = new ItemInfo(415, "minecraft:rabbit_hide", "Rabbit Hide"); + ArmorStand = new ItemInfo(416, "minecraft:armor_stand", "Armor Stand"); + IronHorseArmor = new ItemInfo(417, "minecraft:iron_horse_armor", "Iron Horse Armor"); + GoldHorseArmor = new ItemInfo(418, "minecraft:golden_horse_armor", "Gold Horse Armor"); + DiamondHorseArmor = new ItemInfo(419, "minecraft:diamond_horse_armor", "Diamond Horse Armor"); + Lead = new ItemInfo(420, "minecraft:lead", "Lead") { StackSize = 64 }; + NameTag = new ItemInfo(421, "minecraft:name_tag", "Name Tag") { StackSize = 64 }; + MinecartWithCommandBlock = new ItemInfo(422, "minecraft:command_block_minecart", "Minecart With Command Block"); + RawMutton = new ItemInfo(423, "minecraft:mutton", "Raw Mutton"); + CookedMutton = new ItemInfo(424, "minecraft:cooked_mutton", "Cooked Mutton"); + Banner = new ItemInfo(425, "minecraft:banner", "Banner"); + + SpruceDoor = new ItemInfo(427, "minecraft:spruce_door", "Spruce Door"); + BirchDoor = new ItemInfo(428, "minecraft:birch_door", "Birch Door"); + JungleDoor = new ItemInfo(429, "minecraft:jungle_door", "Jungle Door"); + AcaciaDoor = new ItemInfo(430, "minecraft:acacia_door", "Acacia Door"); + DarkOakDoor = new ItemInfo(431, "minecraft:dark_oak_door", "Dark Oak Door"); + + MusicDisc13 = new ItemInfo(2256, "minecraft:record_13", "13 Disc"); + MusicDiscCat = new ItemInfo(2257, "minecraft:record_cat", "Cat Disc"); + MusicDiscBlocks = new ItemInfo(2258, "minecraft:record_blocks", "Blocks Disc"); + MusicDiscChirp = new ItemInfo(2259, "minecraft:record_chirp", "Chirp Disc"); + MusicDiscFar = new ItemInfo(2260, "minecraft:record_far", "Far Disc"); + MusicDiscMall = new ItemInfo(2261, "minecraft:record_mall", "Mall Disc"); + MusicDiscMellohi = new ItemInfo(2262, "minecraft:record_mellohi", "Mellohi Disc"); + MusicDiscStal = new ItemInfo(2263, "minecraft:record_stal", "Stal Disc"); + MusicDiscStrad = new ItemInfo(2264, "minecraft:record_strad", "Strad Disc"); + MusicDiscWard = new ItemInfo(2265, "minecraft:record_ward", "Ward Disc"); + MusicDisc11 = new ItemInfo(2266, "minecraft:record_11", "11 Disc"); + MusicDiscWait = new ItemInfo(2267, "minecraft:record_wait", "Wait Disc"); + } + } +} diff --git a/SubstrateCS/Source/Level.cs b/Substrate/Source/Level.cs similarity index 61% rename from SubstrateCS/Source/Level.cs rename to Substrate/Source/Level.cs index 8faf5822..79e0d66d 100644 --- a/SubstrateCS/Source/Level.cs +++ b/Substrate/Source/Level.cs @@ -17,6 +17,12 @@ public class GameRules : ICopyable private bool _doTileDrops = true; private bool _keepInventory = false; private bool _mobGriefing = true; + private bool _doDaylightCycle = true; + private bool _logAdminCommands = true; + private bool _naturalRegeneration = true; + private int _randomTickSpeed = 3; + private bool _sendCommandFeedback = true; + private bool _showDeathMessages = true; /// /// Gets or sets whether or not actions performed by command blocks are displayed in the chat. @@ -81,6 +87,60 @@ public bool MobGriefing set { _mobGriefing = value; } } + /// + /// Whether to do the Daylight Cycle or not. True by default. + /// + public bool DoDaylightCycle + { + get { return _doDaylightCycle; } + set { _doDaylightCycle = value; } + } + + /// + /// Whether to log admin commands to server log. True by default. + /// + public bool LogAdminCommands + { + get { return _logAdminCommands; } + set { _logAdminCommands = value; } + } + + /// + /// Whether the player naturally regenerates health if hunger is high enough. True by default. + /// + public bool NaturalRegeneration + { + get { return _naturalRegeneration; } + set { _naturalRegeneration = value; } + } + + /// + /// How often a random tick occurs, such as plant growth, leaf decay, etc. 3 by default. + /// + public int RandomTickSpeed + { + get { return _randomTickSpeed; } + set { _randomTickSpeed = value; } + } + + /// + /// Whether the feedback from commands executed by a player should show up in chat. True by default. + /// + public bool SendCommandFeedback + { + get { return _sendCommandFeedback; } + set { _sendCommandFeedback = value; } + } + + /// + /// Whether a message appears in chat when a player dies. True by default. + /// + public bool ShowDeathMessages + { + get { return _showDeathMessages; } + set { _showDeathMessages = value; } + } + #region ICopyable Members /// @@ -94,6 +154,12 @@ public GameRules Copy () gr._doTileDrops = _doTileDrops; gr._keepInventory = _keepInventory; gr._mobGriefing = _mobGriefing; + gr._doDaylightCycle = _doDaylightCycle; + gr._logAdminCommands = _logAdminCommands; + gr._naturalRegeneration = _naturalRegeneration; + gr._randomTickSpeed = _randomTickSpeed; + gr._sendCommandFeedback = _sendCommandFeedback; + gr._showDeathMessages = _showDeathMessages; return gr; } @@ -115,6 +181,24 @@ public enum GameType /// The world will be played in Creative mode. /// CREATIVE = 1, + + /// + /// The world will be played in Adventure mode. + /// + ADVENTURE = 2, + + /// + /// The world will be played in Spectator mode. + /// + SPECTATOR = 3, + } + + public enum Difficulty + { + Peaceful = 0, + Easy = 1, + Normal = 2, + Hard = 3, } public enum TimeOfDay @@ -127,6 +211,15 @@ public enum TimeOfDay Sunrise = 22200, } + public class LevelData + { + [TagNode] + public long Time { get; set; } + + [TagNode] + public Player Player { get; set; } + } + /// /// Represents general data and metadata of a single world. /// @@ -136,38 +229,56 @@ public class Level : INbtObject, ICopyable { new SchemaNodeCompound("Data") { - new SchemaNodeScaler("Time", TagType.TAG_LONG), - new SchemaNodeScaler("LastPlayed", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeScalar("Time", TagType.TAG_LONG), + new SchemaNodeScalar("LastPlayed", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), new SchemaNodeCompound("Player", Player.Schema, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("SpawnX", TagType.TAG_INT), - new SchemaNodeScaler("SpawnY", TagType.TAG_INT), - new SchemaNodeScaler("SpawnZ", TagType.TAG_INT), - new SchemaNodeScaler("SizeOnDisk", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), - new SchemaNodeScaler("RandomSeed", TagType.TAG_LONG), - new SchemaNodeScaler("version", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("LevelName", TagType.TAG_STRING, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("generatorName", TagType.TAG_STRING, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("raining", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("thundering", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("rainTime", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("thunderTime", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("GameType", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("MapFeatures", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("hardcore", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("generatorVersion", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("generatorOptions", TagType.TAG_STRING, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("initialized", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("allowCommands", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("DayTime", TagType.TAG_LONG, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("SpawnX", TagType.TAG_INT), + new SchemaNodeScalar("SpawnY", TagType.TAG_INT), + new SchemaNodeScalar("SpawnZ", TagType.TAG_INT), + new SchemaNodeScalar("SizeOnDisk", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeScalar("RandomSeed", TagType.TAG_LONG), + new SchemaNodeScalar("version", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("LevelName", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("generatorName", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("raining", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("thundering", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("rainTime", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("thunderTime", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("GameType", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("MapFeatures", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("hardcore", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("generatorVersion", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("generatorOptions", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("initialized", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("allowCommands", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("DayTime", TagType.TAG_LONG, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("Difficulty", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("DifficultyLocked", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("BorderCenterX", TagType.TAG_DOUBLE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("BorderCenterZ", TagType.TAG_DOUBLE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("BorderSize", TagType.TAG_DOUBLE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("BorderSafeZone", TagType.TAG_DOUBLE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("BorderWarningBlocks", TagType.TAG_DOUBLE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("BorderWarningTime", TagType.TAG_DOUBLE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("BorderSizeLerpTarget", TagType.TAG_DOUBLE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("BorderSizeLerpTime", TagType.TAG_LONG, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("BorderDamagePerBlock", TagType.TAG_DOUBLE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("clearWeatherTime", TagType.TAG_INT, SchemaOptions.OPTIONAL), new SchemaNodeCompound("GameRules", SchemaOptions.OPTIONAL) - { - new SchemaNodeScaler("commandBlockOutput", TagType.TAG_STRING), - new SchemaNodeScaler("doFireTick", TagType.TAG_STRING), - new SchemaNodeScaler("doMobLoot", TagType.TAG_STRING), - new SchemaNodeScaler("doMobSpawning", TagType.TAG_STRING), - new SchemaNodeScaler("doTileDrops", TagType.TAG_STRING), - new SchemaNodeScaler("keepInventory", TagType.TAG_STRING), - new SchemaNodeScaler("mobGriefing", TagType.TAG_STRING), + { + new SchemaNodeScalar("commandBlockOutput", TagType.TAG_STRING), + new SchemaNodeScalar("doFireTick", TagType.TAG_STRING), + new SchemaNodeScalar("doMobLoot", TagType.TAG_STRING), + new SchemaNodeScalar("doMobSpawning", TagType.TAG_STRING), + new SchemaNodeScalar("doTileDrops", TagType.TAG_STRING), + new SchemaNodeScalar("keepInventory", TagType.TAG_STRING), + new SchemaNodeScalar("mobGriefing", TagType.TAG_STRING), + new SchemaNodeScalar("doDaylightCycle", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("logAdminCommands", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("naturalRegeneration", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("randomTickSpeed", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("sendCommandFeedback", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("showDeathMessages", TagType.TAG_STRING, SchemaOptions.OPTIONAL), }, }, }; @@ -206,8 +317,25 @@ public class Level : INbtObject, ICopyable private byte? _allowCommands; private long? _DayTime; + private byte? _difficulty; + private byte? _difficultyLocked; + private double? _borderCenterX; + private double? _borderCenterZ; + private double? _borderSize; + private double? _borderSafeZone; + private double? _borderWarningBlocks; + private double? _borderWarningTime; + private double? _borderSizeLerpTarget; + private long? _borderSizeLerpTime; + private double? _borderDamagePerBlock; + private int? _clearWeatherTime; + + private GameRules _gameRules; + [TagNode] + public LevelData Data { get; set; } + /// /// Gets or sets the creation time of the world as a long timestamp. /// @@ -423,6 +551,78 @@ public long DayTime set { _DayTime = value; } } + public Difficulty Difficulty + { + get { return (Difficulty)(_difficulty ?? (int)Difficulty.Normal); } + set { _difficulty = (byte)value; } + } + + public byte DifficultyLocked + { + get { return _difficultyLocked ?? 0; } + set { _difficultyLocked = value; } + } + + public double BorderCenterX + { + get { return _borderCenterX ?? 0; } + set { _borderCenterX = value; } + } + + public double BorderCenterZ + { + get { return _borderCenterZ ?? 0; } + set { _borderCenterZ = value; } + } + + public double BorderSize + { + get { return _borderSize ?? 60000000; } + set { _borderSize = value; } + } + + public double BorderSafeZone + { + get { return _borderSafeZone ?? 5; } + set { _borderSafeZone = value; } + } + + public double BorderWarningBlocks + { + get { return _borderWarningBlocks ?? 5; } + set { _borderWarningBlocks = value; } + } + + public double BorderWarningTime + { + get { return _borderWarningTime ?? 15; } + set { _borderWarningTime = value; } + } + + public double BorderSizeLerpTarget + { + get { return _borderSizeLerpTarget ?? 60000000; } + set { _borderSizeLerpTarget = value; } + } + + public long BorderSizeLerpTime + { + get { return _borderSizeLerpTime ?? 0; } + set { _borderSizeLerpTime = value; } + } + + public double BorderDamagePerBlock + { + get { return _borderDamagePerBlock ?? 5; } + set { _borderDamagePerBlock = value; } + } + + public int ClearWeatherTime + { + get { return _clearWeatherTime ?? 0; } + set { _clearWeatherTime = value; } + } + /// /// Gets the level's game rules. /// @@ -517,6 +717,20 @@ protected Level (Level p) _DayTime = p._DayTime; _gameRules = p._gameRules.Copy(); + + _difficulty = p._difficulty; + _difficultyLocked = p._difficultyLocked; + _borderCenterX = p._borderCenterX; + _borderCenterZ = p._borderCenterZ; + _borderSize = p._borderSize; + _borderSafeZone = p._borderSafeZone; + _borderWarningBlocks = p._borderWarningBlocks; + _borderWarningTime = p._borderWarningTime; + _borderSizeLerpTarget = p._borderSizeLerpTarget; + _borderSizeLerpTime = p._borderSizeLerpTime; + _borderDamagePerBlock = p._borderDamagePerBlock; + _clearWeatherTime = p._clearWeatherTime; + if (p._player != null) { _player = p._player.Copy(); } @@ -666,6 +880,55 @@ public virtual Level LoadTree (TagNode tree) if (ctree.ContainsKey("DayTime")) { _DayTime = ctree["DayTime"].ToTagLong(); } + if (ctree.ContainsKey("Difficulty")) + { + _difficulty = ctree["Difficulty"].ToTagByte(); + } + if (ctree.ContainsKey("DifficultyLocked")) + { + _difficultyLocked = ctree["DifficultyLocked"].ToTagByte(); + } + if (ctree.ContainsKey("BorderCenterX")) + { + _borderCenterX = ctree["BorderCenterX"].ToTagDouble(); + } + if (ctree.ContainsKey("BorderCenterZ")) + { + _borderCenterZ = ctree["BorderCenterZ"].ToTagDouble(); + } + if (ctree.ContainsKey("BorderSize")) + { + _borderSize = ctree["BorderSize"].ToTagDouble(); + } + if (ctree.ContainsKey("BorderSafeZone")) + { + _borderSafeZone = ctree["BorderSafeZone"].ToTagDouble(); + } + if (ctree.ContainsKey("BorderWarningBlocks")) + { + _borderWarningBlocks = ctree["BorderWarningBlocks"].ToTagDouble(); + } + if (ctree.ContainsKey("BorderWarningTime")) + { + _borderWarningTime = ctree["BorderWarningTime"].ToTagDouble(); + } + if (ctree.ContainsKey("BorderSizeLerpTarget")) + { + _borderSizeLerpTarget = ctree["BorderSizeLerpTarget"].ToTagDouble(); + } + if (ctree.ContainsKey("BorderSizeLerpTime")) + { + _borderSizeLerpTime = ctree["BorderSizeLerpTime"].ToTagLong(); + } + if (ctree.ContainsKey("BorderDamagePerBlock")) + { + _borderDamagePerBlock = ctree["BorderDamagePerBlock"].ToTagDouble(); + } + if (ctree.ContainsKey("clearWeatherTime")) + { + _clearWeatherTime = ctree["clearWeatherTime"].ToTagInt(); + } + if (ctree.ContainsKey("GameRules")) { TagNodeCompound gr = ctree["GameRules"].ToTagCompound(); @@ -678,6 +941,38 @@ public virtual Level LoadTree (TagNode tree) _gameRules.DoTileDrops = gr["doTileDrops"].ToTagString().Data == "true"; _gameRules.KeepInventory = gr["keepInventory"].ToTagString().Data == "true"; _gameRules.MobGriefing = gr["mobGriefing"].ToTagString().Data == "true"; + + if (gr.ContainsKey("doDaylightCycle")) + { + _gameRules.DoDaylightCycle = gr["doDaylightCycle"].ToTagString().Data == "true"; + } + + if (gr.ContainsKey("logAdminCommands")) + { + _gameRules.LogAdminCommands = gr["logAdminCommands"].ToTagString().Data == "true"; + } + + if (gr.ContainsKey("naturalRegeneration")) + { + _gameRules.NaturalRegeneration = gr["naturalRegeneration"].ToTagString().Data == "true"; + } + + if (gr.ContainsKey("randomTickSpeed")) + { + int temp = 3; + int.TryParse(gr["randomTickSpeed"].ToTagString().Data, out temp); + _gameRules.RandomTickSpeed = temp; + } + + if (gr.ContainsKey("sendCommandFeedback")) + { + _gameRules.SendCommandFeedback = gr["sendCommandFeedback"].ToTagString().Data == "true"; + } + + if (gr.ContainsKey("showDeathMessages")) + { + _gameRules.ShowDeathMessages = gr["showDeathMessages"].ToTagString().Data == "true"; + } } _source = ctree.Copy() as TagNodeCompound; @@ -769,6 +1064,58 @@ public virtual TagNode BuildTree () if (_DayTime != null) { data["DayTime"] = new TagNodeLong(_DayTime ?? 0); } + + + if (_difficulty != null) + { + data["Difficulty"] = new TagNodeByte(_difficulty ?? 2); + } + if (_difficultyLocked != null) + { + data["DifficultyLocked"] = new TagNodeByte(_difficultyLocked ?? 0); + } + if (_borderCenterX != null) + { + data["BorderCenterX"] = new TagNodeDouble(_borderCenterX ?? 0); + } + if (_borderCenterZ != null) + { + data["BorderCenterZ"] = new TagNodeDouble(_borderCenterZ ?? 0); + } + if (_borderSize != null) + { + data["BorderSize"] = new TagNodeDouble(_borderSize ?? 60000000); + } + if (_borderSafeZone != null) + { + data["BorderSafeZone"] = new TagNodeDouble(_borderSafeZone ?? 5); + } + if (_borderWarningBlocks != null) + { + data["BorderWarningBlocks"] = new TagNodeDouble(_borderWarningBlocks ?? 5); + } + if (_borderWarningTime != null) + { + data["BorderWarningTime"] = new TagNodeDouble(_borderWarningTime ?? 15); + } + if (_borderSizeLerpTarget != null) + { + data["BorderSizeLerpTarget"] = new TagNodeDouble(_borderSizeLerpTarget ?? 60000000); + } + if (_borderSizeLerpTime != null) + { + data["BorderSizeLerpTime"] = new TagNodeLong(_borderSizeLerpTime ?? 0); + } + if (_borderDamagePerBlock != null) + { + data["BorderDamagePerBlock"] = new TagNodeDouble(_borderDamagePerBlock ?? 0.2); + } + if (_clearWeatherTime != null) + { + data["clearWeatherTime"] = new TagNodeInt(_clearWeatherTime ?? 0); + } + + TagNodeCompound gr = new TagNodeCompound(); gr["commandBlockOutput"] = new TagNodeString(_gameRules.CommandBlockOutput ? "true" : "false"); gr["doFireTick"] = new TagNodeString(_gameRules.DoFireTick ? "true" : "false"); @@ -777,6 +1124,12 @@ public virtual TagNode BuildTree () gr["doTileDrops"] = new TagNodeString(_gameRules.DoTileDrops ? "true" : "false"); gr["keepInventory"] = new TagNodeString(_gameRules.KeepInventory ? "true" : "false"); gr["mobGriefing"] = new TagNodeString(_gameRules.MobGriefing ? "true" : "false"); + gr["doDaylightCycle"] = new TagNodeString(_gameRules.DoDaylightCycle ? "true" : "false"); + gr["logAdminCommands"] = new TagNodeString(_gameRules.LogAdminCommands ? "true" : "false"); + gr["naturalRegeneration"] = new TagNodeString(_gameRules.NaturalRegeneration ? "true" : "false"); + gr["randomTickSpeed"] = new TagNodeString(_gameRules.RandomTickSpeed.ToString()); + gr["sendCommandFeedback"] = new TagNodeString(_gameRules.SendCommandFeedback ? "true" : "false"); + gr["showDeathMessages"] = new TagNodeString(_gameRules.ShowDeathMessages ? "true" : "false"); data["GameRules"] = gr; if (_source != null) { diff --git a/SubstrateCS/Source/LevelIOException.cs b/Substrate/Source/LevelIOException.cs similarity index 100% rename from SubstrateCS/Source/LevelIOException.cs rename to Substrate/Source/LevelIOException.cs diff --git a/SubstrateCS/Source/Nbt/INbtObject.cs b/Substrate/Source/Nbt/INbtObject.cs similarity index 100% rename from SubstrateCS/Source/Nbt/INbtObject.cs rename to Substrate/Source/Nbt/INbtObject.cs diff --git a/Substrate/Source/Nbt/INbtObject2.cs b/Substrate/Source/Nbt/INbtObject2.cs new file mode 100644 index 00000000..13ed4d58 --- /dev/null +++ b/Substrate/Source/Nbt/INbtObject2.cs @@ -0,0 +1,23 @@ +using System; + +namespace Substrate.Nbt +{ + /// + /// Defines methods for loading or extracting an NBT tree. + /// + public interface INbtObject2 + { + /// + /// Attempt to load an NBT tree into the object without validation. + /// + /// The root node of an NBT tree. + /// + void LoadTree(TagNode tree); + + /// + /// Builds an NBT tree from the object's data. + /// + /// The root node of an NBT tree representing the object's data. + TagNode BuildTree(); + } +} diff --git a/SubstrateCS/Source/Nbt/JSONSerializer.cs b/Substrate/Source/Nbt/JSONSerializer.cs similarity index 93% rename from SubstrateCS/Source/Nbt/JSONSerializer.cs rename to Substrate/Source/Nbt/JSONSerializer.cs index a42d00c1..03ac9172 100644 --- a/SubstrateCS/Source/Nbt/JSONSerializer.cs +++ b/Substrate/Source/Nbt/JSONSerializer.cs @@ -29,7 +29,7 @@ public static string Serialize (TagNode tag, int level) SerializeIntArray(tag as TagNodeIntArray, str, level); } else { - SerializeScaler(tag, str); + SerializeScalar(tag, str); } return str.ToString(); @@ -69,7 +69,7 @@ private static void SerializeCompound (TagNodeCompound tag, StringBuilder str, i SerializeIntArray(item.Value as TagNodeIntArray, str, level + 1); } else { - SerializeScaler(item.Value, str); + SerializeScalar(item.Value, str); } first = false; @@ -116,8 +116,8 @@ private static void SerializeList (TagNodeList tag, StringBuilder str, int level SerializeByteArray(item as TagNodeByteArray, str, level); } else { - SerializeScaler(item, str); - } + SerializeScalar(item, str); + } } @@ -172,7 +172,7 @@ private static void SerializeIntArray (TagNodeIntArray tag, StringBuilder str, i str.Append(" ]"); } - private static void SerializeScaler (TagNode tag, StringBuilder str) + private static void SerializeScalar(TagNode tag, StringBuilder str) { switch (tag.GetTagType()) { case TagType.TAG_STRING: diff --git a/SubstrateCS/Source/Nbt/NbtIOException.cs b/Substrate/Source/Nbt/NbtIOException.cs similarity index 100% rename from SubstrateCS/Source/Nbt/NbtIOException.cs rename to Substrate/Source/Nbt/NbtIOException.cs diff --git a/SubstrateCS/Source/Nbt/NbtTree.cs b/Substrate/Source/Nbt/NbtTree.cs similarity index 100% rename from SubstrateCS/Source/Nbt/NbtTree.cs rename to Substrate/Source/Nbt/NbtTree.cs diff --git a/SubstrateCS/Source/Nbt/NbtVerifier.cs b/Substrate/Source/Nbt/NbtVerifier.cs similarity index 63% rename from SubstrateCS/Source/Nbt/NbtVerifier.cs rename to Substrate/Source/Nbt/NbtVerifier.cs index 34067ef0..80f81dfa 100644 --- a/SubstrateCS/Source/Nbt/NbtVerifier.cs +++ b/Substrate/Source/Nbt/NbtVerifier.cs @@ -30,51 +30,34 @@ public enum TagEventCode /// public class TagEventArgs : EventArgs { - private string _tagName; - private TagNode _parent; - private TagNode _tag; - private SchemaNode _schema; - /// /// Gets the expected name of the referenced by this event. /// - public string TagName - { - get { return _tagName; } - } + public string TagName { get; private set; } /// /// Gets the parent of the referenced by this event, if it exists. /// - public TagNode Parent - { - get { return _parent; } - } + public TagNode Parent { get; private set; } /// /// Gets the referenced by this event. /// - public TagNode Tag - { - get { return _tag; } - } + public TagNode Tag { get; private set; } /// /// Gets the corresponding to the referenced by this event. /// - public SchemaNode Schema - { - get { return _schema; } - } + public SchemaNode Schema { get; private set; } /// /// Constructs a new event argument set. /// /// The expected name of a . - public TagEventArgs (string tagName) + public TagEventArgs(string tagName) : base() { - _tagName = tagName; + TagName = tagName; } /// @@ -82,11 +65,13 @@ public TagEventArgs (string tagName) /// /// The expected name of a . /// The involved in this event. - public TagEventArgs (string tagName, TagNode tag) + /// The optional parent of tag. + public TagEventArgs(string tagName, TagNode tag, TagNode parent = null) : base() { - _tag = tag; - _tagName = tagName; + Tag = tag; + TagName = tagName; + Parent = parent; } /// @@ -94,11 +79,25 @@ public TagEventArgs (string tagName, TagNode tag) /// /// The corresponding to the involved in this event. /// The involved in this event. - public TagEventArgs (SchemaNode schema, TagNode tag) + public TagEventArgs(SchemaNode schema, TagNode tag) : base() { - _tag = tag; - _schema = schema; + Tag = tag; + Schema = schema; + } + + /// + /// Constructs a new event argument set. + /// + /// The unexpected name of a . + /// The corresponding to the involved in this event. + /// The optional parent of tag. + public TagEventArgs(string tagName, SchemaNode schema, TagNode parent = null) + : base() + { + TagName = tagName; + Schema = schema; + Parent = parent; } } @@ -107,7 +106,7 @@ public TagEventArgs (SchemaNode schema, TagNode tag) /// /// Information relating to a verification event. /// A determining how the event processor should respond. - public delegate TagEventCode VerifierEventHandler (TagEventArgs eventArgs); + public delegate TagEventCode VerifierEventHandler(TagEventArgs eventArgs); /// /// Verifies the integrity of an NBT tree against a schema definition. @@ -122,6 +121,11 @@ public class NbtVerifier /// public static event VerifierEventHandler MissingTag; + /// + /// An event that gets fired whenever an unexpected is found. + /// + public static event VerifierEventHandler UnexpectedTag; + /// /// An event that gets fired whenever an expected is of the wrong type and cannot be cast. /// @@ -137,7 +141,7 @@ public class NbtVerifier /// /// A representing the root of an NBT tree. /// A representing the root of a schema definition for the NBT tree. - public NbtVerifier (TagNode root, SchemaNode schema) + public NbtVerifier(TagNode root, SchemaNode schema) { _root = root; _schema = schema; @@ -147,64 +151,75 @@ public NbtVerifier (TagNode root, SchemaNode schema) /// Invokes the verifier. /// /// Status indicating whether the NBT tree is valid for the given schema. - public virtual bool Verify () + public virtual bool Verify() { return Verify(null, _root, _schema); } - private bool Verify (TagNode parent, TagNode tag, SchemaNode schema) + private bool Verify(TagNode parent, TagNode tag, SchemaNode schema) { - if (tag == null) { + if (tag == null) + { return OnMissingTag(new TagEventArgs(schema.Name)); } - SchemaNodeScaler scaler = schema as SchemaNodeScaler; - if (scaler != null) { - return VerifyScaler(tag, scaler); + SchemaNodeScalar scalar = schema as SchemaNodeScalar; + if (scalar != null) + { + return VerifyScalar(tag, scalar); } SchemaNodeString str = schema as SchemaNodeString; - if (str != null) { + if (str != null) + { return VerifyString(tag, str); } - SchemaNodeArray array = schema as SchemaNodeArray; - if (array != null) { + SchemaNodeByteArray array = schema as SchemaNodeByteArray; + if (array != null) + { return VerifyArray(tag, array); } SchemaNodeIntArray intarray = schema as SchemaNodeIntArray; - if (intarray != null) { + if (intarray != null) + { return VerifyIntArray(tag, intarray); } SchemaNodeLongArray longarray = schema as SchemaNodeLongArray; - if (longarray != null) { + if (longarray != null) + { return VerifyLongArray(tag, longarray); } SchemaNodeShortArray shortarray = schema as SchemaNodeShortArray; - if (shortarray != null) { + if (shortarray != null) + { return VerifyShortArray(tag, shortarray); } SchemaNodeList list = schema as SchemaNodeList; - if (list != null) { + if (list != null) + { return VerifyList(tag, list); } SchemaNodeCompound compound = schema as SchemaNodeCompound; - if (compound != null) { + if (compound != null) + { return VerifyCompound(tag, compound); } - return OnInvalidTagType(new TagEventArgs(schema.Name, tag)); + return OnInvalidTagType(new TagEventArgs(schema.Name, tag, parent)); } - private bool VerifyScaler (TagNode tag, SchemaNodeScaler schema) + private bool VerifyScalar(TagNode tag, SchemaNodeScalar schema) { - if (!tag.IsCastableTo(schema.Type)) { - if (!OnInvalidTagType(new TagEventArgs(schema.Name, tag))) { + if (!tag.IsCastableTo(schema.Type)) + { + if (!OnInvalidTagType(new TagEventArgs(schema.Name, tag))) + { return false; } } @@ -212,21 +227,27 @@ private bool VerifyScaler (TagNode tag, SchemaNodeScaler schema) return true; } - private bool VerifyString (TagNode tag, SchemaNodeString schema) + private bool VerifyString(TagNode tag, SchemaNodeString schema) { TagNodeString stag = tag as TagNodeString; - if (stag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { + if (stag == null) + { + if (!OnInvalidTagType(new TagEventArgs(schema, tag))) + { return false; } } - if (schema.Length > 0 && stag.Length > schema.Length) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + if (schema.Length > 0 && stag.Length > schema.Length) + { + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) + { return false; } } - if (schema.Value != null && stag.Data != schema.Value) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + if (schema.Value != null && stag.Data != schema.Value) + { + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) + { return false; } } @@ -235,16 +256,20 @@ private bool VerifyString (TagNode tag, SchemaNodeString schema) } - private bool VerifyArray (TagNode tag, SchemaNodeArray schema) + private bool VerifyArray(TagNode tag, SchemaNodeByteArray schema) { TagNodeByteArray atag = tag as TagNodeByteArray; - if (atag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { + if (atag == null) + { + if (!OnInvalidTagType(new TagEventArgs(schema, tag))) + { return false; } } - if (schema.Length > 0 && atag.Length != schema.Length) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + if (schema.Length > 0 && atag.Length != schema.Length) + { + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) + { return false; } } @@ -252,16 +277,20 @@ private bool VerifyArray (TagNode tag, SchemaNodeArray schema) return true; } - private bool VerifyIntArray (TagNode tag, SchemaNodeIntArray schema) + private bool VerifyIntArray(TagNode tag, SchemaNodeIntArray schema) { TagNodeIntArray atag = tag as TagNodeIntArray; - if (atag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { + if (atag == null) + { + if (!OnInvalidTagType(new TagEventArgs(schema, tag))) + { return false; } } - if (schema.Length > 0 && atag.Length != schema.Length) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + if (schema.Length > 0 && atag.Length != schema.Length) + { + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) + { return false; } } @@ -269,7 +298,7 @@ private bool VerifyIntArray (TagNode tag, SchemaNodeIntArray schema) return true; } - private bool VerifyLongArray (TagNode tag, SchemaNodeLongArray schema) + private bool VerifyLongArray(TagNode tag, SchemaNodeLongArray schema) { TagNodeLongArray atag = tag as TagNodeLongArray; if (atag == null) { @@ -286,16 +315,20 @@ private bool VerifyLongArray (TagNode tag, SchemaNodeLongArray schema) return true; } - private bool VerifyShortArray (TagNode tag, SchemaNodeShortArray schema) + private bool VerifyShortArray(TagNode tag, SchemaNodeShortArray schema) { TagNodeShortArray atag = tag as TagNodeShortArray; - if (atag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { + if (atag == null) + { + if (!OnInvalidTagType(new TagEventArgs(schema, tag))) + { return false; } } - if (schema.Length > 0 && atag.Length != schema.Length) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + if (schema.Length > 0 && atag.Length != schema.Length) + { + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) + { return false; } } @@ -303,21 +336,27 @@ private bool VerifyShortArray (TagNode tag, SchemaNodeShortArray schema) return true; } - private bool VerifyList (TagNode tag, SchemaNodeList schema) + private bool VerifyList(TagNode tag, SchemaNodeList schema) { TagNodeList ltag = tag as TagNodeList; - if (ltag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { + if (ltag == null) + { + if (!OnInvalidTagType(new TagEventArgs(schema, tag))) + { return false; } } - if (ltag.Count > 0 && ltag.ValueType != schema.Type) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + if (ltag.Count > 0 && ltag.ValueType != schema.ItemType) + { + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) + { return false; } } - if (schema.Length > 0 && ltag.Count != schema.Length) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { + if (schema.Length > 0 && ltag.Count != schema.Length) + { + if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) + { return false; } } @@ -331,38 +370,52 @@ private bool VerifyList (TagNode tag, SchemaNodeList schema) // If a subschema is set, test all items in list against it - if (schema.SubSchema != null) { - foreach (TagNode v in ltag) { - pass = Verify(tag, v, schema.SubSchema) && pass; + if (schema.ItemSchema != null) + { + foreach (TagNode v in ltag) + { + pass = Verify(tag, v, schema.ItemSchema) && pass; } } return pass; } - private bool VerifyCompound (TagNode tag, SchemaNodeCompound schema) + private bool VerifyCompound(TagNode tag, SchemaNodeCompound schema) { TagNodeCompound ctag = tag as TagNodeCompound; - if (ctag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { + if (ctag == null) + { + if (!OnInvalidTagType(new TagEventArgs(schema, tag))) + { return false; } } bool pass = true; - Dictionary _scratch = new Dictionary(); + Dictionary _scratch = new Dictionary(); + var foundNames = new HashSet(); - foreach (SchemaNode node in schema) { + foreach (SchemaNode node in schema) + { TagNode value; - ctag.TryGetValue(node.Name, out value); + bool found = ctag.TryGetValue(node.Name, out value); - if (value == null) { - if ((node.Options & SchemaOptions.CREATE_ON_MISSING) == SchemaOptions.CREATE_ON_MISSING) { + if (found) + { + foundNames.Add(node.Name.ToLower()); + } + + if (value == null) + { + if ((node.Options & SchemaOptions.CREATE_ON_MISSING) == SchemaOptions.CREATE_ON_MISSING) + { _scratch[node.Name] = node.BuildDefaultTree(); continue; } - else if ((node.Options & SchemaOptions.OPTIONAL) == SchemaOptions.OPTIONAL) { + else if ((node.Options & SchemaOptions.OPTIONAL) == SchemaOptions.OPTIONAL) + { continue; } } @@ -370,7 +423,19 @@ private bool VerifyCompound (TagNode tag, SchemaNodeCompound schema) pass = Verify(tag, value, node) && pass; } - foreach (KeyValuePair item in _scratch) { + foreach (var tagName in ctag.Keys) + { + if (!foundNames.Contains(tagName.ToLower())) + { + if (!OnUnexpectedTag(new TagEventArgs(tagName, schema, ctag))) + { + return false; + } + } + } + + foreach (KeyValuePair item in _scratch) + { ctag[item.Key] = item.Value; } @@ -386,12 +451,15 @@ private bool VerifyCompound (TagNode tag, SchemaNodeCompound schema) /// /// Arguments for this event. /// Status indicating whether this event can be ignored. - protected virtual bool OnMissingTag (TagEventArgs e) + protected virtual bool OnMissingTag(TagEventArgs e) { - if (MissingTag != null) { - foreach (VerifierEventHandler func in MissingTag.GetInvocationList()) { + if (MissingTag != null) + { + foreach (VerifierEventHandler func in MissingTag.GetInvocationList()) + { TagEventCode code = func(e); - switch (code) { + switch (code) + { case TagEventCode.FAIL: return false; case TagEventCode.PASS: @@ -403,17 +471,45 @@ protected virtual bool OnMissingTag (TagEventArgs e) return false; } + /// + /// Processes registered events for whenever an unexpected is found. + /// + /// Arguments for this event. + /// Status indicating whether this event can be ignored. + protected virtual bool OnUnexpectedTag(TagEventArgs e) + { + if (UnexpectedTag != null) + { + foreach (VerifierEventHandler func in UnexpectedTag.GetInvocationList()) + { + TagEventCode code = func(e); + switch (code) + { + case TagEventCode.FAIL: + return false; + case TagEventCode.PASS: + return true; + } + } + } + + return true; + } + /// /// Processes registered events for whenever an expected is of the wrong type and cannot be cast. /// /// Arguments for this event. /// Status indicating whether this event can be ignored. - protected virtual bool OnInvalidTagType (TagEventArgs e) + protected virtual bool OnInvalidTagType(TagEventArgs e) { - if (InvalidTagType != null) { - foreach (VerifierEventHandler func in InvalidTagType.GetInvocationList()) { + if (InvalidTagType != null) + { + foreach (VerifierEventHandler func in InvalidTagType.GetInvocationList()) + { TagEventCode code = func(e); - switch (code) { + switch (code) + { case TagEventCode.FAIL: return false; case TagEventCode.PASS: @@ -430,12 +526,15 @@ protected virtual bool OnInvalidTagType (TagEventArgs e) /// /// Arguments for this event. /// Status indicating whether this event can be ignored. - protected virtual bool OnInvalidTagValue (TagEventArgs e) + protected virtual bool OnInvalidTagValue(TagEventArgs e) { - if (InvalidTagValue != null) { - foreach (VerifierEventHandler func in InvalidTagValue.GetInvocationList()) { + if (InvalidTagValue != null) + { + foreach (VerifierEventHandler func in InvalidTagValue.GetInvocationList()) + { TagEventCode code = func(e); - switch (code) { + switch (code) + { case TagEventCode.FAIL: return false; case TagEventCode.PASS: diff --git a/Substrate/Source/Nbt/SchemaBuilder.cs b/Substrate/Source/Nbt/SchemaBuilder.cs new file mode 100644 index 00000000..fed3d36f --- /dev/null +++ b/Substrate/Source/Nbt/SchemaBuilder.cs @@ -0,0 +1,377 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using Substrate.Nbt; + +namespace Substrate.Source.Nbt +{ + public class SchemaBuilder + { + public struct PropertyDetails + { + public TagType TagType; + public TagType ListItemTagType; + public Type ListItemType; + public SchemaOptions SchemaOptions; + public bool CustomType; + } + + public static SchemaNodeCompound FromClass(Type type, string enclosingName = null, SchemaOptions enclosingOptions = 0) + { + SchemaNodeCompound schema = new SchemaNodeCompound(enclosingName, enclosingOptions); + + var properties = type.GetProperties(); + foreach (var property in properties) + { + var attribute = property.GetCustomAttributes(typeof(TagNodeAttribute), false) + .Cast() + .SingleOrDefault(); + + if (attribute != null) + { + var name = attribute.Name ?? property.Name; + + var propertyInfo = GetTagTypeForPropertyType(property.PropertyType); + + TagType tagType = propertyInfo.CustomType ? propertyInfo.TagType : + attribute.TagType != TagType.TAG_END ? attribute.TagType : + propertyInfo.TagType; + + SchemaOptions schemaOptions = propertyInfo.SchemaOptions; + if (attribute.Optional) { schemaOptions |= SchemaOptions.OPTIONAL; } + if (attribute.CreateOnMissing) { schemaOptions |= SchemaOptions.CREATE_ON_MISSING; } + + switch (tagType) + { + case TagType.TAG_BYTE: + case TagType.TAG_SHORT: + case TagType.TAG_INT: + case TagType.TAG_LONG: + case TagType.TAG_FLOAT: + case TagType.TAG_DOUBLE: + schema.Add(new SchemaNodeScalar(name, tagType, schemaOptions)); + break; + + case TagType.TAG_STRING: + schema.Add(new SchemaNodeString(name, schemaOptions)); + break; + + case TagType.TAG_BYTE_ARRAY: + schema.Add(new SchemaNodeByteArray(name, schemaOptions)); + break; + + case TagType.TAG_INT_ARRAY: + schema.Add(new SchemaNodeIntArray(name, schemaOptions)); + break; + + case TagType.TAG_SHORT_ARRAY: + schema.Add(new SchemaNodeShortArray(name, schemaOptions)); + break; + + case TagType.TAG_LIST: + if (propertyInfo.ListItemTagType == TagType.TAG_COMPOUND) + { + var listItemSchema = FromClass(propertyInfo.ListItemType); + schema.Add(new SchemaNodeList(name, TagType.TAG_COMPOUND, listItemSchema, schemaOptions)); + } + else + { + schema.Add(new SchemaNodeList(name, propertyInfo.ListItemTagType, schemaOptions)); + } + break; + + case TagType.TAG_COMPOUND: + schema.Add(FromClass(property.PropertyType, name, schemaOptions)); + break; + } + } + } + + return schema; + } + + private static PropertyDetails GetTagTypeForPropertyType(Type type) + { + PropertyDetails details = new PropertyDetails(); + + var attr = type.GetCustomAttributes(typeof(TagNodeTypeAttribute), true).SingleOrDefault() as TagNodeTypeAttribute; + if (attr != null) + { + details.TagType = attr.TagType; + details.ListItemTagType = attr.ListItemTagType; + details.ListItemType = attr.ListItemType; + details.CustomType = true; + return details; + } + + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) + { + details.ListItemType = type.GetGenericArguments()[0]; + var subTagType = GetTagTypeForPropertyType(details.ListItemType); + + details.TagType = TagType.TAG_LIST; + details.ListItemTagType = subTagType.TagType; + return details; + } + + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>)) + { + if (type.GetGenericArguments()[0] != typeof(int)) + { + throw new InvalidOperationException("Dictionary-as-list is only supported with int key type"); + } + + details.ListItemType = type.GetGenericArguments()[1]; + var subTagType = GetTagTypeForPropertyType(details.ListItemType); + + details.TagType = TagType.TAG_LIST; + details.ListItemTagType = subTagType.TagType; + return details; + } + + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + type = type.GetGenericArguments()[0]; + details.SchemaOptions |= SchemaOptions.OPTIONAL; + } + + if (type.IsEnum) + { + type = type.GetEnumUnderlyingType(); + } + + if (type == typeof(byte)) { details.TagType = TagType.TAG_BYTE; } + else if (type == typeof(bool)) { details.TagType = TagType.TAG_BYTE; } + else if (type == typeof(short)) { details.TagType = TagType.TAG_SHORT; } + else if (type == typeof(int)) { details.TagType = TagType.TAG_INT; } + else if (type == typeof(long)) { details.TagType = TagType.TAG_LONG; } + else if (type == typeof(float)) { details.TagType = TagType.TAG_FLOAT; } + else if (type == typeof(double)) { details.TagType = TagType.TAG_DOUBLE; } + else if (type == typeof(string)) { details.TagType = TagType.TAG_STRING; } + else if (type == typeof(List)) { details.TagType = TagType.TAG_BYTE_ARRAY; } + else if (type == typeof(List)) { details.TagType = TagType.TAG_INT_ARRAY; } + else if (type == typeof(List)) { details.TagType = TagType.TAG_SHORT_ARRAY; } + else if (type == typeof(List)) { details.TagType = TagType.TAG_LONG_ARRAY; } + else { details.TagType = TagType.TAG_COMPOUND; } + + return details; + } + + public static string FormatTree(SchemaNode root) + { + StringBuilder builder = new StringBuilder(); + + FormatNode(root, builder, 0); + + return builder.ToString(); + } + + public static void FormatNode(SchemaNode node, StringBuilder builder, int tablevel) + { + for (int i = 0; i < tablevel; ++i) + { + builder.Append("\t|"); + } + builder.AppendFormat($"'{node.Name}', {node.Type} ({node.GetType().Name}), {node.Options}"); + builder.AppendLine(); + + if (node is SchemaNodeCompound) + { + var ctree = node as SchemaNodeCompound; + + foreach (var subnode in ctree) + { + FormatNode(subnode, builder, tablevel + 1); + } + } + else if (node is SchemaNodeList) + { + var atree = node as SchemaNodeList; + + if (atree.ItemType == TagType.TAG_COMPOUND) + { + FormatNode(atree.ItemSchema, builder, tablevel + 1); + } + } + } + + public static object LoadCompound(object nbtObject, TagNodeCompound tree, SchemaNodeCompound schemaNode) + { + var properties = nbtObject.GetType().GetProperties(); + + foreach (var node in schemaNode) + { + tree.TryGetValue(node.Name, out var treeValue); + + if (treeValue == null) { continue; } + + var prop = properties.SingleOrDefault(p => + { + var attr = p.GetCustomAttributes(typeof(TagNodeAttribute), false).SingleOrDefault() as TagNodeAttribute; + return attr != null && (attr.Name != null ? attr.Name == node.Name : p.Name == node.Name); + }); + + if (prop == null || !prop.CanWrite) + { + continue; + } + + var subObject = prop.GetValue(nbtObject, null); + if (subObject == null) + { + subObject = Activator.CreateInstance(prop.PropertyType); + prop.SetValue(nbtObject, subObject, null); + } + + var nbtObject2 = subObject as INbtObject2; + if (nbtObject2 != null) + { + nbtObject2.LoadTree(treeValue); + } + else if (node.Type == TagType.TAG_COMPOUND) + { + LoadCompound(subObject, treeValue as TagNodeCompound, node as SchemaNodeCompound); + } + else if (node.Type == TagType.TAG_LIST) + { + LoadList(subObject, prop, treeValue, node as SchemaNodeList); + } + else + { + var baseType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType; + var typeCode = Type.GetTypeCode(baseType); + + object propVal = null; + switch (typeCode) + { + case TypeCode.Boolean: + propVal = treeValue.ToTagByte().Data != 0 ? true : false; + break; + case TypeCode.Byte: + propVal = treeValue.ToTagByte().Data; + break; + case TypeCode.Int16: + propVal = treeValue.ToTagShort().Data; + break; + case TypeCode.Int32: + propVal = treeValue.ToTagInt().Data; + break; + case TypeCode.Int64: + propVal = treeValue.ToTagLong().Data; + break; + case TypeCode.String: + propVal = treeValue.ToTagString().Data; + break; + case TypeCode.Single: + propVal = treeValue.ToTagFloat().Data; + break; + case TypeCode.Double: + propVal = treeValue.ToTagDouble().Data; + break; + default: + break; + } + + if (baseType.IsEnum) + { + propVal = Enum.ToObject(baseType, propVal); + } + + prop.SetValue(nbtObject, propVal, null); + } + } + + return nbtObject; + } + + private static void LoadList(object subObject, PropertyInfo prop, TagNode treeValue, SchemaNodeList schemeNodeList) + { + if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(List<>)) + { + var listNode = treeValue.ToTagList(); + + var listProp = (IList)subObject; + listProp.Clear(); + + var listItemType = prop.PropertyType.GetGenericArguments()[0]; + + var typeCode = Type.GetTypeCode(listItemType); + switch (typeCode) + { + case TypeCode.Boolean: + foreach (var n in listNode) + { + listProp.Add(n.ToTagByte().Data != 0); + } + break; + case TypeCode.Byte: + foreach (var n in listNode) + { + listProp.Add(n.ToTagByte().Data); + } + break; + case TypeCode.Int16: + foreach (var n in listNode) + { + listProp.Add(n.ToTagShort().Data); + } + break; + case TypeCode.Int32: + foreach (var n in listNode) + { + listProp.Add(n.ToTagInt().Data); + } + break; + case TypeCode.Int64: + foreach (var n in listNode) + { + listProp.Add(n.ToTagLong().Data); + } + break; + case TypeCode.String: + foreach (var n in listNode) + { + listProp.Add(n.ToTagString().Data); + } + break; + case TypeCode.Single: + foreach (var n in listNode) + { + listProp.Add(n.ToTagFloat().Data); + } + break; + case TypeCode.Double: + foreach (var n in listNode) + { + listProp.Add(n.ToTagDouble().Data); + } + break; + default: + foreach (var n in listNode) + { + var itemObject = Activator.CreateInstance(listItemType); + LoadCompound(itemObject, n as TagNodeCompound, schemeNodeList.ItemSchema as SchemaNodeCompound); + listProp.Add(itemObject); + } + break; + } + + // prop.SetValue(nbtObject, list.ToList(), null); + } + else if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Dictionary<,>)) + { + var list = treeValue.ToTagList(); + + var dict = subObject as IDictionary; + foreach (var val in list) + { + int slot = val.ToTagCompound()["slot"].ToTagInt(); + dict.Add(slot, val); + } + } + } + } +} diff --git a/SubstrateCS/Source/Nbt/SchemaNode.cs b/Substrate/Source/Nbt/SchemaNode.cs similarity index 59% rename from SubstrateCS/Source/Nbt/SchemaNode.cs rename to Substrate/Source/Nbt/SchemaNode.cs index e8d34ce0..d4fc5a9f 100644 --- a/SubstrateCS/Source/Nbt/SchemaNode.cs +++ b/Substrate/Source/Nbt/SchemaNode.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Text; namespace Substrate.Nbt @@ -7,52 +8,53 @@ namespace Substrate.Nbt /// /// A node in an NBT schema definition, used to define what values are considered valid for a given NBT node. /// + [DebuggerDisplay("Name = '{Name}', Type = {Type}, Options = {Options}")] public abstract class SchemaNode { - private string _name; - private SchemaOptions _options; - /// /// Gets the name of an expected NBT node. /// - public string Name - { - get { return _name; } - } + public string Name { get; private set; } + + /// + /// Gets the scalar that this node represents. + /// + public TagType Type { get; private set; } /// /// Gets additional schema options defined for this node. /// - public SchemaOptions Options - { - get { return _options; } - } + public SchemaOptions Options { get; private set; } /// /// Constructs a new representing a named . /// /// The name of the corresponding . - protected SchemaNode (string name) + /// The type of the corresponding . + protected SchemaNode(string name, TagType type) { - _name = name; + Name = name; + Type = type; } /// /// Constructs a new with additional options. /// /// The name of the corresponding . + /// The type of the corresponding . /// One or more option flags modifying the processing of this node. - protected SchemaNode (string name, SchemaOptions options) + protected SchemaNode(string name, TagType type, SchemaOptions options) { - _name = name; - _options = options; + Name = name; + Type = type; + Options = options; } /// /// Construct a sensible default NBT tree representative of this schema node. /// /// A that is valid for this schema node. - public virtual TagNode BuildDefaultTree () + public virtual TagNode BuildDefaultTree() { return null; } diff --git a/SubstrateCS/Source/Nbt/SchemaNodeArray.cs b/Substrate/Source/Nbt/SchemaNodeByteArray.cs similarity index 57% rename from SubstrateCS/Source/Nbt/SchemaNodeArray.cs rename to Substrate/Source/Nbt/SchemaNodeByteArray.cs index 9d3f3544..84eee925 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeArray.cs +++ b/Substrate/Source/Nbt/SchemaNodeByteArray.cs @@ -1,81 +1,76 @@ -using System; - -namespace Substrate.Nbt -{ - /// - /// A concrete representing a . - /// - public sealed class SchemaNodeArray : SchemaNode - { - private int _length; - - /// - /// Gets the expected length of the corresponding byte array. - /// - public int Length - { - get { return _length; } - } - - /// - /// Indicates whether there is an expected length of the corresponding byte array. - /// - public bool HasExpectedLength - { - get { return _length > 0; } - } - - /// - /// Constructs a new representing a named . - /// - /// The name of the corresponding . - public SchemaNodeArray (string name) - : base(name) - { - _length = 0; - } - - /// - /// Constructs a new with additional options. - /// - /// The name of the corresponding . - /// One or more option flags modifying the processing of this node. - public SchemaNodeArray (string name, SchemaOptions options) - : base(name, options) - { - _length = 0; - } - - /// - /// Constructs a new representing a named with expected length . - /// - /// The name of the corresponding . - /// The expected length of corresponding byte array. - public SchemaNodeArray (string name, int length) - : base(name) - { - _length = length; - } - - /// - /// Constructs a new with additional options. - /// - /// The name of the corresponding . - /// The expected length of corresponding byte array. - /// One or more option flags modifying the processing of this node. - public SchemaNodeArray (string name, int length, SchemaOptions options) - : base(name, options) - { - _length = length; - } - - /// - /// Constructs a default satisfying the constraints of this node. - /// - /// A with a sensible default value. - public override TagNode BuildDefaultTree () - { - return new TagNodeByteArray(new byte[_length]); - } - } -} +using System; + +namespace Substrate.Nbt +{ + /// + /// A concrete representing a . + /// + public sealed class SchemaNodeByteArray : SchemaNode + { + /// + /// Gets the expected length of the corresponding byte array. + /// + public int Length { get; private set; } + + /// + /// Indicates whether there is an expected length of the corresponding byte array. + /// + public bool HasExpectedLength + { + get { return Length > 0; } + } + + /// + /// Constructs a new representing a named . + /// + /// The name of the corresponding . + public SchemaNodeByteArray(string name) + : base(name, TagType.TAG_BYTE_ARRAY) + { + Length = 0; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// One or more option flags modifying the processing of this node. + public SchemaNodeByteArray(string name, SchemaOptions options) + : base(name, TagType.TAG_BYTE_ARRAY, options) + { + Length = 0; + } + + /// + /// Constructs a new representing a named with expected length . + /// + /// The name of the corresponding . + /// The expected length of corresponding byte array. + public SchemaNodeByteArray(string name, int length) + : base(name, TagType.TAG_BYTE_ARRAY) + { + Length = length; + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// The expected length of corresponding byte array. + /// One or more option flags modifying the processing of this node. + public SchemaNodeByteArray(string name, int length, SchemaOptions options) + : base(name, TagType.TAG_BYTE_ARRAY, options) + { + Length = length; + } + + /// + /// Constructs a default satisfying the constraints of this node. + /// + /// A with a sensible default value. + public override TagNode BuildDefaultTree() + { + return new TagNodeByteArray(new byte[Length]); + } + } +} diff --git a/SubstrateCS/Source/Nbt/SchemaNodeCompound.cs b/Substrate/Source/Nbt/SchemaNodeCompound.cs similarity index 94% rename from SubstrateCS/Source/Nbt/SchemaNodeCompound.cs rename to Substrate/Source/Nbt/SchemaNodeCompound.cs index a7670f9b..e637ba1c 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeCompound.cs +++ b/Substrate/Source/Nbt/SchemaNodeCompound.cs @@ -107,7 +107,7 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () /// Constructs a new representing a root . /// public SchemaNodeCompound () - : base("") + : base("", TagType.TAG_COMPOUND) { _subnodes = new List(); } @@ -117,7 +117,7 @@ public SchemaNodeCompound () /// /// One or more option flags modifying the processing of this node. public SchemaNodeCompound (SchemaOptions options) - : base("", options) + : base("", TagType.TAG_COMPOUND, options) { _subnodes = new List(); } @@ -127,7 +127,7 @@ public SchemaNodeCompound (SchemaOptions options) /// /// The name of the corresponding . public SchemaNodeCompound (string name) - : base(name) + : base(name, TagType.TAG_COMPOUND) { _subnodes = new List(); } @@ -138,7 +138,7 @@ public SchemaNodeCompound (string name) /// The name of the corresponding . /// One or more option flags modifying the processing of this node. public SchemaNodeCompound (string name, SchemaOptions options) - : base(name, options) + : base(name, TagType.TAG_COMPOUND, options) { _subnodes = new List(); } @@ -149,7 +149,7 @@ public SchemaNodeCompound (string name, SchemaOptions options) /// The name of the corresponding . /// A representing a schema to verify against the corresponding . public SchemaNodeCompound (string name, SchemaNode subschema) - : base(name) + : base(name, TagType.TAG_COMPOUND) { _subnodes = new List(); @@ -170,7 +170,7 @@ public SchemaNodeCompound (string name, SchemaNode subschema) /// A representing a schema to verify against the corresponding . /// One or more option flags modifying the processing of this node. public SchemaNodeCompound (string name, SchemaNode subschema, SchemaOptions options) - : base(name, options) + : base(name, TagType.TAG_COMPOUND, options) { _subnodes = new List(); diff --git a/SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs b/Substrate/Source/Nbt/SchemaNodeIntArray.cs similarity index 75% rename from SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs rename to Substrate/Source/Nbt/SchemaNodeIntArray.cs index 086b67fb..9119d97d 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs +++ b/Substrate/Source/Nbt/SchemaNodeIntArray.cs @@ -9,32 +9,27 @@ namespace Substrate.Nbt /// public sealed class SchemaNodeIntArray : SchemaNode { - private int _length; - /// /// Gets the expected length of the corresponding int array. /// - public int Length - { - get { return _length; } - } + public int Length { get; private set; } /// /// Indicates whether there is an expected length of the corresponding int array. /// public bool HasExpectedLength { - get { return _length > 0; } + get { return Length > 0; } } /// /// Constructs a new representing a named . /// /// The name of the corresponding . - public SchemaNodeIntArray (string name) - : base(name) + public SchemaNodeIntArray(string name) + : base(name, TagType.TAG_INT_ARRAY) { - _length = 0; + Length = 0; } /// @@ -42,10 +37,10 @@ public SchemaNodeIntArray (string name) /// /// The name of the corresponding . /// One or more option flags modifying the processing of this node. - public SchemaNodeIntArray (string name, SchemaOptions options) - : base(name, options) + public SchemaNodeIntArray(string name, SchemaOptions options) + : base(name, TagType.TAG_INT_ARRAY, options) { - _length = 0; + Length = 0; } /// @@ -53,10 +48,10 @@ public SchemaNodeIntArray (string name, SchemaOptions options) /// /// The name of the corresponding . /// The expected length of corresponding byte array. - public SchemaNodeIntArray (string name, int length) - : base(name) + public SchemaNodeIntArray(string name, int length) + : base(name, TagType.TAG_INT_ARRAY) { - _length = length; + Length = length; } /// @@ -65,19 +60,19 @@ public SchemaNodeIntArray (string name, int length) /// The name of the corresponding . /// The expected length of corresponding byte array. /// One or more option flags modifying the processing of this node. - public SchemaNodeIntArray (string name, int length, SchemaOptions options) - : base(name, options) + public SchemaNodeIntArray(string name, int length, SchemaOptions options) + : base(name, TagType.TAG_INT_ARRAY, options) { - _length = length; + Length = length; } /// /// Constructs a default satisfying the constraints of this node. /// /// A with a sensible default value. - public override TagNode BuildDefaultTree () + public override TagNode BuildDefaultTree() { - return new TagNodeIntArray(new int[_length]); + return new TagNodeIntArray(new int[Length]); } } } diff --git a/SubstrateCS/Source/Nbt/SchemaNodeList.cs b/Substrate/Source/Nbt/SchemaNodeList.cs similarity index 73% rename from SubstrateCS/Source/Nbt/SchemaNodeList.cs rename to Substrate/Source/Nbt/SchemaNodeList.cs index d7bf6e2a..7e624dcd 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeList.cs +++ b/Substrate/Source/Nbt/SchemaNodeList.cs @@ -7,40 +7,27 @@ namespace Substrate.Nbt /// public sealed class SchemaNodeList : SchemaNode { - private TagType _type; - private int _length; - private SchemaNode _subschema; - /// /// Gets the expected number of items contained in the corresponding . /// - public int Length - { - get { return _length; } - } + public int Length { get; private set; } /// /// Gets the expected of the items contained in the corresponding . /// - public TagType Type - { - get { return _type; } - } + public TagType ItemType { get; private set; } /// /// Gets a representing a schema that items contained in the corresponding should be verified against. /// - public SchemaNode SubSchema - { - get { return _subschema; } - } + public SchemaNode ItemSchema { get; private set; } /// /// Indicates whether there is an expected number of items of the corresponding . /// public bool HasExpectedLength { - get { return _length > 0; } + get { return Length > 0; } } /// @@ -48,10 +35,10 @@ public bool HasExpectedLength /// /// The name of the corresponding . /// The type of items contained in the corresponding . - public SchemaNodeList (string name, TagType type) - : base(name) + public SchemaNodeList(string name, TagType type) + : base(name, TagType.TAG_LIST) { - _type = type; + ItemType = type; } /// @@ -60,10 +47,10 @@ public SchemaNodeList (string name, TagType type) /// The name of the corresponding . /// The type of items contained in the corresponding . /// One or more option flags modifying the processing of this node. - public SchemaNodeList (string name, TagType type, SchemaOptions options) - : base(name, options) + public SchemaNodeList(string name, TagType type, SchemaOptions options) + : base(name, TagType.TAG_LIST, options) { - _type = type; + ItemType = type; } /// @@ -72,11 +59,11 @@ public SchemaNodeList (string name, TagType type, SchemaOptions options) /// The name of the corresponding . /// The type of items contained in the corresponding . /// The number of items contained in the corresponding . - public SchemaNodeList (string name, TagType type, int length) - : base(name) + public SchemaNodeList(string name, TagType type, int length) + : base(name, TagType.TAG_LIST) { - _type = type; - _length = length; + ItemType = type; + Length = length; } /// @@ -86,11 +73,11 @@ public SchemaNodeList (string name, TagType type, int length) /// The type of items contained in the corresponding . /// The number of items contained in the corresponding . /// One or more option flags modifying the processing of this node. - public SchemaNodeList (string name, TagType type, int length, SchemaOptions options) - : base(name, options) + public SchemaNodeList(string name, TagType type, int length, SchemaOptions options) + : base(name, TagType.TAG_LIST, options) { - _type = type; - _length = length; + ItemType = type; + Length = length; } /// @@ -99,11 +86,11 @@ public SchemaNodeList (string name, TagType type, int length, SchemaOptions opti /// The name of the corresponding . /// The type of items contained in the corresponding . /// A representing a schema to verify against items contained in the corresponding . - public SchemaNodeList (string name, TagType type, SchemaNode subschema) - : base(name) + public SchemaNodeList(string name, TagType type, SchemaNode subschema) + : base(name, TagType.TAG_LIST) { - _type = type; - _subschema = subschema; + ItemType = type; + ItemSchema = subschema; } /// @@ -113,11 +100,11 @@ public SchemaNodeList (string name, TagType type, SchemaNode subschema) /// The type of items contained in the corresponding . /// A representing a schema to verify against items contained in the corresponding . /// One or more option flags modifying the processing of this node. - public SchemaNodeList (string name, TagType type, SchemaNode subschema, SchemaOptions options) - : base(name, options) + public SchemaNodeList(string name, TagType type, SchemaNode subschema, SchemaOptions options) + : base(name, TagType.TAG_LIST, options) { - _type = type; - _subschema = subschema; + ItemType = type; + ItemSchema = subschema; } /// @@ -127,12 +114,12 @@ public SchemaNodeList (string name, TagType type, SchemaNode subschema, SchemaOp /// The type of items contained in the corresponding . /// The number of items contained in the corresponding . /// A representing a schema to verify against items contained in the corresponding . - public SchemaNodeList (string name, TagType type, int length, SchemaNode subschema) - : base(name) + public SchemaNodeList(string name, TagType type, int length, SchemaNode subschema) + : base(name, TagType.TAG_LIST) { - _type = type; - _length = length; - _subschema = subschema; + ItemType = type; + Length = length; + ItemSchema = subschema; } /// @@ -143,27 +130,29 @@ public SchemaNodeList (string name, TagType type, int length, SchemaNode subsche /// The number of items contained in the corresponding . /// A representing a schema to verify against items contained in the corresponding . /// One or more option flags modifying the processing of this node. - public SchemaNodeList (string name, TagType type, int length, SchemaNode subschema, SchemaOptions options) - : base(name, options) + public SchemaNodeList(string name, TagType type, int length, SchemaNode subschema, SchemaOptions options) + : base(name, TagType.TAG_LIST, options) { - _type = type; - _length = length; - _subschema = subschema; + ItemType = type; + Length = length; + ItemSchema = subschema; } /// /// Constructs a default satisfying the constraints of this node. /// /// A with a sensible default value. If a length is specified, default child objects of the necessary type will be created and added to the . - public override TagNode BuildDefaultTree () + public override TagNode BuildDefaultTree() { - if (_length == 0) { - return new TagNodeList(_type); + if (Length == 0) + { + return new TagNodeList(ItemType); } - TagNodeList list = new TagNodeList(_type); - for (int i = 0; i < _length; i++) { - list.Add(_subschema.BuildDefaultTree()); + TagNodeList list = new TagNodeList(ItemType); + for (int i = 0; i < Length; i++) + { + list.Add(ItemSchema.BuildDefaultTree()); } return list; diff --git a/SubstrateCS/Source/Nbt/SchemaNodeLongArray.cs b/Substrate/Source/Nbt/SchemaNodeLongArray.cs similarity index 93% rename from SubstrateCS/Source/Nbt/SchemaNodeLongArray.cs rename to Substrate/Source/Nbt/SchemaNodeLongArray.cs index 702bed1a..a2520e56 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeLongArray.cs +++ b/Substrate/Source/Nbt/SchemaNodeLongArray.cs @@ -32,7 +32,7 @@ public bool HasExpectedLength /// /// The name of the corresponding . public SchemaNodeLongArray (string name) - : base(name) + : base(name, TagType.TAG_LONG_ARRAY) { _length = 0; } @@ -43,7 +43,7 @@ public SchemaNodeLongArray (string name) /// The name of the corresponding . /// One or more option flags modifying the processing of this node. public SchemaNodeLongArray (string name, SchemaOptions options) - : base(name, options) + : base(name, TagType.TAG_LONG_ARRAY, options) { _length = 0; } @@ -54,7 +54,7 @@ public SchemaNodeLongArray (string name, SchemaOptions options) /// The name of the corresponding . /// The expected length of corresponding byte array. public SchemaNodeLongArray (string name, int length) - : base(name) + : base(name, TagType.TAG_LONG_ARRAY) { _length = length; } @@ -66,7 +66,7 @@ public SchemaNodeLongArray (string name, int length) /// The expected length of corresponding byte array. /// One or more option flags modifying the processing of this node. public SchemaNodeLongArray (string name, int length, SchemaOptions options) - : base(name, options) + : base(name, TagType.TAG_LONG_ARRAY, options) { _length = length; } diff --git a/Substrate/Source/Nbt/SchemaNodeScalar.cs b/Substrate/Source/Nbt/SchemaNodeScalar.cs new file mode 100644 index 00000000..11e3d76a --- /dev/null +++ b/Substrate/Source/Nbt/SchemaNodeScalar.cs @@ -0,0 +1,66 @@ +using System; +using System.Diagnostics; + +namespace Substrate.Nbt +{ + /// + /// A concrete representing a scalar-type . + /// + [DebuggerDisplay("Name = {Name}, Options = {Options}, Scalar Type={Type}")] + public sealed class SchemaNodeScalar : SchemaNode + { + /// + /// Constructs a new representing a named and of type . + /// + /// The name of the corresponding . + /// The type of the corresponding , restricted to scalar types. + public SchemaNodeScalar(string name, TagType type) + : base(name, type) + { + } + + /// + /// Constructs a new with additional options. + /// + /// The name of the corresponding . + /// The type of the corresponding , restricted to scalar types. + /// One or more option flags modifying the processing of this node. + public SchemaNodeScalar(string name, TagType type, SchemaOptions options) + : base(name, type, options) + { + } + + /// + /// Constructs a default according to the this node represents. + /// + /// A with a sensible default value. + public override TagNode BuildDefaultTree() + { + switch (Type) + { + case TagType.TAG_STRING: + return new TagNodeString(); + + case TagType.TAG_BYTE: + return new TagNodeByte(); + + case TagType.TAG_SHORT: + return new TagNodeShort(); + + case TagType.TAG_INT: + return new TagNodeInt(); + + case TagType.TAG_LONG: + return new TagNodeLong(); + + case TagType.TAG_FLOAT: + return new TagNodeFloat(); + + case TagType.TAG_DOUBLE: + return new TagNodeDouble(); + } + + return null; + } + } +} diff --git a/SubstrateCS/Source/Nbt/SchemaNodeShortArray.cs b/Substrate/Source/Nbt/SchemaNodeShortArray.cs similarity index 75% rename from SubstrateCS/Source/Nbt/SchemaNodeShortArray.cs rename to Substrate/Source/Nbt/SchemaNodeShortArray.cs index d6e1e8f1..45ba1db9 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeShortArray.cs +++ b/Substrate/Source/Nbt/SchemaNodeShortArray.cs @@ -9,32 +9,27 @@ namespace Substrate.Nbt /// public sealed class SchemaNodeShortArray : SchemaNode { - private int _length; - /// /// Gets the expected length of the corresponding int array. /// - public int Length - { - get { return _length; } - } + public int Length { get; private set; } /// /// Indicates whether there is an expected length of the corresponding int array. /// public bool HasExpectedLength { - get { return _length > 0; } + get { return Length > 0; } } /// /// Constructs a new representing a named . /// /// The name of the corresponding . - public SchemaNodeShortArray (string name) - : base(name) + public SchemaNodeShortArray(string name) + : base(name, TagType.TAG_SHORT_ARRAY) { - _length = 0; + Length = 0; } /// @@ -42,10 +37,10 @@ public SchemaNodeShortArray (string name) /// /// The name of the corresponding . /// One or more option flags modifying the processing of this node. - public SchemaNodeShortArray (string name, SchemaOptions options) - : base(name, options) + public SchemaNodeShortArray(string name, SchemaOptions options) + : base(name, TagType.TAG_SHORT_ARRAY, options) { - _length = 0; + Length = 0; } /// @@ -53,10 +48,10 @@ public SchemaNodeShortArray (string name, SchemaOptions options) /// /// The name of the corresponding . /// The expected length of corresponding byte array. - public SchemaNodeShortArray (string name, int length) - : base(name) + public SchemaNodeShortArray(string name, int length) + : base(name, TagType.TAG_SHORT_ARRAY) { - _length = length; + Length = length; } /// @@ -65,19 +60,19 @@ public SchemaNodeShortArray (string name, int length) /// The name of the corresponding . /// The expected length of corresponding byte array. /// One or more option flags modifying the processing of this node. - public SchemaNodeShortArray (string name, int length, SchemaOptions options) - : base(name, options) + public SchemaNodeShortArray(string name, int length, SchemaOptions options) + : base(name, TagType.TAG_SHORT_ARRAY, options) { - _length = length; + Length = length; } /// /// Constructs a default satisfying the constraints of this node. /// /// A with a sensible default value. - public override TagNode BuildDefaultTree () + public override TagNode BuildDefaultTree() { - return new TagNodeShortArray(new short[_length]); + return new TagNodeShortArray(new short[Length]); } } } diff --git a/SubstrateCS/Source/Nbt/SchemaNodeString.cs b/Substrate/Source/Nbt/SchemaNodeString.cs similarity index 75% rename from SubstrateCS/Source/Nbt/SchemaNodeString.cs rename to Substrate/Source/Nbt/SchemaNodeString.cs index 54c1f9b2..c2a25844 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeString.cs +++ b/Substrate/Source/Nbt/SchemaNodeString.cs @@ -7,40 +7,31 @@ namespace Substrate.Nbt /// public sealed class SchemaNodeString : SchemaNode { - private string _value = ""; - private int _length; - /// /// Gets the maximum length of a valid string. /// - public int Length - { - get { return _length; } - } + public int Length { get; private set; } /// /// Gets the expected value of a valid string. /// /// A must be set to this value to be considered valid. - public string Value - { - get { return _value; } - } + public string Value { get; private set; } = ""; /// /// Indicates whether there is a maximum-length constraint on strings in this node. /// public bool HasMaxLength { - get { return _length > 0; } + get { return Length > 0; } } /// /// Constructs a new representing a named . /// /// The name of the corresponding . - public SchemaNodeString (string name) - : base(name) + public SchemaNodeString(string name) + : base(name, TagType.TAG_STRING) { } @@ -49,8 +40,8 @@ public SchemaNodeString (string name) /// /// The name of the corresponding . /// One or more option flags modifying the processing of this node. - public SchemaNodeString (string name, SchemaOptions options) - : base(name, options) + public SchemaNodeString(string name, SchemaOptions options) + : base(name, TagType.TAG_STRING, options) { } @@ -59,10 +50,10 @@ public SchemaNodeString (string name, SchemaOptions options) /// /// The name of the corresponding . /// The value that the corresponding must be set to. - public SchemaNodeString (string name, string value) - : base(name) + public SchemaNodeString(string name, string value) + : base(name, TagType.TAG_STRING) { - _value = value; + Value = value; } /// @@ -71,10 +62,10 @@ public SchemaNodeString (string name, string value) /// The name of the corresponding . /// The value that the corresponding must be set to. /// One or more option flags modifying the processing of this node. - public SchemaNodeString (string name, string value, SchemaOptions options) - : base(name, options) + public SchemaNodeString(string name, string value, SchemaOptions options) + : base(name, TagType.TAG_STRING, options) { - _value = value; + Value = value; } /// @@ -82,10 +73,10 @@ public SchemaNodeString (string name, string value, SchemaOptions options) /// /// The name of the corresponding . /// The maximum length of strings in the corresponding . - public SchemaNodeString (string name, int length) - : base(name) + public SchemaNodeString(string name, int length) + : base(name, TagType.TAG_STRING) { - _length = length; + Length = length; } /// @@ -94,20 +85,21 @@ public SchemaNodeString (string name, int length) /// The name of the corresponding . /// The maximum length of strings in the corresponding . /// One or more option flags modifying the processing of this node. - public SchemaNodeString (string name, int length, SchemaOptions options) - : base(name, options) + public SchemaNodeString(string name, int length, SchemaOptions options) + : base(name, TagType.TAG_STRING, options) { - _length = length; + Length = length; } /// /// Constructs a default satisfying the constraints of this node. /// /// A with a sensible default value. If this node represents a particular string, the constructed will be set to that string. - public override TagNode BuildDefaultTree () + public override TagNode BuildDefaultTree() { - if (_value.Length > 0) { - return new TagNodeString(_value); + if (Value.Length > 0) + { + return new TagNodeString(Value); } return new TagNodeString(); diff --git a/SubstrateCS/Source/Nbt/SchemaOptions.cs b/Substrate/Source/Nbt/SchemaOptions.cs similarity index 100% rename from SubstrateCS/Source/Nbt/SchemaOptions.cs rename to Substrate/Source/Nbt/SchemaOptions.cs diff --git a/SubstrateCS/Source/Nbt/TagNode.cs b/Substrate/Source/Nbt/TagNode.cs similarity index 100% rename from SubstrateCS/Source/Nbt/TagNode.cs rename to Substrate/Source/Nbt/TagNode.cs diff --git a/Substrate/Source/Nbt/TagNodeAttribute.cs b/Substrate/Source/Nbt/TagNodeAttribute.cs new file mode 100644 index 00000000..7359ffd5 --- /dev/null +++ b/Substrate/Source/Nbt/TagNodeAttribute.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.Nbt +{ + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] + public class TagNodeAttribute : Attribute + { + public string Name { get; set; } + + public TagType TagType { get; set; } + + public bool Optional { get; set; } + + public bool CreateOnMissing { get; set; } + + public int Length { get; set; } = -1; + + public TagNodeAttribute() + { + } + + public TagNodeAttribute(string name) + { + Name = name; + } + } +} diff --git a/SubstrateCS/Source/Nbt/TagNodeByte.cs b/Substrate/Source/Nbt/TagNodeByte.cs similarity index 66% rename from SubstrateCS/Source/Nbt/TagNodeByte.cs rename to Substrate/Source/Nbt/TagNodeByte.cs index ee483ed0..1f7a345c 100644 --- a/SubstrateCS/Source/Nbt/TagNodeByte.cs +++ b/Substrate/Source/Nbt/TagNodeByte.cs @@ -7,13 +7,16 @@ namespace Substrate.Nbt /// public sealed class TagNodeByte : TagNode { - private byte _data = 0; + /// + /// Gets or sets a byte of tag data. + /// + public byte Data { get; set; } = 0; /// /// Converts the node to itself. /// /// A reference to itself. - public override TagNodeByte ToTagByte () + public override TagNodeByte ToTagByte() { return this; } @@ -22,34 +25,34 @@ public override TagNodeByte ToTagByte () /// Converts the node to a new short node. /// /// A short node representing the same data. - public override TagNodeShort ToTagShort () + public override TagNodeShort ToTagShort() { - return new TagNodeShort(_data); + return new TagNodeShort(Data); } /// /// Converts the node to a new int node. /// /// An int node representing the same data. - public override TagNodeInt ToTagInt () + public override TagNodeInt ToTagInt() { - return new TagNodeInt(_data); + return new TagNodeInt(Data); } /// /// Converts the node to a new long node. /// /// A long node representing the same data. - public override TagNodeLong ToTagLong () + public override TagNodeLong ToTagLong() { - return new TagNodeLong(_data); + return new TagNodeLong(Data); } /// /// Gets the tag type of the node. /// /// The TAG_BYTE tag type. - public override TagType GetTagType () + public override TagType GetTagType() { return TagType.TAG_BYTE; } @@ -59,7 +62,7 @@ public override TagType GetTagType () /// /// An NBT tag type. /// Status indicating whether this object could be cast to a node type represented by the given tag type. - public override bool IsCastableTo (TagType type) + public override bool IsCastableTo(TagType type) { return (type == TagType.TAG_BYTE || type == TagType.TAG_SHORT || @@ -68,44 +71,44 @@ public override bool IsCastableTo (TagType type) } /// - /// Gets or sets a byte of tag data. + /// Constructs a new byte node with a data value of 0. /// - public byte Data - { - get { return _data; } - set { _data = value; } - } + public TagNodeByte() { } /// - /// Constructs a new byte node with a data value of 0. + /// Constructs a new byte node. /// - public TagNodeByte () { } + /// The value to set the node's tag data value. + public TagNodeByte(byte d) + { + Data = d; + } /// /// Constructs a new byte node. /// /// The value to set the node's tag data value. - public TagNodeByte (byte d) + public TagNodeByte(bool d) { - _data = d; + Data = d ? (byte)1 : (byte)0; } /// /// Makes a deep copy of the node. /// /// A new byte node representing the same data. - public override TagNode Copy () + public override TagNode Copy() { - return new TagNodeByte(_data); + return new TagNodeByte(Data); } /// /// Gets a string representation of the node's data. /// /// String representation of the node's data. - public override string ToString () + public override string ToString() { - return _data.ToString(); + return Data.ToString(); } /// @@ -113,19 +116,29 @@ public override string ToString () /// /// A byte value. /// A new byte node containing the given value. - public static implicit operator TagNodeByte (byte b) + public static implicit operator TagNodeByte(byte b) { return new TagNodeByte(b); } + /// + /// Converts a byte node to a system bool representing the same value. + /// + /// A byte node. + /// A system bool set to true if the node's data value is non-zero. + public static implicit operator bool(TagNodeByte b) + { + return b.Data != 0; + } + /// /// Converts a byte node to a system byte representing the same value. /// /// A byte node. /// A system byte set to the node's data value. - public static implicit operator byte (TagNodeByte b) + public static implicit operator byte(TagNodeByte b) { - return b._data; + return b.Data; } /// @@ -133,9 +146,9 @@ public static implicit operator byte (TagNodeByte b) /// /// A byte node. /// A system short set to the node's data value. - public static implicit operator short (TagNodeByte b) + public static implicit operator short(TagNodeByte b) { - return b._data; + return b.Data; } /// @@ -143,9 +156,9 @@ public static implicit operator short (TagNodeByte b) /// /// A byte node. /// A system int set to the node's data value. - public static implicit operator int (TagNodeByte b) + public static implicit operator int(TagNodeByte b) { - return b._data; + return b.Data; } /// @@ -153,9 +166,9 @@ public static implicit operator int (TagNodeByte b) /// /// A byte node. /// A system long set to the node's data value. - public static implicit operator long (TagNodeByte b) + public static implicit operator long(TagNodeByte b) { - return b._data; + return b.Data; } } } \ No newline at end of file diff --git a/SubstrateCS/Source/Nbt/TagNodeByteArray.cs b/Substrate/Source/Nbt/TagNodeByteArray.cs similarity index 73% rename from SubstrateCS/Source/Nbt/TagNodeByteArray.cs rename to Substrate/Source/Nbt/TagNodeByteArray.cs index a39347c0..3cb14b0e 100644 --- a/SubstrateCS/Source/Nbt/TagNodeByteArray.cs +++ b/Substrate/Source/Nbt/TagNodeByteArray.cs @@ -7,13 +7,11 @@ namespace Substrate.Nbt /// public sealed class TagNodeByteArray : TagNode { - private byte[] _data = null; - /// /// Converts the node to itself. /// /// A reference to itself. - public override TagNodeByteArray ToTagByteArray () + public override TagNodeByteArray ToTagByteArray() { return this; } @@ -22,50 +20,46 @@ public override TagNodeByteArray ToTagByteArray () /// Gets the tag type of the node. /// /// The TAG_BYTE_ARRAY tag type. - public override TagType GetTagType () + public override TagType GetTagType() { - return TagType.TAG_BYTE_ARRAY; + return TagType.TAG_BYTE_ARRAY; } /// /// Gets or sets a byte array of tag data. /// - public byte[] Data - { - get { return _data; } - set { _data = value; } - } + public byte[] Data { get; set; } /// /// Gets the length of the stored byte array. /// public int Length { - get { return _data.Length; } + get { return Data.Length; } } /// /// Constructs a new byte array node with a null data value. /// - public TagNodeByteArray () { } + public TagNodeByteArray() { } /// /// Constructs a new byte array node. /// /// The value to set the node's tag data value. - public TagNodeByteArray (byte[] d) + public TagNodeByteArray(byte[] d) { - _data = d; + Data = d; } /// /// Makes a deep copy of the node. /// /// A new byte array node representing the same data. - public override TagNode Copy () + public override TagNode Copy() { - byte[] arr = new byte[_data.Length]; - _data.CopyTo(arr, 0); + byte[] arr = new byte[Data.Length]; + Data.CopyTo(arr, 0); return new TagNodeByteArray(arr); } @@ -74,9 +68,9 @@ public override TagNode Copy () /// Gets a string representation of the node's data. /// /// String representation of the node's data. - public override string ToString () + public override string ToString() { - return _data.ToString(); + return Data.ToString(); } /// @@ -86,8 +80,8 @@ public override string ToString () /// The byte value at the given index of the stored byte array. public byte this[int index] { - get { return _data[index]; } - set { _data[index] = value; } + get { return Data[index]; } + set { Data[index] = value; } } /// @@ -95,7 +89,7 @@ public byte this[int index] /// /// A byte array. /// A new byte array node containing the given value. - public static implicit operator TagNodeByteArray (byte[] b) + public static implicit operator TagNodeByteArray(byte[] b) { return new TagNodeByteArray(b); } @@ -107,7 +101,7 @@ public static implicit operator TagNodeByteArray (byte[] b) /// A system byte array set to the node's data. public static implicit operator byte[] (TagNodeByteArray b) { - return b._data; + return b.Data; } } } \ No newline at end of file diff --git a/SubstrateCS/Source/Nbt/TagNodeCompound.cs b/Substrate/Source/Nbt/TagNodeCompound.cs similarity index 100% rename from SubstrateCS/Source/Nbt/TagNodeCompound.cs rename to Substrate/Source/Nbt/TagNodeCompound.cs diff --git a/SubstrateCS/Source/Nbt/TagNodeDouble.cs b/Substrate/Source/Nbt/TagNodeDouble.cs similarity index 71% rename from SubstrateCS/Source/Nbt/TagNodeDouble.cs rename to Substrate/Source/Nbt/TagNodeDouble.cs index 8cdbbb37..b2ffd89d 100644 --- a/SubstrateCS/Source/Nbt/TagNodeDouble.cs +++ b/Substrate/Source/Nbt/TagNodeDouble.cs @@ -7,65 +7,59 @@ namespace Substrate.Nbt /// public sealed class TagNodeDouble : TagNode { - private double _data = 0; - /// /// Converts the node to itself. /// /// A reference to itself. - public override TagNodeDouble ToTagDouble () + public override TagNodeDouble ToTagDouble() { - return this; + return this; } /// /// Gets the tag type of the node. /// /// The TAG_DOUBLE tag type. - public override TagType GetTagType () + public override TagType GetTagType() { - return TagType.TAG_DOUBLE; + return TagType.TAG_DOUBLE; } /// /// Gets or sets a double of tag data. /// - public double Data - { - get { return _data; } - set { _data = value; } - } + public double Data { get; set; } /// /// Constructs a new double node with a data value of 0.0. /// - public TagNodeDouble () { } + public TagNodeDouble() { } /// /// Constructs a new double node. /// /// The value to set the node's tag data value. - public TagNodeDouble (double d) + public TagNodeDouble(double d) { - _data = d; + Data = d; } /// /// Makes a deep copy of the node. /// /// A new double node representing the same data. - public override TagNode Copy () + public override TagNode Copy() { - return new TagNodeDouble(_data); + return new TagNodeDouble(Data); } /// /// Gets a string representation of the node's data. /// /// String representation of the node's data. - public override string ToString () + public override string ToString() { - return _data.ToString(); + return Data.ToString(); } /// @@ -73,7 +67,7 @@ public override string ToString () /// /// A float value. /// A new double node containing the given value. - public static implicit operator TagNodeDouble (float f) + public static implicit operator TagNodeDouble(float f) { return new TagNodeDouble(f); } @@ -83,7 +77,7 @@ public static implicit operator TagNodeDouble (float f) /// /// A double value. /// A new double node containing the given value. - public static implicit operator TagNodeDouble (double d) + public static implicit operator TagNodeDouble(double d) { return new TagNodeDouble(d); } @@ -93,9 +87,9 @@ public static implicit operator TagNodeDouble (double d) /// /// A double node. /// A system double set to the node's data value. - public static implicit operator double (TagNodeDouble d) + public static implicit operator double(TagNodeDouble d) { - return d._data; + return d.Data; } } } \ No newline at end of file diff --git a/SubstrateCS/Source/Nbt/TagNodeFloat.cs b/Substrate/Source/Nbt/TagNodeFloat.cs similarity index 71% rename from SubstrateCS/Source/Nbt/TagNodeFloat.cs rename to Substrate/Source/Nbt/TagNodeFloat.cs index bce9c202..f56be36a 100644 --- a/SubstrateCS/Source/Nbt/TagNodeFloat.cs +++ b/Substrate/Source/Nbt/TagNodeFloat.cs @@ -7,33 +7,31 @@ namespace Substrate.Nbt /// public sealed class TagNodeFloat : TagNode { - private float _data = 0; - /// /// Converts the node to itself. /// /// A reference to itself. - public override TagNodeFloat ToTagFloat () - { - return this; + public override TagNodeFloat ToTagFloat() + { + return this; } /// /// Converts the node to a new double node. /// /// A double node representing the same data. - public override TagNodeDouble ToTagDouble () - { - return new TagNodeDouble(_data); + public override TagNodeDouble ToTagDouble() + { + return new TagNodeDouble(Data); } /// /// Gets the tag type of the node. /// /// The TAG_FLOAT tag type. - public override TagType GetTagType () - { - return TagType.TAG_FLOAT; + public override TagType GetTagType() + { + return TagType.TAG_FLOAT; } /// @@ -41,7 +39,7 @@ public override TagType GetTagType () /// /// An NBT tag type. /// Status indicating whether this object could be cast to a node type represented by the given tag type. - public override bool IsCastableTo (TagType type) + public override bool IsCastableTo(TagType type) { return (type == TagType.TAG_FLOAT || type == TagType.TAG_DOUBLE); @@ -50,42 +48,38 @@ public override bool IsCastableTo (TagType type) /// /// Gets or sets a float of tag data. /// - public float Data - { - get { return _data; } - set { _data = value; } - } + public float Data { get; set; } /// /// Constructs a new float node with a data value of 0.0. /// - public TagNodeFloat () { } + public TagNodeFloat() { } /// /// Constructs a new float node. /// /// The value to set the node's tag data value. - public TagNodeFloat (float d) + public TagNodeFloat(float d) { - _data = d; + Data = d; } /// /// Makes a deep copy of the node. /// /// A new float node representing the same data. - public override TagNode Copy () + public override TagNode Copy() { - return new TagNodeFloat(_data); + return new TagNodeFloat(Data); } /// /// Gets a string representation of the node's data. /// /// String representation of the node's data. - public override string ToString () + public override string ToString() { - return _data.ToString(); + return Data.ToString(); } /// @@ -93,7 +87,7 @@ public override string ToString () /// /// A float value. /// A new float node containing the given value. - public static implicit operator TagNodeFloat (float f) + public static implicit operator TagNodeFloat(float f) { return new TagNodeFloat(f); } @@ -103,9 +97,9 @@ public static implicit operator TagNodeFloat (float f) /// /// A float node. /// A system float set to the node's data value. - public static implicit operator float (TagNodeFloat f) + public static implicit operator float(TagNodeFloat f) { - return f._data; + return f.Data; } /// @@ -113,9 +107,9 @@ public static implicit operator float (TagNodeFloat f) /// /// A float node. /// A system double set to the node's data value. - public static implicit operator double (TagNodeFloat f) + public static implicit operator double(TagNodeFloat f) { - return f._data; + return f.Data; } } } \ No newline at end of file diff --git a/SubstrateCS/Source/Nbt/TagNodeInt.cs b/Substrate/Source/Nbt/TagNodeInt.cs similarity index 74% rename from SubstrateCS/Source/Nbt/TagNodeInt.cs rename to Substrate/Source/Nbt/TagNodeInt.cs index a1bbbccb..2d16aa2a 100644 --- a/SubstrateCS/Source/Nbt/TagNodeInt.cs +++ b/Substrate/Source/Nbt/TagNodeInt.cs @@ -7,14 +7,12 @@ namespace Substrate.Nbt /// public sealed class TagNodeInt : TagNode { - private int _data = 0; - /// /// Converts the node to itself. /// /// A reference to itself. - public override TagNodeInt ToTagInt () - { + public override TagNodeInt ToTagInt() + { return this; } @@ -22,16 +20,16 @@ public override TagNodeInt ToTagInt () /// Converts the node to a new long node. /// /// A long node representing the same data. - public override TagNodeLong ToTagLong () - { - return new TagNodeLong(_data); + public override TagNodeLong ToTagLong() + { + return new TagNodeLong(Data); } /// /// Gets the tag type of the node. /// /// The TAG_INT tag type. - public override TagType GetTagType () + public override TagType GetTagType() { return TagType.TAG_INT; } @@ -41,7 +39,7 @@ public override TagType GetTagType () /// /// An NBT tag type. /// Status indicating whether this object could be cast to a node type represented by the given tag type. - public override bool IsCastableTo (TagType type) + public override bool IsCastableTo(TagType type) { return (type == TagType.TAG_INT || type == TagType.TAG_LONG); @@ -50,42 +48,38 @@ public override bool IsCastableTo (TagType type) /// /// Gets or sets an int of tag data. /// - public int Data - { - get { return _data; } - set { _data = value; } - } + public int Data { get; set; } /// /// Constructs a new int node with a data value of 0. /// - public TagNodeInt () { } + public TagNodeInt() { } /// /// Constructs a new int node. /// /// The value to set the node's tag data value. - public TagNodeInt (int d) + public TagNodeInt(int d) { - _data = d; + Data = d; } /// /// Makes a deep copy of the node. /// /// A new int node representing the same data. - public override TagNode Copy () + public override TagNode Copy() { - return new TagNodeInt(_data); + return new TagNodeInt(Data); } /// /// Gets a string representation of the node's data. /// /// String representation of the node's data. - public override string ToString () + public override string ToString() { - return _data.ToString(); + return Data.ToString(); } /// @@ -93,7 +87,7 @@ public override string ToString () /// /// A byte value. /// A new int node containing the given value. - public static implicit operator TagNodeInt (byte b) + public static implicit operator TagNodeInt(byte b) { return new TagNodeInt(b); } @@ -103,7 +97,7 @@ public static implicit operator TagNodeInt (byte b) /// /// A short value. /// A new int node containing the given value. - public static implicit operator TagNodeInt (short s) + public static implicit operator TagNodeInt(short s) { return new TagNodeInt(s); } @@ -113,7 +107,7 @@ public static implicit operator TagNodeInt (short s) /// /// An int value. /// A new int node containing the given value. - public static implicit operator TagNodeInt (int i) + public static implicit operator TagNodeInt(int i) { return new TagNodeInt(i); } @@ -123,9 +117,9 @@ public static implicit operator TagNodeInt (int i) /// /// An int node. /// A system int set to the node's data value. - public static implicit operator int (TagNodeInt i) + public static implicit operator int(TagNodeInt i) { - return i._data; + return i.Data; } /// @@ -133,9 +127,9 @@ public static implicit operator int (TagNodeInt i) /// /// An int node. /// A system long set to the node's data value. - public static implicit operator long (TagNodeInt i) + public static implicit operator long(TagNodeInt i) { - return i._data; + return i.Data; } } } \ No newline at end of file diff --git a/SubstrateCS/Source/Nbt/TagNodeIntArray.cs b/Substrate/Source/Nbt/TagNodeIntArray.cs similarity index 75% rename from SubstrateCS/Source/Nbt/TagNodeIntArray.cs rename to Substrate/Source/Nbt/TagNodeIntArray.cs index c44c171f..5ac450ad 100644 --- a/SubstrateCS/Source/Nbt/TagNodeIntArray.cs +++ b/Substrate/Source/Nbt/TagNodeIntArray.cs @@ -6,13 +6,11 @@ namespace Substrate.Nbt { public sealed class TagNodeIntArray : TagNode { - private int[] _data = null; - /// /// Converts the node to itself. /// /// A reference to itself. - public override TagNodeIntArray ToTagIntArray () + public override TagNodeIntArray ToTagIntArray() { return this; } @@ -21,50 +19,46 @@ public override TagNodeIntArray ToTagIntArray () /// Gets the tag type of the node. /// /// The TAG_INT_ARRAY tag type. - public override TagType GetTagType () + public override TagType GetTagType() { - return TagType.TAG_INT_ARRAY; + return TagType.TAG_INT_ARRAY; } /// /// Gets or sets an int array of tag data. /// - public int[] Data - { - get { return _data; } - set { _data = value; } - } + public int[] Data { get; set; } /// /// Gets the length of the stored byte array. /// public int Length { - get { return _data.Length; } + get { return Data.Length; } } /// /// Constructs a new byte array node with a null data value. /// - public TagNodeIntArray () { } + public TagNodeIntArray() { } /// /// Constructs a new byte array node. /// /// The value to set the node's tag data value. - public TagNodeIntArray (int[] d) + public TagNodeIntArray(int[] d) { - _data = d; + Data = d; } /// /// Makes a deep copy of the node. /// /// A new int array node representing the same data. - public override TagNode Copy () + public override TagNode Copy() { - int[] arr = new int[_data.Length]; - _data.CopyTo(arr, 0); + int[] arr = new int[Data.Length]; + Data.CopyTo(arr, 0); return new TagNodeIntArray(arr); } @@ -73,9 +67,9 @@ public override TagNode Copy () /// Gets a string representation of the node's data. /// /// String representation of the node's data. - public override string ToString () + public override string ToString() { - return _data.ToString(); + return Data.ToString(); } /// @@ -85,8 +79,8 @@ public override string ToString () /// The int value at the given index of the stored byte array. public int this[int index] { - get { return _data[index]; } - set { _data[index] = value; } + get { return Data[index]; } + set { Data[index] = value; } } /// @@ -94,7 +88,7 @@ public int this[int index] /// /// A int array. /// A new int array node containing the given value. - public static implicit operator TagNodeIntArray (int[] i) + public static implicit operator TagNodeIntArray(int[] i) { return new TagNodeIntArray(i); } @@ -106,7 +100,7 @@ public static implicit operator TagNodeIntArray (int[] i) /// A system int array set to the node's data. public static implicit operator int[] (TagNodeIntArray i) { - return i._data; + return i.Data; } } } diff --git a/SubstrateCS/Source/Nbt/TagNodeList.cs b/Substrate/Source/Nbt/TagNodeList.cs similarity index 83% rename from SubstrateCS/Source/Nbt/TagNodeList.cs rename to Substrate/Source/Nbt/TagNodeList.cs index b227cb8a..8782b1f6 100644 --- a/SubstrateCS/Source/Nbt/TagNodeList.cs +++ b/Substrate/Source/Nbt/TagNodeList.cs @@ -12,15 +12,13 @@ namespace Substrate.Nbt /// public sealed class TagNodeList : TagNode, IList { - private TagType _type = TagType.TAG_END; - private List _items = null; /// /// Converts the node to itself. /// /// A reference to itself. - public override TagNodeList ToTagList () + public override TagNodeList ToTagList() { return this; } @@ -29,9 +27,9 @@ public override TagNodeList ToTagList () /// Gets the tag type of the node. /// /// The TAG_STRING tag type. - public override TagType GetTagType () - { - return TagType.TAG_LIST; + public override TagType GetTagType() + { + return TagType.TAG_LIST; } /// @@ -47,16 +45,16 @@ public int Count /// public TagType ValueType { - get { return _type; } + get; private set; } /// /// Constructs a new empty list node. /// /// The tag type of the list's subnodes. - public TagNodeList (TagType type) + public TagNodeList(TagType type) { - _type = type; + ValueType = type; _items = new List(); } @@ -65,9 +63,9 @@ public TagNodeList (TagType type) /// /// The tag type of the list's subnodes. /// A list containing node objects matching the type parameter. - public TagNodeList (TagType type, List items) + public TagNodeList(TagType type, List items) { - _type = type; + ValueType = type; _items = items; } @@ -75,10 +73,11 @@ public TagNodeList (TagType type, List items) /// Makes a deep copy of the node. /// /// A new list node containing new subnodes representing the same data. - public override TagNode Copy () + public override TagNode Copy() { - TagNodeList list = new TagNodeList(_type); - foreach (TagNode item in _items) { + TagNodeList list = new TagNodeList(ValueType); + foreach (TagNode item in _items) + { list.Add(item.Copy()); } return list; @@ -89,7 +88,7 @@ public override TagNode Copy () /// /// The delegate that defines the conditions of the subnode to search for. /// The first subnode matching the predicate. - public TagNode Find (Predicate match) + public TagNode Find(Predicate match) { return _items.Find(match); } @@ -99,7 +98,7 @@ public TagNode Find (Predicate match) /// /// The delegate that defines the conditions of the subnode to search for. /// A list of all subnodes matching the predicate. - public List FindAll (Predicate match) + public List FindAll(Predicate match) { return _items.FindAll(match); } @@ -109,7 +108,7 @@ public List FindAll (Predicate match) /// /// The delegate that defines the conditions of the subnode to search for. /// The number of subnodes removed from the node. - public int RemoveAll (Predicate match) + public int RemoveAll(Predicate match) { return _items.RemoveAll(match); } @@ -117,7 +116,7 @@ public int RemoveAll (Predicate match) /// /// Reverses the order of all the subnodes in the list. /// - public void Reverse () + public void Reverse() { _items.Reverse(); } @@ -130,7 +129,7 @@ public void Reverse () /// is less than 0.-or- /// is less than 0. /// and do not denote a valid range of elements in the list. - public void Reverse (int index, int count) + public void Reverse(int index, int count) { _items.Reverse(index, count); } @@ -138,7 +137,7 @@ public void Reverse (int index, int count) /// /// Sorts all the subnodes in the list using the default comparator /// - public void Sort () + public void Sort() { _items.Sort(); } @@ -147,7 +146,7 @@ public void Sort () /// Gets a string representation of the node's data. /// /// String representation of the node's data. - public override string ToString () + public override string ToString() { return _items.ToString(); } @@ -156,13 +155,13 @@ public override string ToString () /// Resets and changes the storage type of the list. /// /// The new tag type to store in the list. - public void ChangeValueType (TagType type) + public void ChangeValueType(TagType type) { - if (type == _type) + if (type == ValueType) return; _items.Clear(); - _type = type; + ValueType = type; } #region IList Members @@ -172,7 +171,7 @@ public void ChangeValueType (TagType type) /// /// The subnode to locate. /// The zero-based index of the subnode within the node's list if found, or -1 otherwise. - public int IndexOf (TagNode item) + public int IndexOf(TagNode item) { return _items.IndexOf(item); } @@ -183,9 +182,10 @@ public int IndexOf (TagNode item) /// The zero-based index at which the subnode should be inserted. /// The subnode to insert. /// Thrown when a subnode being inserted has the wrong tag type. - public void Insert (int index, TagNode item) + public void Insert(int index, TagNode item) { - if (item.GetTagType() != _type) { + if (item.GetTagType() != ValueType) + { throw new ArgumentException("The tag type of item is invalid for this node"); } _items.Insert(index, item); @@ -195,7 +195,7 @@ public void Insert (int index, TagNode item) /// Removes the subnode from the node's list at the specified index. /// /// The zero-based index to remove a subnode at. - public void RemoveAt (int index) + public void RemoveAt(int index) { _items.RemoveAt(index); } @@ -214,7 +214,8 @@ public TagNode this[int index] } set { - if (value.GetTagType() != _type) { + if (value.GetTagType() != ValueType) + { throw new ArgumentException("The tag type of the assigned subnode is invalid for this node"); } _items[index] = value; @@ -230,9 +231,10 @@ public TagNode this[int index] /// /// The subnode to add. /// Thrown when a subnode being added has the wrong tag type. - public void Add (TagNode item) + public void Add(TagNode item) { - if (item.GetTagType() != _type) { + if (item.GetTagType() != ValueType) + { throw new ArgumentException("The tag type of item is invalid for this node"); } @@ -242,7 +244,7 @@ public void Add (TagNode item) /// /// Removes all subnode's from the node's list. /// - public void Clear () + public void Clear() { _items.Clear(); } @@ -252,7 +254,7 @@ public void Clear () /// /// The subnode to check for existance. /// Status indicating if the subnode exists in the node's list. - public bool Contains (TagNode item) + public bool Contains(TagNode item) { return _items.Contains(item); } @@ -262,7 +264,7 @@ public bool Contains (TagNode item) /// /// The one-dimensional that is the destination of the subnodes copied. The Array must have zero-based indexing. /// The zero-based index in at which copying begins. - public void CopyTo (TagNode[] array, int arrayIndex) + public void CopyTo(TagNode[] array, int arrayIndex) { _items.CopyTo(array, arrayIndex); } @@ -280,7 +282,7 @@ public bool IsReadOnly /// /// The subnode to remove. /// Status indicating whether a subnode was removed. - public bool Remove (TagNode item) + public bool Remove(TagNode item) { return _items.Remove(item); } @@ -293,7 +295,7 @@ public bool Remove (TagNode item) /// Returns an enumerator that iterates through all of the subnodes in the node's list. /// /// An enumerator for this node. - public IEnumerator GetEnumerator () + public IEnumerator GetEnumerator() { return _items.GetEnumerator(); } @@ -306,7 +308,7 @@ public IEnumerator GetEnumerator () /// Returns an enumerator that iterates through all of the subnodes in the node's list. /// /// An enumerator for this node. - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return _items.GetEnumerator(); } diff --git a/SubstrateCS/Source/Nbt/TagNodeLong.cs b/Substrate/Source/Nbt/TagNodeLong.cs similarity index 74% rename from SubstrateCS/Source/Nbt/TagNodeLong.cs rename to Substrate/Source/Nbt/TagNodeLong.cs index 5d6bad3d..9e2fb4fd 100644 --- a/SubstrateCS/Source/Nbt/TagNodeLong.cs +++ b/Substrate/Source/Nbt/TagNodeLong.cs @@ -7,13 +7,11 @@ namespace Substrate.Nbt /// public sealed class TagNodeLong : TagNode { - private long _data = 0; - /// /// Converts the node to itself. /// /// A reference to itself. - public override TagNodeLong ToTagLong () + public override TagNodeLong ToTagLong() { return this; } @@ -22,50 +20,46 @@ public override TagNodeLong ToTagLong () /// Gets the tag type of the node. /// /// The TAG_LONG tag type. - public override TagType GetTagType () - { + public override TagType GetTagType() + { return TagType.TAG_LONG; } /// /// Gets or sets a long of tag data. /// - public long Data - { - get { return _data; } - set { _data = value; } - } + public long Data { get; set; } /// /// Constructs a new long node with a data value of 0. /// - public TagNodeLong () { } + public TagNodeLong() { } /// /// Constructs a new long node. /// /// The value to set the node's tag data value. - public TagNodeLong (long d) + public TagNodeLong(long d) { - _data = d; + Data = d; } /// /// Makes a deep copy of the node. /// /// A new long node representing the same data. - public override TagNode Copy () + public override TagNode Copy() { - return new TagNodeLong(_data); + return new TagNodeLong(Data); } /// /// Gets a string representation of the node's data. /// /// String representation of the node's data. - public override string ToString () + public override string ToString() { - return _data.ToString(); + return Data.ToString(); } /// @@ -73,7 +67,7 @@ public override string ToString () /// /// A byte value. /// A new long node containing the given value. - public static implicit operator TagNodeLong (byte b) + public static implicit operator TagNodeLong(byte b) { return new TagNodeLong(b); } @@ -83,7 +77,7 @@ public static implicit operator TagNodeLong (byte b) /// /// A short value. /// A new long node containing the given value. - public static implicit operator TagNodeLong (short s) + public static implicit operator TagNodeLong(short s) { return new TagNodeLong(s); } @@ -93,7 +87,7 @@ public static implicit operator TagNodeLong (short s) /// /// An int value. /// A new long node containing the given value. - public static implicit operator TagNodeLong (int i) + public static implicit operator TagNodeLong(int i) { return new TagNodeLong(i); } @@ -103,7 +97,7 @@ public static implicit operator TagNodeLong (int i) /// /// A long value. /// A new long node containing the given value. - public static implicit operator TagNodeLong (long l) + public static implicit operator TagNodeLong(long l) { return new TagNodeLong(l); } @@ -113,9 +107,9 @@ public static implicit operator TagNodeLong (long l) /// /// A long node. /// A system long set to the node's data value. - public static implicit operator long (TagNodeLong l) + public static implicit operator long(TagNodeLong l) { - return l._data; + return l.Data; } } } \ No newline at end of file diff --git a/SubstrateCS/Source/Nbt/TagNodeLongArray.cs b/Substrate/Source/Nbt/TagNodeLongArray.cs similarity index 100% rename from SubstrateCS/Source/Nbt/TagNodeLongArray.cs rename to Substrate/Source/Nbt/TagNodeLongArray.cs diff --git a/SubstrateCS/Source/Nbt/TagNodeNull.cs b/Substrate/Source/Nbt/TagNodeNull.cs similarity index 77% rename from SubstrateCS/Source/Nbt/TagNodeNull.cs rename to Substrate/Source/Nbt/TagNodeNull.cs index bc1b4965..3b563c9f 100644 --- a/SubstrateCS/Source/Nbt/TagNodeNull.cs +++ b/Substrate/Source/Nbt/TagNodeNull.cs @@ -1,6 +1,4 @@ -using System; - -namespace Substrate.Nbt +namespace Substrate.Nbt { /// /// An NBT node representing a null tag type. @@ -11,7 +9,7 @@ public sealed class TagNodeNull : TagNode /// Converts the node to itself. /// /// A reference to itself. - public override TagNodeNull ToTagNull () + public override TagNodeNull ToTagNull() { return this; } @@ -20,7 +18,7 @@ public override TagNodeNull ToTagNull () /// Gets the tag type of the node. /// /// The TAG_END tag type. - public override TagType GetTagType () + public override TagType GetTagType() { return TagType.TAG_END; } @@ -29,7 +27,7 @@ public override TagType GetTagType () /// Makes a deep copy of the node. /// /// A new null node. - public override TagNode Copy () + public override TagNode Copy() { return new TagNodeNull(); } diff --git a/SubstrateCS/Source/Nbt/TagNodeShort.cs b/Substrate/Source/Nbt/TagNodeShort.cs similarity index 86% rename from SubstrateCS/Source/Nbt/TagNodeShort.cs rename to Substrate/Source/Nbt/TagNodeShort.cs index 27f4350b..c17661c5 100644 --- a/SubstrateCS/Source/Nbt/TagNodeShort.cs +++ b/Substrate/Source/Nbt/TagNodeShort.cs @@ -7,15 +7,13 @@ namespace Substrate.Nbt /// public sealed class TagNodeShort : TagNode { - private short _data = 0; - /// /// Converts the node to itself. /// /// A reference to itself. public override TagNodeShort ToTagShort() - { - return this; + { + return this; } /// @@ -23,8 +21,8 @@ public override TagNodeShort ToTagShort() /// /// An int node representing the same data. public override TagNodeInt ToTagInt() - { - return new TagNodeInt(_data); + { + return new TagNodeInt(Data); } /// @@ -32,8 +30,8 @@ public override TagNodeInt ToTagInt() /// /// A long node representing the same data. public override TagNodeLong ToTagLong() - { - return new TagNodeLong(_data); + { + return new TagNodeLong(Data); } /// @@ -42,7 +40,7 @@ public override TagNodeLong ToTagLong() /// A float node representing the same data. public override TagNodeFloat ToTagFloat() { - return new TagNodeFloat(_data); + return new TagNodeFloat(Data); } /// @@ -51,7 +49,7 @@ public override TagNodeFloat ToTagFloat() /// A double node representing the same data. public override TagNodeDouble ToTagDouble() { - return new TagNodeDouble(_data); + return new TagNodeDouble(Data); } /// @@ -59,7 +57,7 @@ public override TagNodeDouble ToTagDouble() /// /// The TAG_SHORT tag type. public override TagType GetTagType() - { + { return TagType.TAG_SHORT; } @@ -80,11 +78,7 @@ public override bool IsCastableTo(TagType type) /// /// Gets or sets a short of tag data. /// - public short Data - { - get { return _data; } - set { _data = value; } - } + public short Data { get; set; } /// /// Constructs a new short node with a data value of 0. @@ -97,7 +91,7 @@ public TagNodeShort() { } /// The value to set the node's tag data value. public TagNodeShort(short d) { - _data = d; + Data = d; } /// @@ -106,7 +100,7 @@ public TagNodeShort(short d) /// A new short node representing the same data. public override TagNode Copy() { - return new TagNodeShort(_data); + return new TagNodeShort(Data); } /// @@ -115,7 +109,7 @@ public override TagNode Copy() /// String representation of the node's data. public override string ToString() { - return _data.ToString(); + return Data.ToString(); } /// @@ -145,7 +139,7 @@ public static implicit operator TagNodeShort(short s) /// A system short set to the node's data value. public static implicit operator short(TagNodeShort s) { - return s._data; + return s.Data; } /// @@ -155,7 +149,7 @@ public static implicit operator short(TagNodeShort s) /// A system int set to the node's data value. public static implicit operator int(TagNodeShort s) { - return s._data; + return s.Data; } /// @@ -165,7 +159,7 @@ public static implicit operator int(TagNodeShort s) /// A system long set to the node's data value. public static implicit operator long(TagNodeShort s) { - return s._data; + return s.Data; } } } \ No newline at end of file diff --git a/SubstrateCS/Source/Nbt/TagNodeShortArray.cs b/Substrate/Source/Nbt/TagNodeShortArray.cs similarity index 76% rename from SubstrateCS/Source/Nbt/TagNodeShortArray.cs rename to Substrate/Source/Nbt/TagNodeShortArray.cs index 54a9b260..600eda78 100644 --- a/SubstrateCS/Source/Nbt/TagNodeShortArray.cs +++ b/Substrate/Source/Nbt/TagNodeShortArray.cs @@ -6,13 +6,11 @@ namespace Substrate.Nbt { public sealed class TagNodeShortArray : TagNode { - private short[] _data = null; - /// /// Converts the node to itself. /// /// A reference to itself. - public override TagNodeShortArray ToTagShortArray () + public override TagNodeShortArray ToTagShortArray() { return this; } @@ -21,7 +19,7 @@ public override TagNodeShortArray ToTagShortArray () /// Gets the tag type of the node. /// /// The TAG_SHORT_ARRAY tag type. - public override TagType GetTagType () + public override TagType GetTagType() { return TagType.TAG_SHORT_ARRAY; } @@ -29,42 +27,38 @@ public override TagType GetTagType () /// /// Gets or sets an short array of tag data. /// - public short[] Data - { - get { return _data; } - set { _data = value; } - } + public short[] Data { get; set; } /// /// Gets the length of the stored short array. /// public int Length { - get { return _data.Length; } + get { return Data.Length; } } /// /// Constructs a new short array node with a null data value. /// - public TagNodeShortArray () { } + public TagNodeShortArray() { } /// /// Constructs a new short array node. /// /// The value to set the node's tag data value. - public TagNodeShortArray (short[] d) + public TagNodeShortArray(short[] d) { - _data = d; + Data = d; } /// /// Makes a deep copy of the node. /// /// A new int array node representing the same data. - public override TagNode Copy () + public override TagNode Copy() { - short[] arr = new short[_data.Length]; - _data.CopyTo(arr, 0); + short[] arr = new short[Data.Length]; + Data.CopyTo(arr, 0); return new TagNodeShortArray(arr); } @@ -73,9 +67,9 @@ public override TagNode Copy () /// Gets a string representation of the node's data. /// /// String representation of the node's data. - public override string ToString () + public override string ToString() { - return _data.ToString(); + return Data.ToString(); } /// @@ -85,8 +79,8 @@ public override string ToString () /// The short value at the given index of the stored short array. public short this[int index] { - get { return _data[index]; } - set { _data[index] = value; } + get { return Data[index]; } + set { Data[index] = value; } } /// @@ -94,7 +88,7 @@ public short this[int index] /// /// A short array. /// A new short array node containing the given value. - public static implicit operator TagNodeShortArray (short[] i) + public static implicit operator TagNodeShortArray(short[] i) { return new TagNodeShortArray(i); } @@ -106,7 +100,7 @@ public static implicit operator TagNodeShortArray (short[] i) /// A system short array set to the node's data. public static implicit operator short[] (TagNodeShortArray i) { - return i._data; + return i.Data; } } } diff --git a/SubstrateCS/Source/Nbt/TagNodeString.cs b/Substrate/Source/Nbt/TagNodeString.cs similarity index 69% rename from SubstrateCS/Source/Nbt/TagNodeString.cs rename to Substrate/Source/Nbt/TagNodeString.cs index 7c075b25..fc072585 100644 --- a/SubstrateCS/Source/Nbt/TagNodeString.cs +++ b/Substrate/Source/Nbt/TagNodeString.cs @@ -7,75 +7,67 @@ namespace Substrate.Nbt /// public sealed class TagNodeString : TagNode { - private string _data = ""; - /// /// Converts the node to itself. /// /// A reference to itself. - public override TagNodeString ToTagString () + public override TagNodeString ToTagString() { - return this; + return this; } /// /// Gets the tag type of the node. /// /// The TAG_STRING tag type. - public override TagType GetTagType () - { + public override TagType GetTagType() + { return TagType.TAG_STRING; } /// /// Gets or sets a string of tag data. /// - public string Data - { - get { return _data; } - set { _data = value; } - } + public string Data { get; set; } = ""; /// /// Gets the length of the stored string. /// public int Length { - get { return _data.Length; } + get { return Data.Length; } } /// /// Constructs a new byte array node with an empty string. /// - public TagNodeString () { } + public TagNodeString() { } /// /// Constructs a new string node. /// /// The value to set the node's tag data value. - public TagNodeString (string d) + public TagNodeString(string d) { - _data = d; - if (_data == null) - _data = ""; + Data = d ?? ""; } /// /// Makes a deep copy of the node. /// /// A new string node representing the same data. - public override TagNode Copy () + public override TagNode Copy() { - return new TagNodeString(_data); + return new TagNodeString(Data); } /// /// Gets a string representation of the node's data. /// /// String representation of the node's data. - public override string ToString () + public override string ToString() { - return _data.ToString(); + return Data.ToString(); } /// @@ -83,7 +75,7 @@ public override string ToString () /// /// A string. /// A new string node containing the given value. - public static implicit operator TagNodeString (string s) + public static implicit operator TagNodeString(string s) { return new TagNodeString(s); } @@ -93,9 +85,9 @@ public static implicit operator TagNodeString (string s) /// /// A string node. /// A system string set to the node's data. - public static implicit operator string (TagNodeString s) + public static implicit operator string(TagNodeString s) { - return s._data; + return s.Data; } } } \ No newline at end of file diff --git a/Substrate/Source/Nbt/TagNodeTypeAttribute.cs b/Substrate/Source/Nbt/TagNodeTypeAttribute.cs new file mode 100644 index 00000000..b3da87f7 --- /dev/null +++ b/Substrate/Source/Nbt/TagNodeTypeAttribute.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.Nbt +{ + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] + public class TagNodeTypeAttribute : Attribute + { + public TagType TagType { get; set; } = TagType.TAG_END; + + public TagType ListItemTagType { get; set; } = TagType.TAG_END; + + public Type ListItemType { get; set; } + + public TagNodeTypeAttribute(TagType tagType) + { + TagType = tagType; + } + } +} diff --git a/SubstrateCS/Source/Nbt/TagType.cs b/Substrate/Source/Nbt/TagType.cs similarity index 100% rename from SubstrateCS/Source/Nbt/TagType.cs rename to Substrate/Source/Nbt/TagType.cs diff --git a/SubstrateCS/Source/Nbt/VerifierLogger.cs b/Substrate/Source/Nbt/VerifierLogger.cs similarity index 100% rename from SubstrateCS/Source/Nbt/VerifierLogger.cs rename to Substrate/Source/Nbt/VerifierLogger.cs diff --git a/SubstrateCS/Source/NbtWorld.cs b/Substrate/Source/NbtWorld.cs similarity index 100% rename from SubstrateCS/Source/NbtWorld.cs rename to Substrate/Source/NbtWorld.cs diff --git a/Substrate/Source/Orientation.cs b/Substrate/Source/Orientation.cs new file mode 100644 index 00000000..f7e0a348 --- /dev/null +++ b/Substrate/Source/Orientation.cs @@ -0,0 +1,28 @@ +using System; +using Substrate.Nbt; + +namespace Substrate +{ + [TagNodeType(TagType.TAG_LIST, ListItemTagType = TagType.TAG_DOUBLE)] + public class Orientation : INbtObject2 + { + public double Pitch { get; set; } + + public double Yaw { get; set; } + + public TagNode BuildTree() + { + var list = new TagNodeList(TagType.TAG_DOUBLE); + list.Add(new TagNodeDouble(Yaw)); + list.Add(new TagNodeDouble(Pitch)); + return list; + } + + public void LoadTree(TagNode tree) + { + var list = tree.ToTagList(); + Yaw = list[0].ToTagDouble(); + Pitch = list[1].ToTagDouble(); + } + } +} diff --git a/Substrate/Source/Player.cs b/Substrate/Source/Player.cs new file mode 100644 index 00000000..57d99158 --- /dev/null +++ b/Substrate/Source/Player.cs @@ -0,0 +1,601 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Substrate.Core; +using Substrate.Nbt; + +namespace Substrate +{ + /// + /// Encompases data to specify player abilities, especially mode-dependent abilities. + /// + /// Whether or not any of these values are respected by the game client is dependent upon the active game mode. + public class PlayerAbilities : ICopyable + { + /// + /// Gets or sets whether the player is currently flying. + /// + [TagNode("flying")] + public bool Flying { get; set; } + + /// + /// Gets or sets whether the player can instantly build or mine. + /// + [TagNode("instabuild")] + public bool InstantBuild { get; set; } + + /// + /// Gets or sets whether the player is allowed to fly. + /// + [TagNode("mayfly")] + public bool MayFly { get; set; } + + /// + /// Gets or sets whether the player can take damage. + /// + [TagNode("invulnerable")] + public bool Invulnerable { get; set; } + + /// + /// Gets or sets whether the player can create or destroy blocks. + /// + [TagNode("mayBuild")] + public bool? MayBuild { get; set; } + + /// + /// Gets or sets the player's flying speed. Always 0.05. + /// + [TagNode("walkSpeed")] + public float? WalkSpeed { get; set; } = 0.05f; + + /// + /// Gets or sets the player's walking speed. Always 0.1. + /// + [TagNode("flySpeed")] + public float? FlySpeed { get; set; } = 0.1f; + + #region ICopyable Members + + /// + public PlayerAbilities Copy() + { + PlayerAbilities pa = new PlayerAbilities + { + Flying = Flying, + InstantBuild = InstantBuild, + MayFly = MayFly, + Invulnerable = Invulnerable, + MayBuild = MayBuild, + WalkSpeed = WalkSpeed, + FlySpeed = FlySpeed, + }; + return pa; + } + + #endregion + } + + public enum PlayerGameType + { + Survival = 0, + Creative = 1, + Adventure = 2, + } + + /// + /// Represents a Player from either single- or multi-player Minecraft. + /// + /// Unlike objects, objects do not need to be added to chunks. They + /// are stored individually or within level data. + public class Player : Entity, INbtObject, ICopyable, IItemContainer + { + private static readonly SchemaNodeCompound _schema = Entity.Schema.MergeInto(new SchemaNodeCompound("") + { + new SchemaNodeScalar("AttackTime", TagType.TAG_SHORT, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeScalar("DeathTime", TagType.TAG_SHORT), + new SchemaNodeScalar("Health", TagType.TAG_FLOAT), + new SchemaNodeScalar("HurtTime", TagType.TAG_SHORT), + new SchemaNodeScalar("Dimension", TagType.TAG_INT), + new SchemaNodeList("Inventory", TagType.TAG_COMPOUND, ItemCollection.ItemSchema), + //new SchemaNodeList("EnderItems", TagType.TAG_COMPOUND, ItemCollection.Schema, SchemaOptions.OPTIONAL), + new SchemaNodeString("World", SchemaOptions.OPTIONAL), + new SchemaNodeScalar("Sleeping", TagType.TAG_BYTE, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeScalar("SleepTimer", TagType.TAG_SHORT, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeScalar("SpawnX", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("SpawnY", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("SpawnZ", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("foodLevel", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("foodTickTimer", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("foodExhaustionLevel", TagType.TAG_FLOAT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("foodSaturationLevel", TagType.TAG_FLOAT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("XpP", TagType.TAG_FLOAT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("XpLevel", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("XpTotal", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("Score", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("playerGameType", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeCompound("abilities", new SchemaNodeCompound("") { + new SchemaNodeScalar("flying", TagType.TAG_BYTE), + new SchemaNodeScalar("instabuild", TagType.TAG_BYTE), + new SchemaNodeScalar("mayfly", TagType.TAG_BYTE), + new SchemaNodeScalar("invulnerable", TagType.TAG_BYTE), + new SchemaNodeScalar("mayBuild", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("walkSpeed", TagType.TAG_FLOAT, SchemaOptions.OPTIONAL), + new SchemaNodeScalar("flySpeed", TagType.TAG_FLOAT, SchemaOptions.OPTIONAL), + }, SchemaOptions.OPTIONAL), + }); + + private const int _CAPACITY = 105; + private const int _ENDER_CAPACITY = 27; + + private ItemCollection _inventory; + private ItemCollection _enderItems; + + /// + /// Gets or sets the number of ticks left in the player's "invincibility shield" after last struck. + /// + [TagNode(CreateOnMissing = true)] + public short AttackTime { get; set; } + + /// + /// Gets or sets the number of ticks that the player has been dead for. + /// + [TagNode] + public short DeathTime { get; set; } + + /// + /// Gets or sets the amount of the player's health. + /// + [TagNode] + public float Health { get; set; } + + /// + /// Gets or sets the player's Hurt Time value. + /// + [TagNode] + public short HurtTime { get; set; } + + /// + /// Gets or sets the dimension that the player is currently in. + /// + [TagNode] + public int Dimension { get; set; } + + [TagNode] + public ItemCollection Inventory { get; } = new ItemCollection(_CAPACITY); + + /// + /// Gets or sets the name of the world that the player is currently within. + /// + [TagNode(Optional = true)] + public string World { get; set; } + + /// + /// Gets or sets a value indicating whether the player is sleeping in a bed. + /// + [TagNode(Name = "Sleeping", CreateOnMissing = true)] + public bool IsSleeping { get; set; } + + /// + /// Gets or sets the player's Sleep Timer value. + /// + [TagNode(CreateOnMissing = true)] + public short SleepTimer { get; set; } + + + [TagNode(Optional = true)] + public int? SpawnX { get; set; } + + [TagNode(Optional = true)] + public int? SpawnY { get; set; } + + [TagNode(Optional = true)] + public int? SpawnZ { get; set; } + + /// + /// Gets or sets the player's personal spawn point, set by sleeping in beds. + /// + public SpawnPoint Spawn + { + get { return new SpawnPoint(SpawnX ?? 0, SpawnY ?? 0, SpawnZ ?? 0); } + set + { + SpawnX = value.X; + SpawnY = value.Y; + SpawnZ = value.Z; + } + } + + /// + /// Tests if the player currently has a personal spawn point. + /// + public bool HasSpawn + { + get { return SpawnX != null && SpawnY != null && SpawnZ != null; } + } + + /// + /// Gets or sets the hunger level of the player. Valid values range 0 - 20. + /// + [TagNode(Name = "foodLevel", Optional = true)] + public int? HungerLevel { get; set; } + + /// + /// Gets or sets the timer used to periodically heal or damage the player based on . Valid values range 0 - 80. + /// + [TagNode(Name = "foodTickTimer", Optional = true)] + public int? HungerTimer { get; set; } + + /// + /// Gets or sets the counter towards the next hunger point decrement. Valid values range 0.0 - 4.0. + /// + [TagNode(Name = "foodExhaustionLevel", Optional = true)] + public float? HungerExhaustionLevel { get; set; } + + /// + /// Gets or sets the player's hunger saturation level, which is reserve food capacity above . + /// + [TagNode(Name = "foodSaturationLevel", Optional = true)] + public float? HungerSaturationLevel { get; set; } + + /// + /// Gets or sets the name that is used when the player is read or written from a . + /// + public string Name { get; set; } + + /// + /// Gets or sets the player's XP Level. + /// + [TagNode(Name = "XpP", Optional = true)] + public float? XpP { get; set; } + + /// + /// Gets or sets the player's XP Level. + /// + [TagNode(Optional = true)] + public int? XpLevel { get; set; } + + /// + /// Gets or sets the amount of the player's XP points. + /// + [TagNode(Optional = true)] + public int? XpTotal { get; set; } + + /// + /// Gets or sets the player's score. + /// + [TagNode(Optional = true)] + public int? Score { get; set; } + + [TagNode(Name = "playerGameType", Optional = true)] + public PlayerGameType? GameType { get; set; } + + /// + /// Gets the state of the player's abilities. + /// + [TagNode("abilities", Optional = true)] + public PlayerAbilities Abilities { get; private set; } = new PlayerAbilities(); + + /// + /// Creates a new object with reasonable default values. + /// + public Player() + : base() + { + _inventory = new ItemCollection(_CAPACITY); + _enderItems = new ItemCollection(_ENDER_CAPACITY); + + Air = 300; + Health = 20.0f; + Fire = -20; + } + + /// + /// Creates a copy of a object. + /// + /// The to copy fields from. + protected Player(Player p) + : base(p) + { + AttackTime = p.AttackTime; + DeathTime = p.DeathTime; + Health = p.Health; + HurtTime = p.HurtTime; + + Dimension = p.Dimension; + GameType = p.GameType; + IsSleeping = p.IsSleeping; + SleepTimer = p.SleepTimer; + SpawnX = p.SpawnX; + SpawnY = p.SpawnY; + SpawnZ = p.SpawnZ; + World = p.World; + _inventory = p._inventory.Copy(); + _enderItems = p._enderItems.Copy(); + + HungerLevel = p.HungerLevel; + HungerTimer = p.HungerTimer; + HungerSaturationLevel = p.HungerSaturationLevel; + HungerExhaustionLevel = p.HungerExhaustionLevel; + XpP = p.XpP; + XpLevel = p.XpLevel; + XpTotal = p.XpTotal; + Abilities = p.Abilities.Copy(); + } + + /// + /// Clears the player's personal spawn point. + /// + public void ClearSpawn() + { + SpawnX = null; + SpawnY = null; + SpawnZ = null; + } + + private bool AbilitiesSet() + { + return Abilities.Flying + || Abilities.InstantBuild + || Abilities.MayFly + || Abilities.Invulnerable; + } + + + #region INBTObject Members + + /// + /// Gets a representing the schema of a Player. + /// + public static new SchemaNodeCompound Schema + { + get { return _schema; } + } + + /// + /// Attempt to load a Player subtree into the without validation. + /// + /// The root node of a Player subtree. + /// The returns itself on success, or null if the tree was unparsable. + public virtual new Player LoadTree(TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null || base.LoadTree(tree) == null) + { + return null; + } + + AttackTime = ctree["AttackTime"].ToTagShort(); + DeathTime = ctree["DeathTime"].ToTagShort(); + Health = ctree["Health"].ToTagFloat(); + HurtTime = ctree["HurtTime"].ToTagShort(); + + Dimension = ctree["Dimension"].ToTagInt(); + IsSleeping = ctree["Sleeping"].ToTagByte(); + SleepTimer = ctree["SleepTimer"].ToTagShort(); + + if (ctree.ContainsKey("SpawnX")) + { + SpawnX = ctree["SpawnX"].ToTagInt(); + } + if (ctree.ContainsKey("SpawnY")) + { + SpawnY = ctree["SpawnY"].ToTagInt(); + } + if (ctree.ContainsKey("SpawnZ")) + { + SpawnZ = ctree["SpawnZ"].ToTagInt(); + } + + if (ctree.ContainsKey("World")) + { + World = ctree["World"].ToTagString(); + } + + if (ctree.ContainsKey("foodLevel")) + { + HungerLevel = ctree["foodLevel"].ToTagInt(); + } + if (ctree.ContainsKey("foodTickTimer")) + { + HungerTimer = ctree["foodTickTimer"].ToTagInt(); + } + if (ctree.ContainsKey("foodExhaustionLevel")) + { + HungerExhaustionLevel = ctree["foodExhaustionLevel"].ToTagFloat(); + } + if (ctree.ContainsKey("foodSaturationLevel")) + { + HungerSaturationLevel = ctree["foodSaturationLevel"].ToTagFloat(); + } + if (ctree.ContainsKey("XpP")) + { + XpP = ctree["XpP"].ToTagFloat(); + } + if (ctree.ContainsKey("XpLevel")) + { + XpLevel = ctree["XpLevel"].ToTagInt(); + } + if (ctree.ContainsKey("XpTotal")) + { + XpTotal = ctree["XpTotal"].ToTagInt(); + } + if (ctree.ContainsKey("Score")) + { + Score = ctree["Score"].ToTagInt(); + } + + if (ctree.ContainsKey("abilities")) + { + TagNodeCompound pb = ctree["abilities"].ToTagCompound(); + + Abilities = new PlayerAbilities(); + Abilities.Flying = pb["flying"].ToTagByte().Data == 1; + Abilities.InstantBuild = pb["instabuild"].ToTagByte().Data == 1; + Abilities.MayFly = pb["mayfly"].ToTagByte().Data == 1; + Abilities.Invulnerable = pb["invulnerable"].ToTagByte().Data == 1; + + if (pb.ContainsKey("mayBuild")) + Abilities.MayBuild = pb["mayBuild"].ToTagByte().Data == 1; + if (pb.ContainsKey("walkSpeed")) + Abilities.WalkSpeed = pb["walkSpeed"].ToTagFloat(); + if (pb.ContainsKey("flySpeed")) + Abilities.FlySpeed = pb["flySpeed"].ToTagFloat(); + } + + if (ctree.ContainsKey("PlayerGameType")) + { + GameType = (PlayerGameType)ctree["PlayerGameType"].ToTagInt().Data; + } + + _inventory.LoadTree(ctree["Inventory"].ToTagList()); + + if (ctree.ContainsKey("EnderItems")) + { + if (ctree["EnderItems"].ToTagList().Count > 0) + _enderItems.LoadTree(ctree["EnderItems"].ToTagList()); + } + + return this; + } + + /// + /// Attempt to load a Player subtree into the with validation. + /// + /// The root node of a Player subtree. + /// The returns itself on success, or null if the tree failed validation. + public virtual new Player LoadTreeSafe(TagNode tree) + { + if (!ValidateTree(tree)) + { + return null; + } + + return LoadTree(tree); + } + + /// + /// Builds a Player subtree from the current data. + /// + /// The root node of a Player subtree representing the current data. + public virtual new TagNode BuildTree() + { + TagNodeCompound tree = base.BuildTree() as TagNodeCompound; + tree["AttackTime"] = new TagNodeShort(AttackTime); + tree["DeathTime"] = new TagNodeShort(DeathTime); + tree["Health"] = new TagNodeFloat(Health); + tree["HurtTime"] = new TagNodeShort(HurtTime); + + tree["Dimension"] = new TagNodeInt(Dimension); + tree["Sleeping"] = new TagNodeByte(IsSleeping); + tree["SleepTimer"] = new TagNodeShort(SleepTimer); + + if (SpawnX != null && SpawnY != null && SpawnZ != null) + { + tree["SpawnX"] = new TagNodeInt(SpawnX.Value); + tree["SpawnY"] = new TagNodeInt(SpawnY.Value); + tree["SpawnZ"] = new TagNodeInt(SpawnZ.Value); + } + else + { + tree.Remove("SpawnX"); + tree.Remove("SpawnY"); + tree.Remove("SpawnZ"); + } + + if (World != null) + { + tree["World"] = new TagNodeString(World); + } + + if (HungerLevel != null) + tree["foodLevel"] = new TagNodeInt(HungerLevel.Value); + if (HungerTimer != null) + tree["foodTickTimer"] = new TagNodeInt(HungerTimer.Value); + if (HungerExhaustionLevel != null) + tree["foodExhaustionLevel"] = new TagNodeFloat(HungerExhaustionLevel.Value); + if (HungerSaturationLevel != null) + tree["foodSaturation"] = new TagNodeFloat(HungerSaturationLevel.Value); + if (XpP != null) + tree["XpP"] = new TagNodeFloat(XpP.Value); + if (XpLevel != null) + tree["XpLevel"] = new TagNodeInt(XpLevel.Value); + if (XpTotal != null) + tree["XpTotal"] = new TagNodeInt(XpTotal.Value); + if (Score != null) + tree["Score"] = new TagNodeInt(Score.Value); + + if (GameType != null) + tree["playerGameType"] = new TagNodeInt((int)(GameType.Value)); + + if (AbilitiesSet()) + { + TagNodeCompound pb = new TagNodeCompound(); + pb["flying"] = new TagNodeByte(Abilities.Flying); + pb["instabuild"] = new TagNodeByte(Abilities.InstantBuild); + pb["mayfly"] = new TagNodeByte(Abilities.MayFly); + pb["invulnerable"] = new TagNodeByte(Abilities.Invulnerable); + + if (Abilities.MayBuild != null) + pb["mayBuild"] = new TagNodeByte(Abilities.MayBuild.Value); + + if (Abilities.WalkSpeed != null) + pb["walkSpeed"] = new TagNodeFloat(Abilities.WalkSpeed.Value); + + + if (Abilities.FlySpeed != null) + pb["flySpeed"] = new TagNodeFloat(Abilities.FlySpeed.Value); + + tree["abilities"] = pb; + } + + tree["Inventory"] = _inventory.BuildTree(); + tree["EnderItems"] = _enderItems.BuildTree(); + + return tree; + } + + /// + /// Validate a Player subtree against a schema defintion. + /// + /// The root node of a Player subtree. + /// Status indicating whether the tree was valid against the internal schema. + public virtual new bool ValidateTree(TagNode tree) + { + return new NbtVerifier(tree, _schema).Verify(); + } + + #endregion + + + #region ICopyable Members + + /// + /// Creates a deep-copy of the . + /// + /// A deep-copy of the . + public virtual new Player Copy() + { + return new Player(this); + } + + #endregion + + + #region IItemContainer Members + + /// + /// Gets access to an representing the player's equipment and inventory. + /// + public ItemCollection Items + { + get { return _inventory; } + } + + #endregion + + public ItemCollection EnderItems + { + get { return _enderItems; } + } + } +} \ No newline at end of file diff --git a/SubstrateCS/Source/PlayerIOException.cs b/Substrate/Source/PlayerIOException.cs similarity index 100% rename from SubstrateCS/Source/PlayerIOException.cs rename to Substrate/Source/PlayerIOException.cs diff --git a/SubstrateCS/Source/PlayerManager.cs b/Substrate/Source/PlayerManager.cs similarity index 100% rename from SubstrateCS/Source/PlayerManager.cs rename to Substrate/Source/PlayerManager.cs diff --git a/SubstrateCS/Source/RegionChunkManager.cs b/Substrate/Source/RegionChunkManager.cs similarity index 100% rename from SubstrateCS/Source/RegionChunkManager.cs rename to Substrate/Source/RegionChunkManager.cs diff --git a/SubstrateCS/Source/SpawnPoint.cs b/Substrate/Source/SpawnPoint.cs similarity index 100% rename from SubstrateCS/Source/SpawnPoint.cs rename to Substrate/Source/SpawnPoint.cs diff --git a/SubstrateCS/Source/SubstrateException.cs b/Substrate/Source/SubstrateException.cs similarity index 100% rename from SubstrateCS/Source/SubstrateException.cs rename to Substrate/Source/SubstrateException.cs diff --git a/SubstrateCS/Source/TileEntity.cs b/Substrate/Source/TileEntity.cs similarity index 94% rename from SubstrateCS/Source/TileEntity.cs rename to Substrate/Source/TileEntity.cs index 616f9820..b1e0c3b8 100644 --- a/SubstrateCS/Source/TileEntity.cs +++ b/Substrate/Source/TileEntity.cs @@ -14,10 +14,10 @@ public class TileEntity : INbtObject, ICopyable { private static readonly SchemaNodeCompound _schema = new SchemaNodeCompound("") { - new SchemaNodeScaler("id", TagType.TAG_STRING), - new SchemaNodeScaler("x", TagType.TAG_INT), - new SchemaNodeScaler("y", TagType.TAG_INT), - new SchemaNodeScaler("z", TagType.TAG_INT), + new SchemaNodeScalar("id", TagType.TAG_STRING), + new SchemaNodeScalar("x", TagType.TAG_INT), + new SchemaNodeScalar("y", TagType.TAG_INT), + new SchemaNodeScalar("z", TagType.TAG_INT), }; private TagNodeCompound _source; diff --git a/SubstrateCS/Source/TileEntityFactory.cs b/Substrate/Source/TileEntityFactory.cs similarity index 79% rename from SubstrateCS/Source/TileEntityFactory.cs rename to Substrate/Source/TileEntityFactory.cs index 6704c648..183c0d84 100644 --- a/SubstrateCS/Source/TileEntityFactory.cs +++ b/Substrate/Source/TileEntityFactory.cs @@ -4,7 +4,6 @@ namespace Substrate { using Nbt; - using TileEntities; /// /// Creates new instances of concrete types from a dynamic registry. @@ -109,23 +108,6 @@ public static IEnumerable> RegisteredTileEntities } } } - - static TileEntityFactory () - { - _registry[TileEntityEndPortal.TypeId] = typeof(TileEntityEndPortal); - _registry[TileEntityBeacon.TypeId] = typeof(TileEntityBeacon); - _registry[TileEntityBrewingStand.TypeId] = typeof(TileEntityBrewingStand); - _registry[TileEntityChest.TypeId] = typeof(TileEntityChest); - _registry[TileEntityControl.TypeId] = typeof(TileEntityControl); - _registry[TileEntityEnchantmentTable.TypeId] = typeof(TileEntityEnchantmentTable); - _registry[TileEntityFurnace.TypeId] = typeof(TileEntityFurnace); - _registry[TileEntityMobSpawner.TypeId] = typeof(TileEntityMobSpawner); - _registry[TileEntityMusic.TypeId] = typeof(TileEntityMusic); - _registry[TileEntityPiston.TypeId] = typeof(TileEntityPiston); - _registry[TileEntityRecordPlayer.TypeId] = typeof(TileEntityRecordPlayer); - _registry[TileEntitySign.TypeId] = typeof(TileEntitySign); - _registry[TileEntityTrap.TypeId] = typeof(TileEntityTrap); - } } /// diff --git a/SubstrateCS/Source/TileTick.cs b/Substrate/Source/TileTick.cs similarity index 96% rename from SubstrateCS/Source/TileTick.cs rename to Substrate/Source/TileTick.cs index 3d28943c..c87914d7 100644 --- a/SubstrateCS/Source/TileTick.cs +++ b/Substrate/Source/TileTick.cs @@ -13,11 +13,11 @@ public class TileTick : INbtObject, ICopyable { private static readonly SchemaNodeCompound _schema = new SchemaNodeCompound("") { - new SchemaNodeScaler("i", TagType.TAG_INT), - new SchemaNodeScaler("t", TagType.TAG_INT), - new SchemaNodeScaler("x", TagType.TAG_INT), - new SchemaNodeScaler("y", TagType.TAG_INT), - new SchemaNodeScaler("z", TagType.TAG_INT), + new SchemaNodeScalar("i", TagType.TAG_INT), + new SchemaNodeScalar("t", TagType.TAG_INT), + new SchemaNodeScalar("x", TagType.TAG_INT), + new SchemaNodeScalar("y", TagType.TAG_INT), + new SchemaNodeScalar("z", TagType.TAG_INT), }; private int _blockId; diff --git a/Substrate/Source/Vector.cs b/Substrate/Source/Vector.cs new file mode 100644 index 00000000..b9de4868 --- /dev/null +++ b/Substrate/Source/Vector.cs @@ -0,0 +1,32 @@ +using System; +using Substrate.Nbt; + +namespace Substrate +{ + [TagNodeType(TagType.TAG_LIST, ListItemTagType = TagType.TAG_DOUBLE)] + public class Vector3 : INbtObject2 + { + public double X { get; set; } + + public double Y { get; set; } + + public double Z { get; set; } + + public TagNode BuildTree() + { + var list = new TagNodeList(TagType.TAG_DOUBLE); + list.Add(new TagNodeDouble(X)); + list.Add(new TagNodeDouble(Y)); + list.Add(new TagNodeDouble(Z)); + return list; + } + + public void LoadTree(TagNode tree) + { + var list = tree.ToTagList(); + X = list[0].ToTagDouble(); + Y = list[1].ToTagDouble(); + Z = list[2].ToTagDouble(); + } + } +} diff --git a/Substrate/Source/Villages.cs b/Substrate/Source/Villages.cs new file mode 100644 index 00000000..1e2bde54 --- /dev/null +++ b/Substrate/Source/Villages.cs @@ -0,0 +1,182 @@ +using Substrate.Core; +using Substrate.Nbt; +using Substrate.Source.Nbt; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate +{ + public class Villages + { + public static SchemaNodeCompound Schema { get; } = SchemaBuilder.FromClass(typeof(Villages)); + + [TagNode("data")] + public VillageCompound Data { get; set; } + + public class VillageCompound + { + /// + /// Internal clock. + /// + [TagNode] + public int Tick { get; set; } + + /// + /// List of Byte tags when empty, list of Compound tags otherwise. + /// + [TagNode] + public List Villages { get; set; } + } + + /// + /// A village + /// + public class VillagesCompound + { + /// + /// Aggregate of the x-coordinates of all houses. + /// + [TagNode] + public int ACX { get; set; } + + /// + /// Aggregate of the y-coordinates of all houses. + /// + [TagNode] + public int ACY { get; set; } + + /// + /// Aggregate of the z-coordinates of all houses. + /// + [TagNode] + public int ACZ { get; set; } + + /// + /// X coordinate of the village center. + /// + [TagNode] + public int CX { get; set; } + + /// + /// Y coordinate of the village center. + /// + [TagNode] + public int CY { get; set; } + + /// + /// Z coordinate of the village center. + /// + [TagNode] + public int CZ { get; set; } + + /// + /// The number of Iron Golems. + /// + [TagNode] + public int Golems { get; set; } + + /// + /// Last time a villager was killed by a mob, or by a damage source that's not related to an entity while a player was nearby. + /// + [TagNode] + public int MTick { get; set; } + + /// + /// The number of Villagers. + /// + [TagNode] + public int PopSize { get; set; } + + /// + /// Radius of the village. + /// + [TagNode] + public int Radius { get; set; } + + /// + /// Last time a house was added to the village. + /// + [TagNode] + public int Stable { get; set; } + + /// + /// Internal clock. + /// + [TagNode] + public int Tick { get; set; } + + /// + /// The doors in the village. + /// + [TagNode] + public List Doors { get; set; } + + /// + /// List of Byte tags when empty, list of Compound tags otherwise. + /// + [TagNode] + public List Players { get; set; } + } + + /// + /// A door. + /// + public class DoorsCompound + { + /// + /// Specifies the inside direction along x. + /// + [TagNode] + public int IDX { get; set; } + + /// + /// Specifies the inside direction along z. + /// + [TagNode] + public int IDZ { get; set; } + + /// + /// Last time a villager was nearby. + /// + [TagNode] + public int TS { get; set; } + + /// + /// X coordinate. + /// + [TagNode] + public int X { get; set; } + + /// + /// Y coordinate. + /// + [TagNode] + public int Y { get; set; } + + /// + /// Z coordinate. + /// + [TagNode] + public int Z { get; set; } + } + + /// + /// A player who has traded or harmed villagers. + /// + public class PlayersCompound + { + /// + /// The name of the player. + /// + [TagNode] + public int Name { get; set; } + + /// + /// The social rank of the player. Can be negative. Goes up with trading and down with harming villagers + /// + [TagNode] + public int S { get; set; } + } + } +} diff --git a/SubstrateCS/Source/World.cs b/Substrate/Source/World.cs similarity index 100% rename from SubstrateCS/Source/World.cs rename to Substrate/Source/World.cs diff --git a/Substrate/Substrate.csproj b/Substrate/Substrate.csproj new file mode 100644 index 00000000..206e1f7f --- /dev/null +++ b/Substrate/Substrate.csproj @@ -0,0 +1,28 @@ + + + + + Substrate + Substrate + + + + publish\Substrate.net.xml + + + + minecraft-dotnet.Substrate + Substrate + + Justin Aquadro, Simon Stevenson + + + + + + + diff --git a/Substrate/packages.config b/Substrate/packages.config new file mode 100644 index 00000000..d905e5ff --- /dev/null +++ b/Substrate/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/SubstrateCS/Examples/Examples.sln b/SubstrateCS/Examples/Examples.sln deleted file mode 100644 index da154b01..00000000 --- a/SubstrateCS/Examples/Examples.sln +++ /dev/null @@ -1,138 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C# Express 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Convert", "Convert\Convert.csproj", "{5BD42656-9BCF-4C55-8272-A5D3507EFDF3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlatMap", "FlatMap\FlatMap.csproj", "{EDA894F2-00AF-456B-9D07-591ED61A9AE7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlockReplace", "BlockReplace\BlockReplace.csproj", "{6D24D262-34D3-43A6-B066-1312A0C72B16}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GiveItem", "GiveItem\GiveItem.csproj", "{426B01F4-B0C0-488E-8A5A-5531C8DFA98C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoveSpawn", "MoveSpawn\MoveSpawn.csproj", "{15C04C0C-FD50-47E9-B62C-AA0A814189ED}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Relight", "Relight\Relight.csproj", "{EBDD447B-01FA-4A29-B4AB-380EC4379B5F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Maze", "Maze\Maze.csproj", "{62D70576-FE3A-4530-B283-889C14B52E9E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PurgeEntities", "PurgeEntities\PurgeEntities.csproj", "{A64F274A-D5B7-45C2-92BA-4C9A64863DDC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GoodyChest", "GoodyChest\GoodyChest.csproj", "{6A998912-C939-4029-9F1D-D5C2A5E9C804}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomBlocks", "CustomBlocks\CustomBlocks.csproj", "{B01AD681-31A7-43A0-A84B-F839FBCB2F01}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Debug|x86.ActiveCfg = Debug|Any CPU - {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Release|Any CPU.Build.0 = Release|Any CPU - {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {5BD42656-9BCF-4C55-8272-A5D3507EFDF3}.Release|x86.ActiveCfg = Release|Any CPU - {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Debug|x86.ActiveCfg = Debug|Any CPU - {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Release|Any CPU.Build.0 = Release|Any CPU - {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {EDA894F2-00AF-456B-9D07-591ED61A9AE7}.Release|x86.ActiveCfg = Release|Any CPU - {6D24D262-34D3-43A6-B066-1312A0C72B16}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6D24D262-34D3-43A6-B066-1312A0C72B16}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6D24D262-34D3-43A6-B066-1312A0C72B16}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {6D24D262-34D3-43A6-B066-1312A0C72B16}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {6D24D262-34D3-43A6-B066-1312A0C72B16}.Debug|x86.ActiveCfg = Debug|Any CPU - {6D24D262-34D3-43A6-B066-1312A0C72B16}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6D24D262-34D3-43A6-B066-1312A0C72B16}.Release|Any CPU.Build.0 = Release|Any CPU - {6D24D262-34D3-43A6-B066-1312A0C72B16}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {6D24D262-34D3-43A6-B066-1312A0C72B16}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {6D24D262-34D3-43A6-B066-1312A0C72B16}.Release|x86.ActiveCfg = Release|Any CPU - {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Debug|x86.ActiveCfg = Debug|Any CPU - {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Release|Any CPU.Build.0 = Release|Any CPU - {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {426B01F4-B0C0-488E-8A5A-5531C8DFA98C}.Release|x86.ActiveCfg = Release|Any CPU - {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Debug|x86.ActiveCfg = Debug|Any CPU - {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Release|Any CPU.Build.0 = Release|Any CPU - {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {15C04C0C-FD50-47E9-B62C-AA0A814189ED}.Release|x86.ActiveCfg = Release|Any CPU - {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Debug|x86.ActiveCfg = Debug|Any CPU - {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Release|Any CPU.Build.0 = Release|Any CPU - {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {EBDD447B-01FA-4A29-B4AB-380EC4379B5F}.Release|x86.ActiveCfg = Release|Any CPU - {62D70576-FE3A-4530-B283-889C14B52E9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {62D70576-FE3A-4530-B283-889C14B52E9E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {62D70576-FE3A-4530-B283-889C14B52E9E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {62D70576-FE3A-4530-B283-889C14B52E9E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {62D70576-FE3A-4530-B283-889C14B52E9E}.Debug|x86.ActiveCfg = Debug|Any CPU - {62D70576-FE3A-4530-B283-889C14B52E9E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {62D70576-FE3A-4530-B283-889C14B52E9E}.Release|Any CPU.Build.0 = Release|Any CPU - {62D70576-FE3A-4530-B283-889C14B52E9E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {62D70576-FE3A-4530-B283-889C14B52E9E}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {62D70576-FE3A-4530-B283-889C14B52E9E}.Release|x86.ActiveCfg = Release|Any CPU - {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Debug|x86.ActiveCfg = Debug|Any CPU - {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Release|Any CPU.Build.0 = Release|Any CPU - {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {A64F274A-D5B7-45C2-92BA-4C9A64863DDC}.Release|x86.ActiveCfg = Release|Any CPU - {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Debug|Any CPU.ActiveCfg = Debug|x86 - {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Debug|x86.ActiveCfg = Debug|x86 - {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Debug|x86.Build.0 = Debug|x86 - {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Release|Any CPU.ActiveCfg = Release|x86 - {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Release|Mixed Platforms.Build.0 = Release|x86 - {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Release|x86.ActiveCfg = Release|x86 - {6A998912-C939-4029-9F1D-D5C2A5E9C804}.Release|x86.Build.0 = Release|x86 - {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Debug|Any CPU.ActiveCfg = Debug|x86 - {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Debug|x86.ActiveCfg = Debug|x86 - {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Debug|x86.Build.0 = Debug|x86 - {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Release|Any CPU.ActiveCfg = Release|x86 - {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Release|Mixed Platforms.Build.0 = Release|x86 - {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Release|x86.ActiveCfg = Release|x86 - {B01AD681-31A7-43A0-A84B-F839FBCB2F01}.Release|x86.Build.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/SubstrateCS/Properties/AssemblyInfo.cs b/SubstrateCS/Properties/AssemblyInfo.cs deleted file mode 100644 index 22d20d2e..00000000 --- a/SubstrateCS/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Substrate")] -[assembly: AssemblyDescription("SDK for loading and modifying Minecraft worlds")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Substrate")] -[assembly: AssemblyCopyright("2011-2012 Justin Aquadro")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("0e6cc672-bcea-401f-a5f3-30e8ef39c673")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyVersion("1.3.9.0")] -[assembly: AssemblyFileVersion("1.3.9.0")] - -// This library is compatible with all CLS-compliant .NET programming languages. -[assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/SubstrateCS/Source/BiomeInfo.cs b/SubstrateCS/Source/BiomeInfo.cs deleted file mode 100644 index 2545f610..00000000 --- a/SubstrateCS/Source/BiomeInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Substrate -{ - public class BiomeType - { - public const int Ocean = 0; - public const int Plains = 1; - public const int Desert = 2; - public const int ExtremeHills = 3; - public const int Forest = 4; - public const int Taiga = 5; - public const int Swampland = 6; - public const int River = 7; - public const int Hell = 8; - public const int Sky = 9; - public const int FrozenOcean = 10; - public const int FrozenRiver = 11; - public const int IcePlains = 12; - public const int IceMountains = 13; - public const int MushroomIsland = 14; - public const int MushroomIslandShore = 15; - public const int Beach = 16; - public const int DesertHills = 17; - public const int ForestHills = 18; - public const int TaigaHills = 19; - public const int ExtremeHillsEdge = 20; - public const int Jungle = 21; - public const int JungleHills = 22; - - public const int Default = 255; - } -} diff --git a/SubstrateCS/Source/BlockInfo.cs b/SubstrateCS/Source/BlockInfo.cs deleted file mode 100644 index 4d0702f0..00000000 --- a/SubstrateCS/Source/BlockInfo.cs +++ /dev/null @@ -1,1069 +0,0 @@ -using System; -using System.Collections.Generic; -using Substrate.Nbt; -using System.Collections; - -namespace Substrate -{ - /// - /// Provides named id values for known block types. - /// - /// The preferred method to lookup - /// Minecraft block IDs is to access the ID field of the corresponding static BlockInfo - /// object in the BlockInfo class. - /// The static BlockInfo objects can be re-bound to new BlockInfo objects, allowing - /// the named object to be bound to a new block ID. This gives the developer more flexibility - /// in supporting nonstandard worlds, and the ability to future-proof their application against - /// changes to Block IDs, by implementing functionality to import block/ID mappings from an - /// external source and rebinding the objects in BlockInfo. - public static class BlockType - { - public const int AIR = 0; - public const int STONE = 1; - public const int GRASS = 2; - public const int DIRT = 3; - public const int COBBLESTONE = 4; - public const int WOOD_PLANK = 5; - public const int SAPLING = 6; - public const int BEDROCK = 7; - public const int WATER = 8; - public const int STATIONARY_WATER = 9; - public const int LAVA = 10; - public const int STATIONARY_LAVA = 11; - public const int SAND = 12; - public const int GRAVEL = 13; - public const int GOLD_ORE = 14; - public const int IRON_ORE = 15; - public const int COAL_ORE = 16; - public const int WOOD = 17; - public const int LEAVES = 18; - public const int SPONGE = 19; - public const int GLASS = 20; - public const int LAPIS_ORE = 21; - public const int LAPIS_BLOCK = 22; - public const int DISPENSER = 23; - public const int SANDSTONE = 24; - public const int NOTE_BLOCK = 25; - public const int BED = 26; - public const int POWERED_RAIL = 27; - public const int DETECTOR_RAIL = 28; - public const int STICKY_PISTON = 29; - public const int COBWEB = 30; - public const int TALL_GRASS = 31; - public const int DEAD_SHRUB = 32; - public const int PISTON = 33; - public const int PISTON_HEAD = 34; - public const int WOOL = 35; - public const int PISTON_MOVING = 36; - public const int YELLOW_FLOWER = 37; - public const int RED_ROSE = 38; - public const int BROWN_MUSHROOM = 39; - public const int RED_MUSHROOM = 40; - public const int GOLD_BLOCK = 41; - public const int IRON_BLOCK = 42; - public const int DOUBLE_STONE_SLAB = 43; - public const int STONE_SLAB = 44; - public const int BRICK_BLOCK = 45; - public const int TNT = 46; - public const int BOOKSHELF = 47; - public const int MOSS_STONE = 48; - public const int OBSIDIAN = 49; - public const int TORCH = 50; - public const int FIRE = 51; - public const int MONSTER_SPAWNER = 52; - public const int WOOD_STAIRS = 53; - public const int CHEST = 54; - public const int REDSTONE_WIRE = 55; - public const int DIAMOND_ORE = 56; - public const int DIAMOND_BLOCK = 57; - public const int CRAFTING_TABLE = 58; - public const int CROPS = 59; - public const int FARMLAND = 60; - public const int FURNACE = 61; - public const int BURNING_FURNACE = 62; - public const int SIGN_POST = 63; - public const int WOOD_DOOR = 64; - public const int LADDER = 65; - public const int RAILS = 66; - public const int COBBLESTONE_STAIRS = 67; - public const int WALL_SIGN = 68; - public const int LEVER = 69; - public const int STONE_PLATE = 70; - public const int IRON_DOOR = 71; - public const int WOOD_PLATE = 72; - public const int REDSTONE_ORE = 73; - public const int GLOWING_REDSTONE_ORE = 74; - public const int REDSTONE_TORCH_OFF = 75; - public const int REDSTONE_TORCH_ON = 76; - public const int STONE_BUTTON = 77; - public const int SNOW = 78; - public const int ICE = 79; - public const int SNOW_BLOCK = 80; - public const int CACTUS = 81; - public const int CLAY_BLOCK = 82; - public const int SUGAR_CANE = 83; - public const int JUKEBOX = 84; - public const int FENCE = 85; - public const int PUMPKIN = 86; - public const int NETHERRACK = 87; - public const int SOUL_SAND = 88; - public const int GLOWSTONE_BLOCK = 89; - public const int PORTAL = 90; - public const int JACK_O_LANTERN = 91; - public const int CAKE_BLOCK = 92; - public const int REDSTONE_REPEATER_OFF = 93; - public const int REDSTONE_REPEATER_ON = 94; - public const int LOCKED_CHEST = 95; - public const int STAINED_GLASS = 95; - public const int TRAPDOOR = 96; - public const int SILVERFISH_STONE = 97; - public const int STONE_BRICK = 98; - public const int HUGE_RED_MUSHROOM = 99; - public const int HUGE_BROWN_MUSHROOM = 100; - public const int IRON_BARS = 101; - public const int GLASS_PANE = 102; - public const int MELON = 103; - public const int PUMPKIN_STEM = 104; - public const int MELON_STEM = 105; - public const int VINES = 106; - public const int FENCE_GATE = 107; - public const int BRICK_STAIRS = 108; - public const int STONE_BRICK_STAIRS = 109; - public const int MYCELIUM = 110; - public const int LILLY_PAD = 111; - public const int NETHER_BRICK = 112; - public const int NETHER_BRICK_FENCE = 113; - public const int NETHER_BRICK_STAIRS = 114; - public const int NETHER_WART = 115; - public const int ENCHANTMENT_TABLE = 116; - public const int BREWING_STAND = 117; - public const int CAULDRON = 118; - public const int END_PORTAL = 119; - public const int END_PORTAL_FRAME = 120; - public const int END_STONE = 121; - public const int DRAGON_EGG = 122; - public const int REDSTONE_LAMP_OFF = 123; - public const int REDSTONE_LAMP_ON = 124; - public const int DOUBLE_WOOD_SLAB = 125; - public const int WOOD_SLAB = 126; - public const int COCOA_PLANT = 127; - public const int SANDSTONE_STAIRS = 128; - public const int EMERALD_ORE = 129; - public const int ENDER_CHEST = 130; - public const int TRIPWIRE_HOOK = 131; - public const int TRIPWIRE = 132; - public const int EMERALD_BLOCK = 133; - public const int SPRUCE_WOOD_STAIRS = 134; - public const int BIRCH_WOOD_STAIRS = 135; - public const int JUNGLE_WOOD_STAIRS = 136; - public const int COMMAND_BLOCK = 137; - public const int BEACON_BLOCK = 138; - public const int COBBLESTONE_WALL = 139; - public const int FLOWER_POT = 140; - public const int CARROTS = 141; - public const int POTATOES = 142; - public const int WOOD_BUTTON = 143; - public const int HEADS = 144; - public const int ANVIL = 145; - public const int TRAPPED_CHEST = 146; - public const int WEIGHTED_PRESSURE_PLATE_LIGHT = 147; - public const int WEIGHTED_PRESSURE_PLATE_HEAVY = 148; - public const int REDSTONE_COMPARATOR_INACTIVE = 149; - public const int REDSTONE_COMPARATOR_ACTIVE = 150; - public const int DAYLIGHT_SENSOR = 151; - public const int REDSTONE_BLOCK = 152; - public const int NETHER_QUARTZ_ORE = 153; - public const int HOPPER = 154; - public const int QUARTZ_BLOCK = 155; - public const int QUARTZ_STAIRS = 156; - public const int ACTIVATOR_RAIL = 157; - public const int DROPPER = 158; - public const int STAINED_CLAY = 159; - public const int STAINED_GLASS_PANE = 160; - public const int HAY_BLOCK = 170; - public const int CARPET = 171; - public const int HARDENED_CLAY = 172; - public const int COAL_BLOCK = 173; - } - - /// - /// Represents the physical state of a block, such as solid or fluid. - /// - public enum BlockState - { - /// - /// A solid state that stops movement. - /// - SOLID, - - /// - /// A nonsolid state that can be passed through. - /// - NONSOLID, - - /// - /// A fluid state that flows and impedes movement. - /// - FLUID - } - - /// - /// Provides information on a specific type of block. - /// - /// By default, all known MC block types are already defined and registered, assuming Substrate - /// is up to date with the current MC version. All unknown blocks are given a default type and unregistered status. - /// New block types may be created and used at runtime, and will automatically populate various static lookup tables - /// in the class. - public class BlockInfo - { - /// - /// The maximum number of sequential blocks starting at 0 that can be registered. - /// - public const int MAX_BLOCKS = 4096; - - /// - /// The maximum opacity value that can be assigned to a block (fully opaque). - /// - public const int MAX_OPACITY = 15; - - /// - /// The minimum opacity value that can be assigned to a block (fully transparent). - /// - public const int MIN_OPACITY = 0; - - /// - /// The maximum luminance value that can be assigned to a block. - /// - public const int MAX_LUMINANCE = 15; - - /// - /// The minimum luminance value that can be assigned to a block. - /// - public const int MIN_LUMINANCE = 0; - - private static readonly BlockInfo[] _blockTable; - private static readonly int[] _opacityTable; - private static readonly int[] _luminanceTable; - - private class CacheTableArray : ICacheTable - { - private T[] _cache; - - public T this[int index] - { - get { return _cache[index]; } - } - - public CacheTableArray (T[] cache) - { - _cache = cache; - } - - public IEnumerator GetEnumerator () - { - for (int i = 0; i < _cache.Length; i++) { - if (_cache[i] != null) - yield return _cache[i]; - } - } - - IEnumerator IEnumerable.GetEnumerator () - { - return GetEnumerator(); - } - } - - private class DataLimits - { - private int _low; - private int _high; - private int _bitmask; - - public int Low - { - get { return _low; } - } - - public int High - { - get { return _high; } - } - - public int Bitmask - { - get { return _bitmask; } - } - - public DataLimits (int low, int high, int bitmask) - { - _low = low; - _high = high; - _bitmask = bitmask; - } - - public bool Test (int data) - { - int rdata = data & ~_bitmask; - return rdata >= _low && rdata <= _high; - } - } - - private int _id = 0; - private string _name = ""; - private int _tick = 0; - private int _opacity = MAX_OPACITY; - private int _luminance = MIN_LUMINANCE; - private bool _transmitLight = false; - private bool _blocksFluid = true; - private bool _registered = false; - - private BlockState _state = BlockState.SOLID; - - private DataLimits _dataLimits; - - private static readonly CacheTableArray _blockTableCache; - private static readonly CacheTableArray _opacityTableCache; - private static readonly CacheTableArray _luminanceTableCache; - - /// - /// Gets the lookup table for id-to-info values. - /// - public static ICacheTable BlockTable - { - get { return _blockTableCache; } - } - - /// - /// Gets the lookup table for id-to-opacity values. - /// - public static ICacheTable OpacityTable - { - get { return _opacityTableCache; } - } - - /// - /// Gets the lookup table for id-to-luminance values. - /// - public static ICacheTable LuminanceTable - { - get { return _luminanceTableCache; } - } - - /// - /// Get's the block's Id. - /// - public int ID - { - get { return _id; } - } - - /// - /// Get's the name of the block type. - /// - public string Name - { - get { return _name; } - } - - /// - /// Gets the block's opacity value. An opacity of 0 is fully transparent to light. - /// - public int Opacity - { - get { return _opacity; } - } - - /// - /// Gets the block's luminance value. - /// - /// Blocks with luminance act as light sources and transmit light to other blocks. - public int Luminance - { - get { return _luminance; } - } - - /// - /// Checks whether the block transmits light to neighboring blocks. - /// - /// A block may stop the transmission of light, but still be illuminated. - public bool TransmitsLight - { - get { return _transmitLight; } - } - - /// - /// Checks whether the block partially or fully blocks the transmission of light. - /// - public bool ObscuresLight - { - get { return _opacity > MIN_OPACITY || !_transmitLight; } - } - - /// - /// Checks whether the block stops fluid from passing through it. - /// - /// A block that does not block fluids will be destroyed by fluid. - public bool BlocksFluid - { - get { return _blocksFluid; } - } - - /// - /// Gets the block's physical state type. - /// - public BlockState State - { - get { return _state; } - } - - /// - /// Checks whether this block type has been registered as a known type. - /// - public bool Registered - { - get { return _registered; } - } - - public int Tick - { - get { return _tick; } - } - - internal BlockInfo (int id) - { - _id = id; - _name = "Unknown Block"; - _blockTable[_id] = this; - } - - /// - /// Constructs a new record for a given block id and name. - /// - /// The id of the block. - /// The name of the block. - /// All user-constructed objects are registered automatically. - public BlockInfo (int id, string name) - { - _id = id; - _name = name; - _blockTable[_id] = this; - _registered = true; - } - - /// - /// Sets a new opacity value for this block type. - /// - /// A new opacity value. - /// The object instance used to invoke this method. - /// - public BlockInfo SetOpacity (int opacity) - { - _opacity = MIN_OPACITY + opacity; - _opacityTable[_id] = _opacity; - - if (opacity == MAX_OPACITY) { - _transmitLight = false; - } - else { - _transmitLight = true; - } - - return this; - } - - /// - /// Sets a new luminance value for this block type. - /// - /// A new luminance value. - /// The object instance used to invoke this method. - /// - public BlockInfo SetLuminance (int luminance) - { - _luminance = luminance; - _luminanceTable[_id] = _luminance; - return this; - } - - /// - /// Sets whether or not this block type will transmit light to neigboring blocks. - /// - /// True if this block type can transmit light to neighbors, false otherwise. - /// The object instance used to invoke this method. - /// - public BlockInfo SetLightTransmission (bool transmit) - { - _transmitLight = transmit; - return this; - } - - /// - /// Sets limitations on what data values are considered valid for this block type. - /// - /// The lowest valid integer value. - /// The highest valid integer value. - /// A mask representing which bits are interpreted as a bitmask in the data value. - /// The object instance used to invoke this method. - public BlockInfo SetDataLimits (int low, int high, int bitmask) - { - _dataLimits = new DataLimits(low, high, bitmask); - return this; - } - - /// - /// Sets the physical state of the block type. - /// - /// A physical state. - /// The object instance used to invoke this method. - public BlockInfo SetState (BlockState state) - { - _state = state; - - if (_state == BlockState.SOLID) { - _blocksFluid = true; - } - else { - _blocksFluid = false; - } - - return this; - } - - /// - /// Sets whether or not this block type blocks fluids. - /// - /// True if this block type blocks fluids, false otherwise. - /// The object instance used to invoke this method. - /// - public BlockInfo SetBlocksFluid (bool blocks) - { - _blocksFluid = blocks; - return this; - } - - /// - /// Sets the default tick rate/delay used for updating this block. - /// - /// Set to 0 to indicate that this block is not processed by tick updates. - /// The tick rate in frames between scheduled updates on this block. - /// The object instance used to invoke this method. - /// - public BlockInfo SetTick (int tick) - { - _tick = tick; - return this; - } - - /// - /// Tests if the given data value is valid for this block type. - /// - /// A data value to test. - /// True if the data value is valid, false otherwise. - /// This method uses internal information set by . - public bool TestData (int data) - { - if (_dataLimits == null) { - return true; - } - return _dataLimits.Test(data); - } - - public static BlockInfo Air; - public static BlockInfo Stone; - public static BlockInfo Grass; - public static BlockInfo Dirt; - public static BlockInfo Cobblestone; - public static BlockInfo WoodPlank; - public static BlockInfo Sapling; - public static BlockInfo Bedrock; - public static BlockInfo Water; - public static BlockInfo StationaryWater; - public static BlockInfo Lava; - public static BlockInfo StationaryLava; - public static BlockInfo Sand; - public static BlockInfo Gravel; - public static BlockInfo GoldOre; - public static BlockInfo IronOre; - public static BlockInfo CoalOre; - public static BlockInfo Wood; - public static BlockInfo Leaves; - public static BlockInfo Sponge; - public static BlockInfo Glass; - public static BlockInfo LapisOre; - public static BlockInfo LapisBlock; - public static BlockInfoEx Dispenser; - public static BlockInfo Sandstone; - public static BlockInfoEx NoteBlock; - public static BlockInfo Bed; - public static BlockInfo PoweredRail; - public static BlockInfo DetectorRail; - public static BlockInfo StickyPiston; - public static BlockInfo Cobweb; - public static BlockInfo TallGrass; - public static BlockInfo DeadShrub; - public static BlockInfo Piston; - public static BlockInfo PistonHead; - public static BlockInfo Wool; - public static BlockInfoEx PistonMoving; - public static BlockInfo YellowFlower; - public static BlockInfo RedRose; - public static BlockInfo BrownMushroom; - public static BlockInfo RedMushroom; - public static BlockInfo GoldBlock; - public static BlockInfo IronBlock; - public static BlockInfo DoubleStoneSlab; - public static BlockInfo StoneSlab; - public static BlockInfo BrickBlock; - public static BlockInfo TNT; - public static BlockInfo Bookshelf; - public static BlockInfo MossStone; - public static BlockInfo Obsidian; - public static BlockInfo Torch; - public static BlockInfo Fire; - public static BlockInfoEx MonsterSpawner; - public static BlockInfo WoodStairs; - public static BlockInfoEx Chest; - public static BlockInfo RedstoneWire; - public static BlockInfo DiamondOre; - public static BlockInfo DiamondBlock; - public static BlockInfo CraftTable; - public static BlockInfo Crops; - public static BlockInfo Farmland; - public static BlockInfoEx Furnace; - public static BlockInfoEx BurningFurnace; - public static BlockInfoEx SignPost; - public static BlockInfo WoodDoor; - public static BlockInfo Ladder; - public static BlockInfo Rails; - public static BlockInfo CobbleStairs; - public static BlockInfoEx WallSign; - public static BlockInfo Lever; - public static BlockInfo StonePlate; - public static BlockInfo IronDoor; - public static BlockInfo WoodPlate; - public static BlockInfo RedstoneOre; - public static BlockInfo GlowRedstoneOre; - public static BlockInfo RedstoneTorch; - public static BlockInfo RedstoneTorchOn; - public static BlockInfo StoneButton; - public static BlockInfo Snow; - public static BlockInfo Ice; - public static BlockInfo SnowBlock; - public static BlockInfo Cactus; - public static BlockInfo ClayBlock; - public static BlockInfo SugarCane; - public static BlockInfo Jukebox; - public static BlockInfo Fence; - public static BlockInfo Pumpkin; - public static BlockInfo Netherrack; - public static BlockInfo SoulSand; - public static BlockInfo Glowstone; - public static BlockInfo Portal; - public static BlockInfo JackOLantern; - public static BlockInfo CakeBlock; - public static BlockInfo RedstoneRepeater; - public static BlockInfo RedstoneRepeaterOn; - public static BlockInfoEx LockedChest; - public static BlockInfo StainedGlass; - public static BlockInfo Trapdoor; - public static BlockInfo SilverfishStone; - public static BlockInfo StoneBrick; - public static BlockInfo HugeRedMushroom; - public static BlockInfo HugeBrownMushroom; - public static BlockInfo IronBars; - public static BlockInfo GlassPane; - public static BlockInfo Melon; - public static BlockInfo PumpkinStem; - public static BlockInfo MelonStem; - public static BlockInfo Vines; - public static BlockInfo FenceGate; - public static BlockInfo BrickStairs; - public static BlockInfo StoneBrickStairs; - public static BlockInfo Mycelium; - public static BlockInfo LillyPad; - public static BlockInfo NetherBrick; - public static BlockInfo NetherBrickFence; - public static BlockInfo NetherBrickStairs; - public static BlockInfo NetherWart; - public static BlockInfoEx EnchantmentTable; - public static BlockInfoEx BrewingStand; - public static BlockInfo Cauldron; - public static BlockInfoEx EndPortal; - public static BlockInfo EndPortalFrame; - public static BlockInfo EndStone; - public static BlockInfo DragonEgg; - public static BlockInfo RedstoneLampOff; - public static BlockInfo RedstoneLampOn; - public static BlockInfo DoubleWoodSlab; - public static BlockInfo WoodSlab; - public static BlockInfo CocoaPlant; - public static BlockInfo SandstoneStairs; - public static BlockInfo EmeraldOre; - public static BlockInfoEx EnderChest; - public static BlockInfo TripwireHook; - public static BlockInfo Tripwire; - public static BlockInfo EmeraldBlock; - public static BlockInfo SpruceWoodStairs; - public static BlockInfo BirchWoodStairs; - public static BlockInfo JungleWoodStairs; - public static BlockInfoEx CommandBlock; - public static BlockInfoEx BeaconBlock; - public static BlockInfo CobblestoneWall; - public static BlockInfo FlowerPot; - public static BlockInfo Carrots; - public static BlockInfo Potatoes; - public static BlockInfo WoodButton; - public static BlockInfo Heads; - public static BlockInfo Anvil; - public static BlockInfoEx TrappedChest; - public static BlockInfo WeightedPressurePlateLight; - public static BlockInfo WeightedPressurePlateHeavy; - public static BlockInfo RedstoneComparatorInactive; - public static BlockInfo RedstoneComparatorActive; - public static BlockInfo DaylightSensor; - public static BlockInfo RedstoneBlock; - public static BlockInfo NetherQuartzOre; - public static BlockInfoEx Hopper; - public static BlockInfo QuartzBlock; - public static BlockInfo QuartzStairs; - public static BlockInfo ActivatorRail; - public static BlockInfoEx Dropper; - public static BlockInfo StainedClay; - public static BlockInfo StainedGlassPane; - public static BlockInfo HayBlock; - public static BlockInfo Carpet; - public static BlockInfo HardenedClay; - public static BlockInfo CoalBlock; - - static BlockInfo () - { - _blockTable = new BlockInfo[MAX_BLOCKS]; - _opacityTable = new int[MAX_BLOCKS]; - _luminanceTable = new int[MAX_BLOCKS]; - - _blockTableCache = new CacheTableArray(_blockTable); - _opacityTableCache = new CacheTableArray(_opacityTable); - _luminanceTableCache = new CacheTableArray(_luminanceTable); - - Air = new BlockInfo(0, "Air").SetOpacity(0).SetState(BlockState.NONSOLID); - Stone = new BlockInfo(1, "Stone"); - Grass = new BlockInfo(2, "Grass").SetTick(10); - Dirt = new BlockInfo(3, "Dirt"); - Cobblestone = new BlockInfo(4, "Cobblestone"); - WoodPlank = new BlockInfo(5, "Wooden Plank"); - Sapling = new BlockInfo(6, "Sapling").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - Bedrock = new BlockInfo(7, "Bedrock"); - Water = new BlockInfo(8, "Water").SetOpacity(3).SetState(BlockState.FLUID).SetTick(5); - StationaryWater = new BlockInfo(9, "Stationary Water").SetOpacity(3).SetState(BlockState.FLUID); - Lava = new BlockInfo(10, "Lava").SetOpacity(0).SetLuminance(MAX_LUMINANCE).SetState(BlockState.FLUID).SetTick(30); - StationaryLava = new BlockInfo(11, "Stationary Lava").SetOpacity(0).SetLuminance(MAX_LUMINANCE).SetState(BlockState.FLUID).SetTick(10); - Sand = new BlockInfo(12, "Sand").SetTick(3); - Gravel = new BlockInfo(13, "Gravel").SetTick(3); - GoldOre = new BlockInfo(14, "Gold Ore"); - IronOre = new BlockInfo(15, "Iron Ore"); - CoalOre = new BlockInfo(16, "Coal Ore"); - Wood = new BlockInfo(17, "Wood"); - Leaves = new BlockInfo(18, "Leaves").SetOpacity(1).SetTick(10); - Sponge = new BlockInfo(19, "Sponge"); - Glass = new BlockInfo(20, "Glass").SetOpacity(0); - LapisOre = new BlockInfo(21, "Lapis Lazuli Ore"); - LapisBlock = new BlockInfo(22, "Lapis Lazuli Block"); - Dispenser = (BlockInfoEx)new BlockInfoEx(23, "Dispenser").SetTick(4); - Sandstone = new BlockInfo(24, "Sandstone"); - NoteBlock = new BlockInfoEx(25, "Note Block"); - Bed = new BlockInfo(26, "Bed").SetOpacity(0); - PoweredRail = new BlockInfo(27, "Powered Rail").SetOpacity(0).SetState(BlockState.NONSOLID); - DetectorRail = new BlockInfo(28, "Detector Rail").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(20); - StickyPiston = new BlockInfo(29, "Sticky Piston").SetOpacity(0); - Cobweb = new BlockInfo(30, "Cobweb").SetOpacity(0).SetState(BlockState.NONSOLID); - TallGrass = new BlockInfo(31, "Tall Grass").SetOpacity(0).SetState(BlockState.NONSOLID); - DeadShrub = new BlockInfo(32, "Dead Shrub").SetOpacity(0).SetState(BlockState.NONSOLID); - Piston = new BlockInfo(33, "Piston").SetOpacity(0); - PistonHead = new BlockInfo(34, "Piston Head").SetOpacity(0); - Wool = new BlockInfo(35, "Wool"); - PistonMoving = (BlockInfoEx)new BlockInfoEx(36, "Piston Moving").SetOpacity(0); - YellowFlower = new BlockInfo(37, "Yellow Flower").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - RedRose = new BlockInfo(38, "Red Rose").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - BrownMushroom = new BlockInfo(39, "Brown Mushroom").SetOpacity(0).SetLuminance(1).SetState(BlockState.NONSOLID).SetTick(10); - RedMushroom = new BlockInfo(40, "Red Mushroom").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - GoldBlock = new BlockInfo(41, "Gold Block"); - IronBlock = new BlockInfo(42, "Iron Block"); - DoubleStoneSlab = new BlockInfo(43, "Double Slab"); - StoneSlab = new BlockInfo(44, "Slab").SetOpacity(0); - BrickBlock = new BlockInfo(45, "Brick Block"); - TNT = new BlockInfo(46, "TNT"); - Bookshelf = new BlockInfo(47, "Bookshelf"); - MossStone = new BlockInfo(48, "Moss Stone"); - Obsidian = new BlockInfo(49, "Obsidian"); - Torch = new BlockInfo(50, "Torch").SetOpacity(0).SetLuminance(MAX_LUMINANCE - 1).SetState(BlockState.NONSOLID).SetTick(10); - Fire = new BlockInfo(51, "Fire").SetOpacity(0).SetLuminance(MAX_LUMINANCE).SetState(BlockState.NONSOLID).SetTick(40); - MonsterSpawner = (BlockInfoEx)new BlockInfoEx(52, "Monster Spawner").SetOpacity(0); - WoodStairs = new BlockInfo(53, "Wooden Stairs").SetOpacity(0); - Chest = (BlockInfoEx)new BlockInfoEx(54, "Chest").SetOpacity(0); - RedstoneWire = new BlockInfo(55, "Redstone Wire").SetOpacity(0).SetState(BlockState.NONSOLID); - DiamondOre = new BlockInfo(56, "Diamond Ore"); - DiamondBlock = new BlockInfo(57, "Diamond Block"); - CraftTable = new BlockInfo(58, "Crafting Table"); - Crops = new BlockInfo(59, "Crops").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - Farmland = new BlockInfo(60, "Farmland").SetOpacity(0).SetTick(10); - Furnace = new BlockInfoEx(61, "Furnace"); - BurningFurnace = (BlockInfoEx)new BlockInfoEx(62, "Burning Furnace").SetLuminance(MAX_LUMINANCE - 1); - SignPost = (BlockInfoEx)new BlockInfoEx(63, "Sign Post").SetOpacity(0).SetState(BlockState.NONSOLID); - WoodDoor = new BlockInfo(64, "Wooden Door").SetOpacity(0); - Ladder = new BlockInfo(65, "Ladder").SetOpacity(0); - Rails = new BlockInfo(66, "Rails").SetOpacity(0).SetState(BlockState.NONSOLID); - CobbleStairs = new BlockInfo(67, "Cobblestone Stairs").SetOpacity(0); - WallSign = (BlockInfoEx)new BlockInfoEx(68, "Wall Sign").SetOpacity(0).SetState(BlockState.NONSOLID); - Lever = new BlockInfo(69, "Lever").SetOpacity(0).SetState(BlockState.NONSOLID); - StonePlate = new BlockInfo(70, "Stone Pressure Plate").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(20); - IronDoor = new BlockInfo(71, "Iron Door").SetOpacity(0); - WoodPlate = new BlockInfo(72, "Wooden Pressure Plate").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(20); - RedstoneOre = new BlockInfo(73, "Redstone Ore").SetTick(30); - GlowRedstoneOre = new BlockInfo(74, "Glowing Redstone Ore").SetLuminance(9).SetTick(30); - RedstoneTorch = new BlockInfo(75, "Redstone Torch (Off)").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(2); - RedstoneTorchOn = new BlockInfo(76, "Redstone Torch (On)").SetOpacity(0).SetLuminance(7).SetState(BlockState.NONSOLID).SetTick(2); - StoneButton = new BlockInfo(77, "Stone Button").SetOpacity(0).SetState(BlockState.NONSOLID); - Snow = new BlockInfo(78, "Snow").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - Ice = new BlockInfo(79, "Ice").SetOpacity(3).SetTick(10); - SnowBlock = new BlockInfo(80, "Snow Block").SetTick(10); - Cactus = new BlockInfo(81, "Cactus").SetOpacity(0).SetTick(10); - ClayBlock = new BlockInfo(82, "Clay Block"); - SugarCane = new BlockInfo(83, "Sugar Cane").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - Jukebox = new BlockInfo(84, "Jukebox"); - Fence = new BlockInfo(85, "Fence").SetOpacity(0); - Pumpkin = new BlockInfo(86, "Pumpkin"); - Netherrack = new BlockInfo(87, "Netherrack"); - SoulSand = new BlockInfo(88, "Soul Sand"); - Glowstone = new BlockInfo(89, "Glowstone Block").SetLuminance(MAX_LUMINANCE); - Portal = new BlockInfo(90, "Portal").SetOpacity(0).SetLuminance(11).SetState(BlockState.NONSOLID); - JackOLantern = new BlockInfo(91, "Jack-O-Lantern").SetLuminance(MAX_LUMINANCE); - CakeBlock = new BlockInfo(92, "Cake Block").SetOpacity(0); - RedstoneRepeater = new BlockInfo(93, "Redstone Repeater (Off)").SetOpacity(0).SetTick(10); - RedstoneRepeaterOn = new BlockInfo(94, "Redstone Repeater (On)").SetOpacity(0).SetLuminance(7).SetTick(10); - LockedChest = (BlockInfoEx)new BlockInfoEx(95, "Locked Chest").SetLuminance(MAX_LUMINANCE).SetTick(10); - StainedGlass = new BlockInfo(95, "Stained Glass").SetOpacity(0); - Trapdoor = new BlockInfo(96, "Trapdoor").SetOpacity(0); - SilverfishStone = new BlockInfo(97, "Stone with Silverfish"); - StoneBrick = new BlockInfo(98, "Stone Brick"); - HugeRedMushroom = new BlockInfo(99, "Huge Red Mushroom"); - HugeBrownMushroom = new BlockInfo(100, "Huge Brown Mushroom"); - IronBars = new BlockInfo(101, "Iron Bars").SetOpacity(0); - GlassPane = new BlockInfo(102, "Glass Pane").SetOpacity(0); - Melon = new BlockInfo(103, "Melon"); - PumpkinStem = new BlockInfo(104, "Pumpkin Stem").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - MelonStem = new BlockInfo(105, "Melon Stem").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - Vines = new BlockInfo(106, "Vines").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - FenceGate = new BlockInfo(107, "Fence Gate").SetOpacity(0); - BrickStairs = new BlockInfo(108, "Brick Stairs").SetOpacity(0); - StoneBrickStairs = new BlockInfo(109, "Stone Brick Stairs").SetOpacity(0); - Mycelium = new BlockInfo(110, "Mycelium").SetTick(10); - LillyPad = new BlockInfo(111, "Lilly Pad").SetOpacity(0).SetState(BlockState.NONSOLID); - NetherBrick = new BlockInfo(112, "Nether Brick"); - NetherBrickFence = new BlockInfo(113, "Nether Brick Fence").SetOpacity(0); - NetherBrickStairs = new BlockInfo(114, "Nether Brick Stairs").SetOpacity(0); - NetherWart = new BlockInfo(115, "Nether Wart").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - EnchantmentTable = (BlockInfoEx)new BlockInfoEx(116, "Enchantment Table").SetOpacity(0); - BrewingStand = (BlockInfoEx)new BlockInfoEx(117, "Brewing Stand").SetOpacity(0); - Cauldron = new BlockInfo(118, "Cauldron").SetOpacity(0); - EndPortal = (BlockInfoEx)new BlockInfoEx(119, "End Portal").SetOpacity(0).SetLuminance(MAX_LUMINANCE).SetState(BlockState.NONSOLID); - EndPortalFrame = new BlockInfo(120, "End Portal Frame").SetLuminance(MAX_LUMINANCE); - EndStone = new BlockInfo(121, "End Stone"); - DragonEgg = new BlockInfo(122, "Dragon Egg").SetOpacity(0).SetLuminance(1).SetTick(3); - RedstoneLampOff = new BlockInfo(123, "Redstone Lamp (Off)").SetTick(2); - RedstoneLampOn = new BlockInfo(124, "Redstone Lamp (On)").SetLuminance(15).SetTick(2); - DoubleWoodSlab = new BlockInfo(125, "Double Wood Slab"); - WoodSlab = new BlockInfo(126, "Wood Slab"); - CocoaPlant = new BlockInfo(127, "Cocoa Plant").SetLuminance(2).SetOpacity(0); - SandstoneStairs = new BlockInfo(128, "Sandstone Stairs").SetOpacity(0); - EmeraldOre = new BlockInfo(129, "Emerald Ore"); - EnderChest = (BlockInfoEx)new BlockInfoEx(130, "Ender Chest").SetLuminance(7).SetOpacity(0); - TripwireHook = new BlockInfo(131, "Tripwire Hook").SetOpacity(0).SetState(BlockState.NONSOLID); - Tripwire = new BlockInfo(132, "Tripwire").SetOpacity(0).SetState(BlockState.NONSOLID); - EmeraldBlock = new BlockInfo(133, "Emerald Block"); - SpruceWoodStairs = new BlockInfo(134, "Sprice Wood Stairs").SetOpacity(0); - BirchWoodStairs = new BlockInfo(135, "Birch Wood Stairs").SetOpacity(0); - JungleWoodStairs = new BlockInfo(136, "Jungle Wood Stairs").SetOpacity(0); - CommandBlock = (BlockInfoEx)new BlockInfoEx(137, "Command Block"); - BeaconBlock = (BlockInfoEx)new BlockInfoEx(138, "Beacon Block").SetOpacity(0).SetLuminance(MAX_LUMINANCE); - CobblestoneWall = new BlockInfo(139, "Cobblestone Wall").SetOpacity(0); - FlowerPot = new BlockInfo(140, "Flower Pot").SetOpacity(0); - Carrots = new BlockInfo(141, "Carrots").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - Potatoes = new BlockInfo(142, "Potatoes").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - WoodButton = new BlockInfo(143, "Wooden Button").SetOpacity(0).SetState(BlockState.NONSOLID); - Heads = new BlockInfo(144, "Heads").SetOpacity(0); - Anvil = new BlockInfo(145, "Anvil").SetOpacity(0); - TrappedChest = (BlockInfoEx)new BlockInfoEx(146, "Trapped Chest").SetOpacity(0).SetTick(10); - WeightedPressurePlateLight = new BlockInfo(147, "Weighted Pressure Plate (Light)").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(20); - WeightedPressurePlateHeavy = new BlockInfo(148, "Weighted Pressure Plate (Heavy)").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(20); - RedstoneComparatorInactive = new BlockInfo(149, "Redstone Comparator (Inactive)").SetOpacity(0).SetTick(10); - RedstoneComparatorActive = new BlockInfo(150, "Redstone Comparator (Active)").SetOpacity(0).SetLuminance(9).SetTick(10); - DaylightSensor = new BlockInfo(151, "Daylight Sensor").SetOpacity(0).SetTick(10); - RedstoneBlock = new BlockInfo(152, "Block of Redstone").SetTick(10); - NetherQuartzOre = new BlockInfo(153, "Neither Quartz Ore"); - Hopper = (BlockInfoEx)new BlockInfoEx(154, "Hopper").SetOpacity(0).SetTick(10); - QuartzBlock = new BlockInfo(155, "Block of Quartz"); - QuartzStairs = new BlockInfo(156, "Quartz Stairs").SetOpacity(0); - ActivatorRail = new BlockInfo(157, "Activator Rail").SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); - Dropper = (BlockInfoEx)new BlockInfoEx(158, "Dropper").SetTick(10); - StainedClay = new BlockInfo(159, "Stained Clay"); - StainedGlassPane = new BlockInfo(160, "Stained Glass Pane").SetOpacity(0); - HayBlock = new BlockInfo(170, "Hay Block"); - Carpet = new BlockInfo(171, "Carpet").SetOpacity(0); - HardenedClay = new BlockInfo(172, "Hardened Clay"); - CoalBlock = new BlockInfo(173, "Block of Coal"); - - for (int i = 0; i < MAX_BLOCKS; i++) { - if (_blockTable[i] == null) { - _blockTable[i] = new BlockInfo(i); - } - } - - // Override default light transmission rules - - Lava.SetLightTransmission(false); - StationaryLava.SetLightTransmission(false); - StoneSlab.SetLightTransmission(false); - WoodStairs.SetLightTransmission(false); - Farmland.SetLightTransmission(false); - CobbleStairs.SetLightTransmission(false); - BrickStairs.SetLightTransmission(false); - StoneBrickStairs.SetLightTransmission(false); - NetherBrickStairs.SetLightTransmission(false); - WoodSlab.SetLightTransmission(false); - SandstoneStairs.SetLightTransmission(false); - SpruceWoodStairs.SetLightTransmission(false); - BirchWoodStairs.SetLightTransmission(false); - JungleWoodStairs.SetLightTransmission(false); - QuartzStairs.SetLightTransmission(false); - Carpet.SetLightTransmission(false); - - // Override default fluid blocking rules - - SignPost.SetBlocksFluid(true); - WallSign.SetBlocksFluid(true); - Cactus.SetBlocksFluid(false); - - // Set Tile Entity Data - - Dispenser.SetTileEntity("Trap"); - NoteBlock.SetTileEntity("Music"); - PistonMoving.SetTileEntity("Piston"); - MonsterSpawner.SetTileEntity("MobSpawner"); - Chest.SetTileEntity("Chest"); - Furnace.SetTileEntity("Furnace"); - BurningFurnace.SetTileEntity("Furnace"); - SignPost.SetTileEntity("Sign"); - WallSign.SetTileEntity("Sign"); - EnchantmentTable.SetTileEntity("EnchantTable"); - BrewingStand.SetTileEntity("Cauldron"); - EndPortal.SetTileEntity("Airportal"); - EnderChest.SetTileEntity("EnderChest"); - CommandBlock.SetTileEntity("Control"); - BeaconBlock.SetTileEntity("Beacon"); - TrappedChest.SetTileEntity("Chest"); - Hopper.SetTileEntity("Hopper"); - Dropper.SetTileEntity("Dropper"); - - // Set Data Limits - - Wood.SetDataLimits(0, 2, 0); - Leaves.SetDataLimits(0, 2, 0); - Jukebox.SetDataLimits(0, 2, 0); - Sapling.SetDataLimits(0, 15, 0); - Cactus.SetDataLimits(0, 15, 0); - SugarCane.SetDataLimits(0, 15, 0); - Water.SetDataLimits(0, 7, 0x8); - Lava.SetDataLimits(0, 7, 0x8); - TallGrass.SetDataLimits(0, 2, 0); - Crops.SetDataLimits(0, 7, 0); - PoweredRail.SetDataLimits(0, 5, 0x8); - DetectorRail.SetDataLimits(0, 5, 0x8); - StickyPiston.SetDataLimits(1, 5, 0x8); - Piston.SetDataLimits(1, 5, 0x8); - PistonHead.SetDataLimits(1, 5, 0x8); - Wool.SetDataLimits(0, 15, 0); - Torch.SetDataLimits(1, 5, 0); - RedstoneTorch.SetDataLimits(0, 5, 0); - RedstoneTorchOn.SetDataLimits(0, 5, 0); - Rails.SetDataLimits(0, 9, 0); - Ladder.SetDataLimits(2, 5, 0); - WoodStairs.SetDataLimits(0, 3, 0x4); - CobbleStairs.SetDataLimits(0, 3, 0x4); - Lever.SetDataLimits(0, 6, 0x8); - WoodDoor.SetDataLimits(0, 3, 0xC); - IronDoor.SetDataLimits(0, 3, 0xC); - StoneButton.SetDataLimits(1, 4, 0x8); - Snow.SetDataLimits(0, 7, 0); - SignPost.SetDataLimits(0, 15, 0); - WallSign.SetDataLimits(2, 5, 0); - Furnace.SetDataLimits(2, 5, 0); - BurningFurnace.SetDataLimits(2, 5, 0); - Dispenser.SetDataLimits(2, 5, 0); - Pumpkin.SetDataLimits(0, 3, 0); - JackOLantern.SetDataLimits(0, 3, 0); - StonePlate.SetDataLimits(0, 0, 0x1); - WoodPlate.SetDataLimits(0, 0, 0x1); - StoneSlab.SetDataLimits(0, 5, 0); - DoubleStoneSlab.SetDataLimits(0, 5, 0x8); - Cactus.SetDataLimits(0, 5, 0); - Bed.SetDataLimits(0, 3, 0x8); - RedstoneRepeater.SetDataLimits(0, 0, 0xF); - RedstoneRepeaterOn.SetDataLimits(0, 0, 0xF); - Trapdoor.SetDataLimits(0, 3, 0x4); - StoneBrick.SetDataLimits(0, 2, 0); - HugeRedMushroom.SetDataLimits(0, 10, 0); - HugeBrownMushroom.SetDataLimits(0, 10, 0); - Vines.SetDataLimits(0, 0, 0xF); - FenceGate.SetDataLimits(0, 3, 0x4); - SilverfishStone.SetDataLimits(0, 2, 0); - BrewingStand.SetDataLimits(0, 0, 0x7); - Cauldron.SetDataLimits(0, 3, 0); - EndPortalFrame.SetDataLimits(0, 0, 0x7); - WoodSlab.SetDataLimits(0, 5, 0); - DoubleWoodSlab.SetDataLimits(0, 5, 0x8); - TripwireHook.SetDataLimits(0, 3, 0xC); - Tripwire.SetDataLimits(0, 0, 0x5); - Anvil.SetDataLimits(0, 0, 0xD); - QuartzBlock.SetDataLimits(0, 4, 0); - QuartzStairs.SetDataLimits(0, 3, 0x4); - Carpet.SetDataLimits(0, 15, 0); - Dropper.SetDataLimits(0, 5, 0); - Hopper.SetDataLimits(0, 5, 0); - } - } - - /// - /// An extended that includes information. - /// - public class BlockInfoEx : BlockInfo - { - private string _tileEntityName; - - /// - /// Gets the name of the type associated with this block type. - /// - public string TileEntityName - { - get { return _tileEntityName; } - } - - internal BlockInfoEx (int id) : base(id) { } - - /// - /// Constructs a new with a given block id and name. - /// - /// The id of the block type. - /// The name of the block type. - public BlockInfoEx (int id, string name) : base(id, name) { } - - /// - /// Sets the name of the type associated with this block type. - /// - /// The name of a registered type. - /// The object instance used to invoke this method. - /// - public BlockInfo SetTileEntity (string name) { - _tileEntityName = name; - return this; - } - } -} diff --git a/SubstrateCS/Source/Core/NBTFile.cs b/SubstrateCS/Source/Core/NBTFile.cs deleted file mode 100644 index f77d6702..00000000 --- a/SubstrateCS/Source/Core/NBTFile.cs +++ /dev/null @@ -1,156 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.IO; -using Ionic.Zlib; -using Substrate.Nbt; - -namespace Substrate.Core -{ - public enum CompressionType - { - None, - Zlib, - Deflate, - GZip, - } - - public class NBTFile - { - private string _filename; - - public NBTFile (string path) - { - _filename = path; - } - - public string FileName - { - get { return _filename; } - protected set { _filename = value; } - } - - public bool Exists () - { - return File.Exists(_filename); - } - - public void Delete () - { - File.Delete(_filename); - } - - public int GetModifiedTime () - { - return Timestamp(File.GetLastWriteTime(_filename)); - } - - public Stream GetDataInputStream () - { - return GetDataInputStream(CompressionType.GZip); - } - - public virtual Stream GetDataInputStream (CompressionType compression) - { - try { - switch (compression) - { - case CompressionType.None: - using (FileStream fstr = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - { - long length = fstr.Seek(0, SeekOrigin.End); - fstr.Seek(0, SeekOrigin.Begin); - - byte[] data = new byte[length]; - fstr.Read(data, 0, data.Length); - - return new MemoryStream(data); - } - case CompressionType.GZip: - Stream stream1 = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - return new GZipStream(stream1, CompressionMode.Decompress); - case CompressionType.Zlib: - Stream stream2 = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - return new ZlibStream(stream2, CompressionMode.Decompress); - case CompressionType.Deflate: - Stream stream3 = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - return new DeflateStream(stream3, CompressionMode.Decompress); - default: - throw new ArgumentException("Invalid CompressionType specified", "compression"); - } - } - catch (Exception ex) { - throw new NbtIOException("Failed to open compressed NBT data stream for input.", ex); - } - } - - public Stream GetDataOutputStream () - { - return GetDataOutputStream(CompressionType.GZip); - } - - public virtual Stream GetDataOutputStream (CompressionType compression) - { - try { - switch (compression) { - case CompressionType.None: - return new NBTBuffer(this); - case CompressionType.GZip: - return new GZipStream(new NBTBuffer(this), CompressionMode.Compress); - case CompressionType.Zlib: - return new ZlibStream(new NBTBuffer(this), CompressionMode.Compress); - case CompressionType.Deflate: - return new DeflateStream(new NBTBuffer(this), CompressionMode.Compress); - default: - throw new ArgumentException("Invalid CompressionType specified", "compression"); - } - } - catch (Exception ex) { - throw new NbtIOException("Failed to initialize compressed NBT data stream for output.", ex); - } - } - - class NBTBuffer : MemoryStream - { - private NBTFile file; - - public NBTBuffer (NBTFile c) - : base(8096) - { - this.file = c; - } - - public override void Close () - { - try - { - using (Stream fstr = new FileStream(file._filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - { - try - { - fstr.Write(this.GetBuffer(), 0, (int)this.Length); - } - catch (Exception ex) - { - throw new NbtIOException("Failed to write out NBT data stream.", ex); - } - } - } - catch (NbtIOException) - { - throw; - } - catch (Exception ex) - { - throw new NbtIOException("Failed to open NBT data stream for output.", ex); - } - } - } - - private int Timestamp (DateTime time) - { - DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0); - return (int)((time - epoch).Ticks / (10000L * 1000L)); - } - } -} diff --git a/SubstrateCS/Source/Item.cs b/SubstrateCS/Source/Item.cs deleted file mode 100644 index 28cdd8e5..00000000 --- a/SubstrateCS/Source/Item.cs +++ /dev/null @@ -1,221 +0,0 @@ -using System; -using System.Collections.Generic; -using Substrate.Core; -using Substrate.Nbt; - -namespace Substrate -{ - /// - /// Represents an item (or item stack) within an item slot. - /// - public class Item : INbtObject, ICopyable - { - private static readonly SchemaNodeCompound _schema = new SchemaNodeCompound("") - { - new SchemaNodeScaler("id", TagType.TAG_SHORT), - new SchemaNodeScaler("Damage", TagType.TAG_SHORT), - new SchemaNodeScaler("Count", TagType.TAG_BYTE), - new SchemaNodeCompound("tag", new SchemaNodeCompound("") { - new SchemaNodeList("ench", TagType.TAG_COMPOUND, Enchantment.Schema, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("title", TagType.TAG_STRING, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("author", TagType.TAG_STRING, SchemaOptions.OPTIONAL), - new SchemaNodeList("pages", TagType.TAG_STRING, SchemaOptions.OPTIONAL), - }, SchemaOptions.OPTIONAL), - }; - - private TagNodeCompound _source; - - private short _id; - private byte _count; - private short _damage; - - private List _enchantments; - - /// - /// Constructs an empty instance. - /// - public Item () - { - _enchantments = new List(); - _source = new TagNodeCompound(); - } - - /// - /// Constructs an instance representing the given item id. - /// - /// An item id. - public Item (int id) - : this() - { - _id = (short)id; - } - - #region Properties - - /// - /// Gets an entry for this item's type. - /// - public ItemInfo Info - { - get { return ItemInfo.ItemTable[_id]; } - } - - /// - /// Gets or sets the current type (id) of the item. - /// - public int ID - { - get { return _id; } - set { _id = (short)value; } - } - - /// - /// Gets or sets the damage value of the item. - /// - /// The damage value may represent a generic data value for some items. - public int Damage - { - get { return _damage; } - set { _damage = (short)value; } - } - - /// - /// Gets or sets the number of this item stacked together in an item slot. - /// - public int Count - { - get { return _count; } - set { _count = (byte)value; } - } - - /// - /// Gets the list of s applied to this item. - /// - public IList Enchantments - { - get { return _enchantments; } - } - - /// - /// Gets the source used to create this if it exists. - /// - public TagNodeCompound Source - { - get { return _source; } - } - - /// - /// Gets a representing the schema of an item. - /// - public static SchemaNodeCompound Schema - { - get { return _schema; } - } - - #endregion - - #region ICopyable Members - - /// - public Item Copy () - { - Item item = new Item(); - item._id = _id; - item._count = _count; - item._damage = _damage; - - foreach (Enchantment e in _enchantments) { - item._enchantments.Add(e.Copy()); - } - - if (_source != null) { - item._source = _source.Copy() as TagNodeCompound; - } - - return item; - } - - #endregion - - #region INBTObject Members - - /// - public Item LoadTree (TagNode tree) - { - TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null) { - return null; - } - - _enchantments.Clear(); - - _id = ctree["id"].ToTagShort(); - _count = ctree["Count"].ToTagByte(); - _damage = ctree["Damage"].ToTagShort(); - - if (ctree.ContainsKey("tag")) { - TagNodeCompound tagtree = ctree["tag"].ToTagCompound(); - if (tagtree.ContainsKey("ench")) { - TagNodeList enchList = tagtree["ench"].ToTagList(); - - foreach (TagNode tag in enchList) { - _enchantments.Add(new Enchantment().LoadTree(tag)); - } - } - } - - _source = ctree.Copy() as TagNodeCompound; - - return this; - } - - /// - public Item LoadTreeSafe (TagNode tree) - { - if (!ValidateTree(tree)) { - return null; - } - - return LoadTree(tree); - } - - /// - public TagNode BuildTree () - { - TagNodeCompound tree = new TagNodeCompound(); - tree["id"] = new TagNodeShort(_id); - tree["Count"] = new TagNodeByte(_count); - tree["Damage"] = new TagNodeShort(_damage); - - if (_enchantments.Count > 0) { - TagNodeList enchList = new TagNodeList(TagType.TAG_COMPOUND); - foreach (Enchantment e in _enchantments) { - enchList.Add(e.BuildTree()); - } - - TagNodeCompound tagtree = new TagNodeCompound(); - tagtree["ench"] = enchList; - - if (_source != null && _source.ContainsKey("tag")) { - tagtree.MergeFrom(_source["tag"].ToTagCompound()); - } - - tree["tag"] = tagtree; - } - - if (_source != null) { - tree.MergeFrom(_source); - } - - return tree; - } - - /// - public bool ValidateTree (TagNode tree) - { - return new NbtVerifier(tree, _schema).Verify(); - } - - #endregion - } -} diff --git a/SubstrateCS/Source/ItemInfo.cs b/SubstrateCS/Source/ItemInfo.cs deleted file mode 100644 index a779e2a6..00000000 --- a/SubstrateCS/Source/ItemInfo.cs +++ /dev/null @@ -1,658 +0,0 @@ -using System; -using System.Collections.Generic; -using Substrate.Nbt; -using System.Collections; - -namespace Substrate -{ - /// - /// Provides named id values for known item types. - /// - /// See for additional information. - public static class ItemType - { - public const int IRON_SHOVEL = 256; - public const int IRON_PICKAXE = 257; - public const int IRON_AXE = 258; - public const int FLINT_AND_STEEL = 259; - public const int APPLE = 260; - public const int BOW = 261; - public const int ARROW = 262; - public const int COAL = 263; - public const int DIAMOND = 264; - public const int IRON_INGOT = 265; - public const int GOLD_INGOT = 266; - public const int IRON_SWORD = 267; - public const int WOODEN_SWORD = 268; - public const int WOODEN_SHOVEL = 269; - public const int WOODEN_PICKAXE = 270; - public const int WOODEN_AXE = 271; - public const int STONE_SWORD = 272; - public const int STONE_SHOVEL = 273; - public const int STONE_PICKAXE = 274; - public const int STONE_AXE = 275; - public const int DIAMOND_SWORD = 276; - public const int DIAMOND_SHOVEL = 277; - public const int DIAMOND_PICKAXE = 278; - public const int DIAMOND_AXE = 279; - public const int STICK = 280; - public const int BOWL = 281; - public const int MUSHROOM_SOUP = 282; - public const int GOLD_SWORD = 283; - public const int GOLD_SHOVEL = 284; - public const int GOLD_PICKAXE = 285; - public const int GOLD_AXE = 286; - public const int STRING = 287; - public const int FEATHER = 288; - public const int GUNPOWDER = 289; - public const int WOODEN_HOE = 290; - public const int STONE_HOE = 291; - public const int IRON_HOE = 292; - public const int DIAMOND_HOE = 293; - public const int GOLD_HOE = 294; - public const int SEEDS = 295; - public const int WHEAT = 296; - public const int BREAD = 297; - public const int LEATHER_CAP = 298; - public const int LEATHER_TUNIC = 299; - public const int LEATHER_PANTS = 300; - public const int LEATHER_BOOTS = 301; - public const int CHAIN_HELMET = 302; - public const int CHAIN_CHESTPLATE = 303; - public const int CHAIN_LEGGINGS = 304; - public const int CHAIN_BOOTS = 305; - public const int IRON_HELMET = 306; - public const int IRON_CHESTPLATE = 307; - public const int IRON_LEGGINGS = 308; - public const int IRON_BOOTS = 309; - public const int DIAMOND_HELMET = 310; - public const int DIAMOND_CHESTPLATE = 311; - public const int DIAMOND_LEGGINGS = 312; - public const int DIAMOND_BOOTS = 313; - public const int GOLD_HELMET = 314; - public const int GOLD_CHESTPLATE = 315; - public const int GOLD_LEGGINGS = 316; - public const int GOLD_BOOTS = 317; - public const int FLINT = 318; - public const int RAW_PORKCHOP = 319; - public const int COOKED_PORKCHOP = 320; - public const int PAINTING = 321; - public const int GOLDEN_APPLE = 322; - public const int SIGN = 323; - public const int WOODEN_DOOR = 324; - public const int BUCKET = 325; - public const int WATER_BUCKET = 326; - public const int LAVA_BUCKET = 327; - public const int MINECART = 328; - public const int SADDLE = 329; - public const int IRON_DOOR = 330; - public const int REDSTONE_DUST = 331; - public const int SNOWBALL = 332; - public const int BOAT = 333; - public const int LEATHER = 334; - public const int MILK = 335; - public const int CLAY_BRICK = 336; - public const int CLAY = 337; - public const int SUGAR_CANE = 338; - public const int PAPER = 339; - public const int BOOK = 340; - public const int SLIMEBALL = 341; - public const int STORAGE_MINECART = 342; - public const int POWERED_MINECARD = 343; - public const int EGG = 344; - public const int COMPASS = 345; - public const int FISHING_ROD = 346; - public const int CLOCK = 347; - public const int GLOWSTONE_DUST = 348; - public const int RAW_FISH = 349; - public const int COOKED_FISH = 350; - public const int DYE = 351; - public const int BONE = 352; - public const int SUGAR = 353; - public const int CAKE = 354; - public const int BED = 355; - public const int REDSTONE_REPEATER = 356; - public const int COOKIE = 357; - public const int MAP = 358; - public const int SHEARS = 359; - public const int MELON_SLICE = 360; - public const int PUMPKIN_SEEDS = 361; - public const int MELON_SEEDS = 262; - public const int RAW_BEEF = 363; - public const int STEAK = 364; - public const int RAW_CHICKEN = 365; - public const int COOKED_CHICKEN = 366; - public const int ROTTEN_FLESH = 367; - public const int ENDER_PEARL = 368; - public const int BLAZE_ROD = 369; - public const int GHAST_TEAR = 370; - public const int GOLD_NUGGET = 371; - public const int NETHER_WART = 372; - public const int POTION = 373; - public const int GLASS_BOTTLE = 374; - public const int SPIDER_EYE = 375; - public const int FERMENTED_SPIDER_EYE = 376; - public const int BLAZE_POWDER = 377; - public const int MAGMA_CREAM = 378; - public const int BREWING_STAND = 379; - public const int CAULDRON = 380; - public const int EYE_OF_ENDER = 381; - public const int GLISTERING_MELON = 382; - public const int SPAWN_EGG = 383; - public const int BOTTLE_O_ENCHANTING = 384; - public const int FIRE_CHARGE = 385; - public const int BOOK_AND_QUILL = 386; - public const int WRITTEN_BOOK = 387; - public const int EMERALD = 388; - public const int ITEM_FRAME = 389; - public const int FLOWER_POT = 390; - public const int CARROT = 391; - public const int POTATO = 392; - public const int BAKED_POTATO = 393; - public const int POISON_POTATO = 394; - public const int EMPTY_MAP = 395; - public const int GOLDEN_CARROT = 396; - public const int MOB_HEAD = 397; - public const int CARROT_ON_A_STICK = 398; - public const int NETHER_STAR = 399; - public const int PUMPKIN_PIE = 400; - public const int FIREWORK_ROCKET = 401; - public const int FIREWORK_STAR = 402; - public const int ENCHANTED_BOOK = 403; - public const int REDSTONE_COMPARATOR = 404; - public const int NETHER_BRICK = 405; - public const int NETHER_QUARTZ = 406; - public const int TNT_MINECART = 407; - public const int HOPPER_MINECART = 408; - public const int IRON_HORSE_ARMOR = 417; - public const int GOLD_HORSE_ARMOR = 418; - public const int DIAMOND_HORSE_ARMOR = 419; - public const int LEAD = 420; - public const int NAME_TAG = 421; - public const int MUSIC_DISC_13 = 2256; - public const int MUSIC_DISC_CAT = 2257; - public const int MUSIC_DISC_BLOCKS = 2258; - public const int MUSIC_DISC_CHIRP = 2259; - public const int MUSIC_DISC_FAR = 2260; - public const int MUSIC_DISC_MALL = 2261; - public const int MUSIC_DISC_MELLOHI = 2262; - public const int MUSIC_DISC_STAL = 2263; - public const int MUSIC_DISC_STRAD = 2264; - public const int MUSIC_DISC_WARD = 2265; - public const int MUSIC_DISC_11 = 2266; - } - - /// - /// Provides information on a specific type of item. - /// - /// By default, all known MC item types are already defined and registered, assuming Substrate - /// is up to date with the current MC version. - /// New item types may be created and used at runtime, and will automatically populate various static lookup tables - /// in the class. - public class ItemInfo - { - private static Random _rand = new Random(); - - private class CacheTableDict : ICacheTable - { - private Dictionary _cache; - - public T this[int index] - { - get - { - T val; - if (_cache.TryGetValue(index, out val)) { - return val; - } - return default(T); - } - } - - public CacheTableDict (Dictionary cache) - { - _cache = cache; - } - - public IEnumerator GetEnumerator () - { - foreach (T val in _cache.Values) - yield return val; - } - - IEnumerator IEnumerable.GetEnumerator () - { - return GetEnumerator(); - } - } - - private static readonly Dictionary _itemTable; - - private int _id = 0; - private string _name = ""; - private int _stack = 1; - - private static readonly CacheTableDict _itemTableCache; - - /// - /// Gets the lookup table for id-to-info values. - /// - public static ICacheTable ItemTable - { - get { return _itemTableCache; } - } - - /// - /// Gets the id of the item type. - /// - public int ID - { - get { return _id; } - } - - /// - /// Gets the name of the item type. - /// - public string Name - { - get { return _name; } - } - - /// - /// Gets the maximum stack size allowed for this item type. - /// - public int StackSize - { - get { return _stack; } - } - - /// - /// Constructs a new record for the given item id. - /// - /// The id of an item type. - public ItemInfo (int id) - { - _id = id; - _itemTable[_id] = this; - } - - /// - /// Constructs a new record for the given item id and name. - /// - /// The id of an item type. - /// The name of an item type. - public ItemInfo (int id, string name) - { - _id = id; - _name = name; - _itemTable[_id] = this; - } - - /// - /// Sets the maximum stack size for this item type. - /// - /// A stack size between 1 and 64, inclusive. - /// The object instance used to invoke this method. - public ItemInfo SetStackSize (int stack) - { - _stack = stack; - return this; - } - - /// - /// Chooses a registered item type at random and returns it. - /// - /// - public static ItemInfo GetRandomItem () - { - List list = new List(_itemTable.Values); - return list[_rand.Next(list.Count)]; - } - - public static ItemInfo IronShovel; - public static ItemInfo IronPickaxe; - public static ItemInfo IronAxe; - public static ItemInfo FlintAndSteel; - public static ItemInfo Apple; - public static ItemInfo Bow; - public static ItemInfo Arrow; - public static ItemInfo Coal; - public static ItemInfo Diamond; - public static ItemInfo IronIngot; - public static ItemInfo GoldIngot; - public static ItemInfo IronSword; - public static ItemInfo WoodenSword; - public static ItemInfo WoodenShovel; - public static ItemInfo WoodenPickaxe; - public static ItemInfo WoodenAxe; - public static ItemInfo StoneSword; - public static ItemInfo StoneShovel; - public static ItemInfo StonePickaxe; - public static ItemInfo StoneAxe; - public static ItemInfo DiamondSword; - public static ItemInfo DiamondShovel; - public static ItemInfo DiamondPickaxe; - public static ItemInfo DiamondAxe; - public static ItemInfo Stick; - public static ItemInfo Bowl; - public static ItemInfo MushroomSoup; - public static ItemInfo GoldSword; - public static ItemInfo GoldShovel; - public static ItemInfo GoldPickaxe; - public static ItemInfo GoldAxe; - public static ItemInfo String; - public static ItemInfo Feather; - public static ItemInfo Gunpowder; - public static ItemInfo WoodenHoe; - public static ItemInfo StoneHoe; - public static ItemInfo IronHoe; - public static ItemInfo DiamondHoe; - public static ItemInfo GoldHoe; - public static ItemInfo Seeds; - public static ItemInfo Wheat; - public static ItemInfo Bread; - public static ItemInfo LeatherCap; - public static ItemInfo LeatherTunic; - public static ItemInfo LeatherPants; - public static ItemInfo LeatherBoots; - public static ItemInfo ChainHelmet; - public static ItemInfo ChainChestplate; - public static ItemInfo ChainLeggings; - public static ItemInfo ChainBoots; - public static ItemInfo IronHelmet; - public static ItemInfo IronChestplate; - public static ItemInfo IronLeggings; - public static ItemInfo IronBoots; - public static ItemInfo DiamondHelmet; - public static ItemInfo DiamondChestplate; - public static ItemInfo DiamondLeggings; - public static ItemInfo DiamondBoots; - public static ItemInfo GoldHelmet; - public static ItemInfo GoldChestplate; - public static ItemInfo GoldLeggings; - public static ItemInfo GoldBoots; - public static ItemInfo Flint; - public static ItemInfo RawPorkchop; - public static ItemInfo CookedPorkchop; - public static ItemInfo Painting; - public static ItemInfo GoldenApple; - public static ItemInfo Sign; - public static ItemInfo WoodenDoor; - public static ItemInfo Bucket; - public static ItemInfo WaterBucket; - public static ItemInfo LavaBucket; - public static ItemInfo Minecart; - public static ItemInfo Saddle; - public static ItemInfo IronDoor; - public static ItemInfo RedstoneDust; - public static ItemInfo Snowball; - public static ItemInfo Boat; - public static ItemInfo Leather; - public static ItemInfo Milk; - public static ItemInfo ClayBrick; - public static ItemInfo Clay; - public static ItemInfo SugarCane; - public static ItemInfo Paper; - public static ItemInfo Book; - public static ItemInfo Slimeball; - public static ItemInfo StorageMinecart; - public static ItemInfo PoweredMinecart; - public static ItemInfo Egg; - public static ItemInfo Compass; - public static ItemInfo FishingRod; - public static ItemInfo Clock; - public static ItemInfo GlowstoneDust; - public static ItemInfo RawFish; - public static ItemInfo CookedFish; - public static ItemInfo Dye; - public static ItemInfo Bone; - public static ItemInfo Sugar; - public static ItemInfo Cake; - public static ItemInfo Bed; - public static ItemInfo RedstoneRepeater; - public static ItemInfo Cookie; - public static ItemInfo Map; - public static ItemInfo Shears; - public static ItemInfo MelonSlice; - public static ItemInfo PumpkinSeeds; - public static ItemInfo MelonSeeds; - public static ItemInfo RawBeef; - public static ItemInfo Steak; - public static ItemInfo RawChicken; - public static ItemInfo CookedChicken; - public static ItemInfo RottenFlesh; - public static ItemInfo EnderPearl; - public static ItemInfo BlazeRod; - public static ItemInfo GhastTear; - public static ItemInfo GoldNugget; - public static ItemInfo NetherWart; - public static ItemInfo Potion; - public static ItemInfo GlassBottle; - public static ItemInfo SpiderEye; - public static ItemInfo FermentedSpiderEye; - public static ItemInfo BlazePowder; - public static ItemInfo MagmaCream; - public static ItemInfo BrewingStand; - public static ItemInfo Cauldron; - public static ItemInfo EyeOfEnder; - public static ItemInfo GlisteringMelon; - public static ItemInfo SpawnEgg; - public static ItemInfo BottleOEnchanting; - public static ItemInfo FireCharge; - public static ItemInfo BookAndQuill; - public static ItemInfo WrittenBook; - public static ItemInfo Emerald; - public static ItemInfo ItemFrame; - public static ItemInfo FlowerPot; - public static ItemInfo Carrot; - public static ItemInfo Potato; - public static ItemInfo BakedPotato; - public static ItemInfo PoisonPotato; - public static ItemInfo EmptyMap; - public static ItemInfo GoldenCarrot; - public static ItemInfo MobHead; - public static ItemInfo CarrotOnStick; - public static ItemInfo NetherStar; - public static ItemInfo PumpkinPie; - public static ItemInfo FireworkRocket; - public static ItemInfo FireworkStar; - public static ItemInfo EnchantedBook; - public static ItemInfo RedstoneComparator; - public static ItemInfo NetherBrick; - public static ItemInfo NetherQuartz; - public static ItemInfo TntMinecart; - public static ItemInfo HopperMinecart; - public static ItemInfo IronHorseArmor; - public static ItemInfo GoldHorseArmor; - public static ItemInfo DiamondHorseArmor; - public static ItemInfo Lead; - public static ItemInfo NameTag; - public static ItemInfo MusicDisc13; - public static ItemInfo MusicDiscCat; - public static ItemInfo MusicDiscBlocks; - public static ItemInfo MusicDiscChirp; - public static ItemInfo MusicDiscFar; - public static ItemInfo MusicDiscMall; - public static ItemInfo MusicDiscMellohi; - public static ItemInfo MusicDiscStal; - public static ItemInfo MusicDiscStrad; - public static ItemInfo MusicDiscWard; - public static ItemInfo MusicDisc11; - - static ItemInfo () - { - _itemTable = new Dictionary(); - _itemTableCache = new CacheTableDict(_itemTable); - - IronShovel = new ItemInfo(256, "Iron Shovel"); - IronPickaxe = new ItemInfo(257, "Iron Pickaxe"); - IronAxe = new ItemInfo(258, "Iron Axe"); - FlintAndSteel = new ItemInfo(259, "Flint and Steel"); - Apple = new ItemInfo(260, "Apple").SetStackSize(64); - Bow = new ItemInfo(261, "Bow"); - Arrow = new ItemInfo(262, "Arrow").SetStackSize(64); - Coal = new ItemInfo(263, "Coal").SetStackSize(64); - Diamond = new ItemInfo(264, "Diamond").SetStackSize(64); - IronIngot = new ItemInfo(265, "Iron Ingot").SetStackSize(64); - GoldIngot = new ItemInfo(266, "Gold Ingot").SetStackSize(64); - IronSword = new ItemInfo(267, "Iron Sword"); - WoodenSword = new ItemInfo(268, "Wooden Sword"); - WoodenShovel = new ItemInfo(269, "Wooden Shovel"); - WoodenPickaxe = new ItemInfo(270, "Wooden Pickaxe"); - WoodenAxe = new ItemInfo(271, "Wooden Axe"); - StoneSword = new ItemInfo(272, "Stone Sword"); - StoneShovel = new ItemInfo(273, "Stone Shovel"); - StonePickaxe = new ItemInfo(274, "Stone Pickaxe"); - StoneAxe = new ItemInfo(275, "Stone Axe"); - DiamondSword = new ItemInfo(276, "Diamond Sword"); - DiamondShovel = new ItemInfo(277, "Diamond Shovel"); - DiamondPickaxe = new ItemInfo(278, "Diamond Pickaxe"); - DiamondAxe = new ItemInfo(279, "Diamond Axe"); - Stick = new ItemInfo(280, "Stick").SetStackSize(64); - Bowl = new ItemInfo(281, "Bowl").SetStackSize(64); - MushroomSoup = new ItemInfo(282, "Mushroom Soup"); - GoldSword = new ItemInfo(283, "Gold Sword"); - GoldShovel = new ItemInfo(284, "Gold Shovel"); - GoldPickaxe = new ItemInfo(285, "Gold Pickaxe"); - GoldAxe = new ItemInfo(286, "Gold Axe"); - String = new ItemInfo(287, "String").SetStackSize(64); - Feather = new ItemInfo(288, "Feather").SetStackSize(64); - Gunpowder = new ItemInfo(289, "Gunpowder").SetStackSize(64); - WoodenHoe = new ItemInfo(290, "Wooden Hoe"); - StoneHoe = new ItemInfo(291, "Stone Hoe"); - IronHoe = new ItemInfo(292, "Iron Hoe"); - DiamondHoe = new ItemInfo(293, "Diamond Hoe"); - GoldHoe = new ItemInfo(294, "Gold Hoe"); - Seeds = new ItemInfo(295, "Seeds").SetStackSize(64); - Wheat = new ItemInfo(296, "Wheat").SetStackSize(64); - Bread = new ItemInfo(297, "Bread").SetStackSize(64); - LeatherCap = new ItemInfo(298, "Leather Cap"); - LeatherTunic = new ItemInfo(299, "Leather Tunic"); - LeatherPants = new ItemInfo(300, "Leather Pants"); - LeatherBoots = new ItemInfo(301, "Leather Boots"); - ChainHelmet = new ItemInfo(302, "Chain Helmet"); - ChainChestplate = new ItemInfo(303, "Chain Chestplate"); - ChainLeggings = new ItemInfo(304, "Chain Leggings"); - ChainBoots = new ItemInfo(305, "Chain Boots"); - IronHelmet = new ItemInfo(306, "Iron Helmet"); - IronChestplate = new ItemInfo(307, "Iron Chestplate"); - IronLeggings = new ItemInfo(308, "Iron Leggings"); - IronBoots = new ItemInfo(309, "Iron Boots"); - DiamondHelmet = new ItemInfo(310, "Diamond Helmet"); - DiamondChestplate = new ItemInfo(311, "Diamond Chestplate"); - DiamondLeggings = new ItemInfo(312, "Diamond Leggings"); - DiamondBoots = new ItemInfo(313, "Diamond Boots"); - GoldHelmet = new ItemInfo(314, "Gold Helmet"); - GoldChestplate = new ItemInfo(315, "Gold Chestplate"); - GoldLeggings = new ItemInfo(316, "Gold Leggings"); - GoldBoots = new ItemInfo(317, "Gold Boots"); - Flint = new ItemInfo(318, "Flint").SetStackSize(64); - RawPorkchop = new ItemInfo(319, "Raw Porkchop").SetStackSize(64); - CookedPorkchop = new ItemInfo(320, "Cooked Porkchop").SetStackSize(64); - Painting = new ItemInfo(321, "Painting").SetStackSize(64); - GoldenApple = new ItemInfo(322, "Golden Apple").SetStackSize(64); - Sign = new ItemInfo(323, "Sign"); - WoodenDoor = new ItemInfo(324, "Door"); - Bucket = new ItemInfo(325, "Bucket"); - WaterBucket = new ItemInfo(326, "Water Bucket"); - LavaBucket = new ItemInfo(327, "Lava Bucket"); - Minecart = new ItemInfo(328, "Minecart"); - Saddle = new ItemInfo(329, "Saddle"); - IronDoor = new ItemInfo(330, "Iron Door"); - RedstoneDust = new ItemInfo(331, "Redstone Dust").SetStackSize(64); - Snowball = new ItemInfo(332, "Snowball").SetStackSize(16); - Boat = new ItemInfo(333, "Boat"); - Leather = new ItemInfo(334, "Leather").SetStackSize(64); - Milk = new ItemInfo(335, "Milk"); - ClayBrick = new ItemInfo(336, "Clay Brick").SetStackSize(64); - Clay = new ItemInfo(337, "Clay").SetStackSize(64); - SugarCane = new ItemInfo(338, "Sugar Cane").SetStackSize(64); - Paper = new ItemInfo(339, "Paper").SetStackSize(64); - Book = new ItemInfo(340, "Book").SetStackSize(64); - Slimeball = new ItemInfo(341, "Slimeball").SetStackSize(64); - StorageMinecart = new ItemInfo(342, "Storage Minecart"); - PoweredMinecart = new ItemInfo(343, "Powered Minecart"); - Egg = new ItemInfo(344, "Egg").SetStackSize(16); - Compass = new ItemInfo(345, "Compass"); - FishingRod = new ItemInfo(346, "Fishing Rod"); - Clock = new ItemInfo(347, "Clock"); - GlowstoneDust = new ItemInfo(348, "Glowstone Dust").SetStackSize(64); - RawFish = new ItemInfo(349, "Raw Fish").SetStackSize(64); - CookedFish = new ItemInfo(350, "Cooked Fish").SetStackSize(64); - Dye = new ItemInfo(351, "Dye").SetStackSize(64); - Bone = new ItemInfo(352, "Bone").SetStackSize(64); - Sugar = new ItemInfo(353, "Sugar").SetStackSize(64); - Cake = new ItemInfo(354, "Cake"); - Bed = new ItemInfo(355, "Bed"); - RedstoneRepeater = new ItemInfo(356, "Redstone Repeater").SetStackSize(64); - Cookie = new ItemInfo(357, "Cookie").SetStackSize(8); - Map = new ItemInfo(358, "Map"); - Shears = new ItemInfo(359, "Shears"); - MelonSlice = new ItemInfo(360, "Melon Slice").SetStackSize(64); - PumpkinSeeds = new ItemInfo(361, "Pumpkin Seeds").SetStackSize(64); - MelonSeeds = new ItemInfo(362, "Melon Seeds").SetStackSize(64); - RawBeef = new ItemInfo(363, "Raw Beef").SetStackSize(64); - Steak = new ItemInfo(364, "Steak").SetStackSize(64); - RawChicken = new ItemInfo(365, "Raw Chicken").SetStackSize(64); - CookedChicken = new ItemInfo(366, "Cooked Chicken").SetStackSize(64); - RottenFlesh = new ItemInfo(367, "Rotten Flesh").SetStackSize(64); - EnderPearl = new ItemInfo(368, "Ender Pearl").SetStackSize(64); - BlazeRod = new ItemInfo(369, "Blaze Rod").SetStackSize(64); - GhastTear = new ItemInfo(370, "Ghast Tear").SetStackSize(64); - GoldNugget = new ItemInfo(371, "Gold Nugget").SetStackSize(64); - NetherWart = new ItemInfo(372, "Nether Wart").SetStackSize(64); - Potion = new ItemInfo(373, "Potion"); - GlassBottle = new ItemInfo(374, "Glass Bottle").SetStackSize(64); - SpiderEye = new ItemInfo(375, "Spider Eye").SetStackSize(64); - FermentedSpiderEye = new ItemInfo(376, "Fermented Spider Eye").SetStackSize(64); - BlazePowder = new ItemInfo(377, "Blaze Powder").SetStackSize(64); - MagmaCream = new ItemInfo(378, "Magma Cream").SetStackSize(64); - BrewingStand = new ItemInfo(379, "Brewing Stand").SetStackSize(64); - Cauldron = new ItemInfo(380, "Cauldron"); - EyeOfEnder = new ItemInfo(381, "Eye of Ender").SetStackSize(64); - GlisteringMelon = new ItemInfo(382, "Glistering Melon").SetStackSize(64); - SpawnEgg = new ItemInfo(383, "Spawn Egg").SetStackSize(64); - BottleOEnchanting = new ItemInfo(384, "Bottle O' Enchanting").SetStackSize(64); - FireCharge = new ItemInfo(385, "Fire Charge").SetStackSize(64); - BookAndQuill = new ItemInfo(386, "Book and Quill"); - WrittenBook = new ItemInfo(387, "Written Book"); - Emerald = new ItemInfo(388, "Emerald").SetStackSize(64); - ItemFrame = new ItemInfo(389, "Item Frame").SetStackSize(64); - FlowerPot = new ItemInfo(390, "Flower Pot").SetStackSize(64); - Carrot = new ItemInfo(391, "Carrot").SetStackSize(64); - Potato = new ItemInfo(392, "Potato").SetStackSize(64); - BakedPotato = new ItemInfo(393, "Baked Potato").SetStackSize(64); - PoisonPotato = new ItemInfo(394, "Poisonous Potato").SetStackSize(64); - EmptyMap = new ItemInfo(395, "Empty Map").SetStackSize(64); - GoldenCarrot = new ItemInfo(396, "Golden Carrot").SetStackSize(64); - MobHead = new ItemInfo(397, "Mob Head").SetStackSize(64); - CarrotOnStick = new ItemInfo(398, "Carrot on a Stick"); - NetherStar = new ItemInfo(399, "Nether Star").SetStackSize(64); - PumpkinPie = new ItemInfo(400, "Pumpkin Pie").SetStackSize(64); - FireworkRocket = new ItemInfo(401, "Firework Rocket"); - FireworkStar = new ItemInfo(402, "Firework Star").SetStackSize(64); - EnchantedBook = new ItemInfo(403, "Enchanted Book"); - RedstoneComparator = new ItemInfo(404, "Redstone Comparator").SetStackSize(64); - NetherBrick = new ItemInfo(405, "Nether Brick").SetStackSize(64); - NetherQuartz = new ItemInfo(406, "Nether Quartz").SetStackSize(64); - TntMinecart = new ItemInfo(407, "Minecart with TNT"); - HopperMinecart = new ItemInfo(408, "Minecart with Hopper"); - IronHorseArmor = new ItemInfo(417, "Iron Horse Armor"); - GoldHorseArmor = new ItemInfo(418, "Gold Horse Armor"); - DiamondHorseArmor = new ItemInfo(419, "Diamond Horse Armor"); - Lead = new ItemInfo(420, "Lead").SetStackSize(64); - NameTag = new ItemInfo(421, "Name Tag").SetStackSize(64); - MusicDisc13 = new ItemInfo(2256, "13 Disc"); - MusicDiscCat = new ItemInfo(2257, "Cat Disc"); - MusicDiscBlocks = new ItemInfo(2258, "Blocks Disc"); - MusicDiscChirp = new ItemInfo(2259, "Chirp Disc"); - MusicDiscFar = new ItemInfo(2260, "Far Disc"); - MusicDiscMall = new ItemInfo(2261, "Mall Disc"); - MusicDiscMellohi = new ItemInfo(2262, "Mellohi Disc"); - MusicDiscStal = new ItemInfo(2263, "Stal Disc"); - MusicDiscStrad = new ItemInfo(2264, "Strad Disc"); - MusicDiscWard = new ItemInfo(2265, "Ward Disc"); - MusicDisc11 = new ItemInfo(2266, "11 Disc"); - } - } -} diff --git a/SubstrateCS/Source/Nbt/SchemaNodeScaler.cs b/SubstrateCS/Source/Nbt/SchemaNodeScaler.cs deleted file mode 100644 index b156c8d8..00000000 --- a/SubstrateCS/Source/Nbt/SchemaNodeScaler.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; - -namespace Substrate.Nbt -{ - /// - /// A concrete representing a scaler-type . - /// - public sealed class SchemaNodeScaler : SchemaNode - { - private TagType _type; - - /// - /// Gets the scaler that this node represents. - /// - public TagType Type - { - get { return _type; } - } - - /// - /// Constructs a new representing a named and of type . - /// - /// The name of the corresponding . - /// The type of the corresponding , restricted to scaler types. - public SchemaNodeScaler (string name, TagType type) - : base(name) - { - _type = type; - } - - /// - /// Constructs a new with additional options. - /// - /// The name of the corresponding . - /// The type of the corresponding , restricted to scaler types. - /// One or more option flags modifying the processing of this node. - public SchemaNodeScaler (string name, TagType type, SchemaOptions options) - : base(name, options) - { - _type = type; - } - - /// - /// Constructs a default according to the this node represents. - /// - /// A with a sensible default value. - public override TagNode BuildDefaultTree () - { - switch (_type) { - case TagType.TAG_STRING: - return new TagNodeString(); - - case TagType.TAG_BYTE: - return new TagNodeByte(); - - case TagType.TAG_SHORT: - return new TagNodeShort(); - - case TagType.TAG_INT: - return new TagNodeInt(); - - case TagType.TAG_LONG: - return new TagNodeLong(); - - case TagType.TAG_FLOAT: - return new TagNodeFloat(); - - case TagType.TAG_DOUBLE: - return new TagNodeDouble(); - } - - return null; - } - } -} diff --git a/SubstrateCS/Source/Orientation.cs b/SubstrateCS/Source/Orientation.cs deleted file mode 100644 index 4ce80822..00000000 --- a/SubstrateCS/Source/Orientation.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace Substrate -{ - public class Orientation - { - public double Pitch { get; set; } - public double Yaw { get; set; } - } -} diff --git a/SubstrateCS/Source/Player.cs b/SubstrateCS/Source/Player.cs deleted file mode 100644 index 99821399..00000000 --- a/SubstrateCS/Source/Player.cs +++ /dev/null @@ -1,671 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Substrate.Core; -using Substrate.Nbt; - -namespace Substrate -{ - /// - /// Encompases data to specify player abilities, especially mode-dependent abilities. - /// - /// Whether or not any of these values are respected by the game client is dependent upon the active game mode. - public class PlayerAbilities : ICopyable - { - private bool _flying = false; - private bool _instabuild = false; - private bool _mayfly = false; - private bool _invulnerable = false; - private bool _maybuild = true; - - private float _walkSpeed = 0.1f; - private float _flySpeed = 0.05f; - - /// - /// Gets or sets whether the player is currently flying. - /// - public bool Flying - { - get { return _flying; } - set { _flying = value; } - } - - /// - /// Gets or sets whether the player can instantly build or mine. - /// - public bool InstantBuild - { - get { return _instabuild; } - set { _instabuild = value; } - } - - /// - /// Gets or sets whether the player is allowed to fly. - /// - public bool MayFly - { - get { return _mayfly; } - set { _mayfly = value; } - } - - /// - /// Gets or sets whether the player can take damage. - /// - public bool Invulnerable - { - get { return _invulnerable; } - set { _invulnerable = value; } - } - - /// - /// Gets or sets whether the player can create or destroy blocks. - /// - public bool MayBuild - { - get { return _maybuild; } - set { _maybuild = value; } - } - - /// - /// Gets or sets the player's walking speed. Always 0.1. - /// - public float FlySpeed - { - get { return _flySpeed; } - set { _flySpeed = value; } - } - - /// - /// Gets or sets the player's flying speed. Always 0.05. - /// - public float WalkSpeed - { - get { return _walkSpeed; } - set { _walkSpeed = value; } - } - - #region ICopyable Members - - /// - public PlayerAbilities Copy () - { - PlayerAbilities pa = new PlayerAbilities(); - pa._flying = _flying; - pa._instabuild = _instabuild; - pa._mayfly = _mayfly; - pa._invulnerable = _invulnerable; - pa._maybuild = _maybuild; - pa._walkSpeed = _walkSpeed; - pa._flySpeed = _flySpeed; - - return pa; - } - - #endregion - } - - public enum PlayerGameType - { - Survival = 0, - Creative = 1, - Adventure = 2, - } - - /// - /// Represents a Player from either single- or multi-player Minecraft. - /// - /// Unlike objects, objects do not need to be added to chunks. They - /// are stored individually or within level data. - public class Player : Entity, INbtObject, ICopyable, IItemContainer - { - private static readonly SchemaNodeCompound _schema = Entity.Schema.MergeInto(new SchemaNodeCompound("") - { - new SchemaNodeScaler("AttackTime", TagType.TAG_SHORT, SchemaOptions.CREATE_ON_MISSING), - new SchemaNodeScaler("DeathTime", TagType.TAG_SHORT), - new SchemaNodeScaler("Health", TagType.TAG_FLOAT), - new SchemaNodeScaler("HurtTime", TagType.TAG_SHORT), - new SchemaNodeScaler("Dimension", TagType.TAG_INT), - new SchemaNodeList("Inventory", TagType.TAG_COMPOUND, ItemCollection.Schema), - //new SchemaNodeList("EnderItems", TagType.TAG_COMPOUND, ItemCollection.Schema, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("World", TagType.TAG_STRING, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("Sleeping", TagType.TAG_BYTE, SchemaOptions.CREATE_ON_MISSING), - new SchemaNodeScaler("SleepTimer", TagType.TAG_SHORT, SchemaOptions.CREATE_ON_MISSING), - new SchemaNodeScaler("SpawnX", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("SpawnY", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("SpawnZ", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("foodLevel", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("foodTickTimer", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("foodExhaustionLevel", TagType.TAG_FLOAT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("foodSaturationLevel", TagType.TAG_FLOAT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("XpP", TagType.TAG_FLOAT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("XpLevel", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("XpTotal", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("Score", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("playerGameType", TagType.TAG_INT, SchemaOptions.OPTIONAL), - new SchemaNodeCompound("abilities", new SchemaNodeCompound("") { - new SchemaNodeScaler("flying", TagType.TAG_BYTE), - new SchemaNodeScaler("instabuild", TagType.TAG_BYTE), - new SchemaNodeScaler("mayfly", TagType.TAG_BYTE), - new SchemaNodeScaler("invulnerable", TagType.TAG_BYTE), - new SchemaNodeScaler("mayBuild", TagType.TAG_BYTE, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("walkSpeed", TagType.TAG_FLOAT, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("flySpeed", TagType.TAG_FLOAT, SchemaOptions.OPTIONAL), - }, SchemaOptions.OPTIONAL), - }); - - private const int _CAPACITY = 105; - private const int _ENDER_CAPACITY = 27; - - private short _attackTime; - private short _deathTime; - private float _health; - private short _hurtTime; - - private int _dimension; - private byte _sleeping; - private short _sleepTimer; - private int? _spawnX; - private int? _spawnY; - private int? _spawnZ; - - private int? _foodLevel; - private int? _foodTickTimer; - private float? _foodExhaustion; - private float? _foodSaturation; - private float? _xpP; - private int? _xpLevel; - private int? _xpTotal; - private int? _score; - - private string _world; - private string _name; - - - private PlayerAbilities _abilities; - private PlayerGameType? _gameType; - - private ItemCollection _inventory; - private ItemCollection _enderItems; - - /// - /// Gets or sets the number of ticks left in the player's "invincibility shield" after last struck. - /// - public int AttackTime - { - get { return _attackTime; } - set { _attackTime = (short)value; } - } - - /// - /// Gets or sets the number of ticks that the player has been dead for. - /// - public int DeathTime - { - get { return _deathTime; } - set { _deathTime = (short)value; } - } - - /// - /// Gets or sets the amount of the player's health. - /// - public float Health - { - get { return _health; } - set { _health = value; } - } - - /// - /// Gets or sets the player's Hurt Time value. - /// - public int HurtTime - { - get { return _hurtTime; } - set { _hurtTime = (short)value; } - } - - /// - /// Gets or sets the dimension that the player is currently in. - /// - public int Dimension - { - get { return _dimension; } - set { _dimension = value; } - } - - public PlayerGameType GameType - { - get { return _gameType ?? PlayerGameType.Survival; } - set { _gameType = value; } - } - - /// - /// Gets or sets a value indicating whether the player is sleeping in a bed. - /// - public bool IsSleeping - { - get { return _sleeping == 1; } - set { _sleeping = (byte)(value ? 1 : 0); } - } - - /// - /// Gets or sets the player's Sleep Timer value. - /// - public int SleepTimer - { - get { return _sleepTimer; } - set { _sleepTimer = (short)value; } - } - - /// - /// Gets or sets the player's personal spawn point, set by sleeping in beds. - /// - public SpawnPoint Spawn - { - get { return new SpawnPoint(_spawnX ?? 0, _spawnY ?? 0, _spawnZ ?? 0); } - set - { - _spawnX = value.X; - _spawnY = value.Y; - _spawnZ = value.Z; - } - } - - /// - /// Tests if the player currently has a personal spawn point. - /// - public bool HasSpawn - { - get { return _spawnX != null && _spawnY != null && _spawnZ != null; } - } - - /// - /// Gets or sets the name of the world that the player is currently within. - /// - public string World - { - get { return _world; } - set { _world = value; } - } - - /// - /// Gets or sets the name that is used when the player is read or written from a . - /// - public string Name - { - get { return _name; } - set { _name = value; } - } - - /// - /// Gets or sets the player's score. - /// - public int Score - { - get { return _score ?? 0; } - set { _score = value; } - } - - /// - /// Gets or sets the player's XP Level. - /// - public int XPLevel - { - get { return _xpLevel ?? 0; } - set { _xpLevel = value; } - } - - /// - /// Gets or sets the amount of the player's XP points. - /// - public int XPTotal - { - get { return _xpTotal ?? 0; } - set { _xpTotal = value; } - } - - /// - /// Gets or sets the hunger level of the player. Valid values range 0 - 20. - /// - public int HungerLevel - { - get { return _foodLevel ?? 0; } - set { _foodLevel = value; } - } - - /// - /// Gets or sets the player's hunger saturation level, which is reserve food capacity above . - /// - public float HungerSaturationLevel - { - get { return _foodSaturation ?? 0; } - set { _foodSaturation = value; } - } - - /// - /// Gets or sets the counter towards the next hunger point decrement. Valid values range 0.0 - 4.0. - /// - public float HungerExhaustionLevel - { - get { return _foodExhaustion ?? 0; } - set { _foodExhaustion = value; } - } - - /// - /// Gets or sets the timer used to periodically heal or damage the player based on . Valid values range 0 - 80. - /// - public int HungerTimer - { - get { return _foodTickTimer ?? 0; } - set { _foodTickTimer = value; } - } - - /// - /// Gets the state of the player's abilities. - /// - public PlayerAbilities Abilities - { - get { return _abilities; } - } - - /// - /// Creates a new object with reasonable default values. - /// - public Player () - : base() - { - _inventory = new ItemCollection(_CAPACITY); - _enderItems = new ItemCollection(_ENDER_CAPACITY); - _abilities = new PlayerAbilities(); - - // Sane defaults - _dimension = 0; - _sleeping = 0; - _sleepTimer = 0; - - Air = 300; - Health = 20.0f; - Fire = -20; - } - - /// - /// Creates a copy of a object. - /// - /// The to copy fields from. - protected Player (Player p) - : base(p) - { - _attackTime = p._attackTime; - _deathTime = p._deathTime; - _health = p._health; - _hurtTime = p._hurtTime; - - _dimension = p._dimension; - _gameType = p._gameType; - _sleeping = p._sleeping; - _sleepTimer = p._sleepTimer; - _spawnX = p._spawnX; - _spawnY = p._spawnY; - _spawnZ = p._spawnZ; - _world = p._world; - _inventory = p._inventory.Copy(); - _enderItems = p._inventory.Copy(); - - _foodLevel = p._foodLevel; - _foodTickTimer = p._foodTickTimer; - _foodSaturation = p._foodSaturation; - _foodExhaustion = p._foodExhaustion; - _xpP = p._xpP; - _xpLevel = p._xpLevel; - _xpTotal = p._xpTotal; - _abilities = p._abilities.Copy(); - } - - /// - /// Clears the player's personal spawn point. - /// - public void ClearSpawn () - { - _spawnX = null; - _spawnY = null; - _spawnZ = null; - } - - private bool AbilitiesSet () - { - return _abilities.Flying - || _abilities.InstantBuild - || _abilities.MayFly - || _abilities.Invulnerable; - } - - - #region INBTObject Members - - /// - /// Gets a representing the schema of a Player. - /// - public static new SchemaNodeCompound Schema - { - get { return _schema; } - } - - /// - /// Attempt to load a Player subtree into the without validation. - /// - /// The root node of a Player subtree. - /// The returns itself on success, or null if the tree was unparsable. - public virtual new Player LoadTree (TagNode tree) - { - TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null || base.LoadTree(tree) == null) { - return null; - } - - _attackTime = ctree["AttackTime"].ToTagShort(); - _deathTime = ctree["DeathTime"].ToTagShort(); - _health = ctree["Health"].ToTagFloat(); - _hurtTime = ctree["HurtTime"].ToTagShort(); - - _dimension = ctree["Dimension"].ToTagInt(); - _sleeping = ctree["Sleeping"].ToTagByte(); - _sleepTimer = ctree["SleepTimer"].ToTagShort(); - - if (ctree.ContainsKey("SpawnX")) { - _spawnX = ctree["SpawnX"].ToTagInt(); - } - if (ctree.ContainsKey("SpawnY")) { - _spawnY = ctree["SpawnY"].ToTagInt(); - } - if (ctree.ContainsKey("SpawnZ")) { - _spawnZ = ctree["SpawnZ"].ToTagInt(); - } - - if (ctree.ContainsKey("World")) { - _world = ctree["World"].ToTagString(); - } - - if (ctree.ContainsKey("foodLevel")) { - _foodLevel = ctree["foodLevel"].ToTagInt(); - } - if (ctree.ContainsKey("foodTickTimer")) { - _foodTickTimer = ctree["foodTickTimer"].ToTagInt(); - } - if (ctree.ContainsKey("foodExhaustionLevel")) { - _foodExhaustion = ctree["foodExhaustionLevel"].ToTagFloat(); - } - if (ctree.ContainsKey("foodSaturationLevel")) { - _foodSaturation = ctree["foodSaturationLevel"].ToTagFloat(); - } - if (ctree.ContainsKey("XpP")) { - _xpP = ctree["XpP"].ToTagFloat(); - } - if (ctree.ContainsKey("XpLevel")) { - _xpLevel = ctree["XpLevel"].ToTagInt(); - } - if (ctree.ContainsKey("XpTotal")) { - _xpTotal = ctree["XpTotal"].ToTagInt(); - } - if (ctree.ContainsKey("Score")) { - _score = ctree["Score"].ToTagInt(); - } - - if (ctree.ContainsKey("abilities")) { - TagNodeCompound pb = ctree["abilities"].ToTagCompound(); - - _abilities = new PlayerAbilities(); - _abilities.Flying = pb["flying"].ToTagByte().Data == 1; - _abilities.InstantBuild = pb["instabuild"].ToTagByte().Data == 1; - _abilities.MayFly = pb["mayfly"].ToTagByte().Data == 1; - _abilities.Invulnerable = pb["invulnerable"].ToTagByte().Data == 1; - - if (pb.ContainsKey("mayBuild")) - _abilities.MayBuild = pb["mayBuild"].ToTagByte().Data == 1; - if (pb.ContainsKey("walkSpeed")) - _abilities.WalkSpeed = pb["walkSpeed"].ToTagFloat(); - if (pb.ContainsKey("flySpeed")) - _abilities.FlySpeed = pb["flySpeed"].ToTagFloat(); - } - - if (ctree.ContainsKey("PlayerGameType")) { - _gameType = (PlayerGameType)ctree["PlayerGameType"].ToTagInt().Data; - } - - _inventory.LoadTree(ctree["Inventory"].ToTagList()); - - if (ctree.ContainsKey("EnderItems")) { - if (ctree["EnderItems"].ToTagList().Count > 0) - _enderItems.LoadTree(ctree["EnderItems"].ToTagList()); - } - - return this; - } - - /// - /// Attempt to load a Player subtree into the with validation. - /// - /// The root node of a Player subtree. - /// The returns itself on success, or null if the tree failed validation. - public virtual new Player LoadTreeSafe (TagNode tree) - { - if (!ValidateTree(tree)) { - return null; - } - - return LoadTree(tree); - } - - /// - /// Builds a Player subtree from the current data. - /// - /// The root node of a Player subtree representing the current data. - public virtual new TagNode BuildTree () - { - TagNodeCompound tree = base.BuildTree() as TagNodeCompound; - tree["AttackTime"] = new TagNodeShort(_attackTime); - tree["DeathTime"] = new TagNodeShort(_deathTime); - tree["Health"] = new TagNodeFloat(_health); - tree["HurtTime"] = new TagNodeShort(_hurtTime); - - tree["Dimension"] = new TagNodeInt(_dimension); - tree["Sleeping"] = new TagNodeByte(_sleeping); - tree["SleepTimer"] = new TagNodeShort(_sleepTimer); - - if (_spawnX != null && _spawnY != null && _spawnZ != null) { - tree["SpawnX"] = new TagNodeInt(_spawnX ?? 0); - tree["SpawnY"] = new TagNodeInt(_spawnY ?? 0); - tree["SpawnZ"] = new TagNodeInt(_spawnZ ?? 0); - } - else { - tree.Remove("SpawnX"); - tree.Remove("SpawnY"); - tree.Remove("SpawnZ"); - } - - if (_world != null) { - tree["World"] = new TagNodeString(_world); - } - - if (_foodLevel != null) - tree["foodLevel"] = new TagNodeInt(_foodLevel ?? 0); - if (_foodTickTimer != null) - tree["foodTickTimer"] = new TagNodeInt(_foodTickTimer ?? 0); - if (_foodExhaustion != null) - tree["foodExhaustionLevel"] = new TagNodeFloat(_foodExhaustion ?? 0); - if (_foodSaturation != null) - tree["foodSaturation"] = new TagNodeFloat(_foodSaturation ?? 0); - if (_xpP != null) - tree["XpP"] = new TagNodeFloat(_xpP ?? 0); - if (_xpLevel != null) - tree["XpLevel"] = new TagNodeInt(_xpLevel ?? 0); - if (_xpTotal != null) - tree["XpTotal"] = new TagNodeInt(_xpTotal ?? 0); - if (_score != null) - tree["Score"] = new TagNodeInt(_score ?? 0); - - if (_gameType != null) - tree["playerGameType"] = new TagNodeInt((int)(_gameType ?? PlayerGameType.Survival)); - - if (AbilitiesSet()) { - TagNodeCompound pb = new TagNodeCompound(); - pb["flying"] = new TagNodeByte(_abilities.Flying ? (byte)1 : (byte)0); - pb["instabuild"] = new TagNodeByte(_abilities.InstantBuild ? (byte)1 : (byte)0); - pb["mayfly"] = new TagNodeByte(_abilities.MayFly ? (byte)1 : (byte)0); - pb["invulnerable"] = new TagNodeByte(_abilities.Invulnerable ? (byte)1 : (byte)0); - pb["mayBuild"] = new TagNodeByte(_abilities.MayBuild ? (byte)1 : (byte)0); - pb["walkSpeed"] = new TagNodeFloat(_abilities.WalkSpeed); - pb["flySpeed"] = new TagNodeFloat(_abilities.FlySpeed); - - tree["abilities"] = pb; - } - - tree["Inventory"] = _inventory.BuildTree(); - tree["EnderItems"] = _enderItems.BuildTree(); - - return tree; - } - - /// - /// Validate a Player subtree against a schema defintion. - /// - /// The root node of a Player subtree. - /// Status indicating whether the tree was valid against the internal schema. - public virtual new bool ValidateTree (TagNode tree) - { - return new NbtVerifier(tree, _schema).Verify(); - } - - #endregion - - - #region ICopyable Members - - /// - /// Creates a deep-copy of the . - /// - /// A deep-copy of the . - public virtual new Player Copy () - { - return new Player(this); - } - - #endregion - - - #region IItemContainer Members - - /// - /// Gets access to an representing the player's equipment and inventory. - /// - public ItemCollection Items - { - get { return _inventory; } - } - - #endregion - - public ItemCollection EnderItems - { - get { return _enderItems; } - } - } -} \ No newline at end of file diff --git a/SubstrateCS/Source/Vector.cs b/SubstrateCS/Source/Vector.cs deleted file mode 100644 index de484eaa..00000000 --- a/SubstrateCS/Source/Vector.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Substrate -{ - public class Vector3 - { - public double X { get; set; } - public double Y { get; set; } - public double Z { get; set; } - } -} diff --git a/SubstrateCS/Substrate (NET2).csproj b/SubstrateCS/Substrate (NET2).csproj deleted file mode 100644 index f96fd267..00000000 --- a/SubstrateCS/Substrate (NET2).csproj +++ /dev/null @@ -1,299 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {AFE30E14-3F2F-4461-9F7D-147AB4DCA4C3} - Library - Properties - Substrate - Substrate - v2.0 - 512 - false - - - - - 3.5 - - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - bin\Debug\Substrate.XML - - - pdbonly - true - bin\Release\NET2\ - TRACE - prompt - 4 - bin\Release\Substrate.XML - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - - - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 2.0 %28x86%29 - false - - - False - .NET Framework 3.0 %28x86%29 - false - - - False - .NET Framework 3.5 - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - - - - - - - - \ No newline at end of file diff --git a/SubstrateCS/Substrate (NET4).csproj b/SubstrateCS/Substrate (NET4).csproj deleted file mode 100644 index f293012e..00000000 --- a/SubstrateCS/Substrate (NET4).csproj +++ /dev/null @@ -1,298 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {7264A1C4-AB4A-4437-B252-7379B98B5509} - Library - Properties - Substrate - Substrate - v4.0 - 512 - false - - - - - 3.5 - - Client - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - bin\Debug\Substrate.XML - - - pdbonly - true - bin\Release\NET4\ - TRACE - prompt - 4 - bin\Release\Substrate.XML - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - - - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 2.0 %28x86%29 - false - - - False - .NET Framework 3.0 %28x86%29 - false - - - False - .NET Framework 3.5 - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - - - - - - - \ No newline at end of file diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/Crc32.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/Crc32.cs deleted file mode 100644 index 4d685d52..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/Crc32.cs +++ /dev/null @@ -1,572 +0,0 @@ -// Crc32.cs -// ------------------------------------------------------------------ -// -// Copyright (c) 2006-2009 Dino Chiesa and Microsoft Corporation. -// All rights reserved. -// -// This code module is part of DotNetZip, a zipfile class library. -// -// ------------------------------------------------------------------ -// -// This code is licensed under the Microsoft Public License. -// See the file License.txt for the license details. -// More info on: http://dotnetzip.codeplex.com -// -// ------------------------------------------------------------------ -// -// last saved (in emacs): -// Time-stamp: <2010-January-16 13:16:27> -// -// ------------------------------------------------------------------ -// -// Implements the CRC algorithm, which is used in zip files. The zip format calls for -// the zipfile to contain a CRC for the unencrypted byte stream of each file. -// -// It is based on example source code published at -// http://www.vbaccelerator.com/home/net/code/libraries/CRC32/Crc32_zip_CRC32_CRC32_cs.asp -// -// This implementation adds a tweak of that code for use within zip creation. While -// computing the CRC we also compress the byte stream, in the same read loop. This -// avoids the need to read through the uncompressed stream twice - once to compute CRC -// and another time to compress. -// -// ------------------------------------------------------------------ - - - -using System; -using Interop=System.Runtime.InteropServices; - - -namespace Ionic.Zlib -{ - /// - /// Calculates a 32bit Cyclic Redundancy Checksum (CRC) using the same polynomial - /// used by Zip. This type is used internally by DotNetZip; it is generally not used - /// directly by applications wishing to create, read, or manipulate zip archive - /// files. - /// - - [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000C")] - [Interop.ComVisible(true)] -#if !NETCF - [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)] -#endif - internal class CRC32 - { - /// - /// indicates the total number of bytes read on the CRC stream. - /// This is used when writing the ZipDirEntry when compressing files. - /// - public Int64 TotalBytesRead - { - get - { - return _TotalBytesRead; - } - } - - /// - /// Indicates the current CRC for all blocks slurped in. - /// - public Int32 Crc32Result - { - get - { - // return one's complement of the running result - return unchecked((Int32)(~_RunningCrc32Result)); - } - } - - /// - /// Returns the CRC32 for the specified stream. - /// - /// The stream over which to calculate the CRC32 - /// the CRC32 calculation - public Int32 GetCrc32(System.IO.Stream input) - { - return GetCrc32AndCopy(input, null); - } - - /// - /// Returns the CRC32 for the specified stream, and writes the input into the - /// output stream. - /// - /// The stream over which to calculate the CRC32 - /// The stream into which to deflate the input - /// the CRC32 calculation - public Int32 GetCrc32AndCopy(System.IO.Stream input, System.IO.Stream output) - { - if (input == null) - throw new ZlibException("The input stream must not be null."); - - unchecked - { - //UInt32 crc32Result; - //crc32Result = 0xFFFFFFFF; - byte[] buffer = new byte[BUFFER_SIZE]; - int readSize = BUFFER_SIZE; - - _TotalBytesRead = 0; - int count = input.Read(buffer, 0, readSize); - if (output != null) output.Write(buffer, 0, count); - _TotalBytesRead += count; - while (count > 0) - { - SlurpBlock(buffer, 0, count); - count = input.Read(buffer, 0, readSize); - if (output != null) output.Write(buffer, 0, count); - _TotalBytesRead += count; - } - - return (Int32)(~_RunningCrc32Result); - } - } - - - /// - /// Get the CRC32 for the given (word,byte) combo. This is a computation - /// defined by PKzip. - /// - /// The word to start with. - /// The byte to combine it with. - /// The CRC-ized result. - public Int32 ComputeCrc32(Int32 W, byte B) - { - return _InternalComputeCrc32((UInt32)W, B); - } - - internal Int32 _InternalComputeCrc32(UInt32 W, byte B) - { - return (Int32)(crc32Table[(W ^ B) & 0xFF] ^ (W >> 8)); - } - - /// - /// Update the value for the running CRC32 using the given block of bytes. - /// This is useful when using the CRC32() class in a Stream. - /// - /// block of bytes to slurp - /// starting point in the block - /// how many bytes within the block to slurp - public void SlurpBlock(byte[] block, int offset, int count) - { - if (block == null) - throw new ZlibException("The data buffer must not be null."); - - for (int i = 0; i < count; i++) - { - int x = offset + i; - _RunningCrc32Result = ((_RunningCrc32Result) >> 8) ^ crc32Table[(block[x]) ^ ((_RunningCrc32Result) & 0x000000FF)]; - } - _TotalBytesRead += count; - } - - - // pre-initialize the crc table for speed of lookup. - static CRC32() - { - unchecked - { - // PKZip specifies CRC32 with a polynomial of 0xEDB88320; - // This is also the CRC-32 polynomial used bby Ethernet, FDDI, - // bzip2, gzip, and others. - // Often the polynomial is shown reversed as 0x04C11DB7. - // For more details, see http://en.wikipedia.org/wiki/Cyclic_redundancy_check - UInt32 dwPolynomial = 0xEDB88320; - UInt32 i, j; - - crc32Table = new UInt32[256]; - - UInt32 dwCrc; - for (i = 0; i < 256; i++) - { - dwCrc = i; - for (j = 8; j > 0; j--) - { - if ((dwCrc & 1) == 1) - { - dwCrc = (dwCrc >> 1) ^ dwPolynomial; - } - else - { - dwCrc >>= 1; - } - } - crc32Table[i] = dwCrc; - } - } - } - - - - - private uint gf2_matrix_times(uint[] matrix, uint vec) - { - uint sum = 0; - int i=0; - while (vec != 0) - { - if ((vec & 0x01)== 0x01) - sum ^= matrix[i]; - vec >>= 1; - i++; - } - return sum; - } - - private void gf2_matrix_square(uint[] square, uint[] mat) - { - for (int i = 0; i < 32; i++) - square[i] = gf2_matrix_times(mat, mat[i]); - } - - - - /// - /// Combines the given CRC32 value with the current running total. - /// - /// - /// This is useful when using a divide-and-conquer approach to calculating a CRC. - /// Multiple threads can each calculate a CRC32 on a segment of the data, and then - /// combine the individual CRC32 values at the end. - /// - /// the crc value to be combined with this one - /// the length of data the CRC value was calculated on - public void Combine(int crc, int length) - { - uint[] even = new uint[32]; // even-power-of-two zeros operator - uint[] odd = new uint[32]; // odd-power-of-two zeros operator - - if (length == 0) - return; - - uint crc1= ~_RunningCrc32Result; - uint crc2= (uint) crc; - - // put operator for one zero bit in odd - odd[0] = 0xEDB88320; // the CRC-32 polynomial - uint row = 1; - for (int i = 1; i < 32; i++) - { - odd[i] = row; - row <<= 1; - } - - // put operator for two zero bits in even - gf2_matrix_square(even, odd); - - // put operator for four zero bits in odd - gf2_matrix_square(odd, even); - - uint len2 = (uint) length; - - // apply len2 zeros to crc1 (first square will put the operator for one - // zero byte, eight zero bits, in even) - do { - // apply zeros operator for this bit of len2 - gf2_matrix_square(even, odd); - - if ((len2 & 1)== 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - if (len2 == 0) - break; - - // another iteration of the loop with odd and even swapped - gf2_matrix_square(odd, even); - if ((len2 & 1)==1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - - } while (len2 != 0); - - crc1 ^= crc2; - - _RunningCrc32Result= ~crc1; - - //return (int) crc1; - return; - } - - - - // private member vars - private Int64 _TotalBytesRead; - private static readonly UInt32[] crc32Table; - private const int BUFFER_SIZE = 8192; - private UInt32 _RunningCrc32Result = 0xFFFFFFFF; - - } - - - - - /// - /// A Stream that calculates a CRC32 (a checksum) on all bytes read, - /// or on all bytes written. - /// - /// - /// - /// - /// This class can be used to verify the CRC of a ZipEntry when - /// reading from a stream, or to calculate a CRC when writing to a - /// stream. The stream should be used to either read, or write, but - /// not both. If you intermix reads and writes, the results are not - /// defined. - /// - /// - /// - /// This class is intended primarily for use internally by the - /// DotNetZip library. - /// - /// - internal class CrcCalculatorStream : System.IO.Stream, System.IDisposable - { - private static readonly Int64 UnsetLengthLimit = -99; - - internal System.IO.Stream _innerStream; - private CRC32 _Crc32; - private Int64 _lengthLimit = -99; - private bool _leaveOpen; - - /// - /// Gets the total number of bytes run through the CRC32 calculator. - /// - /// - /// - /// This is either the total number of bytes read, or the total number of bytes - /// written, depending on the direction of this stream. - /// - public Int64 TotalBytesSlurped - { - get { return _Crc32.TotalBytesRead; } - } - - - /// - /// The default constructor. - /// - /// - /// Instances returned from this constructor will leave the underlying stream - /// open upon Close(). - /// - /// The underlying stream - public CrcCalculatorStream(System.IO.Stream stream) - : this(true, CrcCalculatorStream.UnsetLengthLimit, stream) - { - } - - - /// - /// The constructor allows the caller to specify how to handle the underlying - /// stream at close. - /// - /// The underlying stream - /// true to leave the underlying stream - /// open upon close of the CrcCalculatorStream.; false otherwise. - public CrcCalculatorStream(System.IO.Stream stream, bool leaveOpen) - : this(leaveOpen, CrcCalculatorStream.UnsetLengthLimit, stream) - { - } - - - /// - /// A constructor allowing the specification of the length of the stream to read. - /// - /// - /// Instances returned from this constructor will leave the underlying stream open - /// upon Close(). - /// - /// The underlying stream - /// The length of the stream to slurp - public CrcCalculatorStream(System.IO.Stream stream, Int64 length) - : this(true, length, stream) - { - if (length < 0) - throw new ArgumentException("length"); - } - - /// - /// A constructor allowing the specification of the length of the stream to - /// read, as well as whether to keep the underlying stream open upon Close(). - /// - /// The underlying stream - /// The length of the stream to slurp - /// true to leave the underlying stream - /// open upon close of the CrcCalculatorStream.; false otherwise. - public CrcCalculatorStream(System.IO.Stream stream, Int64 length, bool leaveOpen) - : this(leaveOpen, length, stream) - { - if (length < 0) - throw new ArgumentException("length"); - } - - - // This ctor is private - no validation is done here. This is to allow the use - // of a (specific) negative value for the _lengthLimit, to indicate that there - // is no length set. So we validate the length limit in those ctors that use an - // explicit param, otherwise we don't validate, because it could be our special - // value. - private CrcCalculatorStream(bool leaveOpen, Int64 length, System.IO.Stream stream) - : base() - { - _innerStream = stream; - _Crc32 = new CRC32(); - _lengthLimit = length; - _leaveOpen = leaveOpen; - } - - /// - /// Provides the current CRC for all blocks slurped in. - /// - public Int32 Crc - { - get { return _Crc32.Crc32Result; } - } - - /// - /// Indicates whether the underlying stream will be left open when the - /// CrcCalculatorStream is Closed. - /// - public bool LeaveOpen - { - get { return _leaveOpen; } - set { _leaveOpen = value; } - } - - /// - /// Read from the stream - /// - /// the buffer to read - /// the offset at which to start - /// the number of bytes to read - /// the number of bytes actually read - public override int Read(byte[] buffer, int offset, int count) - { - int bytesToRead = count; - - // Need to limit the # of bytes returned, if the stream is intended to have - // a definite length. This is especially useful when returning a stream for - // the uncompressed data directly to the application. The app won't - // necessarily read only the UncompressedSize number of bytes. For example - // wrapping the stream returned from OpenReader() into a StreadReader() and - // calling ReadToEnd() on it, We can "over-read" the zip data and get a - // corrupt string. The length limits that, prevents that problem. - - if (_lengthLimit != CrcCalculatorStream.UnsetLengthLimit) - { - if (_Crc32.TotalBytesRead >= _lengthLimit) return 0; // EOF - Int64 bytesRemaining = _lengthLimit - _Crc32.TotalBytesRead; - if (bytesRemaining < count) bytesToRead = (int)bytesRemaining; - } - int n = _innerStream.Read(buffer, offset, bytesToRead); - if (n > 0) _Crc32.SlurpBlock(buffer, offset, n); - return n; - } - - /// - /// Write to the stream. - /// - /// the buffer from which to write - /// the offset at which to start writing - /// the number of bytes to write - public override void Write(byte[] buffer, int offset, int count) - { - if (count > 0) _Crc32.SlurpBlock(buffer, offset, count); - _innerStream.Write(buffer, offset, count); - } - - /// - /// Indicates whether the stream supports reading. - /// - public override bool CanRead - { - get { return _innerStream.CanRead; } - } - - /// - /// Indicates whether the stream supports seeking. - /// - public override bool CanSeek - { - get { return _innerStream.CanSeek; } - } - - /// - /// Indicates whether the stream supports writing. - /// - public override bool CanWrite - { - get { return _innerStream.CanWrite; } - } - - /// - /// Flush the stream. - /// - public override void Flush() - { - _innerStream.Flush(); - } - - /// - /// Not implemented. - /// - public override long Length - { - get - { - if (_lengthLimit == CrcCalculatorStream.UnsetLengthLimit) - return _innerStream.Length; - else return _lengthLimit; - } - } - - /// - /// Not implemented. - /// - public override long Position - { - get { return _Crc32.TotalBytesRead; } - set { throw new NotImplementedException(); } - } - - /// - /// Not implemented. - /// - /// N/A - /// N/A - /// N/A - public override long Seek(long offset, System.IO.SeekOrigin origin) - { - throw new NotImplementedException(); - } - - /// - /// Not implemented. - /// - /// N/A - public override void SetLength(long value) - { - throw new NotImplementedException(); - } - - - void IDisposable.Dispose() - { - Close(); - } - - /// - /// Closes the stream. - /// - public override void Close() - { - base.Close(); - if (!_leaveOpen) - _innerStream.Close(); - } - - } -} diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/Deflate.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/Deflate.cs deleted file mode 100644 index 652c2dd0..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/Deflate.cs +++ /dev/null @@ -1,1927 +0,0 @@ -// Deflate.cs -// ------------------------------------------------------------------ -// -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. -// All rights reserved. -// -// This code module is part of DotNetZip, a zipfile class library. -// -// ------------------------------------------------------------------ -// -// This code is licensed under the Microsoft Public License. -// See the file License.txt for the license details. -// More info on: http://dotnetzip.codeplex.com -// -// ------------------------------------------------------------------ -// -// last saved (in emacs): -// Time-stamp: <2009-October-28 13:44:59> -// -// ------------------------------------------------------------------ -// -// This module defines logic for handling the Deflate or compression. -// -// This code is based on multiple sources: -// - the original zlib v1.2.3 source, which is Copyright (C) 1995-2005 Jean-loup Gailly. -// - the original jzlib, which is Copyright (c) 2000-2003 ymnk, JCraft,Inc. -// -// However, this code is significantly different from both. -// The object model is not the same, and many of the behaviors are different. -// -// In keeping with the license for these other works, the copyrights for -// jzlib and zlib are here. -// -// ----------------------------------------------------------------------- -// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in -// the documentation and/or other materials provided with the distribution. -// -// 3. The names of the authors may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// ----------------------------------------------------------------------- -// -// This program is based on zlib-1.1.3; credit to authors -// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) -// and contributors of zlib. -// -// ----------------------------------------------------------------------- - - -using System; - -namespace Ionic.Zlib -{ - - /// - /// Describes how to flush the current deflate operation. - /// - /// - /// The different FlushType values are useful when using a Deflate in a streaming application. - /// - internal enum FlushType - { - /// No flush at all. - None = 0, - - /// Closes the current block, but doesn't flush it to - /// the output. Used internally only in hypothetical - /// scenarios. This was supposed to be removed by Zlib, but it is - /// still in use in some edge cases. - /// - Partial, - - /// - /// Use this during compression to specify that all pending output should be - /// flushed to the output buffer and the output should be aligned on a byte - /// boundary. You might use this in a streaming communication scenario, so that - /// the decompressor can get all input data available so far. When using this - /// with a ZlibCodec, AvailableBytesIn will be zero after the call if - /// enough output space has been provided before the call. Flushing will - /// degrade compression and so it should be used only when necessary. - /// - Sync, - - /// - /// Use this during compression to specify that all output should be flushed, as - /// with FlushType.Sync, but also, the compression state should be reset - /// so that decompression can restart from this point if previous compressed - /// data has been damaged or if random access is desired. Using - /// FlushType.Full too often can significantly degrade the compression. - /// - Full, - - /// Signals the end of the compression/decompression stream. - Finish, - } - - internal enum BlockState - { - NeedMore = 0, // block not completed, need more input or more output - BlockDone, // block flush performed - FinishStarted, // finish started, need only more output at next deflate - FinishDone // finish done, accept no more input or output - } - - internal enum DeflateFlavor - { - Store, - Fast, - Slow - } - - internal sealed class DeflateManager - { - private static readonly int MEM_LEVEL_MAX = 9; - private static readonly int MEM_LEVEL_DEFAULT = 8; - - internal delegate BlockState CompressFunc(FlushType flush); - - internal class Config - { - // Use a faster search when the previous match is longer than this - internal int GoodLength; // reduce lazy search above this match length - - // Attempt to find a better match only when the current match is - // strictly smaller than this value. This mechanism is used only for - // compression levels >= 4. For levels 1,2,3: MaxLazy is actually - // MaxInsertLength. (See DeflateFast) - - internal int MaxLazy; // do not perform lazy search above this match length - - internal int NiceLength; // quit search above this match length - - // To speed up deflation, hash chains are never searched beyond this - // length. A higher limit improves compression ratio but degrades the speed. - - internal int MaxChainLength; - - internal DeflateFlavor Flavor; - - private Config(int goodLength, int maxLazy, int niceLength, int maxChainLength, DeflateFlavor flavor) - { - this.GoodLength = goodLength; - this.MaxLazy = maxLazy; - this.NiceLength = niceLength; - this.MaxChainLength = maxChainLength; - this.Flavor = flavor; - } - - public static Config Lookup(CompressionLevel level) - { - return Table[(int)level]; - } - - - static Config() - { - Table = new Config[] { - new Config(0, 0, 0, 0, DeflateFlavor.Store), - new Config(4, 4, 8, 4, DeflateFlavor.Fast), - new Config(4, 5, 16, 8, DeflateFlavor.Fast), - new Config(4, 6, 32, 32, DeflateFlavor.Fast), - - new Config(4, 4, 16, 16, DeflateFlavor.Slow), - new Config(8, 16, 32, 32, DeflateFlavor.Slow), - new Config(8, 16, 128, 128, DeflateFlavor.Slow), - new Config(8, 32, 128, 256, DeflateFlavor.Slow), - new Config(32, 128, 258, 1024, DeflateFlavor.Slow), - new Config(32, 258, 258, 4096, DeflateFlavor.Slow), - }; - } - - private static readonly Config[] Table; - } - - - private CompressFunc DeflateFunction; - - private static readonly System.String[] _ErrorMessage = new System.String[] - { - "need dictionary", - "stream end", - "", - "file error", - "stream error", - "data error", - "insufficient memory", - "buffer error", - "incompatible version", - "" - }; - - // preset dictionary flag in zlib header - private static readonly int PRESET_DICT = 0x20; - - private static readonly int INIT_STATE = 42; - private static readonly int BUSY_STATE = 113; - private static readonly int FINISH_STATE = 666; - - // The deflate compression method - private static readonly int Z_DEFLATED = 8; - - private static readonly int STORED_BLOCK = 0; - private static readonly int STATIC_TREES = 1; - private static readonly int DYN_TREES = 2; - - // The three kinds of block type - private static readonly int Z_BINARY = 0; - private static readonly int Z_ASCII = 1; - private static readonly int Z_UNKNOWN = 2; - - private static readonly int Buf_size = 8 * 2; - - private static readonly int MIN_MATCH = 3; - private static readonly int MAX_MATCH = 258; - - private static readonly int MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1); - - private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1); - - private static readonly int END_BLOCK = 256; - - internal ZlibCodec _codec; // the zlib encoder/decoder - internal int status; // as the name implies - internal byte[] pending; // output still pending - waiting to be compressed - internal int nextPending; // index of next pending byte to output to the stream - internal int pendingCount; // number of bytes in the pending buffer - - internal sbyte data_type; // UNKNOWN, BINARY or ASCII - internal int last_flush; // value of flush param for previous deflate call - - internal int w_size; // LZ77 window size (32K by default) - internal int w_bits; // log2(w_size) (8..16) - internal int w_mask; // w_size - 1 - - //internal byte[] dictionary; - internal byte[] window; - - // Sliding window. Input bytes are read into the second half of the window, - // and move to the first half later to keep a dictionary of at least wSize - // bytes. With this organization, matches are limited to a distance of - // wSize-MAX_MATCH bytes, but this ensures that IO is always - // performed with a length multiple of the block size. - // - // To do: use the user input buffer as sliding window. - - internal int window_size; - // Actual size of window: 2*wSize, except when the user input buffer - // is directly used as sliding window. - - internal short[] prev; - // Link to older string with same hash index. To limit the size of this - // array to 64K, this link is maintained only for the last 32K strings. - // An index in this array is thus a window index modulo 32K. - - internal short[] head; // Heads of the hash chains or NIL. - - internal int ins_h; // hash index of string to be inserted - internal int hash_size; // number of elements in hash table - internal int hash_bits; // log2(hash_size) - internal int hash_mask; // hash_size-1 - - // Number of bits by which ins_h must be shifted at each input - // step. It must be such that after MIN_MATCH steps, the oldest - // byte no longer takes part in the hash key, that is: - // hash_shift * MIN_MATCH >= hash_bits - internal int hash_shift; - - // Window position at the beginning of the current output block. Gets - // negative when the window is moved backwards. - - internal int block_start; - - Config config; - internal int match_length; // length of best match - internal int prev_match; // previous match - internal int match_available; // set if previous match exists - internal int strstart; // start of string to insert into.....???? - internal int match_start; // start of matching string - internal int lookahead; // number of valid bytes ahead in window - - // Length of the best match at previous step. Matches not greater than this - // are discarded. This is used in the lazy match evaluation. - internal int prev_length; - - // Insert new strings in the hash table only if the match length is not - // greater than this length. This saves time but degrades compression. - // max_insert_length is used only for compression levels <= 3. - - internal CompressionLevel compressionLevel; // compression level (1..9) - internal CompressionStrategy compressionStrategy; // favor or force Huffman coding - - - internal short[] dyn_ltree; // literal and length tree - internal short[] dyn_dtree; // distance tree - internal short[] bl_tree; // Huffman tree for bit lengths - - internal Tree treeLiterals = new Tree(); // desc for literal tree - internal Tree treeDistances = new Tree(); // desc for distance tree - internal Tree treeBitLengths = new Tree(); // desc for bit length tree - - // number of codes at each bit length for an optimal tree - internal short[] bl_count = new short[InternalConstants.MAX_BITS + 1]; - - // heap used to build the Huffman trees - internal int[] heap = new int[2 * InternalConstants.L_CODES + 1]; - - internal int heap_len; // number of elements in the heap - internal int heap_max; // element of largest frequency - - // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - // The same heap array is used to build all trees. - - // Depth of each subtree used as tie breaker for trees of equal frequency - internal sbyte[] depth = new sbyte[2 * InternalConstants.L_CODES + 1]; - - internal int _lengthOffset; // index for literals or lengths - - - // Size of match buffer for literals/lengths. There are 4 reasons for - // limiting lit_bufsize to 64K: - // - frequencies can be kept in 16 bit counters - // - if compression is not successful for the first block, all input - // data is still in the window so we can still emit a stored block even - // when input comes from standard input. (This can also be done for - // all blocks if lit_bufsize is not greater than 32K.) - // - if compression is not successful for a file smaller than 64K, we can - // even emit a stored file instead of a stored block (saving 5 bytes). - // This is applicable only for zip (not gzip or zlib). - // - creating new Huffman trees less frequently may not provide fast - // adaptation to changes in the input data statistics. (Take for - // example a binary file with poorly compressible code followed by - // a highly compressible string table.) Smaller buffer sizes give - // fast adaptation but have of course the overhead of transmitting - // trees more frequently. - - internal int lit_bufsize; - - internal int last_lit; // running index in l_buf - - // Buffer for distances. To simplify the code, d_buf and l_buf have - // the same number of elements. To use different lengths, an extra flag - // array would be necessary. - - internal int _distanceOffset; // index into pending; points to distance data?? - - internal int opt_len; // bit length of current block with optimal trees - internal int static_len; // bit length of current block with static trees - internal int matches; // number of string matches in current block - internal int last_eob_len; // bit length of EOB code for last block - - // Output buffer. bits are inserted starting at the bottom (least - // significant bits). - internal short bi_buf; - - // Number of valid bits in bi_buf. All bits above the last valid bit - // are always zero. - internal int bi_valid; - - - internal DeflateManager() - { - dyn_ltree = new short[HEAP_SIZE * 2]; - dyn_dtree = new short[(2 * InternalConstants.D_CODES + 1) * 2]; // distance tree - bl_tree = new short[(2 * InternalConstants.BL_CODES + 1) * 2]; // Huffman tree for bit lengths - } - - - // lm_init - private void _InitializeLazyMatch() - { - window_size = 2 * w_size; - - // clear the hash - workitem 9063 - Array.Clear(head, 0, hash_size); - //for (int i = 0; i < hash_size; i++) head[i] = 0; - - config = Config.Lookup(compressionLevel); - SetDeflater(); - - strstart = 0; - block_start = 0; - lookahead = 0; - match_length = prev_length = MIN_MATCH - 1; - match_available = 0; - ins_h = 0; - } - - // Initialize the tree data structures for a new zlib stream. - private void _InitializeTreeData() - { - treeLiterals.dyn_tree = dyn_ltree; - treeLiterals.staticTree = StaticTree.Literals; - - treeDistances.dyn_tree = dyn_dtree; - treeDistances.staticTree = StaticTree.Distances; - - treeBitLengths.dyn_tree = bl_tree; - treeBitLengths.staticTree = StaticTree.BitLengths; - - bi_buf = 0; - bi_valid = 0; - last_eob_len = 8; // enough lookahead for inflate - - // Initialize the first block of the first file: - _InitializeBlocks(); - } - - internal void _InitializeBlocks() - { - // Initialize the trees. - for (int i = 0; i < InternalConstants.L_CODES; i++) - dyn_ltree[i * 2] = 0; - for (int i = 0; i < InternalConstants.D_CODES; i++) - dyn_dtree[i * 2] = 0; - for (int i = 0; i < InternalConstants.BL_CODES; i++) - bl_tree[i * 2] = 0; - - dyn_ltree[END_BLOCK * 2] = 1; - opt_len = static_len = 0; - last_lit = matches = 0; - } - - // Restore the heap property by moving down the tree starting at node k, - // exchanging a node with the smallest of its two sons if necessary, stopping - // when the heap property is re-established (each father smaller than its - // two sons). - internal void pqdownheap(short[] tree, int k) - { - int v = heap[k]; - int j = k << 1; // left son of k - while (j <= heap_len) - { - // Set j to the smallest of the two sons: - if (j < heap_len && _IsSmaller(tree, heap[j + 1], heap[j], depth)) - { - j++; - } - // Exit if v is smaller than both sons - if (_IsSmaller(tree, v, heap[j], depth)) - break; - - // Exchange v with the smallest son - heap[k] = heap[j]; k = j; - // And continue down the tree, setting j to the left son of k - j <<= 1; - } - heap[k] = v; - } - - internal static bool _IsSmaller(short[] tree, int n, int m, sbyte[] depth) - { - short tn2 = tree[n * 2]; - short tm2 = tree[m * 2]; - return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m])); - } - - - // Scan a literal or distance tree to determine the frequencies of the codes - // in the bit length tree. - internal void scan_tree(short[] tree, int max_code) - { - int n; // iterates over all tree elements - int prevlen = -1; // last emitted length - int curlen; // length of current code - int nextlen = (int)tree[0 * 2 + 1]; // length of next code - int count = 0; // repeat count of the current code - int max_count = 7; // max repeat count - int min_count = 4; // min repeat count - - if (nextlen == 0) - { - max_count = 138; min_count = 3; - } - tree[(max_code + 1) * 2 + 1] = (short)0x7fff; // guard //?? - - for (n = 0; n <= max_code; n++) - { - curlen = nextlen; nextlen = (int)tree[(n + 1) * 2 + 1]; - if (++count < max_count && curlen == nextlen) - { - continue; - } - else if (count < min_count) - { - bl_tree[curlen * 2] = (short)(bl_tree[curlen * 2] + count); - } - else if (curlen != 0) - { - if (curlen != prevlen) - bl_tree[curlen * 2]++; - bl_tree[InternalConstants.REP_3_6 * 2]++; - } - else if (count <= 10) - { - bl_tree[InternalConstants.REPZ_3_10 * 2]++; - } - else - { - bl_tree[InternalConstants.REPZ_11_138 * 2]++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) - { - max_count = 138; min_count = 3; - } - else if (curlen == nextlen) - { - max_count = 6; min_count = 3; - } - else - { - max_count = 7; min_count = 4; - } - } - } - - // Construct the Huffman tree for the bit lengths and return the index in - // bl_order of the last bit length code to send. - internal int build_bl_tree() - { - int max_blindex; // index of last bit length code of non zero freq - - // Determine the bit length frequencies for literal and distance trees - scan_tree(dyn_ltree, treeLiterals.max_code); - scan_tree(dyn_dtree, treeDistances.max_code); - - // Build the bit length tree: - treeBitLengths.build_tree(this); - // opt_len now includes the length of the tree representations, except - // the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - - // Determine the number of bit length codes to send. The pkzip format - // requires that at least 4 bit length codes be sent. (appnote.txt says - // 3 but the actual value used is 4.) - for (max_blindex = InternalConstants.BL_CODES - 1; max_blindex >= 3; max_blindex--) - { - if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] != 0) - break; - } - // Update opt_len to include the bit length tree and counts - opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; - - return max_blindex; - } - - - // Send the header for a block using dynamic Huffman trees: the counts, the - // lengths of the bit length codes, the literal tree and the distance tree. - // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - internal void send_all_trees(int lcodes, int dcodes, int blcodes) - { - int rank; // index in bl_order - - send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt - send_bits(dcodes - 1, 5); - send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt - for (rank = 0; rank < blcodes; rank++) - { - send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3); - } - send_tree(dyn_ltree, lcodes - 1); // literal tree - send_tree(dyn_dtree, dcodes - 1); // distance tree - } - - // Send a literal or distance tree in compressed form, using the codes in - // bl_tree. - internal void send_tree(short[] tree, int max_code) - { - int n; // iterates over all tree elements - int prevlen = -1; // last emitted length - int curlen; // length of current code - int nextlen = tree[0 * 2 + 1]; // length of next code - int count = 0; // repeat count of the current code - int max_count = 7; // max repeat count - int min_count = 4; // min repeat count - - if (nextlen == 0) - { - max_count = 138; min_count = 3; - } - - for (n = 0; n <= max_code; n++) - { - curlen = nextlen; nextlen = tree[(n + 1) * 2 + 1]; - if (++count < max_count && curlen == nextlen) - { - continue; - } - else if (count < min_count) - { - do - { - send_code(curlen, bl_tree); - } - while (--count != 0); - } - else if (curlen != 0) - { - if (curlen != prevlen) - { - send_code(curlen, bl_tree); count--; - } - send_code(InternalConstants.REP_3_6, bl_tree); - send_bits(count - 3, 2); - } - else if (count <= 10) - { - send_code(InternalConstants.REPZ_3_10, bl_tree); - send_bits(count - 3, 3); - } - else - { - send_code(InternalConstants.REPZ_11_138, bl_tree); - send_bits(count - 11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) - { - max_count = 138; min_count = 3; - } - else if (curlen == nextlen) - { - max_count = 6; min_count = 3; - } - else - { - max_count = 7; min_count = 4; - } - } - } - - // Output a block of bytes on the stream. - // IN assertion: there is enough room in pending_buf. - private void put_bytes(byte[] p, int start, int len) - { - Array.Copy(p, start, pending, pendingCount, len); - pendingCount += len; - } - -#if NOTNEEDED - private void put_byte(byte c) - { - pending[pendingCount++] = c; - } - internal void put_short(int b) - { - unchecked - { - pending[pendingCount++] = (byte)b; - pending[pendingCount++] = (byte)(b >> 8); - } - } - internal void putShortMSB(int b) - { - unchecked - { - pending[pendingCount++] = (byte)(b >> 8); - pending[pendingCount++] = (byte)b; - } - } -#endif - - internal void send_code(int c, short[] tree) - { - int c2 = c * 2; - send_bits((tree[c2] & 0xffff), (tree[c2 + 1] & 0xffff)); - } - - internal void send_bits(int value, int length) - { - int len = length; - unchecked - { - if (bi_valid > (int)Buf_size - len) - { - //int val = value; - // bi_buf |= (val << bi_valid); - - bi_buf |= (short)((value << bi_valid) & 0xffff); - //put_short(bi_buf); - pending[pendingCount++] = (byte)bi_buf; - pending[pendingCount++] = (byte)(bi_buf >> 8); - - - bi_buf = (short)((uint)value >> (Buf_size - bi_valid)); - bi_valid += len - Buf_size; - } - else - { - // bi_buf |= (value) << bi_valid; - bi_buf |= (short)((value << bi_valid) & 0xffff); - bi_valid += len; - } - } - } - - // Send one empty static block to give enough lookahead for inflate. - // This takes 10 bits, of which 7 may remain in the bit buffer. - // The current inflate code requires 9 bits of lookahead. If the - // last two codes for the previous block (real code plus EOB) were coded - // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - // the last real code. In this case we send two empty static blocks instead - // of one. (There are no problems if the previous block is stored or fixed.) - // To simplify the code, we assume the worst case of last real code encoded - // on one bit only. - internal void _tr_align() - { - send_bits(STATIC_TREES << 1, 3); - send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes); - - bi_flush(); - - // Of the 10 bits for the empty block, we have already sent - // (10 - bi_valid) bits. The lookahead for the last real code (before - // the EOB of the previous block) was thus at least one plus the length - // of the EOB plus what we have just sent of the empty static block. - if (1 + last_eob_len + 10 - bi_valid < 9) - { - send_bits(STATIC_TREES << 1, 3); - send_code(END_BLOCK, StaticTree.lengthAndLiteralsTreeCodes); - bi_flush(); - } - last_eob_len = 7; - } - - - // Save the match info and tally the frequency counts. Return true if - // the current block must be flushed. - internal bool _tr_tally(int dist, int lc) - { - pending[_distanceOffset + last_lit * 2] = unchecked((byte) ( (uint)dist >> 8 ) ); - pending[_distanceOffset + last_lit * 2 + 1] = unchecked((byte)dist); - pending[_lengthOffset + last_lit] = unchecked((byte)lc); - last_lit++; - - if (dist == 0) - { - // lc is the unmatched char - dyn_ltree[lc * 2]++; - } - else - { - matches++; - // Here, lc is the match length - MIN_MATCH - dist--; // dist = match distance - 1 - dyn_ltree[(Tree.LengthCode[lc] + InternalConstants.LITERALS + 1) * 2]++; - dyn_dtree[Tree.DistanceCode(dist) * 2]++; - } - - if ((last_lit & 0x1fff) == 0 && (int)compressionLevel > 2) - { - // Compute an upper bound for the compressed length - int out_length = last_lit << 3; - int in_length = strstart - block_start; - int dcode; - for (dcode = 0; dcode < InternalConstants.D_CODES; dcode++) - { - out_length = (int)(out_length + (int)dyn_dtree[dcode * 2] * (5L + Tree.ExtraDistanceBits[dcode])); - } - out_length >>= 3; - if ((matches < (last_lit / 2)) && out_length < in_length / 2) - return true; - } - - return (last_lit == lit_bufsize - 1) || (last_lit == lit_bufsize); - // dinoch - wraparound? - // We avoid equality with lit_bufsize because of wraparound at 64K - // on 16 bit machines and because stored blocks are restricted to - // 64K-1 bytes. - } - - - - // Send the block data compressed using the given Huffman trees - internal void send_compressed_block(short[] ltree, short[] dtree) - { - int distance; // distance of matched string - int lc; // match length or unmatched char (if dist == 0) - int lx = 0; // running index in l_buf - int code; // the code to send - int extra; // number of extra bits to send - - if (last_lit != 0) - { - do - { - int ix = _distanceOffset + lx * 2; - distance = ((pending[ix] << 8) & 0xff00) | - (pending[ix + 1] & 0xff); - lc = (pending[_lengthOffset + lx]) & 0xff; - lx++; - - if (distance == 0) - { - send_code(lc, ltree); // send a literal byte - } - else - { - // literal or match pair - // Here, lc is the match length - MIN_MATCH - code = Tree.LengthCode[lc]; - - // send the length code - send_code(code + InternalConstants.LITERALS + 1, ltree); - extra = Tree.ExtraLengthBits[code]; - if (extra != 0) - { - // send the extra length bits - lc -= Tree.LengthBase[code]; - send_bits(lc, extra); - } - distance--; // dist is now the match distance - 1 - code = Tree.DistanceCode(distance); - - // send the distance code - send_code(code, dtree); - - extra = Tree.ExtraDistanceBits[code]; - if (extra != 0) - { - // send the extra distance bits - distance -= Tree.DistanceBase[code]; - send_bits(distance, extra); - } - } - - // Check that the overlay between pending and d_buf+l_buf is ok: - } - while (lx < last_lit); - } - - send_code(END_BLOCK, ltree); - last_eob_len = ltree[END_BLOCK * 2 + 1]; - } - - - - // Set the data type to ASCII or BINARY, using a crude approximation: - // binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. - // IN assertion: the fields freq of dyn_ltree are set and the total of all - // frequencies does not exceed 64K (to fit in an int on 16 bit machines). - internal void set_data_type() - { - int n = 0; - int ascii_freq = 0; - int bin_freq = 0; - while (n < 7) - { - bin_freq += dyn_ltree[n * 2]; n++; - } - while (n < 128) - { - ascii_freq += dyn_ltree[n * 2]; n++; - } - while (n < InternalConstants.LITERALS) - { - bin_freq += dyn_ltree[n * 2]; n++; - } - data_type = (sbyte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); - } - - - - // Flush the bit buffer, keeping at most 7 bits in it. - internal void bi_flush() - { - if (bi_valid == 16) - { - pending[pendingCount++] = (byte)bi_buf; - pending[pendingCount++] = (byte)(bi_buf >> 8); - bi_buf = 0; - bi_valid = 0; - } - else if (bi_valid >= 8) - { - //put_byte((byte)bi_buf); - pending[pendingCount++] = (byte)bi_buf; - bi_buf >>= 8; - bi_valid -= 8; - } - } - - // Flush the bit buffer and align the output on a byte boundary - internal void bi_windup() - { - if (bi_valid > 8) - { - pending[pendingCount++] = (byte)bi_buf; - pending[pendingCount++] = (byte)(bi_buf >> 8); - } - else if (bi_valid > 0) - { - //put_byte((byte)bi_buf); - pending[pendingCount++] = (byte)bi_buf; - } - bi_buf = 0; - bi_valid = 0; - } - - // Copy a stored block, storing first the length and its - // one's complement if requested. - internal void copy_block(int buf, int len, bool header) - { - bi_windup(); // align on byte boundary - last_eob_len = 8; // enough lookahead for inflate - - if (header) - unchecked - { - //put_short((short)len); - pending[pendingCount++] = (byte)len; - pending[pendingCount++] = (byte)(len >> 8); - //put_short((short)~len); - pending[pendingCount++] = (byte)~len; - pending[pendingCount++] = (byte)(~len >> 8); - } - - put_bytes(window, buf, len); - } - - internal void flush_block_only(bool eof) - { - _tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof); - block_start = strstart; - _codec.flush_pending(); - } - - // Copy without compression as much as possible from the input stream, return - // the current block state. - // This function does not insert new strings in the dictionary since - // uncompressible data is probably not useful. This function is used - // only for the level=0 compression option. - // NOTE: this function should be optimized to avoid extra copying from - // window to pending_buf. - internal BlockState DeflateNone(FlushType flush) - { - // Stored blocks are limited to 0xffff bytes, pending is limited - // to pending_buf_size, and each stored block has a 5 byte header: - - int max_block_size = 0xffff; - int max_start; - - if (max_block_size > pending.Length - 5) - { - max_block_size = pending.Length - 5; - } - - // Copy as much as possible from input to output: - while (true) - { - // Fill the window as much as possible: - if (lookahead <= 1) - { - _fillWindow(); - if (lookahead == 0 && flush == FlushType.None) - return BlockState.NeedMore; - if (lookahead == 0) - break; // flush the current block - } - - strstart += lookahead; - lookahead = 0; - - // Emit a stored block if pending will be full: - max_start = block_start + max_block_size; - if (strstart == 0 || strstart >= max_start) - { - // strstart == 0 is possible when wraparound on 16-bit machine - lookahead = (int)(strstart - max_start); - strstart = (int)max_start; - - flush_block_only(false); - if (_codec.AvailableBytesOut == 0) - return BlockState.NeedMore; - } - - // Flush if we may have to slide, otherwise block_start may become - // negative and the data will be gone: - if (strstart - block_start >= w_size - MIN_LOOKAHEAD) - { - flush_block_only(false); - if (_codec.AvailableBytesOut == 0) - return BlockState.NeedMore; - } - } - - flush_block_only(flush == FlushType.Finish); - if (_codec.AvailableBytesOut == 0) - return (flush == FlushType.Finish) ? BlockState.FinishStarted : BlockState.NeedMore; - - return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone; - } - - - // Send a stored block - internal void _tr_stored_block(int buf, int stored_len, bool eof) - { - send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type - copy_block(buf, stored_len, true); // with header - } - - // Determine the best encoding for the current block: dynamic trees, static - // trees or store, and output the encoded block to the zip file. - internal void _tr_flush_block(int buf, int stored_len, bool eof) - { - int opt_lenb, static_lenb; // opt_len and static_len in bytes - int max_blindex = 0; // index of last bit length code of non zero freq - - // Build the Huffman trees unless a stored block is forced - if (compressionLevel > 0) - { - // Check if the file is ascii or binary - if (data_type == Z_UNKNOWN) - set_data_type(); - - // Construct the literal and distance trees - treeLiterals.build_tree(this); - - treeDistances.build_tree(this); - - // At this point, opt_len and static_len are the total bit lengths of - // the compressed block data, excluding the tree representations. - - // Build the bit length tree for the above two trees, and get the index - // in bl_order of the last bit length code to send. - max_blindex = build_bl_tree(); - - // Determine the best encoding. Compute first the block length in bytes - opt_lenb = (opt_len + 3 + 7) >> 3; - static_lenb = (static_len + 3 + 7) >> 3; - - if (static_lenb <= opt_lenb) - opt_lenb = static_lenb; - } - else - { - opt_lenb = static_lenb = stored_len + 5; // force a stored block - } - - if (stored_len + 4 <= opt_lenb && buf != -1) - { - // 4: two words for the lengths - // The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - // Otherwise we can't have processed more than WSIZE input bytes since - // the last block flush, because compression would have been - // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - // transform a block into a stored block. - _tr_stored_block(buf, stored_len, eof); - } - else if (static_lenb == opt_lenb) - { - send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3); - send_compressed_block(StaticTree.lengthAndLiteralsTreeCodes, StaticTree.distTreeCodes); - } - else - { - send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3); - send_all_trees(treeLiterals.max_code + 1, treeDistances.max_code + 1, max_blindex + 1); - send_compressed_block(dyn_ltree, dyn_dtree); - } - - // The above check is made mod 2^32, for files larger than 512 MB - // and uLong implemented on 32 bits. - - _InitializeBlocks(); - - if (eof) - { - bi_windup(); - } - } - - // Fill the window when the lookahead becomes insufficient. - // Updates strstart and lookahead. - // - // IN assertion: lookahead < MIN_LOOKAHEAD - // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - // At least one byte has been read, or avail_in == 0; reads are - // performed for at least two bytes (required for the zip translate_eol - // option -- not supported here). - private void _fillWindow() - { - int n, m; - int p; - int more; // Amount of free space at the end of the window. - - do - { - more = (window_size - lookahead - strstart); - - // Deal with !@#$% 64K limit: - if (more == 0 && strstart == 0 && lookahead == 0) - { - more = w_size; - } - else if (more == -1) - { - // Very unlikely, but possible on 16 bit machine if strstart == 0 - // and lookahead == 1 (input done one byte at time) - more--; - - // If the window is almost full and there is insufficient lookahead, - // move the upper half to the lower one to make room in the upper half. - } - else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) - { - Array.Copy(window, w_size, window, 0, w_size); - match_start -= w_size; - strstart -= w_size; // we now have strstart >= MAX_DIST - block_start -= w_size; - - // Slide the hash table (could be avoided with 32 bit values - // at the expense of memory usage). We slide even when level == 0 - // to keep the hash table consistent if we switch back to level > 0 - // later. (Using level 0 permanently is not an optimal usage of - // zlib, so we don't care about this pathological case.) - - n = hash_size; - p = n; - do - { - m = (head[--p] & 0xffff); - head[p] = (short)((m >= w_size) ? (m - w_size) : 0); - } - while (--n != 0); - - n = w_size; - p = n; - do - { - m = (prev[--p] & 0xffff); - prev[p] = (short)((m >= w_size) ? (m - w_size) : 0); - // If n is not on any hash chain, prev[n] is garbage but - // its value will never be used. - } - while (--n != 0); - more += w_size; - } - - if (_codec.AvailableBytesIn == 0) - return; - - // If there was no sliding: - // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - // more == window_size - lookahead - strstart - // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - // => more >= window_size - 2*WSIZE + 2 - // In the BIG_MEM or MMAP case (not yet supported), - // window_size == input_size + MIN_LOOKAHEAD && - // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - // Otherwise, window_size == 2*WSIZE so more >= 2. - // If there was sliding, more >= WSIZE. So in all cases, more >= 2. - - n = _codec.read_buf(window, strstart + lookahead, more); - lookahead += n; - - // Initialize the hash value now that we have some input: - if (lookahead >= MIN_MATCH) - { - ins_h = window[strstart] & 0xff; - ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask; - } - // If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - // but this is not important since only literal bytes will be emitted. - } - while (lookahead < MIN_LOOKAHEAD && _codec.AvailableBytesIn != 0); - } - - // Compress as much as possible from the input stream, return the current - // block state. - // This function does not perform lazy evaluation of matches and inserts - // new strings in the dictionary only for unmatched strings or for short - // matches. It is used only for the fast compression options. - internal BlockState DeflateFast(FlushType flush) - { - // short hash_head = 0; // head of the hash chain - int hash_head = 0; // head of the hash chain - bool bflush; // set if current block must be flushed - - while (true) - { - // Make sure that we always have enough lookahead, except - // at the end of the input file. We need MAX_MATCH bytes - // for the next match, plus MIN_MATCH bytes to insert the - // string following the next match. - if (lookahead < MIN_LOOKAHEAD) - { - _fillWindow(); - if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None) - { - return BlockState.NeedMore; - } - if (lookahead == 0) - break; // flush the current block - } - - // Insert the string window[strstart .. strstart+2] in the - // dictionary, and set hash_head to the head of the hash chain: - if (lookahead >= MIN_MATCH) - { - ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; - - // prev[strstart&w_mask]=hash_head=head[ins_h]; - hash_head = (head[ins_h] & 0xffff); - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = unchecked((short)strstart); - } - - // Find the longest match, discarding those <= prev_length. - // At this point we have always match_length < MIN_MATCH - - if (hash_head != 0L && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) - { - // To simplify the code, we prevent matches with the string - // of window index 0 (in particular we have to avoid a match - // of the string with itself at the start of the input file). - if (compressionStrategy != CompressionStrategy.HuffmanOnly) - { - match_length = longest_match(hash_head); - } - // longest_match() sets match_start - } - if (match_length >= MIN_MATCH) - { - // check_match(strstart, match_start, match_length); - - bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH); - - lookahead -= match_length; - - // Insert new strings in the hash table only if the match length - // is not too large. This saves time but degrades compression. - if (match_length <= config.MaxLazy && lookahead >= MIN_MATCH) - { - match_length--; // string at strstart already in hash table - do - { - strstart++; - - ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; - // prev[strstart&w_mask]=hash_head=head[ins_h]; - hash_head = (head[ins_h] & 0xffff); - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = unchecked((short)strstart); - - // strstart never exceeds WSIZE-MAX_MATCH, so there are - // always MIN_MATCH bytes ahead. - } - while (--match_length != 0); - strstart++; - } - else - { - strstart += match_length; - match_length = 0; - ins_h = window[strstart] & 0xff; - - ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask; - // If lookahead < MIN_MATCH, ins_h is garbage, but it does not - // matter since it will be recomputed at next deflate call. - } - } - else - { - // No match, output a literal byte - - bflush = _tr_tally(0, window[strstart] & 0xff); - lookahead--; - strstart++; - } - if (bflush) - { - flush_block_only(false); - if (_codec.AvailableBytesOut == 0) - return BlockState.NeedMore; - } - } - - flush_block_only(flush == FlushType.Finish); - if (_codec.AvailableBytesOut == 0) - { - if (flush == FlushType.Finish) - return BlockState.FinishStarted; - else - return BlockState.NeedMore; - } - return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone; - } - - // Same as above, but achieves better compression. We use a lazy - // evaluation for matches: a match is finally adopted only if there is - // no better match at the next window position. - internal BlockState DeflateSlow(FlushType flush) - { - // short hash_head = 0; // head of hash chain - int hash_head = 0; // head of hash chain - bool bflush; // set if current block must be flushed - - // Process the input block. - while (true) - { - // Make sure that we always have enough lookahead, except - // at the end of the input file. We need MAX_MATCH bytes - // for the next match, plus MIN_MATCH bytes to insert the - // string following the next match. - - if (lookahead < MIN_LOOKAHEAD) - { - _fillWindow(); - if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None) - return BlockState.NeedMore; - - if (lookahead == 0) - break; // flush the current block - } - - // Insert the string window[strstart .. strstart+2] in the - // dictionary, and set hash_head to the head of the hash chain: - - if (lookahead >= MIN_MATCH) - { - ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; - // prev[strstart&w_mask]=hash_head=head[ins_h]; - hash_head = (head[ins_h] & 0xffff); - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = unchecked((short)strstart); - } - - // Find the longest match, discarding those <= prev_length. - prev_length = match_length; - prev_match = match_start; - match_length = MIN_MATCH - 1; - - if (hash_head != 0 && prev_length < config.MaxLazy && - ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) - { - // To simplify the code, we prevent matches with the string - // of window index 0 (in particular we have to avoid a match - // of the string with itself at the start of the input file). - - if (compressionStrategy != CompressionStrategy.HuffmanOnly) - { - match_length = longest_match(hash_head); - } - // longest_match() sets match_start - - if (match_length <= 5 && (compressionStrategy == CompressionStrategy.Filtered || - (match_length == MIN_MATCH && strstart - match_start > 4096))) - { - - // If prev_match is also MIN_MATCH, match_start is garbage - // but we will ignore the current match anyway. - match_length = MIN_MATCH - 1; - } - } - - // If there was a match at the previous step and the current - // match is not better, output the previous match: - if (prev_length >= MIN_MATCH && match_length <= prev_length) - { - int max_insert = strstart + lookahead - MIN_MATCH; - // Do not insert strings in hash table beyond this. - - // check_match(strstart-1, prev_match, prev_length); - - bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH); - - // Insert in hash table all strings up to the end of the match. - // strstart-1 and strstart are already inserted. If there is not - // enough lookahead, the last two strings are not inserted in - // the hash table. - lookahead -= (prev_length - 1); - prev_length -= 2; - do - { - if (++strstart <= max_insert) - { - ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; - //prev[strstart&w_mask]=hash_head=head[ins_h]; - hash_head = (head[ins_h] & 0xffff); - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = unchecked((short)strstart); - } - } - while (--prev_length != 0); - match_available = 0; - match_length = MIN_MATCH - 1; - strstart++; - - if (bflush) - { - flush_block_only(false); - if (_codec.AvailableBytesOut == 0) - return BlockState.NeedMore; - } - } - else if (match_available != 0) - { - - // If there was no match at the previous position, output a - // single literal. If there was a match but the current match - // is longer, truncate the previous match to a single literal. - - bflush = _tr_tally(0, window[strstart - 1] & 0xff); - - if (bflush) - { - flush_block_only(false); - } - strstart++; - lookahead--; - if (_codec.AvailableBytesOut == 0) - return BlockState.NeedMore; - } - else - { - // There is no previous match to compare with, wait for - // the next step to decide. - - match_available = 1; - strstart++; - lookahead--; - } - } - - if (match_available != 0) - { - bflush = _tr_tally(0, window[strstart - 1] & 0xff); - match_available = 0; - } - flush_block_only(flush == FlushType.Finish); - - if (_codec.AvailableBytesOut == 0) - { - if (flush == FlushType.Finish) - return BlockState.FinishStarted; - else - return BlockState.NeedMore; - } - - return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone; - } - - - internal int longest_match(int cur_match) - { - int chain_length = config.MaxChainLength; // max hash chain length - int scan = strstart; // current string - int match; // matched string - int len; // length of current match - int best_len = prev_length; // best match length so far - int limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0; - - int niceLength = config.NiceLength; - - // Stop when cur_match becomes <= limit. To simplify the code, - // we prevent matches with the string of window index 0. - - int wmask = w_mask; - - int strend = strstart + MAX_MATCH; - byte scan_end1 = window[scan + best_len - 1]; - byte scan_end = window[scan + best_len]; - - // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - // It is easy to get rid of this optimization if necessary. - - // Do not waste too much time if we already have a good match: - if (prev_length >= config.GoodLength) - { - chain_length >>= 2; - } - - // Do not look for matches beyond the end of the input. This is necessary - // to make deflate deterministic. - if (niceLength > lookahead) - niceLength = lookahead; - - do - { - match = cur_match; - - // Skip to next match if the match length cannot increase - // or if the match length is less than 2: - if (window[match + best_len] != scan_end || - window[match + best_len - 1] != scan_end1 || - window[match] != window[scan] || - window[++match] != window[scan + 1]) - continue; - - // The check at best_len-1 can be removed because it will be made - // again later. (This heuristic is not always a win.) - // It is not necessary to compare scan[2] and match[2] since they - // are always equal when the other bytes match, given that - // the hash keys are equal and that HASH_BITS >= 8. - scan += 2; match++; - - // We check for insufficient lookahead only every 8th comparison; - // the 256th check will be made at strstart+258. - do - { - } - while (window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && - window[++scan] == window[++match] && scan < strend); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - - if (len > best_len) - { - match_start = cur_match; - best_len = len; - if (len >= niceLength) - break; - scan_end1 = window[scan + best_len - 1]; - scan_end = window[scan + best_len]; - } - } - while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length != 0); - - if (best_len <= lookahead) - return best_len; - return lookahead; - } - - - private bool Rfc1950BytesEmitted = false; - private bool _WantRfc1950HeaderBytes = true; - internal bool WantRfc1950HeaderBytes - { - get { return _WantRfc1950HeaderBytes; } - set { _WantRfc1950HeaderBytes = value; } - } - - - internal int Initialize(ZlibCodec codec, CompressionLevel level) - { - return Initialize(codec, level, ZlibConstants.WindowBitsMax); - } - - internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits) - { - return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, CompressionStrategy.Default); - } - - internal int Initialize(ZlibCodec codec, CompressionLevel level, int bits, CompressionStrategy compressionStrategy) - { - return Initialize(codec, level, bits, MEM_LEVEL_DEFAULT, compressionStrategy); - } - - internal int Initialize(ZlibCodec codec, CompressionLevel level, int windowBits, int memLevel, CompressionStrategy strategy) - { - _codec = codec; - _codec.Message = null; - - // validation - if (windowBits < 9 || windowBits > 15) - throw new ZlibException("windowBits must be in the range 9..15."); - - if (memLevel < 1 || memLevel > MEM_LEVEL_MAX) - throw new ZlibException(String.Format("memLevel must be in the range 1.. {0}", MEM_LEVEL_MAX)); - - _codec.dstate = this; - - w_bits = windowBits; - w_size = 1 << w_bits; - w_mask = w_size - 1; - - hash_bits = memLevel + 7; - hash_size = 1 << hash_bits; - hash_mask = hash_size - 1; - hash_shift = ((hash_bits + MIN_MATCH - 1) / MIN_MATCH); - - window = new byte[w_size * 2]; - prev = new short[w_size]; - head = new short[hash_size]; - - // for memLevel==8, this will be 16384, 16k - lit_bufsize = 1 << (memLevel + 6); - - // Use a single array as the buffer for data pending compression, - // the output distance codes, and the output length codes (aka tree). - // orig comment: This works just fine since the average - // output size for (length,distance) codes is <= 24 bits. - pending = new byte[lit_bufsize * 4]; - _distanceOffset = lit_bufsize; - _lengthOffset = (1 + 2) * lit_bufsize; - - // So, for memLevel 8, the length of the pending buffer is 65536. 64k. - // The first 16k are pending bytes. - // The middle slice, of 32k, is used for distance codes. - // The final 16k are length codes. - - this.compressionLevel = level; - this.compressionStrategy = strategy; - - Reset(); - return ZlibConstants.Z_OK; - } - - - internal void Reset() - { - _codec.TotalBytesIn = _codec.TotalBytesOut = 0; - _codec.Message = null; - //strm.data_type = Z_UNKNOWN; - - pendingCount = 0; - nextPending = 0; - - Rfc1950BytesEmitted = false; - - status = (WantRfc1950HeaderBytes) ? INIT_STATE : BUSY_STATE; - _codec._Adler32 = Adler.Adler32(0, null, 0, 0); - - last_flush = (int)FlushType.None; - - _InitializeTreeData(); - _InitializeLazyMatch(); - } - - - internal int End() - { - if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) - { - return ZlibConstants.Z_STREAM_ERROR; - } - // Deallocate in reverse order of allocations: - pending = null; - head = null; - prev = null; - window = null; - // free - // dstate=null; - return status == BUSY_STATE ? ZlibConstants.Z_DATA_ERROR : ZlibConstants.Z_OK; - } - - - private void SetDeflater() - { - switch (config.Flavor) - { - case DeflateFlavor.Store: - DeflateFunction = DeflateNone; - break; - case DeflateFlavor.Fast: - DeflateFunction = DeflateFast; - break; - case DeflateFlavor.Slow: - DeflateFunction = DeflateSlow; - break; - } - } - - - internal int SetParams(CompressionLevel level, CompressionStrategy strategy) - { - int result = ZlibConstants.Z_OK; - - if (compressionLevel != level) - { - Config newConfig = Config.Lookup(level); - - // change in the deflate flavor (Fast vs slow vs none)? - if (newConfig.Flavor != config.Flavor && _codec.TotalBytesIn != 0) - { - // Flush the last buffer: - result = _codec.Deflate(FlushType.Partial); - } - - compressionLevel = level; - config = newConfig; - SetDeflater(); - } - - // no need to flush with change in strategy? Really? - compressionStrategy = strategy; - - return result; - } - - - internal int SetDictionary(byte[] dictionary) - { - int length = dictionary.Length; - int index = 0; - - if (dictionary == null || status != INIT_STATE) - throw new ZlibException("Stream error."); - - _codec._Adler32 = Adler.Adler32(_codec._Adler32, dictionary, 0, dictionary.Length); - - if (length < MIN_MATCH) - return ZlibConstants.Z_OK; - if (length > w_size - MIN_LOOKAHEAD) - { - length = w_size - MIN_LOOKAHEAD; - index = dictionary.Length - length; // use the tail of the dictionary - } - Array.Copy(dictionary, index, window, 0, length); - strstart = length; - block_start = length; - - // Insert all strings in the hash table (except for the last two bytes). - // s->lookahead stays null, so s->ins_h will be recomputed at the next - // call of fill_window. - - ins_h = window[0] & 0xff; - ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask; - - for (int n = 0; n <= length - MIN_MATCH; n++) - { - ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask; - prev[n & w_mask] = head[ins_h]; - head[ins_h] = (short)n; - } - return ZlibConstants.Z_OK; - } - - - - internal int Deflate(FlushType flush) - { - int old_flush; - - if (_codec.OutputBuffer == null || - (_codec.InputBuffer == null && _codec.AvailableBytesIn != 0) || - (status == FINISH_STATE && flush != FlushType.Finish)) - { - _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_STREAM_ERROR)]; - throw new ZlibException(String.Format("Something is fishy. [{0}]", _codec.Message)); - //return ZlibConstants.Z_STREAM_ERROR; - } - if (_codec.AvailableBytesOut == 0) - { - _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)]; - throw new ZlibException("OutputBuffer is full (AvailableBytesOut == 0)"); - //return ZlibConstants.Z_BUF_ERROR; - } - - old_flush = last_flush; - last_flush = (int)flush; - - // Write the zlib (rfc1950) header bytes - if (status == INIT_STATE) - { - int header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8; - int level_flags = (((int)compressionLevel - 1) & 0xff) >> 1; - - if (level_flags > 3) - level_flags = 3; - header |= (level_flags << 6); - if (strstart != 0) - header |= PRESET_DICT; - header += 31 - (header % 31); - - status = BUSY_STATE; - //putShortMSB(header); - unchecked - { - pending[pendingCount++] = (byte)(header >> 8); - pending[pendingCount++] = (byte)header; - } - // Save the adler32 of the preset dictionary: - if (strstart != 0) - { - ////putShortMSB((int)(SharedUtils.URShift(_codec._Adler32, 16))); - //putShortMSB((int)((UInt64)_codec._Adler32 >> 16)); - //putShortMSB((int)(_codec._Adler32 & 0xffff)); - pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24); - pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16); - pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8); - pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF); - } - _codec._Adler32 = Adler.Adler32(0, null, 0, 0); - } - - // Flush as much pending output as possible - if (pendingCount != 0) - { - _codec.flush_pending(); - if (_codec.AvailableBytesOut == 0) - { - //System.out.println(" avail_out==0"); - // Since avail_out is 0, deflate will be called again with - // more output space, but possibly with both pending and - // avail_in equal to zero. There won't be anything to do, - // but this is not an error situation so make sure we - // return OK instead of BUF_ERROR at next call of deflate: - last_flush = -1; - return ZlibConstants.Z_OK; - } - - // Make sure there is something to do and avoid duplicate consecutive - // flushes. For repeated and useless calls with Z_FINISH, we keep - // returning Z_STREAM_END instead of Z_BUFF_ERROR. - } - else if (_codec.AvailableBytesIn == 0 && - (int)flush <= old_flush && - flush != FlushType.Finish) - { - // workitem 8557 - // Not sure why this needs to be an error. - // pendingCount == 0, which means there's nothing to deflate. - // And the caller has not asked for a FlushType.Finish, but... - // that seems very non-fatal. We can just say "OK" and do nthing. - - // _codec.Message = z_errmsg[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)]; - // throw new ZlibException("AvailableBytesIn == 0 && flush<=old_flush && flush != FlushType.Finish"); - - return ZlibConstants.Z_OK; - } - - // User must not provide more input after the first FINISH: - if (status == FINISH_STATE && _codec.AvailableBytesIn != 0) - { - _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)]; - throw new ZlibException("status == FINISH_STATE && _codec.AvailableBytesIn != 0"); - } - - - // Start a new block or continue the current one. - if (_codec.AvailableBytesIn != 0 || lookahead != 0 || (flush != FlushType.None && status != FINISH_STATE)) - { - - BlockState bstate = DeflateFunction(flush); - - if (bstate == BlockState.FinishStarted || bstate == BlockState.FinishDone) - { - status = FINISH_STATE; - } - if (bstate == BlockState.NeedMore || bstate == BlockState.FinishStarted) - { - if (_codec.AvailableBytesOut == 0) - { - last_flush = -1; // avoid BUF_ERROR next call, see above - } - return ZlibConstants.Z_OK; - // If flush != Z_NO_FLUSH && avail_out == 0, the next call - // of deflate should use the same flush parameter to make sure - // that the flush is complete. So we don't have to output an - // empty block here, this will be done at next call. This also - // ensures that for a very small output buffer, we emit at most - // one empty block. - } - - if (bstate == BlockState.BlockDone) - { - if (flush == FlushType.Partial) - { - _tr_align(); - } - else - { - // FlushType.Full or FlushType.Sync - _tr_stored_block(0, 0, false); - // For a full flush, this empty block will be recognized - // as a special marker by inflate_sync(). - if (flush == FlushType.Full) - { - // clear hash (forget the history) - for (int i = 0; i < hash_size; i++) - head[i] = 0; - } - } - _codec.flush_pending(); - if (_codec.AvailableBytesOut == 0) - { - last_flush = -1; // avoid BUF_ERROR at next call, see above - return ZlibConstants.Z_OK; - } - } - } - - if (flush != FlushType.Finish) - return ZlibConstants.Z_OK; - - if (!WantRfc1950HeaderBytes || Rfc1950BytesEmitted) - return ZlibConstants.Z_STREAM_END; - - // Write the zlib trailer (adler32) - pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24); - pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16); - pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8); - pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF); - //putShortMSB((int)(SharedUtils.URShift(_codec._Adler32, 16))); - //putShortMSB((int)(_codec._Adler32 & 0xffff)); - - _codec.flush_pending(); - - // If avail_out is zero, the application will call deflate again - // to flush the rest. - - Rfc1950BytesEmitted = true; // write the trailer only once! - - return pendingCount != 0 ? ZlibConstants.Z_OK : ZlibConstants.Z_STREAM_END; - } - - } -} \ No newline at end of file diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/DeflateStream.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/DeflateStream.cs deleted file mode 100644 index 2fe7a7c8..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/DeflateStream.cs +++ /dev/null @@ -1,705 +0,0 @@ -// DeflateStream.cs -// ------------------------------------------------------------------ -// -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. -// All rights reserved. -// -// This code module is part of DotNetZip, a zipfile class library. -// -// ------------------------------------------------------------------ -// -// This code is licensed under the Microsoft Public License. -// See the file License.txt for the license details. -// More info on: http://dotnetzip.codeplex.com -// -// ------------------------------------------------------------------ -// -// last saved (in emacs): -// Time-stamp: <2009-November-03 18:48:49> -// -// ------------------------------------------------------------------ -// -// This module defines the DeflateStream class, which can be used as a replacement for -// the System.IO.Compression.DeflateStream class in the .NET BCL. -// -// ------------------------------------------------------------------ - - -using System; - -namespace Ionic.Zlib -{ - /// - /// A class for compressing and decompressing streams using the Deflate algorithm. - /// - /// - /// - /// - /// - /// The DeflateStream is a Decorator on a . It adds DEFLATE compression or decompression to any stream. - /// - /// - /// Using this stream, applications can compress or decompress data via - /// stream Read and Write operations. Either compresssion or - /// decompression can occur through either reading or writing. The compression - /// format used is DEFLATE, which is documented in IETF RFC 1951, "DEFLATE - /// Compressed Data Format Specification version 1.3.". - /// - /// - /// This class is similar to , except that ZlibStream - /// adds the RFC 1950 - ZLIB - /// framing bytes to a compressed stream when compressing, or expects the RFC1950 - /// framing bytes when decompressing. The DeflateStream does not. - /// - /// - /// - /// - /// - /// - internal class DeflateStream : System.IO.Stream - { - internal ZlibBaseStream _baseStream; - internal System.IO.Stream _innerStream; - bool _disposed; - - /// - /// Create a DeflateStream using the specified CompressionMode. - /// - /// - /// When mode is CompressionMode.Compress, the DeflateStream - /// will use the default compression level. The "captive" stream will be closed - /// when the DeflateStream is closed. - /// - /// - /// This example uses a DeflateStream to compress data from a file, and writes - /// the compressed data to another file. - /// - /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) - /// { - /// using (var raw = System.IO.File.Create(fileToCompress + ".deflated")) - /// { - /// using (Stream compressor = new DeflateStream(raw, CompressionMode.Compress)) - /// { - /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; - /// int n; - /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) - /// { - /// compressor.Write(buffer, 0, n); - /// } - /// } - /// } - /// } - /// - /// - /// Using input As Stream = File.OpenRead(fileToCompress) - /// Using raw As FileStream = File.Create(fileToCompress & ".deflated") - /// Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress) - /// Dim buffer As Byte() = New Byte(4096) {} - /// Dim n As Integer = -1 - /// Do While (n <> 0) - /// If (n > 0) Then - /// compressor.Write(buffer, 0, n) - /// End If - /// n = input.Read(buffer, 0, buffer.Length) - /// Loop - /// End Using - /// End Using - /// End Using - /// - /// - /// The stream which will be read or written. - /// Indicates whether the DeflateStream will compress or decompress. - public DeflateStream(System.IO.Stream stream, CompressionMode mode) - : this(stream, mode, CompressionLevel.Default, false) - { - } - - /// - /// Create a DeflateStream using the specified CompressionMode and the specified CompressionLevel. - /// - /// - /// - /// - /// When mode is CompressionMode.Decompress, the level parameter - /// is ignored. The "captive" stream will be closed when the DeflateStream is - /// closed. - /// - /// - /// - /// - /// - /// This example uses a DeflateStream to compress data from a file, and writes - /// the compressed data to another file. - /// - /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) - /// { - /// using (var raw = System.IO.File.Create(fileToCompress + ".deflated")) - /// { - /// using (Stream compressor = new DeflateStream(raw, - /// CompressionMode.Compress, - /// CompressionLevel.BestCompression)) - /// { - /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; - /// int n= -1; - /// while (n != 0) - /// { - /// if (n > 0) - /// compressor.Write(buffer, 0, n); - /// n= input.Read(buffer, 0, buffer.Length); - /// } - /// } - /// } - /// } - /// - /// - /// - /// Using input As Stream = File.OpenRead(fileToCompress) - /// Using raw As FileStream = File.Create(fileToCompress & ".deflated") - /// Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression) - /// Dim buffer As Byte() = New Byte(4096) {} - /// Dim n As Integer = -1 - /// Do While (n <> 0) - /// If (n > 0) Then - /// compressor.Write(buffer, 0, n) - /// End If - /// n = input.Read(buffer, 0, buffer.Length) - /// Loop - /// End Using - /// End Using - /// End Using - /// - /// - /// The stream to be read or written while deflating or inflating. - /// Indicates whether the DeflateStream will compress or decompress. - /// A tuning knob to trade speed for effectiveness. - public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level) - : this(stream, mode, level, false) - { - } - - /// - /// Create a DeflateStream using the specified - /// CompressionMode, and explicitly specify whether the - /// stream should be left open after Deflation or Inflation. - /// - /// - /// - /// - /// - /// This constructor allows the application to request that the captive stream - /// remain open after the deflation or inflation occurs. By default, after - /// Close() is called on the stream, the captive stream is also - /// closed. In some cases this is not desired, for example if the stream is a - /// memory stream that will be re-read after compression. Specify true for - /// the parameter to leave the stream open. - /// - /// - /// - /// The DeflateStream will use the default compression level. - /// - /// - /// - /// See the other overloads of this constructor for example code. - /// - /// - /// - /// - /// The stream which will be read or written. This is called the - /// "captive" stream in other places in this documentation. - /// - /// - /// - /// Indicates whether the DeflateStream will compress or decompress. - /// - /// - /// true if the application would like the stream to - /// remain open after inflation/deflation. - public DeflateStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen) - : this(stream, mode, CompressionLevel.Default, leaveOpen) - { - } - - /// - /// Create a DeflateStream using the specified CompressionMode - /// and the specified CompressionLevel, and explicitly specify whether - /// the stream should be left open after Deflation or Inflation. - /// - /// - /// - /// - /// - /// When mode is CompressionMode.Decompress, the level parameter is ignored. - /// - /// - /// - /// This constructor allows the application to request that the captive stream - /// remain open after the deflation or inflation occurs. By default, after - /// Close() is called on the stream, the captive stream is also - /// closed. In some cases this is not desired, for example if the stream is a - /// that will be re-read after - /// compression. Specify true for the parameter - /// to leave the stream open. - /// - /// - /// - /// - /// - /// - /// This example shows how to use a DeflateStream to compress data from - /// a file, and store the compressed data into another file. - /// - /// - /// using (var output = System.IO.File.Create(fileToCompress + ".deflated")) - /// { - /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) - /// { - /// using (Stream compressor = new DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true)) - /// { - /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; - /// int n= -1; - /// while (n != 0) - /// { - /// if (n > 0) - /// compressor.Write(buffer, 0, n); - /// n= input.Read(buffer, 0, buffer.Length); - /// } - /// } - /// } - /// // can write additional data to the output stream here - /// } - /// - /// - /// - /// Using output As FileStream = File.Create(fileToCompress & ".deflated") - /// Using input As Stream = File.OpenRead(fileToCompress) - /// Using compressor As Stream = New DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True) - /// Dim buffer As Byte() = New Byte(4096) {} - /// Dim n As Integer = -1 - /// Do While (n <> 0) - /// If (n > 0) Then - /// compressor.Write(buffer, 0, n) - /// End If - /// n = input.Read(buffer, 0, buffer.Length) - /// Loop - /// End Using - /// End Using - /// ' can write additional data to the output stream here. - /// End Using - /// - /// - /// The stream which will be read or written. - /// Indicates whether the DeflateStream will compress or decompress. - /// true if the application would like the stream to remain open after inflation/deflation. - /// A tuning knob to trade speed for effectiveness. - public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen) - { - _innerStream = stream; - _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.DEFLATE, leaveOpen); - } - - #region Zlib properties - - /// - /// This property sets the flush behavior on the stream. - /// - /// See the ZLIB documentation for the meaning of the flush behavior. - /// - virtual public FlushType FlushMode - { - get { return (this._baseStream._flushMode); } - set - { - if (_disposed) throw new ObjectDisposedException("DeflateStream"); - this._baseStream._flushMode = value; - } - } - - /// - /// The size of the working buffer for the compression codec. - /// - /// - /// - /// - /// The working buffer is used for all stream operations. The default size is - /// 1024 bytes. The minimum size is 128 bytes. You may get better performance - /// with a larger buffer. Then again, you might not. You would have to test - /// it. - /// - /// - /// - /// Set this before the first call to Read() or Write() on the - /// stream. If you try to set it afterwards, it will throw. - /// - /// - public int BufferSize - { - get - { - return this._baseStream._bufferSize; - } - set - { - if (_disposed) throw new ObjectDisposedException("DeflateStream"); - if (this._baseStream._workingBuffer != null) - throw new ZlibException("The working buffer is already set."); - if (value < ZlibConstants.WorkingBufferSizeMin) - throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin)); - this._baseStream._bufferSize = value; - } - } - - /// - /// The ZLIB strategy to be used during compression. - /// - /// - /// - /// By tweaking this parameter, you may be able to optimize the compression for - /// data with particular characteristics. - /// - public CompressionStrategy Strategy - { - get - { - return this._baseStream.Strategy; - } - set - { - if (_disposed) throw new ObjectDisposedException("DeflateStream"); - this._baseStream.Strategy = value; - } - } - - /// Returns the total number of bytes input so far. - virtual public long TotalIn - { - get - { - return this._baseStream._z.TotalBytesIn; - } - } - - /// Returns the total number of bytes output so far. - virtual public long TotalOut - { - get - { - return this._baseStream._z.TotalBytesOut; - } - } - - #endregion - - #region System.IO.Stream methods - /// - /// Dispose the stream. - /// - /// - /// This may or may not result in a Close() call on the captive stream. - /// See the constructors that have a leaveOpen parameter for more information. - /// - protected override void Dispose(bool disposing) - { - try - { - if (!_disposed) - { - if (disposing && (this._baseStream != null)) - this._baseStream.Close(); - _disposed = true; - } - } - finally - { - base.Dispose(disposing); - } - } - - - - /// - /// Indicates whether the stream can be read. - /// - /// - /// The return value depends on whether the captive stream supports reading. - /// - public override bool CanRead - { - get - { - if (_disposed) throw new ObjectDisposedException("DeflateStream"); - return _baseStream._stream.CanRead; - } - } - - /// - /// Indicates whether the stream supports Seek operations. - /// - /// - /// Always returns false. - /// - public override bool CanSeek - { - get { return false; } - } - - - /// - /// Indicates whether the stream can be written. - /// - /// - /// The return value depends on whether the captive stream supports writing. - /// - public override bool CanWrite - { - get - { - if (_disposed) throw new ObjectDisposedException("DeflateStream"); - return _baseStream._stream.CanWrite; - } - } - - /// - /// Flush the stream. - /// - public override void Flush() - { - if (_disposed) throw new ObjectDisposedException("DeflateStream"); - _baseStream.Flush(); - } - - /// - /// Reading this property always throws a . - /// - public override long Length - { - get { throw new NotImplementedException(); } - } - - /// - /// The position of the stream pointer. - /// - /// - /// - /// Setting this property always throws a . Reading will return the total bytes - /// written out, if used in writing, or the total bytes read in, if used in - /// reading. The count may refer to compressed bytes or uncompressed bytes, - /// depending on how you've used the stream. - /// - public override long Position - { - get - { - if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer) - return this._baseStream._z.TotalBytesOut; - if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader) - return this._baseStream._z.TotalBytesIn; - return 0; - } - set { throw new NotImplementedException(); } - } - - /// - /// Read data from the stream. - /// - /// - /// - /// - /// If you wish to use the DeflateStream to compress data while - /// reading, you can create a DeflateStream with - /// CompressionMode.Compress, providing an uncompressed data stream. - /// Then call Read() on that DeflateStream, and the data read will be - /// compressed as you read. If you wish to use the DeflateStream to - /// decompress data while reading, you can create a DeflateStream with - /// CompressionMode.Decompress, providing a readable compressed data - /// stream. Then call Read() on that DeflateStream, and the data read - /// will be decompressed as you read. - /// - /// - /// - /// A DeflateStream can be used for Read() or Write(), but not both. - /// - /// - /// - /// The buffer into which the read data should be placed. - /// the offset within that data array to put the first byte read. - /// the number of bytes to read. - /// the number of bytes actually read - public override int Read(byte[] buffer, int offset, int count) - { - if (_disposed) throw new ObjectDisposedException("DeflateStream"); - return _baseStream.Read(buffer, offset, count); - } - - - /// - /// Calling this method always throws a . - /// - /// this is irrelevant, since it will always throw! - /// this is irrelevant, since it will always throw! - /// irrelevant! - public override long Seek(long offset, System.IO.SeekOrigin origin) - { - throw new NotImplementedException(); - } - - /// - /// Calling this method always throws a . - /// - /// this is irrelevant, since it will always throw! - public override void SetLength(long value) - { - throw new NotImplementedException(); - } - - /// - /// Write data to the stream. - /// - /// - /// - /// - /// If you wish to use the DeflateStream to compress data while - /// writing, you can create a DeflateStream with - /// CompressionMode.Compress, and a writable output stream. Then call - /// Write() on that DeflateStream, providing uncompressed data - /// as input. The data sent to the output stream will be the compressed form - /// of the data written. If you wish to use the DeflateStream to - /// decompress data while writing, you can create a DeflateStream with - /// CompressionMode.Decompress, and a writable output stream. Then - /// call Write() on that stream, providing previously compressed - /// data. The data sent to the output stream will be the decompressed form of - /// the data written. - /// - /// - /// - /// A DeflateStream can be used for Read() or Write(), - /// but not both. - /// - /// - /// - /// - /// The buffer holding data to write to the stream. - /// the offset within that data array to find the first byte to write. - /// the number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - if (_disposed) throw new ObjectDisposedException("DeflateStream"); - _baseStream.Write(buffer, offset, count); - } - #endregion - - - - - /// - /// Compress a string into a byte array using DEFLATE. - /// - /// - /// - /// Uncompress it with . - /// - /// - /// - /// - /// - /// - /// A string to compress. The string will first be encoded - /// using UTF8, then compressed. - /// - /// - /// The string in compressed form - public static byte[] CompressString(String s) - { - using (var ms = new System.IO.MemoryStream()) - { - System.IO.Stream compressor = - new DeflateStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression); - ZlibBaseStream.CompressString(s, compressor); - return ms.ToArray(); - } - } - - - /// - /// Compress a byte array into a new byte array using DEFLATE. - /// - /// - /// - /// Uncompress it with . - /// - /// - /// - /// - /// - /// - /// A buffer to compress. - /// - /// - /// The data in compressed form - public static byte[] CompressBuffer(byte[] b) - { - using (var ms = new System.IO.MemoryStream()) - { - System.IO.Stream compressor = - new DeflateStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression ); - - ZlibBaseStream.CompressBuffer(b, compressor); - return ms.ToArray(); - } - } - - - /// - /// Uncompress a DEFLATE'd byte array into a single string. - /// - /// - /// - /// - /// - /// - /// A buffer containing GZIP-compressed data. - /// - /// - /// The uncompressed string - public static String UncompressString(byte[] compressed) - { - using (var input = new System.IO.MemoryStream(compressed)) - { - System.IO.Stream decompressor = - new DeflateStream(input, CompressionMode.Decompress); - - return ZlibBaseStream.UncompressString(compressed, decompressor); - } - } - - - /// - /// Uncompress a DEFLATE'd byte array into a byte array. - /// - /// - /// - /// - /// - /// - /// A buffer containing data that has been compressed with DEFLATE. - /// - /// - /// The data in uncompressed form - public static byte[] UncompressBuffer(byte[] compressed) - { - using (var input = new System.IO.MemoryStream(compressed)) - { - System.IO.Stream decompressor = - new DeflateStream( input, CompressionMode.Decompress ); - - return ZlibBaseStream.UncompressBuffer(compressed, decompressor); - } - } - - } - -} - diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/GZipStream.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/GZipStream.cs deleted file mode 100644 index fbbaf2ef..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/GZipStream.cs +++ /dev/null @@ -1,1013 +0,0 @@ -// GZipStream.cs -// ------------------------------------------------------------------ -// -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. -// All rights reserved. -// -// This code module is part of DotNetZip, a zipfile class library. -// -// ------------------------------------------------------------------ -// -// This code is licensed under the Microsoft Public License. -// See the file License.txt for the license details. -// More info on: http://dotnetzip.codeplex.com -// -// ------------------------------------------------------------------ -// -// last saved (in emacs): -// Time-stamp: <2010-January-09 12:04:28> -// -// ------------------------------------------------------------------ -// -// This module defines the GZipStream class, which can be used as a replacement for -// the System.IO.Compression.GZipStream class in the .NET BCL. NB: The design is not -// completely OO clean: there is some intelligence in the ZlibBaseStream that reads the -// GZip header. -// -// ------------------------------------------------------------------ - - -using System; -using System.IO; - -namespace Ionic.Zlib -{ - /// - /// A class for compressing and decompressing GZIP streams. - /// - /// - /// - /// - /// The GZipStream is a Decorator on a - /// . It adds GZIP compression or decompression to any - /// stream. - /// - /// - /// - /// Like the System.IO.Compression.GZipStream in the .NET Base Class Library, the - /// Ionic.Zlib.GZipStream can compress while writing, or decompress while - /// reading, but not vice versa. The compression method used is GZIP, which is - /// documented in IETF RFC - /// 1952, "GZIP file format specification version 4.3". - /// - /// - /// A GZipStream can be used to decompress data (through Read()) or - /// to compress data (through Write()), but not both. - /// - /// - /// - /// If you wish to use the GZipStream to compress data, you must wrap it - /// around a write-able stream. As you call Write() on the GZipStream, the - /// data will be compressed into the GZIP format. If you want to decompress data, - /// you must wrap the GZipStream around a readable stream that contains an - /// IETF RFC 1952-compliant stream. The data will be decompressed as you call - /// Read() on the GZipStream. - /// - /// - /// - /// Though the GZIP format allows data from multiple files to be concatenated - /// together, this stream handles only a single segment of GZIP format, typically - /// representing a single file. - /// - /// - /// - /// This class is similar to and . - /// ZlibStream handles RFC1950-compliant streams. - /// handles RFC1951-compliant streams. This class handles RFC1952-compliant streams. - /// - /// - /// - /// - /// - /// - internal class GZipStream : System.IO.Stream - { - // GZip format - // source: http://tools.ietf.org/html/rfc1952 - // - // header id: 2 bytes 1F 8B - // compress method 1 byte 8= DEFLATE (none other supported) - // flag 1 byte bitfield (See below) - // mtime 4 bytes time_t (seconds since jan 1, 1970 UTC of the file. - // xflg 1 byte 2 = max compress used , 4 = max speed (can be ignored) - // OS 1 byte OS for originating archive. set to 0xFF in compression. - // extra field length 2 bytes optional - only if FEXTRA is set. - // extra field varies - // filename varies optional - if FNAME is set. zero terminated. ISO-8859-1. - // file comment varies optional - if FCOMMENT is set. zero terminated. ISO-8859-1. - // crc16 1 byte optional - present only if FHCRC bit is set - // compressed data varies - // CRC32 4 bytes - // isize 4 bytes data size modulo 2^32 - // - // FLG (FLaGs) - // bit 0 FTEXT - indicates file is ASCII text (can be safely ignored) - // bit 1 FHCRC - there is a CRC16 for the header immediately following the header - // bit 2 FEXTRA - extra fields are present - // bit 3 FNAME - the zero-terminated filename is present. encoding; ISO-8859-1. - // bit 4 FCOMMENT - a zero-terminated file comment is present. encoding: ISO-8859-1 - // bit 5 reserved - // bit 6 reserved - // bit 7 reserved - // - // On consumption: - // Extra field is a bunch of nonsense and can be safely ignored. - // Header CRC and OS, likewise. - // - // on generation: - // all optional fields get 0, except for the OS, which gets 255. - // - - - - /// - /// The comment on the GZIP stream. - /// - /// - /// - /// - /// The GZIP format allows for each file to optionally have an associated - /// comment stored with the file. The comment is encoded with the ISO-8859-1 - /// code page. To include a comment in a GZIP stream you create, set this - /// property before calling Write() for the first time on the - /// GZipStream. - /// - /// - /// - /// When using GZipStream to decompress, you can retrieve this property - /// after the first call to Read(). If no comment has been set in the - /// GZIP bytestream, the Comment property will return null - /// (Nothing in VB). - /// - /// - public String Comment - { - get - { - return _Comment; - } - set - { - if (_disposed) throw new ObjectDisposedException("GZipStream"); - _Comment = value; - } - } - - /// - /// The FileName for the GZIP stream. - /// - /// - /// - /// - /// - /// The GZIP format optionally allows each file to have an associated - /// filename. When compressing data (through Write()), set this - /// FileName before calling Write() the first time on the GZipStream. - /// The actual filename is encoded into the GZIP bytestream with the - /// ISO-8859-1 code page, according to RFC 1952. It is the application's - /// responsibility to insure that the FileName can be encoded and decoded - /// correctly with this code page. - /// - /// - /// - /// When decompressing (through Read()), you can retrieve this value - /// any time after the first Read(). In the case where there was no filename - /// encoded into the GZIP bytestream, the property will return null (Nothing - /// in VB). - /// - /// - public String FileName - { - get { return _FileName; } - set - { - if (_disposed) throw new ObjectDisposedException("GZipStream"); - _FileName = value; - if (_FileName == null) return; - if (_FileName.IndexOf("/") != -1) - { - _FileName = _FileName.Replace("/", "\\"); - } - if (_FileName.EndsWith("\\")) - throw new Exception("Illegal filename"); - if (_FileName.IndexOf("\\") != -1) - { - // trim any leading path - _FileName = Path.GetFileName(_FileName); - } - } - } - - /// - /// The last modified time for the GZIP stream. - /// - /// - /// - /// GZIP allows the storage of a last modified time with each GZIP entry. - /// When compressing data, you can set this before the first call to - /// Write(). When decompressing, you can retrieve this value any time - /// after the first call to Read(). - /// - public DateTime? LastModified; - - /// - /// The CRC on the GZIP stream. - /// - /// - /// This is used for internal error checking. You probably don't need to look at this property. - /// - public int Crc32 { get { return _Crc32; } } - - private int _headerByteCount; - internal ZlibBaseStream _baseStream; - bool _disposed; - bool _firstReadDone; - string _FileName; - string _Comment; - int _Crc32; - - - /// - /// Create a GZipStream using the specified CompressionMode. - /// - /// - /// - /// - /// When mode is CompressionMode.Compress, the GZipStream will use the - /// default compression level. - /// - /// - /// - /// As noted in the class documentation, the CompressionMode (Compress - /// or Decompress) also establishes the "direction" of the stream. A - /// GZipStream with CompressionMode.Compress works only through - /// Write(). A GZipStream with - /// CompressionMode.Decompress works only through Read(). - /// - /// - /// - /// - /// - /// This example shows how to use a GZipStream to compress data. - /// - /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) - /// { - /// using (var raw = System.IO.File.Create(outputFile)) - /// { - /// using (Stream compressor = new GZipStream(raw, CompressionMode.Compress)) - /// { - /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; - /// int n; - /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) - /// { - /// compressor.Write(buffer, 0, n); - /// } - /// } - /// } - /// } - /// - /// - /// Dim outputFile As String = (fileToCompress & ".compressed") - /// Using input As Stream = File.OpenRead(fileToCompress) - /// Using raw As FileStream = File.Create(outputFile) - /// Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress) - /// Dim buffer As Byte() = New Byte(4096) {} - /// Dim n As Integer = -1 - /// Do While (n <> 0) - /// If (n > 0) Then - /// compressor.Write(buffer, 0, n) - /// End If - /// n = input.Read(buffer, 0, buffer.Length) - /// Loop - /// End Using - /// End Using - /// End Using - /// - /// - /// - /// - /// This example shows how to use a GZipStream to uncompress a file. - /// - /// private void GunZipFile(string filename) - /// { - /// if (!filename.EndsWith(".gz)) - /// throw new ArgumentException("filename"); - /// var DecompressedFile = filename.Substring(0,filename.Length-3); - /// byte[] working = new byte[WORKING_BUFFER_SIZE]; - /// int n= 1; - /// using (System.IO.Stream input = System.IO.File.OpenRead(filename)) - /// { - /// using (Stream decompressor= new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, true)) - /// { - /// using (var output = System.IO.File.Create(DecompressedFile)) - /// { - /// while (n !=0) - /// { - /// n= decompressor.Read(working, 0, working.Length); - /// if (n > 0) - /// { - /// output.Write(working, 0, n); - /// } - /// } - /// } - /// } - /// } - /// } - /// - /// - /// - /// Private Sub GunZipFile(ByVal filename as String) - /// If Not (filename.EndsWith(".gz)) Then - /// Throw New ArgumentException("filename") - /// End If - /// Dim DecompressedFile as String = filename.Substring(0,filename.Length-3) - /// Dim working(WORKING_BUFFER_SIZE) as Byte - /// Dim n As Integer = 1 - /// Using input As Stream = File.OpenRead(filename) - /// Using decompressor As Stream = new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, True) - /// Using output As Stream = File.Create(UncompressedFile) - /// Do - /// n= decompressor.Read(working, 0, working.Length) - /// If n > 0 Then - /// output.Write(working, 0, n) - /// End IF - /// Loop While (n > 0) - /// End Using - /// End Using - /// End Using - /// End Sub - /// - /// - /// - /// The stream which will be read or written. - /// Indicates whether the GZipStream will compress or decompress. - public GZipStream(Stream stream, CompressionMode mode) - : this(stream, mode, CompressionLevel.Default, false) - { - } - - /// - /// Create a GZipStream using the specified CompressionMode and - /// the specified CompressionLevel. - /// - /// - /// - /// - /// The CompressionMode (Compress or Decompress) also establishes the - /// "direction" of the stream. A GZipStream with - /// CompressionMode.Compress works only through Write(). A - /// GZipStream with CompressionMode.Decompress works only - /// through Read(). - /// - /// - /// - /// - /// - /// - /// This example shows how to use a GZipStream to compress a file into a .gz file. - /// - /// - /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) - /// { - /// using (var raw = System.IO.File.Create(fileToCompress + ".gz")) - /// { - /// using (Stream compressor = new GZipStream(raw, - /// CompressionMode.Compress, - /// CompressionLevel.BestCompression)) - /// { - /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; - /// int n; - /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) - /// { - /// compressor.Write(buffer, 0, n); - /// } - /// } - /// } - /// } - /// - /// - /// - /// Using input As Stream = File.OpenRead(fileToCompress) - /// Using raw As FileStream = File.Create(fileToCompress & ".gz") - /// Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression) - /// Dim buffer As Byte() = New Byte(4096) {} - /// Dim n As Integer = -1 - /// Do While (n <> 0) - /// If (n > 0) Then - /// compressor.Write(buffer, 0, n) - /// End If - /// n = input.Read(buffer, 0, buffer.Length) - /// Loop - /// End Using - /// End Using - /// End Using - /// - /// - /// The stream to be read or written while deflating or inflating. - /// Indicates whether the GZipStream will compress or decompress. - /// A tuning knob to trade speed for effectiveness. - public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level) - : this(stream, mode, level, false) - { - } - - /// - /// Create a GZipStream using the specified CompressionMode, and - /// explicitly specify whether the stream should be left open after Deflation - /// or Inflation. - /// - /// - /// - /// - /// This constructor allows the application to request that the captive stream - /// remain open after the deflation or inflation occurs. By default, after - /// Close() is called on the stream, the captive stream is also - /// closed. In some cases this is not desired, for example if the stream is a - /// memory stream that will be re-read after compressed data has been written - /// to it. Specify true for the parameter to leave - /// the stream open. - /// - /// - /// - /// The (Compress or Decompress) also - /// establishes the "direction" of the stream. A GZipStream with - /// CompressionMode.Compress works only through Write(). A GZipStream - /// with CompressionMode.Decompress works only through Read(). - /// - /// - /// - /// The GZipStream will use the default compression level. If you want - /// to specify the compression level, see . - /// - /// - /// - /// See the other overloads of this constructor for example code. - /// - /// - /// - /// - /// - /// The stream which will be read or written. This is called the "captive" - /// stream in other places in this documentation. - /// - /// - /// Indicates whether the GZipStream will compress or decompress. - /// - /// - /// - /// true if the application would like the base stream to remain open after - /// inflation/deflation. - /// - public GZipStream(Stream stream, CompressionMode mode, bool leaveOpen) - : this(stream, mode, CompressionLevel.Default, leaveOpen) - { - } - - /// - /// Create a GZipStream using the specified CompressionMode and the - /// specified CompressionLevel, and explicitly specify whether the - /// stream should be left open after Deflation or Inflation. - /// - /// - /// - /// - /// - /// This constructor allows the application to request that the captive stream - /// remain open after the deflation or inflation occurs. By default, after - /// Close() is called on the stream, the captive stream is also - /// closed. In some cases this is not desired, for example if the stream is a - /// memory stream that will be re-read after compressed data has been written - /// to it. Specify true for the parameter to - /// leave the stream open. - /// - /// - /// - /// As noted in the class documentation, the CompressionMode (Compress - /// or Decompress) also establishes the "direction" of the stream. A - /// GZipStream with CompressionMode.Compress works only through - /// Write(). A GZipStream with CompressionMode.Decompress works only - /// through Read(). - /// - /// - /// - /// - /// - /// This example shows how to use a GZipStream to compress data. - /// - /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) - /// { - /// using (var raw = System.IO.File.Create(outputFile)) - /// { - /// using (Stream compressor = new GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression, true)) - /// { - /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; - /// int n; - /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) - /// { - /// compressor.Write(buffer, 0, n); - /// } - /// } - /// } - /// } - /// - /// - /// Dim outputFile As String = (fileToCompress & ".compressed") - /// Using input As Stream = File.OpenRead(fileToCompress) - /// Using raw As FileStream = File.Create(outputFile) - /// Using compressor As Stream = New GZipStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression, True) - /// Dim buffer As Byte() = New Byte(4096) {} - /// Dim n As Integer = -1 - /// Do While (n <> 0) - /// If (n > 0) Then - /// compressor.Write(buffer, 0, n) - /// End If - /// n = input.Read(buffer, 0, buffer.Length) - /// Loop - /// End Using - /// End Using - /// End Using - /// - /// - /// The stream which will be read or written. - /// Indicates whether the GZipStream will compress or decompress. - /// true if the application would like the stream to remain open after inflation/deflation. - /// A tuning knob to trade speed for effectiveness. - public GZipStream(Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen) - { - _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.GZIP, leaveOpen); - } - - #region Zlib properties - - /// - /// This property sets the flush behavior on the stream. - /// - public virtual FlushType FlushMode - { - get { return (this._baseStream._flushMode); } - set { - if (_disposed) throw new ObjectDisposedException("GZipStream"); - this._baseStream._flushMode = value; - } - } - - /// - /// The size of the working buffer for the compression codec. - /// - /// - /// - /// - /// The working buffer is used for all stream operations. The default size is - /// 1024 bytes. The minimum size is 128 bytes. You may get better performance - /// with a larger buffer. Then again, you might not. You would have to test - /// it. - /// - /// - /// - /// Set this before the first call to Read() or Write() on the - /// stream. If you try to set it afterwards, it will throw. - /// - /// - public int BufferSize - { - get - { - return this._baseStream._bufferSize; - } - set - { - if (_disposed) throw new ObjectDisposedException("GZipStream"); - if (this._baseStream._workingBuffer != null) - throw new ZlibException("The working buffer is already set."); - if (value < ZlibConstants.WorkingBufferSizeMin) - throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin)); - this._baseStream._bufferSize = value; - } - } - - - /// Returns the total number of bytes input so far. - public virtual long TotalIn - { - get - { - return this._baseStream._z.TotalBytesIn; - } - } - - /// Returns the total number of bytes output so far. - public virtual long TotalOut - { - get - { - return this._baseStream._z.TotalBytesOut; - } - } - - #endregion - - #region Stream methods - - /// - /// Dispose the stream. - /// - /// - /// This may or may not result in a Close() call on the captive stream. - /// See the doc on constructors that take a leaveOpen parameter for more information. - /// - protected override void Dispose(bool disposing) - { - try - { - if (!_disposed) - { - if (disposing && (this._baseStream != null)) - { - this._baseStream.Close(); - this._Crc32 = _baseStream.Crc32; - } - _disposed = true; - } - } - finally - { - base.Dispose(disposing); - } - } - - - /// - /// Indicates whether the stream can be read. - /// - /// - /// The return value depends on whether the captive stream supports reading. - /// - public override bool CanRead - { - get - { - if (_disposed) throw new ObjectDisposedException("GZipStream"); - return _baseStream._stream.CanRead; - } - } - - /// - /// Indicates whether the stream supports Seek operations. - /// - /// - /// Always returns false. - /// - public override bool CanSeek - { - get { return false; } - } - - - /// - /// Indicates whether the stream can be written. - /// - /// - /// The return value depends on whether the captive stream supports writing. - /// - public override bool CanWrite - { - get - { - if (_disposed) throw new ObjectDisposedException("GZipStream"); - return _baseStream._stream.CanWrite; - } - } - - /// - /// Flush the stream. - /// - public override void Flush() - { - if (_disposed) throw new ObjectDisposedException("GZipStream"); - _baseStream.Flush(); - } - - /// - /// Reading this property always throws a . - /// - public override long Length - { - get { throw new NotImplementedException(); } - } - - /// - /// The position of the stream pointer. - /// - /// - /// - /// Setting this property always throws a . Reading will return the total bytes - /// written out, if used in writing, or the total bytes read in, if used in - /// reading. The count may refer to compressed bytes or uncompressed bytes, - /// depending on how you've used the stream. - /// - public override long Position - { - get - { - if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer) - return this._baseStream._z.TotalBytesOut + _headerByteCount; - if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader) - return this._baseStream._z.TotalBytesIn + this._baseStream._gzipHeaderByteCount; - return 0; - } - - set { throw new NotImplementedException(); } - } - - /// - /// Read and decompress data from the source stream. - /// - /// - /// - /// With a GZipStream, decompression is done through reading. - /// - /// - /// - /// - /// byte[] working = new byte[WORKING_BUFFER_SIZE]; - /// using (System.IO.Stream input = System.IO.File.OpenRead(_CompressedFile)) - /// { - /// using (Stream decompressor= new Ionic.Zlib.GZipStream(input, CompressionMode.Decompress, true)) - /// { - /// using (var output = System.IO.File.Create(_DecompressedFile)) - /// { - /// int n; - /// while ((n= decompressor.Read(working, 0, working.Length)) !=0) - /// { - /// output.Write(working, 0, n); - /// } - /// } - /// } - /// } - /// - /// - /// The buffer into which the decompressed data should be placed. - /// the offset within that data array to put the first byte read. - /// the number of bytes to read. - /// the number of bytes actually read - public override int Read(byte[] buffer, int offset, int count) - { - if (_disposed) throw new ObjectDisposedException("GZipStream"); - int n = _baseStream.Read(buffer, offset, count); - - // Console.WriteLine("GZipStream::Read(buffer, off({0}), c({1}) = {2}", offset, count, n); - // Console.WriteLine( Util.FormatByteArray(buffer, offset, n) ); - - if (!_firstReadDone) - { - _firstReadDone = true; - FileName = _baseStream._GzipFileName; - Comment = _baseStream._GzipComment; - } - return n; - } - - - - /// - /// Calling this method always throws a . - /// - /// irrelevant; it will always throw! - /// irrelevant; it will always throw! - /// irrelevant! - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotImplementedException(); - } - - /// - /// Calling this method always throws a . - /// - /// irrelevant; this method will always throw! - public override void SetLength(long value) - { - throw new NotImplementedException(); - } - - /// - /// Write data to the stream. - /// - /// - /// - /// - /// If you wish to use the GZipStream to compress data while writing, - /// you can create a GZipStream with CompressionMode.Compress, and a - /// writable output stream. Then call Write() on that GZipStream, - /// providing uncompressed data as input. The data sent to the output stream - /// will be the compressed form of the data written. - /// - /// - /// - /// A GZipStream can be used for Read() or Write(), but not - /// both. Writing implies compression. Reading implies decompression. - /// - /// - /// - /// The buffer holding data to write to the stream. - /// the offset within that data array to find the first byte to write. - /// the number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - if (_disposed) throw new ObjectDisposedException("GZipStream"); - if (_baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Undefined) - { - //Console.WriteLine("GZipStream: First write"); - if (_baseStream._wantCompress) - { - // first write in compression, therefore, emit the GZIP header - _headerByteCount = EmitHeader(); - } - else - { - throw new InvalidOperationException(); - } - } - - _baseStream.Write(buffer, offset, count); - } - #endregion - - - internal static readonly System.DateTime _unixEpoch = new System.DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - internal static readonly System.Text.Encoding iso8859dash1 = System.Text.Encoding.GetEncoding("iso-8859-1"); - - - private int EmitHeader() - { - byte[] commentBytes = (Comment == null) ? null : iso8859dash1.GetBytes(Comment); - byte[] filenameBytes = (FileName == null) ? null : iso8859dash1.GetBytes(FileName); - - int cbLength = (Comment == null) ? 0 : commentBytes.Length + 1; - int fnLength = (FileName == null) ? 0 : filenameBytes.Length + 1; - - int bufferLength = 10 + cbLength + fnLength; - byte[] header = new byte[bufferLength]; - int i = 0; - // ID - header[i++] = 0x1F; - header[i++] = 0x8B; - - // compression method - header[i++] = 8; - byte flag = 0; - if (Comment != null) - flag ^= 0x10; - if (FileName != null) - flag ^= 0x8; - - // flag - header[i++] = flag; - - // mtime - if (!LastModified.HasValue) LastModified = DateTime.Now; - System.TimeSpan delta = LastModified.Value - _unixEpoch; - Int32 timet = (Int32)delta.TotalSeconds; - Array.Copy(BitConverter.GetBytes(timet), 0, header, i, 4); - i += 4; - - // xflg - header[i++] = 0; // this field is totally useless - // OS - header[i++] = 0xFF; // 0xFF == unspecified - - // extra field length - only if FEXTRA is set, which it is not. - //header[i++]= 0; - //header[i++]= 0; - - // filename - if (fnLength != 0) - { - Array.Copy(filenameBytes, 0, header, i, fnLength - 1); - i += fnLength - 1; - header[i++] = 0; // terminate - } - - // comment - if (cbLength != 0) - { - Array.Copy(commentBytes, 0, header, i, cbLength - 1); - i += cbLength - 1; - header[i++] = 0; // terminate - } - - _baseStream._stream.Write(header, 0, header.Length); - - return header.Length; // bytes written - } - - - - /// - /// Compress a string into a byte array using GZip. - /// - /// - /// - /// Uncompress it with . - /// - /// - /// - /// - /// - /// - /// A string to compress. The string will first be encoded - /// using UTF8, then compressed. - /// - /// - /// The string in compressed form - public static byte[] CompressString(String s) - { - using (var ms = new MemoryStream()) - { - System.IO.Stream compressor = - new GZipStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression); - ZlibBaseStream.CompressString(s, compressor); - return ms.ToArray(); - } - } - - - /// - /// Compress a byte array into a new byte array using GZip. - /// - /// - /// - /// Uncompress it with . - /// - /// - /// - /// - /// - /// - /// A buffer to compress. - /// - /// - /// The data in compressed form - public static byte[] CompressBuffer(byte[] b) - { - using (var ms = new MemoryStream()) - { - System.IO.Stream compressor = - new GZipStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression ); - - ZlibBaseStream.CompressBuffer(b, compressor); - return ms.ToArray(); - } - } - - - /// - /// Uncompress a GZip'ed byte array into a single string. - /// - /// - /// - /// - /// - /// - /// A buffer containing GZIP-compressed data. - /// - /// - /// The uncompressed string - public static String UncompressString(byte[] compressed) - { - using (var input = new MemoryStream(compressed)) - { - Stream decompressor = new GZipStream(input, CompressionMode.Decompress); - return ZlibBaseStream.UncompressString(compressed, decompressor); - } - } - - - /// - /// Uncompress a GZip'ed byte array into a byte array. - /// - /// - /// - /// - /// - /// - /// A buffer containing data that has been compressed with GZip. - /// - /// - /// The data in uncompressed form - public static byte[] UncompressBuffer(byte[] compressed) - { - using (var input = new System.IO.MemoryStream(compressed)) - { - System.IO.Stream decompressor = - new GZipStream( input, CompressionMode.Decompress ); - - return ZlibBaseStream.UncompressBuffer(compressed, decompressor); - } - } - - - } -} diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/InfTree.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/InfTree.cs deleted file mode 100644 index 416b143a..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/InfTree.cs +++ /dev/null @@ -1,436 +0,0 @@ -// Inftree.cs -// ------------------------------------------------------------------ -// -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. -// All rights reserved. -// -// This code module is part of DotNetZip, a zipfile class library. -// -// ------------------------------------------------------------------ -// -// This code is licensed under the Microsoft Public License. -// See the file License.txt for the license details. -// More info on: http://dotnetzip.codeplex.com -// -// ------------------------------------------------------------------ -// -// last saved (in emacs): -// Time-stamp: <2009-October-28 12:43:54> -// -// ------------------------------------------------------------------ -// -// This module defines classes used in decompression. This code is derived -// from the jzlib implementation of zlib. In keeping with the license for jzlib, -// the copyright to that code is below. -// -// ------------------------------------------------------------------ -// -// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in -// the documentation and/or other materials provided with the distribution. -// -// 3. The names of the authors may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// ----------------------------------------------------------------------- -// -// This program is based on zlib-1.1.3; credit to authors -// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) -// and contributors of zlib. -// -// ----------------------------------------------------------------------- - - - -using System; -namespace Ionic.Zlib -{ - - sealed class InfTree - { - - private const int MANY = 1440; - - private const int Z_OK = 0; - private const int Z_STREAM_END = 1; - private const int Z_NEED_DICT = 2; - private const int Z_ERRNO = - 1; - private const int Z_STREAM_ERROR = - 2; - private const int Z_DATA_ERROR = - 3; - private const int Z_MEM_ERROR = - 4; - private const int Z_BUF_ERROR = - 5; - private const int Z_VERSION_ERROR = - 6; - - internal const int fixed_bl = 9; - internal const int fixed_bd = 5; - - //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_tl'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] fixed_tl = new int[]{96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, - 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, - 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255}; - //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] fixed_td = new int[]{80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577}; - - // Tables for deflate from PKZIP's appnote.txt. - //UPGRADE_NOTE: Final was removed from the declaration of 'cplens'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] cplens = new int[]{3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - - // see note #13 above about 258 - //UPGRADE_NOTE: Final was removed from the declaration of 'cplext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] cplext = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; - - //UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] cpdist = new int[]{1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; - - //UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" - internal static readonly int[] cpdext = new int[]{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; - - // If BMAX needs to be larger than 16, then h and x[] should be uLong. - internal const int BMAX = 15; // maximum bit length of any code - - internal int[] hn = null; // hufts used in space - internal int[] v = null; // work area for huft_build - internal int[] c = null; // bit length count table - internal int[] r = null; // table entry for structure assignment - internal int[] u = null; // table stack - internal int[] x = null; // bit offsets, then code stack - - private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v) - { - // Given a list of code lengths and a maximum table size, make a set of - // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - // if the given code set is incomplete (the tables are still built in this - // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of - // lengths), or Z_MEM_ERROR if not enough memory. - - int a; // counter for codes of length k - int f; // i repeats in table every f entries - int g; // maximum code length - int h; // table level - int i; // counter, current code - int j; // counter - int k; // number of bits in current code - int l; // bits per table (returned in m) - int mask; // (1 << w) - 1, to avoid cc -O bug on HP - int p; // pointer into c[], b[], or v[] - int q; // points to current table - int w; // bits before this table == (l * h) - int xp; // pointer into x - int y; // number of dummy codes added - int z; // number of entries in current table - - // Generate counts for each bit length - - p = 0; i = n; - do - { - c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX - } - while (i != 0); - - if (c[0] == n) - { - // null input--all zero length codes - t[0] = - 1; - m[0] = 0; - return Z_OK; - } - - // Find minimum and maximum length, bound *m by those - l = m[0]; - for (j = 1; j <= BMAX; j++) - if (c[j] != 0) - break; - k = j; // minimum code length - if (l < j) - { - l = j; - } - for (i = BMAX; i != 0; i--) - { - if (c[i] != 0) - break; - } - g = i; // maximum code length - if (l > i) - { - l = i; - } - m[0] = l; - - // Adjust last length count to fill out codes, if needed - for (y = 1 << j; j < i; j++, y <<= 1) - { - if ((y -= c[j]) < 0) - { - return Z_DATA_ERROR; - } - } - if ((y -= c[i]) < 0) - { - return Z_DATA_ERROR; - } - c[i] += y; - - // Generate starting offsets into the value table for each length - x[1] = j = 0; - p = 1; xp = 2; - while (--i != 0) - { - // note that i == g from above - x[xp] = (j += c[p]); - xp++; - p++; - } - - // Make a table of values in order of bit lengths - i = 0; p = 0; - do - { - if ((j = b[bindex + p]) != 0) - { - v[x[j]++] = i; - } - p++; - } - while (++i < n); - n = x[g]; // set n to length of v - - // Generate the Huffman codes and for each, make the table entries - x[0] = i = 0; // first Huffman code is zero - p = 0; // grab values in bit order - h = - 1; // no tables yet--level -1 - w = - l; // bits decoded == (l * h) - u[0] = 0; // just to keep compilers happy - q = 0; // ditto - z = 0; // ditto - - // go through the bit lengths (k already is bits in shortest code) - for (; k <= g; k++) - { - a = c[k]; - while (a-- != 0) - { - // here i is the Huffman code of length k bits for value *p - // make tables up to required level - while (k > w + l) - { - h++; - w += l; // previous table always l bits - // compute minimum size table less than or equal to l bits - z = g - w; - z = (z > l)?l:z; // table size upper limit - if ((f = 1 << (j = k - w)) > a + 1) - { - // try a k-w bit table - // too few codes for k-w bit table - f -= (a + 1); // deduct codes from patterns left - xp = k; - if (j < z) - { - while (++j < z) - { - // try smaller tables up to z bits - if ((f <<= 1) <= c[++xp]) - break; // enough codes to use up j bits - f -= c[xp]; // else deduct codes from patterns - } - } - } - z = 1 << j; // table entries for j-bit table - - // allocate new table - if (hn[0] + z > MANY) - { - // (note: doesn't matter for fixed) - return Z_DATA_ERROR; // overflow of MANY - } - u[h] = q = hn[0]; // DEBUG - hn[0] += z; - - // connect to last table, if there is one - if (h != 0) - { - x[h] = i; // save pattern for backing up - r[0] = (sbyte) j; // bits in this table - r[1] = (sbyte) l; // bits to dump before this table - j = SharedUtils.URShift(i, (w - l)); - r[2] = (int) (q - u[h - 1] - j); // offset to this table - Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table - } - else - { - t[0] = q; // first table is returned result - } - } - - // set up table entry in r - r[1] = (sbyte) (k - w); - if (p >= n) - { - r[0] = 128 + 64; // out of values--invalid code - } - else if (v[p] < s) - { - r[0] = (sbyte) (v[p] < 256?0:32 + 64); // 256 is end-of-block - r[2] = v[p++]; // simple code is just the value - } - else - { - r[0] = (sbyte) (e[v[p] - s] + 16 + 64); // non-simple--look up in lists - r[2] = d[v[p++] - s]; - } - - // fill code-like entries with r - f = 1 << (k - w); - for (j = SharedUtils.URShift(i, w); j < z; j += f) - { - Array.Copy(r, 0, hp, (q + j) * 3, 3); - } - - // backwards increment the k-bit code i - for (j = 1 << (k - 1); (i & j) != 0; j = SharedUtils.URShift(j, 1)) - { - i ^= j; - } - i ^= j; - - // backup over finished tables - mask = (1 << w) - 1; // needed on HP, cc -O bug - while ((i & mask) != x[h]) - { - h--; // don't need to update q - w -= l; - mask = (1 << w) - 1; - } - } - } - // Return Z_BUF_ERROR if we were given an incomplete table - return y != 0 && g != 1?Z_BUF_ERROR:Z_OK; - } - - internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z) - { - int result; - initWorkArea(19); - hn[0] = 0; - result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); - - if (result == Z_DATA_ERROR) - { - z.Message = "oversubscribed dynamic bit lengths tree"; - } - else if (result == Z_BUF_ERROR || bb[0] == 0) - { - z.Message = "incomplete dynamic bit lengths tree"; - result = Z_DATA_ERROR; - } - return result; - } - - internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z) - { - int result; - - // build literal/length tree - initWorkArea(288); - hn[0] = 0; - result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); - if (result != Z_OK || bl[0] == 0) - { - if (result == Z_DATA_ERROR) - { - z.Message = "oversubscribed literal/length tree"; - } - else if (result != Z_MEM_ERROR) - { - z.Message = "incomplete literal/length tree"; - result = Z_DATA_ERROR; - } - return result; - } - - // build distance tree - initWorkArea(288); - result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); - - if (result != Z_OK || (bd[0] == 0 && nl > 257)) - { - if (result == Z_DATA_ERROR) - { - z.Message = "oversubscribed distance tree"; - } - else if (result == Z_BUF_ERROR) - { - z.Message = "incomplete distance tree"; - result = Z_DATA_ERROR; - } - else if (result != Z_MEM_ERROR) - { - z.Message = "empty distance tree with lengths"; - result = Z_DATA_ERROR; - } - return result; - } - - return Z_OK; - } - - internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z) - { - bl[0] = fixed_bl; - bd[0] = fixed_bd; - tl[0] = fixed_tl; - td[0] = fixed_td; - return Z_OK; - } - - private void initWorkArea(int vsize) - { - if (hn == null) - { - hn = new int[1]; - v = new int[vsize]; - c = new int[BMAX + 1]; - r = new int[3]; - u = new int[BMAX]; - x = new int[BMAX + 1]; - } - else - { - if (v.Length < vsize) - { - v = new int[vsize]; - } - Array.Clear(v,0,vsize); - Array.Clear(c,0,BMAX+1); - r[0]=0; r[1]=0; r[2]=0; - // for(int i=0; i -// -// ------------------------------------------------------------------ -// -// This module defines classes for decompression. This code is derived -// from the jzlib implementation of zlib, but significantly modified. -// The object model is not the same, and many of the behaviors are -// different. Nonetheless, in keeping with the license for jzlib, I am -// reproducing the copyright to that code here. -// -// ------------------------------------------------------------------ -// -// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in -// the documentation and/or other materials provided with the distribution. -// -// 3. The names of the authors may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// ----------------------------------------------------------------------- -// -// This program is based on zlib-1.1.3; credit to authors -// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) -// and contributors of zlib. -// -// ----------------------------------------------------------------------- - - -using System; -namespace Ionic.Zlib -{ - sealed class InflateBlocks - { - private const int MANY = 1440; - - // Table for deflate from PKZIP's appnote.txt. - internal static readonly int[] border = new int[] - { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; - - private enum InflateBlockMode - { - TYPE = 0, // get type bits (3, including end bit) - LENS = 1, // get lengths for stored - STORED = 2, // processing stored block - TABLE = 3, // get table lengths - BTREE = 4, // get bit lengths tree for a dynamic block - DTREE = 5, // get length, distance trees for a dynamic block - CODES = 6, // processing fixed or dynamic block - DRY = 7, // output remaining window bytes - DONE = 8, // finished last block, done - BAD = 9, // ot a data error--stuck here - } - - private InflateBlockMode mode; // current inflate_block mode - - internal int left; // if STORED, bytes left to copy - - internal int table; // table lengths (14 bits) - internal int index; // index into blens (or border) - internal int[] blens; // bit lengths of codes - internal int[] bb = new int[1]; // bit length tree depth - internal int[] tb = new int[1]; // bit length decoding tree - - internal InflateCodes codes = new InflateCodes(); // if CODES, current state - - internal int last; // true if this block is the last block - - internal ZlibCodec _codec; // pointer back to this zlib stream - - // mode independent information - internal int bitk; // bits in bit buffer - internal int bitb; // bit buffer - internal int[] hufts; // single malloc for tree space - internal byte[] window; // sliding window - internal int end; // one byte after sliding window - internal int readAt; // window read pointer - internal int writeAt; // window write pointer - internal System.Object checkfn; // check function - internal uint check; // check on output - - internal InfTree inftree = new InfTree(); - - internal InflateBlocks(ZlibCodec codec, System.Object checkfn, int w) - { - _codec = codec; - hufts = new int[MANY * 3]; - window = new byte[w]; - end = w; - this.checkfn = checkfn; - mode = InflateBlockMode.TYPE; - Reset(); - } - - internal uint Reset() - { - uint oldCheck = check; - mode = InflateBlockMode.TYPE; - bitk = 0; - bitb = 0; - readAt = writeAt = 0; - - if (checkfn != null) - _codec._Adler32 = check = Adler.Adler32(0, null, 0, 0); - return oldCheck; - } - - - internal int Process(int r) - { - int t; // temporary storage - int b; // bit buffer - int k; // bits in bit buffer - int p; // input data pointer - int n; // bytes available there - int q; // output window write pointer - int m; // bytes to end of window or read pointer - - // copy input/output information to locals (UPDATE macro restores) - - p = _codec.NextIn; - n = _codec.AvailableBytesIn; - b = bitb; - k = bitk; - - q = writeAt; - m = (int)(q < readAt ? readAt - q - 1 : end - q); - - - // process input based on current state - while (true) - { - switch (mode) - { - case InflateBlockMode.TYPE: - - while (k < (3)) - { - if (n != 0) - { - r = ZlibConstants.Z_OK; - } - else - { - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - - n--; - b |= (_codec.InputBuffer[p++] & 0xff) << k; - k += 8; - } - t = (int)(b & 7); - last = t & 1; - - switch ((uint)t >> 1) - { - case 0: // stored - b >>= 3; k -= (3); - t = k & 7; // go to byte boundary - b >>= t; k -= t; - mode = InflateBlockMode.LENS; // get length of stored block - break; - - case 1: // fixed - int[] bl = new int[1]; - int[] bd = new int[1]; - int[][] tl = new int[1][]; - int[][] td = new int[1][]; - InfTree.inflate_trees_fixed(bl, bd, tl, td, _codec); - codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0); - b >>= 3; k -= 3; - mode = InflateBlockMode.CODES; - break; - - case 2: // dynamic - b >>= 3; k -= 3; - mode = InflateBlockMode.TABLE; - break; - - case 3: // illegal - b >>= 3; k -= 3; - mode = InflateBlockMode.BAD; - _codec.Message = "invalid block type"; - r = ZlibConstants.Z_DATA_ERROR; - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - break; - - case InflateBlockMode.LENS: - - while (k < (32)) - { - if (n != 0) - { - r = ZlibConstants.Z_OK; - } - else - { - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - ; - n--; - b |= (_codec.InputBuffer[p++] & 0xff) << k; - k += 8; - } - - if ( ( ((~b)>>16) & 0xffff) != (b & 0xffff)) - { - mode = InflateBlockMode.BAD; - _codec.Message = "invalid stored block lengths"; - r = ZlibConstants.Z_DATA_ERROR; - - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - left = (b & 0xffff); - b = k = 0; // dump bits - mode = left != 0 ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE); - break; - - case InflateBlockMode.STORED: - if (n == 0) - { - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - - if (m == 0) - { - if (q == end && readAt != 0) - { - q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q); - } - if (m == 0) - { - writeAt = q; - r = Flush(r); - q = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q); - if (q == end && readAt != 0) - { - q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q); - } - if (m == 0) - { - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - } - } - r = ZlibConstants.Z_OK; - - t = left; - if (t > n) - t = n; - if (t > m) - t = m; - Array.Copy(_codec.InputBuffer, p, window, q, t); - p += t; n -= t; - q += t; m -= t; - if ((left -= t) != 0) - break; - mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE; - break; - - case InflateBlockMode.TABLE: - - while (k < (14)) - { - if (n != 0) - { - r = ZlibConstants.Z_OK; - } - else - { - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - - n--; - b |= (_codec.InputBuffer[p++] & 0xff) << k; - k += 8; - } - - table = t = (b & 0x3fff); - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - mode = InflateBlockMode.BAD; - _codec.Message = "too many length or distance symbols"; - r = ZlibConstants.Z_DATA_ERROR; - - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if (blens == null || blens.Length < t) - { - blens = new int[t]; - } - else - { - Array.Clear(blens, 0, t); - // for (int i = 0; i < t; i++) - // { - // blens[i] = 0; - // } - } - - b >>= 14; - k -= 14; - - - index = 0; - mode = InflateBlockMode.BTREE; - goto case InflateBlockMode.BTREE; - - case InflateBlockMode.BTREE: - while (index < 4 + (table >> 10)) - { - while (k < (3)) - { - if (n != 0) - { - r = ZlibConstants.Z_OK; - } - else - { - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - - n--; - b |= (_codec.InputBuffer[p++] & 0xff) << k; - k += 8; - } - - blens[border[index++]] = b & 7; - - b >>= 3; k -= 3; - } - - while (index < 19) - { - blens[border[index++]] = 0; - } - - bb[0] = 7; - t = inftree.inflate_trees_bits(blens, bb, tb, hufts, _codec); - if (t != ZlibConstants.Z_OK) - { - r = t; - if (r == ZlibConstants.Z_DATA_ERROR) - { - blens = null; - mode = InflateBlockMode.BAD; - } - - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - - index = 0; - mode = InflateBlockMode.DTREE; - goto case InflateBlockMode.DTREE; - - case InflateBlockMode.DTREE: - while (true) - { - t = table; - if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) - { - break; - } - - int i, j, c; - - t = bb[0]; - - while (k < t) - { - if (n != 0) - { - r = ZlibConstants.Z_OK; - } - else - { - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - - n--; - b |= (_codec.InputBuffer[p++] & 0xff) << k; - k += 8; - } - - t = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 1]; - c = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 2]; - - if (c < 16) - { - b >>= t; k -= t; - blens[index++] = c; - } - else - { - // c == 16..18 - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - - while (k < (t + i)) - { - if (n != 0) - { - r = ZlibConstants.Z_OK; - } - else - { - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - - n--; - b |= (_codec.InputBuffer[p++] & 0xff) << k; - k += 8; - } - - b >>= t; k -= t; - - j += (b & InternalInflateConstants.InflateMask[i]); - - b >>= i; k -= i; - - i = index; - t = table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) - { - blens = null; - mode = InflateBlockMode.BAD; - _codec.Message = "invalid bit length repeat"; - r = ZlibConstants.Z_DATA_ERROR; - - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - - c = (c == 16) ? blens[i-1] : 0; - do - { - blens[i++] = c; - } - while (--j != 0); - index = i; - } - } - - tb[0] = -1; - { - int[] bl = new int[] { 9 }; // must be <= 9 for lookahead assumptions - int[] bd = new int[] { 6 }; // must be <= 9 for lookahead assumptions - int[] tl = new int[1]; - int[] td = new int[1]; - - t = table; - t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, _codec); - - if (t != ZlibConstants.Z_OK) - { - if (t == ZlibConstants.Z_DATA_ERROR) - { - blens = null; - mode = InflateBlockMode.BAD; - } - r = t; - - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - codes.Init(bl[0], bd[0], hufts, tl[0], hufts, td[0]); - } - mode = InflateBlockMode.CODES; - goto case InflateBlockMode.CODES; - - case InflateBlockMode.CODES: - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - - r = codes.Process(this, r); - if (r != ZlibConstants.Z_STREAM_END) - { - return Flush(r); - } - - r = ZlibConstants.Z_OK; - p = _codec.NextIn; - n = _codec.AvailableBytesIn; - b = bitb; - k = bitk; - q = writeAt; - m = (int)(q < readAt ? readAt - q - 1 : end - q); - - if (last == 0) - { - mode = InflateBlockMode.TYPE; - break; - } - mode = InflateBlockMode.DRY; - goto case InflateBlockMode.DRY; - - case InflateBlockMode.DRY: - writeAt = q; - r = Flush(r); - q = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q); - if (readAt != writeAt) - { - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - mode = InflateBlockMode.DONE; - goto case InflateBlockMode.DONE; - - case InflateBlockMode.DONE: - r = ZlibConstants.Z_STREAM_END; - bitb = b; - bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - - case InflateBlockMode.BAD: - r = ZlibConstants.Z_DATA_ERROR; - - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - - - default: - r = ZlibConstants.Z_STREAM_ERROR; - - bitb = b; bitk = k; - _codec.AvailableBytesIn = n; - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - writeAt = q; - return Flush(r); - } - } - } - - - internal void Free() - { - Reset(); - window = null; - hufts = null; - } - - internal void SetDictionary(byte[] d, int start, int n) - { - Array.Copy(d, start, window, 0, n); - readAt = writeAt = n; - } - - // Returns true if inflate is currently at the end of a block generated - // by Z_SYNC_FLUSH or Z_FULL_FLUSH. - internal int SyncPoint() - { - return mode == InflateBlockMode.LENS ? 1 : 0; - } - - // copy as much as possible from the sliding window to the output area - internal int Flush(int r) - { - int nBytes; - - for (int pass=0; pass < 2; pass++) - { - if (pass==0) - { - // compute number of bytes to copy as far as end of window - nBytes = (int)((readAt <= writeAt ? writeAt : end) - readAt); - } - else - { - // compute bytes to copy - nBytes = writeAt - readAt; - } - - // workitem 8870 - if (nBytes == 0) - { - if (r == ZlibConstants.Z_BUF_ERROR) - r = ZlibConstants.Z_OK; - return r; - } - - if (nBytes > _codec.AvailableBytesOut) - nBytes = _codec.AvailableBytesOut; - - if (nBytes != 0 && r == ZlibConstants.Z_BUF_ERROR) - r = ZlibConstants.Z_OK; - - // update counters - _codec.AvailableBytesOut -= nBytes; - _codec.TotalBytesOut += nBytes; - - // update check information - if (checkfn != null) - _codec._Adler32 = check = Adler.Adler32(check, window, readAt, nBytes); - - // copy as far as end of window - Array.Copy(window, readAt, _codec.OutputBuffer, _codec.NextOut, nBytes); - _codec.NextOut += nBytes; - readAt += nBytes; - - // see if more to copy at beginning of window - if (readAt == end && pass == 0) - { - // wrap pointers - readAt = 0; - if (writeAt == end) - writeAt = 0; - } - else pass++; - } - - // done - return r; - } - } - - - internal static class InternalInflateConstants - { - // And'ing with mask[n] masks the lower n bits - internal static readonly int[] InflateMask = new int[] { - 0x00000000, 0x00000001, 0x00000003, 0x00000007, - 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, - 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, - 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff }; - } - - - sealed class InflateCodes - { - // waiting for "i:"=input, - // "o:"=output, - // "x:"=nothing - private const int START = 0; // x: set up for LEN - private const int LEN = 1; // i: get length/literal/eob next - private const int LENEXT = 2; // i: getting length extra (have base) - private const int DIST = 3; // i: get distance next - private const int DISTEXT = 4; // i: getting distance extra - private const int COPY = 5; // o: copying bytes in window, waiting for space - private const int LIT = 6; // o: got literal, waiting for output space - private const int WASH = 7; // o: got eob, possibly still output waiting - private const int END = 8; // x: got eob and all data flushed - private const int BADCODE = 9; // x: got error - - internal int mode; // current inflate_codes mode - - // mode dependent information - internal int len; - - internal int[] tree; // pointer into tree - internal int tree_index = 0; - internal int need; // bits needed - - internal int lit; - - // if EXT or COPY, where and how much - internal int bitsToGet; // bits to get for extra - internal int dist; // distance back to copy from - - internal byte lbits; // ltree bits decoded per branch - internal byte dbits; // dtree bits decoder per branch - internal int[] ltree; // literal/length/eob tree - internal int ltree_index; // literal/length/eob tree - internal int[] dtree; // distance tree - internal int dtree_index; // distance tree - - internal InflateCodes() - { - } - - internal void Init(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index) - { - mode = START; - lbits = (byte)bl; - dbits = (byte)bd; - ltree = tl; - ltree_index = tl_index; - dtree = td; - dtree_index = td_index; - tree = null; - } - - internal int Process(InflateBlocks blocks, int r) - { - int j; // temporary storage - int tindex; // temporary pointer - int e; // extra bits or operation - int b = 0; // bit buffer - int k = 0; // bits in bit buffer - int p = 0; // input data pointer - int n; // bytes available there - int q; // output window write pointer - int m; // bytes to end of window or read pointer - int f; // pointer to copy strings from - - ZlibCodec z = blocks._codec; - - // copy input/output information to locals (UPDATE macro restores) - p = z.NextIn; - n = z.AvailableBytesIn; - b = blocks.bitb; - k = blocks.bitk; - q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; - - // process input and output based on current state - while (true) - { - switch (mode) - { - // waiting for "i:"=input, "o:"=output, "x:"=nothing - case START: // x: set up for LEN - if (m >= 258 && n >= 10) - { - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; - z.TotalBytesIn += p - z.NextIn; - z.NextIn = p; - blocks.writeAt = q; - r = InflateFast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, blocks, z); - - p = z.NextIn; - n = z.AvailableBytesIn; - b = blocks.bitb; - k = blocks.bitk; - q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; - - if (r != ZlibConstants.Z_OK) - { - mode = (r == ZlibConstants.Z_STREAM_END) ? WASH : BADCODE; - break; - } - } - need = lbits; - tree = ltree; - tree_index = ltree_index; - - mode = LEN; - goto case LEN; - - case LEN: // i: get length/literal/eob next - j = need; - - while (k < j) - { - if (n != 0) - r = ZlibConstants.Z_OK; - else - { - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; - z.TotalBytesIn += p - z.NextIn; - z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - } - n--; - b |= (z.InputBuffer[p++] & 0xff) << k; - k += 8; - } - - tindex = (tree_index + (b & InternalInflateConstants.InflateMask[j])) * 3; - - b >>= (tree[tindex + 1]); - k -= (tree[tindex + 1]); - - e = tree[tindex]; - - if (e == 0) - { - // literal - lit = tree[tindex + 2]; - mode = LIT; - break; - } - if ((e & 16) != 0) - { - // length - bitsToGet = e & 15; - len = tree[tindex + 2]; - mode = LENEXT; - break; - } - if ((e & 64) == 0) - { - // next table - need = e; - tree_index = tindex / 3 + tree[tindex + 2]; - break; - } - if ((e & 32) != 0) - { - // end of block - mode = WASH; - break; - } - mode = BADCODE; // invalid code - z.Message = "invalid literal/length code"; - r = ZlibConstants.Z_DATA_ERROR; - - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; - z.TotalBytesIn += p - z.NextIn; - z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - - - case LENEXT: // i: getting length extra (have base) - j = bitsToGet; - - while (k < j) - { - if (n != 0) - r = ZlibConstants.Z_OK; - else - { - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - } - n--; b |= (z.InputBuffer[p++] & 0xff) << k; - k += 8; - } - - len += (b & InternalInflateConstants.InflateMask[j]); - - b >>= j; - k -= j; - - need = dbits; - tree = dtree; - tree_index = dtree_index; - mode = DIST; - goto case DIST; - - case DIST: // i: get distance next - j = need; - - while (k < j) - { - if (n != 0) - r = ZlibConstants.Z_OK; - else - { - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - } - n--; b |= (z.InputBuffer[p++] & 0xff) << k; - k += 8; - } - - tindex = (tree_index + (b & InternalInflateConstants.InflateMask[j])) * 3; - - b >>= tree[tindex + 1]; - k -= tree[tindex + 1]; - - e = (tree[tindex]); - if ((e & 0x10) != 0) - { - // distance - bitsToGet = e & 15; - dist = tree[tindex + 2]; - mode = DISTEXT; - break; - } - if ((e & 64) == 0) - { - // next table - need = e; - tree_index = tindex / 3 + tree[tindex + 2]; - break; - } - mode = BADCODE; // invalid code - z.Message = "invalid distance code"; - r = ZlibConstants.Z_DATA_ERROR; - - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - - - case DISTEXT: // i: getting distance extra - j = bitsToGet; - - while (k < j) - { - if (n != 0) - r = ZlibConstants.Z_OK; - else - { - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - } - n--; b |= (z.InputBuffer[p++] & 0xff) << k; - k += 8; - } - - dist += (b & InternalInflateConstants.InflateMask[j]); - - b >>= j; - k -= j; - - mode = COPY; - goto case COPY; - - case COPY: // o: copying bytes in window, waiting for space - f = q - dist; - while (f < 0) - { - // modulo window size-"while" instead - f += blocks.end; // of "if" handles invalid distances - } - while (len != 0) - { - if (m == 0) - { - if (q == blocks.end && blocks.readAt != 0) - { - q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; - } - if (m == 0) - { - blocks.writeAt = q; r = blocks.Flush(r); - q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; - - if (q == blocks.end && blocks.readAt != 0) - { - q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; - } - - if (m == 0) - { - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; - z.TotalBytesIn += p - z.NextIn; - z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - } - } - } - - blocks.window[q++] = blocks.window[f++]; m--; - - if (f == blocks.end) - f = 0; - len--; - } - mode = START; - break; - - case LIT: // o: got literal, waiting for output space - if (m == 0) - { - if (q == blocks.end && blocks.readAt != 0) - { - q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; - } - if (m == 0) - { - blocks.writeAt = q; r = blocks.Flush(r); - q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; - - if (q == blocks.end && blocks.readAt != 0) - { - q = 0; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; - } - if (m == 0) - { - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - } - } - } - r = ZlibConstants.Z_OK; - - blocks.window[q++] = (byte)lit; m--; - - mode = START; - break; - - case WASH: // o: got eob, possibly more output - if (k > 7) - { - // return unused byte, if any - k -= 8; - n++; - p--; // can always return one - } - - blocks.writeAt = q; r = blocks.Flush(r); - q = blocks.writeAt; m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; - - if (blocks.readAt != blocks.writeAt) - { - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - } - mode = END; - goto case END; - - case END: - r = ZlibConstants.Z_STREAM_END; - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - - case BADCODE: // x: got error - - r = ZlibConstants.Z_DATA_ERROR; - - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - - default: - r = ZlibConstants.Z_STREAM_ERROR; - - blocks.bitb = b; blocks.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - blocks.writeAt = q; - return blocks.Flush(r); - } - } - } - - - // Called with number of bytes left to write in window at least 258 - // (the maximum string length) and number of input bytes available - // at least ten. The ten bytes are six bytes for the longest length/ - // distance pair plus four bytes for overloading the bit buffer. - - internal int InflateFast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InflateBlocks s, ZlibCodec z) - { - int t; // temporary pointer - int[] tp; // temporary pointer - int tp_index; // temporary pointer - int e; // extra bits or operation - int b; // bit buffer - int k; // bits in bit buffer - int p; // input data pointer - int n; // bytes available there - int q; // output window write pointer - int m; // bytes to end of window or read pointer - int ml; // mask for literal/length tree - int md; // mask for distance tree - int c; // bytes to copy - int d; // distance back to copy from - int r; // copy source pointer - - int tp_index_t_3; // (tp_index+t)*3 - - // load input, output, bit values - p = z.NextIn; n = z.AvailableBytesIn; b = s.bitb; k = s.bitk; - q = s.writeAt; m = q < s.readAt ? s.readAt - q - 1 : s.end - q; - - // initialize masks - ml = InternalInflateConstants.InflateMask[bl]; - md = InternalInflateConstants.InflateMask[bd]; - - // do until not enough input or output space for fast loop - do - { - // assume called with m >= 258 && n >= 10 - // get literal/length code - while (k < (20)) - { - // max bits for literal/length code - n--; - b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; - } - - t = b & ml; - tp = tl; - tp_index = tl_index; - tp_index_t_3 = (tp_index + t) * 3; - if ((e = tp[tp_index_t_3]) == 0) - { - b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); - - s.window[q++] = (byte)tp[tp_index_t_3 + 2]; - m--; - continue; - } - do - { - - b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); - - if ((e & 16) != 0) - { - e &= 15; - c = tp[tp_index_t_3 + 2] + ((int)b & InternalInflateConstants.InflateMask[e]); - - b >>= e; k -= e; - - // decode distance base of block to copy - while (k < 15) - { - // max bits for distance code - n--; - b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; - } - - t = b & md; - tp = td; - tp_index = td_index; - tp_index_t_3 = (tp_index + t) * 3; - e = tp[tp_index_t_3]; - - do - { - - b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); - - if ((e & 16) != 0) - { - // get extra bits to add to distance base - e &= 15; - while (k < e) - { - // get extra bits (up to 13) - n--; - b |= (z.InputBuffer[p++] & 0xff) << k; k += 8; - } - - d = tp[tp_index_t_3 + 2] + (b & InternalInflateConstants.InflateMask[e]); - - b >>= e; k -= e; - - // do the copy - m -= c; - if (q >= d) - { - // offset before dest - // just copy - r = q - d; - if (q - r > 0 && 2 > (q - r)) - { - s.window[q++] = s.window[r++]; // minimum count is three, - s.window[q++] = s.window[r++]; // so unroll loop a little - c -= 2; - } - else - { - Array.Copy(s.window, r, s.window, q, 2); - q += 2; r += 2; c -= 2; - } - } - else - { - // else offset after destination - r = q - d; - do - { - r += s.end; // force pointer in window - } - while (r < 0); // covers invalid distances - e = s.end - r; - if (c > e) - { - // if source crosses, - c -= e; // wrapped copy - if (q - r > 0 && e > (q - r)) - { - do - { - s.window[q++] = s.window[r++]; - } - while (--e != 0); - } - else - { - Array.Copy(s.window, r, s.window, q, e); - q += e; r += e; e = 0; - } - r = 0; // copy rest from start of window - } - } - - // copy all or what's left - if (q - r > 0 && c > (q - r)) - { - do - { - s.window[q++] = s.window[r++]; - } - while (--c != 0); - } - else - { - Array.Copy(s.window, r, s.window, q, c); - q += c; r += c; c = 0; - } - break; - } - else if ((e & 64) == 0) - { - t += tp[tp_index_t_3 + 2]; - t += (b & InternalInflateConstants.InflateMask[e]); - tp_index_t_3 = (tp_index + t) * 3; - e = tp[tp_index_t_3]; - } - else - { - z.Message = "invalid distance code"; - - c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); - - s.bitb = b; s.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - s.writeAt = q; - - return ZlibConstants.Z_DATA_ERROR; - } - } - while (true); - break; - } - - if ((e & 64) == 0) - { - t += tp[tp_index_t_3 + 2]; - t += (b & InternalInflateConstants.InflateMask[e]); - tp_index_t_3 = (tp_index + t) * 3; - if ((e = tp[tp_index_t_3]) == 0) - { - b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]); - s.window[q++] = (byte)tp[tp_index_t_3 + 2]; - m--; - break; - } - } - else if ((e & 32) != 0) - { - c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); - - s.bitb = b; s.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - s.writeAt = q; - - return ZlibConstants.Z_STREAM_END; - } - else - { - z.Message = "invalid literal/length code"; - - c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); - - s.bitb = b; s.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - s.writeAt = q; - - return ZlibConstants.Z_DATA_ERROR; - } - } - while (true); - } - while (m >= 258 && n >= 10); - - // not enough input or output--restore pointers and return - c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3); - - s.bitb = b; s.bitk = k; - z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p; - s.writeAt = q; - - return ZlibConstants.Z_OK; - } - } - - - internal sealed class InflateManager - { - // preset dictionary flag in zlib header - private const int PRESET_DICT = 0x20; - - private const int Z_DEFLATED = 8; - - private enum InflateManagerMode - { - METHOD = 0, // waiting for method byte - FLAG = 1, // waiting for flag byte - DICT4 = 2, // four dictionary check bytes to go - DICT3 = 3, // three dictionary check bytes to go - DICT2 = 4, // two dictionary check bytes to go - DICT1 = 5, // one dictionary check byte to go - DICT0 = 6, // waiting for inflateSetDictionary - BLOCKS = 7, // decompressing blocks - CHECK4 = 8, // four check bytes to go - CHECK3 = 9, // three check bytes to go - CHECK2 = 10, // two check bytes to go - CHECK1 = 11, // one check byte to go - DONE = 12, // finished check, done - BAD = 13, // got an error--stay here - } - - private InflateManagerMode mode; // current inflate mode - internal ZlibCodec _codec; // pointer back to this zlib stream - - // mode dependent information - internal int method; // if FLAGS, method byte - - // if CHECK, check values to compare - internal uint computedCheck; // computed check value - internal uint expectedCheck; // stream check value - - // if BAD, inflateSync's marker bytes count - internal int marker; - - // mode independent information - //internal int nowrap; // flag for no wrapper - private bool _handleRfc1950HeaderBytes = true; - internal bool HandleRfc1950HeaderBytes - { - get { return _handleRfc1950HeaderBytes; } - set { _handleRfc1950HeaderBytes = value; } - } - internal int wbits; // log2(window size) (8..15, defaults to 15) - - internal InflateBlocks blocks; // current inflate_blocks state - - public InflateManager() { } - - public InflateManager(bool expectRfc1950HeaderBytes) - { - _handleRfc1950HeaderBytes = expectRfc1950HeaderBytes; - } - - internal int Reset() - { - _codec.TotalBytesIn = _codec.TotalBytesOut = 0; - _codec.Message = null; - mode = HandleRfc1950HeaderBytes ? InflateManagerMode.METHOD : InflateManagerMode.BLOCKS; - blocks.Reset(); - return ZlibConstants.Z_OK; - } - - internal int End() - { - if (blocks != null) - blocks.Free(); - blocks = null; - return ZlibConstants.Z_OK; - } - - internal int Initialize(ZlibCodec codec, int w) - { - _codec = codec; - _codec.Message = null; - blocks = null; - - // handle undocumented nowrap option (no zlib header or check) - //nowrap = 0; - //if (w < 0) - //{ - // w = - w; - // nowrap = 1; - //} - - // set window size - if (w < 8 || w > 15) - { - End(); - throw new ZlibException("Bad window size."); - - //return ZlibConstants.Z_STREAM_ERROR; - } - wbits = w; - - blocks = new InflateBlocks(codec, - HandleRfc1950HeaderBytes ? this : null, - 1 << w); - - // reset state - Reset(); - return ZlibConstants.Z_OK; - } - - - internal int Inflate(FlushType flush) - { - int b; - - if (_codec.InputBuffer == null) - throw new ZlibException("InputBuffer is null. "); - -// int f = (flush == FlushType.Finish) -// ? ZlibConstants.Z_BUF_ERROR -// : ZlibConstants.Z_OK; - - // workitem 8870 - int f = ZlibConstants.Z_OK; - int r = ZlibConstants.Z_BUF_ERROR; - - while (true) - { - switch (mode) - { - case InflateManagerMode.METHOD: - if (_codec.AvailableBytesIn == 0) return r; - r = f; - _codec.AvailableBytesIn--; - _codec.TotalBytesIn++; - if (((method = _codec.InputBuffer[_codec.NextIn++]) & 0xf) != Z_DEFLATED) - { - mode = InflateManagerMode.BAD; - _codec.Message = String.Format("unknown compression method (0x{0:X2})", method); - marker = 5; // can't try inflateSync - break; - } - if ((method >> 4) + 8 > wbits) - { - mode = InflateManagerMode.BAD; - _codec.Message = String.Format("invalid window size ({0})", (method >> 4) + 8); - marker = 5; // can't try inflateSync - break; - } - mode = InflateManagerMode.FLAG; - break; - - - case InflateManagerMode.FLAG: - if (_codec.AvailableBytesIn == 0) return r; - r = f; - _codec.AvailableBytesIn--; - _codec.TotalBytesIn++; - b = (_codec.InputBuffer[_codec.NextIn++]) & 0xff; - - if ((((method << 8) + b) % 31) != 0) - { - mode = InflateManagerMode.BAD; - _codec.Message = "incorrect header check"; - marker = 5; // can't try inflateSync - break; - } - - mode = ((b & PRESET_DICT) == 0) - ? InflateManagerMode.BLOCKS - : InflateManagerMode.DICT4; - break; - - case InflateManagerMode.DICT4: - if (_codec.AvailableBytesIn == 0) return r; - r = f; - _codec.AvailableBytesIn--; - _codec.TotalBytesIn++; - expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000); - mode = InflateManagerMode.DICT3; - break; - - case InflateManagerMode.DICT3: - if (_codec.AvailableBytesIn == 0) return r; - r = f; - _codec.AvailableBytesIn--; - _codec.TotalBytesIn++; - expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000); - mode = InflateManagerMode.DICT2; - break; - - case InflateManagerMode.DICT2: - - if (_codec.AvailableBytesIn == 0) return r; - r = f; - _codec.AvailableBytesIn--; - _codec.TotalBytesIn++; - expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00); - mode = InflateManagerMode.DICT1; - break; - - - case InflateManagerMode.DICT1: - if (_codec.AvailableBytesIn == 0) return r; - r = f; - _codec.AvailableBytesIn--; _codec.TotalBytesIn++; - expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff); - _codec._Adler32 = expectedCheck; - mode = InflateManagerMode.DICT0; - return ZlibConstants.Z_NEED_DICT; - - - case InflateManagerMode.DICT0: - mode = InflateManagerMode.BAD; - _codec.Message = "need dictionary"; - marker = 0; // can try inflateSync - return ZlibConstants.Z_STREAM_ERROR; - - - case InflateManagerMode.BLOCKS: - r = blocks.Process(r); - if (r == ZlibConstants.Z_DATA_ERROR) - { - mode = InflateManagerMode.BAD; - marker = 0; // can try inflateSync - break; - } - - if (r == ZlibConstants.Z_OK) r = f; - - if (r != ZlibConstants.Z_STREAM_END) - return r; - - r = f; - computedCheck = blocks.Reset(); - if (!HandleRfc1950HeaderBytes) - { - mode = InflateManagerMode.DONE; - return ZlibConstants.Z_STREAM_END; - } - mode = InflateManagerMode.CHECK4; - break; - - case InflateManagerMode.CHECK4: - if (_codec.AvailableBytesIn == 0) return r; - r = f; - _codec.AvailableBytesIn--; - _codec.TotalBytesIn++; - expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000); - mode = InflateManagerMode.CHECK3; - break; - - case InflateManagerMode.CHECK3: - if (_codec.AvailableBytesIn == 0) return r; - r = f; - _codec.AvailableBytesIn--; _codec.TotalBytesIn++; - expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000); - mode = InflateManagerMode.CHECK2; - break; - - case InflateManagerMode.CHECK2: - if (_codec.AvailableBytesIn == 0) return r; - r = f; - _codec.AvailableBytesIn--; - _codec.TotalBytesIn++; - expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00); - mode = InflateManagerMode.CHECK1; - break; - - case InflateManagerMode.CHECK1: - if (_codec.AvailableBytesIn == 0) return r; - r = f; - _codec.AvailableBytesIn--; _codec.TotalBytesIn++; - expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff); - if (computedCheck != expectedCheck) - { - mode = InflateManagerMode.BAD; - _codec.Message = "incorrect data check"; - marker = 5; // can't try inflateSync - break; - } - mode = InflateManagerMode.DONE; - return ZlibConstants.Z_STREAM_END; - - case InflateManagerMode.DONE: - return ZlibConstants.Z_STREAM_END; - - case InflateManagerMode.BAD: - throw new ZlibException(String.Format("Bad state ({0})", _codec.Message)); - - default: - throw new ZlibException("Stream error."); - - } - } - } - - - - internal int SetDictionary(byte[] dictionary) - { - int index = 0; - int length = dictionary.Length; - if (mode != InflateManagerMode.DICT0) - throw new ZlibException("Stream error."); - - if (Adler.Adler32(1, dictionary, 0, dictionary.Length) != _codec._Adler32) - { - return ZlibConstants.Z_DATA_ERROR; - } - - _codec._Adler32 = Adler.Adler32(0, null, 0, 0); - - if (length >= (1 << wbits)) - { - length = (1 << wbits) - 1; - index = dictionary.Length - length; - } - blocks.SetDictionary(dictionary, index, length); - mode = InflateManagerMode.BLOCKS; - return ZlibConstants.Z_OK; - } - - - private static readonly byte[] mark = new byte[] { 0, 0, 0xff, 0xff }; - - internal int Sync() - { - int n; // number of bytes to look at - int p; // pointer to bytes - int m; // number of marker bytes found in a row - long r, w; // temporaries to save total_in and total_out - - // set up - if (mode != InflateManagerMode.BAD) - { - mode = InflateManagerMode.BAD; - marker = 0; - } - if ((n = _codec.AvailableBytesIn) == 0) - return ZlibConstants.Z_BUF_ERROR; - p = _codec.NextIn; - m = marker; - - // search - while (n != 0 && m < 4) - { - if (_codec.InputBuffer[p] == mark[m]) - { - m++; - } - else if (_codec.InputBuffer[p] != 0) - { - m = 0; - } - else - { - m = 4 - m; - } - p++; n--; - } - - // restore - _codec.TotalBytesIn += p - _codec.NextIn; - _codec.NextIn = p; - _codec.AvailableBytesIn = n; - marker = m; - - // return no joy or set up to restart on a new block - if (m != 4) - { - return ZlibConstants.Z_DATA_ERROR; - } - r = _codec.TotalBytesIn; - w = _codec.TotalBytesOut; - Reset(); - _codec.TotalBytesIn = r; - _codec.TotalBytesOut = w; - mode = InflateManagerMode.BLOCKS; - return ZlibConstants.Z_OK; - } - - - // Returns true if inflate is currently at the end of a block generated - // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH - // but removes the length bytes of the resulting empty stored block. When - // decompressing, PPP checks that at the end of input packet, inflate is - // waiting for these length bytes. - internal int SyncPoint(ZlibCodec z) - { - return blocks.SyncPoint(); - } - } -} \ No newline at end of file diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/LICENSE.txt b/SubstrateCS/Vendor/DotNetZip/Zlib/LICENSE.txt deleted file mode 100644 index cdce5007..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/LICENSE.txt +++ /dev/null @@ -1,29 +0,0 @@ -JZlib 0.0.* were released under the GNU LGPL license. Later, we have switched -over to a BSD-style license. - ------------------------------------------------------------------------------- -Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the distribution. - - 3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/ParallelDeflateOutputStream.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/ParallelDeflateOutputStream.cs deleted file mode 100644 index b4695884..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/ParallelDeflateOutputStream.cs +++ /dev/null @@ -1,1158 +0,0 @@ -//#define Trace - -// ParallelDeflateOutputStream.cs -// ------------------------------------------------------------------ -// -// A DeflateStream that does compression only, it uses a -// divide-and-conquer approach with multiple threads to exploit multiple -// CPUs for the DEFLATE computation. -// -// last saved: -// Time-stamp: <2010-January-20 19:24:58> -// ------------------------------------------------------------------ -// -// Copyright (c) 2009-2010 by Dino Chiesa -// All rights reserved! -// -// ------------------------------------------------------------------ - -using System; -using System.Threading; -using Ionic.Zlib; -using System.IO; - - -namespace Ionic.Zlib -{ - internal class WorkItem - { - internal enum Status { None=0, Filling=1, Filled=2, Compressing=3, Compressed=4, Writing=5, Done=6 } - public byte[] buffer; - public byte[] compressed; - public int status; - public int crc; - public int index; - public int inputBytesAvailable; - public int compressedBytesAvailable; - public ZlibCodec compressor; - - public WorkItem(int size, Ionic.Zlib.CompressionLevel compressLevel, CompressionStrategy strategy) - { - buffer= new byte[size]; - // alloc 5 bytes overhead for every block (margin of safety= 2) - int n = size + ((size / 32768)+1) * 5 * 2; - compressed= new byte[n]; - - status = (int)Status.None; - compressor = new ZlibCodec(); - compressor.InitializeDeflate(compressLevel, false); - compressor.OutputBuffer = compressed; - compressor.InputBuffer = buffer; - } - } - - /// - /// A class for compressing and decompressing streams using the - /// Deflate algorithm with multiple threads. - /// - /// - /// - /// - /// This class is for compression only, and that can be only - /// through writing. - /// - /// - /// - /// For more information on the Deflate algorithm, see IETF RFC 1951, "DEFLATE - /// Compressed Data Format Specification version 1.3." - /// - /// - /// - /// This class is similar to , except - /// that this implementation uses an approach that employs multiple worker - /// threads to perform the DEFLATE. On a multi-cpu or multi-core computer, - /// the performance of this class can be significantly higher than the - /// single-threaded DeflateStream, particularly for larger streams. How - /// large? Anything over 10mb is a good candidate for parallel compression. - /// - /// - /// - /// The tradeoff is that this class uses more memory and more CPU than the - /// vanilla DeflateStream, and also is less efficient as a compressor. For - /// large files the size of the compressed data stream can be less than 1% - /// larger than the size of a compressed data stream from the vanialla - /// DeflateStream. For smaller files the difference can be larger. The - /// difference will also be larger if you set the BufferSize to be lower - /// than the default value. Your mileage may vary. Finally, for small - /// files, the ParallelDeflateOutputStream can be much slower than the vanilla - /// DeflateStream, because of the overhead of using the thread pool. - /// - /// - /// - /// - internal class ParallelDeflateOutputStream : System.IO.Stream - { - - private static readonly int IO_BUFFER_SIZE_DEFAULT = 64 * 1024; // 128k - - private System.Collections.Generic.List _pool; - private bool _leaveOpen; - private System.IO.Stream _outStream; - private int _nextToFill, _nextToWrite; - private int _bufferSize = IO_BUFFER_SIZE_DEFAULT; - private ManualResetEvent _writingDone; - private ManualResetEvent _sessionReset; - private bool _noMoreInputForThisSegment; - private object _outputLock = new object(); - private bool _isClosed; - private bool _isDisposed; - private bool _firstWriteDone; - private int _pc; - private int _Crc32; - private Int64 _totalBytesProcessed; - private Ionic.Zlib.CompressionLevel _compressLevel; - private volatile Exception _pendingException; - private object _eLock = new Object(); // protects _pendingException - - // This bitfield is used only when Trace is defined. - //private TraceBits _DesiredTrace = TraceBits.Write | TraceBits.WriteBegin | - //TraceBits.WriteDone | TraceBits.Lifecycle | TraceBits.Fill | TraceBits.Flush | - //TraceBits.Session; - - //private TraceBits _DesiredTrace = TraceBits.WriteBegin | TraceBits.WriteDone | TraceBits.Synch | TraceBits.Lifecycle | TraceBits.Session ; - - private TraceBits _DesiredTrace = TraceBits.WriterThread | TraceBits.Synch | TraceBits.Lifecycle | TraceBits.Session ; - - /// - /// Create a ParallelDeflateOutputStream. - /// - /// - /// - /// - /// This stream compresses data written into it via the DEFLATE - /// algorithm (see RFC 1951), and writes out the compressed byte stream. - /// - /// - /// - /// The instance will use the default compression level, the default - /// buffer sizes and the default number of threads and buffers per - /// thread. - /// - /// - /// - /// This class is similar to , - /// except that this implementation uses an approach that employs - /// multiple worker threads to perform the DEFLATE. On a multi-cpu or - /// multi-core computer, the performance of this class can be - /// significantly higher than the single-threaded DeflateStream, - /// particularly for larger streams. How large? Anything over 10mb is - /// a good candidate for parallel compression. - /// - /// - /// - /// - /// - /// - /// This example shows how to use a ParallelDeflateOutputStream to compress - /// data. It reads a file, compresses it, and writes the compressed data to - /// a second, output file. - /// - /// - /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; - /// int n= -1; - /// String outputFile = fileToCompress + ".compressed"; - /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) - /// { - /// using (var raw = System.IO.File.Create(outputFile)) - /// { - /// using (Stream compressor = new ParallelDeflateOutputStream(raw)) - /// { - /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) - /// { - /// compressor.Write(buffer, 0, n); - /// } - /// } - /// } - /// } - /// - /// - /// Dim buffer As Byte() = New Byte(4096) {} - /// Dim n As Integer = -1 - /// Dim outputFile As String = (fileToCompress & ".compressed") - /// Using input As Stream = File.OpenRead(fileToCompress) - /// Using raw As FileStream = File.Create(outputFile) - /// Using compressor As Stream = New ParallelDeflateOutputStream(raw) - /// Do While (n <> 0) - /// If (n > 0) Then - /// compressor.Write(buffer, 0, n) - /// End If - /// n = input.Read(buffer, 0, buffer.Length) - /// Loop - /// End Using - /// End Using - /// End Using - /// - /// - /// The stream to which compressed data will be written. - public ParallelDeflateOutputStream(System.IO.Stream stream) - : this(stream, CompressionLevel.Default, CompressionStrategy.Default, false) - { - } - - /// - /// Create a ParallelDeflateOutputStream using the specified CompressionLevel. - /// - /// - /// See the - /// constructor for example code. - /// - /// The stream to which compressed data will be written. - /// A tuning knob to trade speed for effectiveness. - public ParallelDeflateOutputStream(System.IO.Stream stream, CompressionLevel level) - : this(stream, level, CompressionStrategy.Default, false) - { - } - - /// - /// Create a ParallelDeflateOutputStream and specify whether to leave the captive stream open - /// when the ParallelDeflateOutputStream is closed. - /// - /// - /// See the - /// constructor for example code. - /// - /// The stream to which compressed data will be written. - /// - /// true if the application would like the stream to remain open after inflation/deflation. - /// - public ParallelDeflateOutputStream(System.IO.Stream stream, bool leaveOpen) - : this(stream, CompressionLevel.Default, CompressionStrategy.Default, leaveOpen) - { - } - - /// - /// Create a ParallelDeflateOutputStream and specify whether to leave the captive stream open - /// when the ParallelDeflateOutputStream is closed. - /// - /// - /// See the - /// constructor for example code. - /// - /// The stream to which compressed data will be written. - /// A tuning knob to trade speed for effectiveness. - /// - /// true if the application would like the stream to remain open after inflation/deflation. - /// - public ParallelDeflateOutputStream(System.IO.Stream stream, CompressionLevel level, bool leaveOpen) - : this(stream, CompressionLevel.Default, CompressionStrategy.Default, leaveOpen) - { - } - - /// - /// Create a ParallelDeflateOutputStream using the specified - /// CompressionLevel and CompressionStrategy, and specifying whether to - /// leave the captive stream open when the ParallelDeflateOutputStream is - /// closed. - /// - /// - /// See the - /// constructor for example code. - /// - /// The stream to which compressed data will be written. - /// A tuning knob to trade speed for effectiveness. - /// - /// By tweaking this parameter, you may be able to optimize the compression for - /// data with particular characteristics. - /// - /// - /// true if the application would like the stream to remain open after inflation/deflation. - /// - public ParallelDeflateOutputStream(System.IO.Stream stream, - CompressionLevel level, - CompressionStrategy strategy, - bool leaveOpen) - { - TraceOutput(TraceBits.Lifecycle | TraceBits.Session, "-------------------------------------------------------"); - TraceOutput(TraceBits.Lifecycle | TraceBits.Session, "Create {0:X8}", this.GetHashCode()); - _compressLevel= level; - _leaveOpen = leaveOpen; - Strategy = strategy; - - BuffersPerCore = 4; // default - - _writingDone = new ManualResetEvent(false); - _sessionReset = new ManualResetEvent(false); - - _outStream = stream; - } - - - /// - /// The ZLIB strategy to be used during compression. - /// - /// - public CompressionStrategy Strategy - { - get; - private set; - } - - /// - /// The number of buffers per CPU or CPU core. - /// - /// - /// - /// - /// This property sets the number of memory buffers to create, for every - /// CPU or CPU core in the machine. The divide-and-conquer approach - /// taken by this class assumes a single thread from the application - /// will call Write(). There will be multiple background threads that - /// then compress (DEFLATE) the data written into the stream, and also a - /// single output thread, also operating in the background, aggregating - /// those results and finally emitting the output. - /// - /// - /// - /// The default value is 4. Different values may deliver better or - /// worse results, depending on the dynamic performance characteristics - /// of your storage and compute resources. - /// - /// - /// - /// The total amount of storage space allocated for buffering will be - /// (n*M*S*2), where n is the number of CPUs, M is the multiple (this - /// property), S is the size of each buffer (), - /// and there are 2 buffers used by the compressor, one for input and - /// one for output. For example, if your machine has 4 cores, and you - /// set BuffersPerCore to 3, and you retain the default buffer size of - /// 128k, then the ParallelDeflateOutputStream will use 3mb of buffer - /// memory in total. - /// - /// - /// - /// The application can set this value at any time, but it is effective - /// only before the first call to Write(), which is when the buffers are - /// allocated. - /// - /// - public int BuffersPerCore - { - get; set; - } - - /// - /// The size of the buffers used by the compressor threads. - /// - /// - /// - /// - /// The default buffer size is 128k. The application can set this value at any - /// time, but it is effective only before the first Write(). - /// - /// - /// - /// Larger buffer sizes implies larger memory consumption but allows - /// more efficient compression. Using smaller buffer sizes consumes less - /// memory but result in less effective compression. For example, using - /// the default buffer size of 128k, the compression delivered is within - /// 1% of the compression delivered by the single-threaded . On the other hand, using a - /// BufferSize of 8k can result in a compressed data stream that is 5% - /// larger than that delivered by the single-threaded - /// DeflateStream. Excessively small buffer sizes can also cause - /// the speed of the ParallelDeflateOutputStream to drop, because of - /// larger thread scheduling overhead dealing with many many small - /// buffers. - /// - /// - /// - /// The total amount of storage space allocated for buffering will be - /// (n*M*S*2), where n is the number of CPUs, M is the multiple (), S is the size of each buffer (this - /// property), and there are 2 buffers used by the compressor, one for - /// input and one for output. For example, if your machine has a total - /// of 4 cores, and if you set to 3, and - /// you keep the default buffer size of 128k, then the - /// ParallelDeflateOutputStream will use 3mb of buffer memory in - /// total. - /// - /// - /// - public int BufferSize - { - get { return _bufferSize;} - set - { - if (value < 1024) - throw new ArgumentException(); - _bufferSize = value; - } - } - - /// - /// The CRC32 for the data that was written out, prior to compression. - /// - /// - /// This value is meaningful only after a call to Close(). - /// - public int Crc32 { get { return _Crc32; } } - - - /// - /// The total number of uncompressed bytes processed by the ParallelDeflateOutputStream. - /// - /// - /// This value is meaningful only after a call to Close(). - /// - public Int64 BytesProcessed { get { return _totalBytesProcessed; } } - - - private void _InitializePoolOfWorkItems() - { - _pool = new System.Collections.Generic.List(); - for(int i=0; i < BuffersPerCore * Environment.ProcessorCount; i++) - _pool.Add(new WorkItem(_bufferSize, _compressLevel, Strategy)); - _pc = _pool.Count; - - for(int i=0; i < _pc; i++) - _pool[i].index= i; - - // set the pointers - _nextToFill= _nextToWrite= 0; - } - - - private void _KickoffWriter() - { - if (!ThreadPool.QueueUserWorkItem(new WaitCallback(this._PerpetualWriterMethod))) - throw new Exception("Cannot enqueue writer thread."); - } - - - /// - /// Write data to the stream. - /// - /// - /// - /// - /// - /// To use the ParallelDeflateOutputStream to compress data, create a - /// ParallelDeflateOutputStream with CompressionMode.Compress, passing a - /// writable output stream. Then call Write() on that - /// ParallelDeflateOutputStream, providing uncompressed data as input. The - /// data sent to the output stream will be the compressed form of the data - /// written. - /// - /// - /// - /// To decompress data, use the class. - /// - /// - /// - /// The buffer holding data to write to the stream. - /// the offset within that data array to find the first byte to write. - /// the number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - // Fill a work buffer; when full, flip state to 'Filled' - - if (_isClosed) - throw new NotSupportedException(); - - // dispense any exceptions that occurred on the BG threads - if (_pendingException != null) - throw _pendingException; - - if (count == 0) return; - - if (!_firstWriteDone) - { - // Want to do this on first Write, first session, and not in the - // constructor. We want to allow the BufferSize and BuffersPerCore to - // change after construction, but before first Write. - _InitializePoolOfWorkItems(); - - // Only do this once (ever), the first time Write() is called: - _KickoffWriter(); - - // Release the writer thread. - TraceOutput(TraceBits.Synch, "Synch _sessionReset.Set() Write (first)"); - _sessionReset.Set(); - - _firstWriteDone = true; - } - - - do - { - int ix = _nextToFill % _pc; - WorkItem workitem = _pool[ix]; - lock(workitem) - { - TraceOutput(TraceBits.Fill, - "Fill lock wi({0}) stat({1}) iba({2}) nf({3})", - workitem.index, - workitem.status, - workitem.inputBytesAvailable, - _nextToFill - ); - - // If the status is what we want, then use the workitem. - if (workitem.status == (int)WorkItem.Status.None || - workitem.status == (int)WorkItem.Status.Done || - workitem.status == (int)WorkItem.Status.Filling) - { - workitem.status = (int)WorkItem.Status.Filling; - int limit = ((workitem.buffer.Length - workitem.inputBytesAvailable) > count) - ? count - : (workitem.buffer.Length - workitem.inputBytesAvailable); - - // copy from the provided buffer to our workitem, starting at - // the tail end of whatever data we might have in there currently. - Array.Copy(buffer, offset, workitem.buffer, workitem.inputBytesAvailable, limit); - - count -= limit; - offset += limit; - workitem.inputBytesAvailable += limit; - if (workitem.inputBytesAvailable==workitem.buffer.Length) - { - workitem.status = (int)WorkItem.Status.Filled; - // No need for interlocked.increment: the Write() method - // is documented as not multi-thread safe, so we can assume Write() - // calls come in from only one thread. - _nextToFill++; - - TraceOutput(TraceBits.Fill, - "Fill QUWI wi({0}) stat({1}) iba({2}) nf({3})", - workitem.index, - workitem.status, - workitem.inputBytesAvailable, - _nextToFill - ); - - if (!ThreadPool.QueueUserWorkItem( _DeflateOne, workitem )) - throw new Exception("Cannot enqueue workitem"); - } - - } - else - { - int wcycles= 0; - - while (workitem.status != (int)WorkItem.Status.None && - workitem.status != (int)WorkItem.Status.Done && - workitem.status != (int)WorkItem.Status.Filling) - { - TraceOutput(TraceBits.Fill, - "Fill waiting wi({0}) stat({1}) nf({2})", - workitem.index, - workitem.status, - _nextToFill); - - wcycles++; - - Monitor.Pulse(workitem); - Monitor.Wait(workitem); - - if (workitem.status == (int)WorkItem.Status.None || - workitem.status == (int)WorkItem.Status.Done || - workitem.status == (int)WorkItem.Status.Filling) - TraceOutput(TraceBits.Fill, - "Fill A-OK wi({0}) stat({1}) iba({2}) cyc({3})", - workitem.index, - workitem.status, - workitem.inputBytesAvailable, - wcycles); - } - } - } - } - while (count > 0); // until no more to write - - return; - } - - - - /// - /// Flush the stream. - /// - public override void Flush() - { - _Flush(false); - } - - - private void _Flush(bool lastInput) - { - if (_isClosed) - throw new NotSupportedException(); - - // pass any partial buffer out to the compressor workers: - WorkItem workitem = _pool[_nextToFill % _pc]; - lock(workitem) - { - if ( workitem.status == (int)WorkItem.Status.Filling) - { - workitem.status = (int)WorkItem.Status.Filled; - _nextToFill++; - - // When flush is called from Close(), we set _noMore. - // can't do it before updating nextToFill, though. - if (lastInput) - _noMoreInputForThisSegment= true; - - TraceOutput(TraceBits.Flush, - "Flush filled wi({0}) iba({1}) nf({2}) nomore({3})", - workitem.index, workitem.inputBytesAvailable, _nextToFill, _noMoreInputForThisSegment); - - if (!ThreadPool.QueueUserWorkItem( _DeflateOne, workitem )) - throw new Exception("Cannot enqueue workitem"); - - //Monitor.Pulse(workitem); - } - else - { - // When flush is called from Close(), we set _noMore. - // Gotta do this whether or not there is another packet to send along. - if (lastInput) - _noMoreInputForThisSegment= true; - - TraceOutput(TraceBits.Flush, - "Flush noaction wi({0}) stat({1}) nf({2}) nomore({3})", - workitem.index, workitem.status, _nextToFill, _noMoreInputForThisSegment); - } - } - } - - - /// - /// Close the stream. - /// - /// - /// You must call Close on the stream to guarantee that all of the data written in has - /// been compressed, and the compressed data has been written out. - /// - public override void Close() - { - TraceOutput(TraceBits.Session, "Close {0:X8}", this.GetHashCode()); - - if (_isClosed) return; - - _Flush(true); - - //System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(1); - //System.Console.WriteLine(st.ToString()); - - // need to get Writer off the workitem, in case he's waiting forever - WorkItem workitem = _pool[_nextToFill % _pc]; - lock(workitem) - { - Monitor.PulseAll(workitem); - } - - // wait for the writer to complete his work - TraceOutput(TraceBits.Synch, "Synch _writingDone.WaitOne(begin) Close"); - _writingDone.WaitOne(); - TraceOutput(TraceBits.Synch, "Synch _writingDone.WaitOne(done) Close"); - - TraceOutput(TraceBits.Session, "-------------------------------------------------------"); - if (!_leaveOpen) - _outStream.Close(); - - _isClosed= true; - } - - - -// /// The destructor -// ~ParallelDeflateOutputStream() -// { -// TraceOutput(TraceBits.Lifecycle, "Destructor {0:X8}", this.GetHashCode()); -// // call Dispose with false. Since we're in the -// // destructor call, the managed resources will be -// // disposed of anyways. -// Dispose(false); -// } - - - - // workitem 10030 - implement a new Dispose method - - /// Dispose the object - /// - /// - /// Because ParallelDeflateOutputStream is IDisposable, the - /// application must call this method when finished using the instance. - /// - /// - /// This method is generally called implicitly upon exit from - /// a using scope in C# (Using in VB). - /// - /// - new public void Dispose() - { - TraceOutput(TraceBits.Lifecycle, "Dispose {0:X8}", this.GetHashCode()); - _isDisposed= true; - _pool = null; - TraceOutput(TraceBits.Synch, "Synch _sessionReset.Set() Dispose"); - _sessionReset.Set(); // tell writer to die - Dispose(true); - } - - - - /// The Dispose method - protected override void Dispose(bool disposeManagedResources) - { - if (disposeManagedResources) - { - // dispose managed resources - _writingDone.Close(); - _sessionReset.Close(); - } - } - - - /// - /// Resets the stream for use with another stream. - /// - /// - /// Because the ParallelDeflateOutputStream is expensive to create, it - /// has been designed so that it can be recycled and re-used. You have - /// to call Close() on the stream first, then you can call Reset() on - /// it, to use it again on another stream. - /// - /// - /// - /// - /// ParallelDeflateOutputStream deflater = null; - /// foreach (var inputFile in listOfFiles) - /// { - /// string outputFile = inputFile + ".compressed"; - /// using (System.IO.Stream input = System.IO.File.OpenRead(inputFile)) - /// { - /// using (var outStream = System.IO.File.Create(outputFile)) - /// { - /// if (deflater == null) - /// deflater = new ParallelDeflateOutputStream(outStream, - /// CompressionLevel.Best, - /// CompressionStrategy.Default, - /// true); - /// deflater.Reset(outStream); - /// - /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) - /// { - /// deflater.Write(buffer, 0, n); - /// } - /// } - /// } - /// } - /// - /// - public void Reset(Stream stream) - { - TraceOutput(TraceBits.Session, "-------------------------------------------------------"); - TraceOutput(TraceBits.Session, "Reset {0:X8} firstDone({1})", this.GetHashCode(), _firstWriteDone); - - if (!_firstWriteDone) return; - - if (_noMoreInputForThisSegment) - { - // wait til done writing: - TraceOutput(TraceBits.Synch, "Synch _writingDone.WaitOne(begin) Reset"); - _writingDone.WaitOne(); - TraceOutput(TraceBits.Synch, "Synch _writingDone.WaitOne(done) Reset"); - - // reset all status - foreach (var workitem in _pool) - workitem.status = (int) WorkItem.Status.None; - - _noMoreInputForThisSegment= false; - _nextToFill= _nextToWrite= 0; - _totalBytesProcessed = 0L; - _Crc32= 0; - _isClosed= false; - - TraceOutput(TraceBits.Synch, "Synch _writingDone.Reset() Reset"); - _writingDone.Reset(); - } - else - { - TraceOutput(TraceBits.Synch, "Synch Reset noMore=false"); - } - - _outStream = stream; - - // release the writer thread for the next "session" - TraceOutput(TraceBits.Synch, "Synch _sessionReset.Set() Reset"); - _sessionReset.Set(); - } - - - - private void _PerpetualWriterMethod(object state) - { - TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod START"); - - try - { - do - { - // wait for the next session - TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch _sessionReset.WaitOne(begin) PWM"); - _sessionReset.WaitOne(); - TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch _sessionReset.WaitOne(done) PWM"); - - if (_isDisposed) break; - - TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch _sessionReset.Reset() PWM"); - _sessionReset.Reset(); - - // repeatedly write buffers as they become ready - WorkItem workitem = null; - Ionic.Zlib.CRC32 c= new Ionic.Zlib.CRC32(); - do - { - workitem = _pool[_nextToWrite % _pc]; - lock(workitem) - { - if (_noMoreInputForThisSegment) - TraceOutput(TraceBits.Write, - "Write drain wi({0}) stat({1}) canuse({2}) cba({3})", - workitem.index, - workitem.status, - (workitem.status == (int)WorkItem.Status.Compressed), - workitem.compressedBytesAvailable); - - do - { - if (workitem.status == (int)WorkItem.Status.Compressed) - { - TraceOutput(TraceBits.WriteBegin, - "Write begin wi({0}) stat({1}) cba({2})", - workitem.index, - workitem.status, - workitem.compressedBytesAvailable); - - workitem.status = (int)WorkItem.Status.Writing; - _outStream.Write(workitem.compressed, 0, workitem.compressedBytesAvailable); - c.Combine(workitem.crc, workitem.inputBytesAvailable); - _totalBytesProcessed += workitem.inputBytesAvailable; - _nextToWrite++; - workitem.inputBytesAvailable= 0; - workitem.status = (int)WorkItem.Status.Done; - - TraceOutput(TraceBits.WriteDone, - "Write done wi({0}) stat({1}) cba({2})", - workitem.index, - workitem.status, - workitem.compressedBytesAvailable); - - - Monitor.Pulse(workitem); - break; - } - else - { - int wcycles = 0; - // I've locked a workitem I cannot use. - // Therefore, wake someone else up, and then release the lock. - while (workitem.status != (int)WorkItem.Status.Compressed) - { - TraceOutput(TraceBits.WriteWait, - "Write waiting wi({0}) stat({1}) nw({2}) nf({3}) nomore({4})", - workitem.index, - workitem.status, - _nextToWrite, _nextToFill, - _noMoreInputForThisSegment ); - - if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill) - break; - - wcycles++; - - // wake up someone else - Monitor.Pulse(workitem); - // release and wait - Monitor.Wait(workitem); - - if (workitem.status == (int)WorkItem.Status.Compressed) - TraceOutput(TraceBits.WriteWait, - "Write A-OK wi({0}) stat({1}) iba({2}) cba({3}) cyc({4})", - workitem.index, - workitem.status, - workitem.inputBytesAvailable, - workitem.compressedBytesAvailable, - wcycles); - } - - if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill) - break; - - } - } - while (true); - } - - if (_noMoreInputForThisSegment) - TraceOutput(TraceBits.Write, - "Write nomore nw({0}) nf({1}) break({2})", - _nextToWrite, _nextToFill, (_nextToWrite == _nextToFill)); - - if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill) - break; - - } while (true); - - - // Finish: - // After writing a series of buffers, closing each one with - // Flush.Sync, we now write the final one as Flush.Finish, and - // then stop. - byte[] buffer = new byte[128]; - ZlibCodec compressor = new ZlibCodec(); - int rc = compressor.InitializeDeflate(_compressLevel, false); - compressor.InputBuffer = null; - compressor.NextIn = 0; - compressor.AvailableBytesIn = 0; - compressor.OutputBuffer = buffer; - compressor.NextOut = 0; - compressor.AvailableBytesOut = buffer.Length; - rc = compressor.Deflate(FlushType.Finish); - - if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) - throw new Exception("deflating: " + compressor.Message); - - if (buffer.Length - compressor.AvailableBytesOut > 0) - { - TraceOutput(TraceBits.WriteBegin, - "Write begin flush bytes({0})", - buffer.Length - compressor.AvailableBytesOut); - - _outStream.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut); - - TraceOutput(TraceBits.WriteBegin, - "Write done flush"); - } - - compressor.EndDeflate(); - - _Crc32 = c.Crc32Result; - - // signal that writing is complete: - TraceOutput(TraceBits.Synch, "Synch _writingDone.Set() PWM"); - _writingDone.Set(); - } - while (true); - } - catch (System.Exception exc1) - { - lock(_eLock) - { - // expose the exception to the main thread - if (_pendingException!=null) - _pendingException = exc1; - } - } - - TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod FINIS"); - } - - - - - private void _DeflateOne(Object wi) - { - WorkItem workitem = (WorkItem) wi; - try - { - // compress one buffer - int myItem = workitem.index; - - lock(workitem) - { - if (workitem.status != (int)WorkItem.Status.Filled) - throw new InvalidOperationException(); - - Ionic.Zlib.CRC32 crc = new CRC32(); - - // use the workitem: - // calc CRC on the buffer - crc.SlurpBlock(workitem.buffer, 0, workitem.inputBytesAvailable); - - // deflate it - DeflateOneSegment(workitem); - - // update status - workitem.status = (int)WorkItem.Status.Compressed; - workitem.crc = crc.Crc32Result; - - TraceOutput(TraceBits.Compress, - "Compress wi({0}) stat({1}) len({2})", - workitem.index, - workitem.status, - workitem.compressedBytesAvailable - ); - - // release the item - Monitor.Pulse(workitem); - } - } - catch (System.Exception exc1) - { - lock(_eLock) - { - // expose the exception to the main thread - if (_pendingException!=null) - _pendingException = exc1; - } - } - } - - - - - private bool DeflateOneSegment(WorkItem workitem) - { - ZlibCodec compressor = workitem.compressor; - int rc= 0; - compressor.ResetDeflate(); - compressor.NextIn = 0; - - compressor.AvailableBytesIn = workitem.inputBytesAvailable; - - // step 1: deflate the buffer - compressor.NextOut = 0; - compressor.AvailableBytesOut = workitem.compressed.Length; - do - { - compressor.Deflate(FlushType.None); - } - while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0); - - // step 2: flush (sync) - rc = compressor.Deflate(FlushType.Sync); - - workitem.compressedBytesAvailable= (int) compressor.TotalBytesOut; - return true; - } - - - [System.Diagnostics.ConditionalAttribute("Trace")] - private void TraceOutput(TraceBits bits, string format, params object[] varParams) - { - if ((bits & _DesiredTrace) != 0) - { - lock(_outputLock) - { - int tid = Thread.CurrentThread.GetHashCode(); - Console.ForegroundColor = (ConsoleColor) (tid % 8 + 8); - Console.Write("{0:000} PDOS ", tid); - Console.WriteLine(format, varParams); - Console.ResetColor(); - } - } - } - - - // used only when Trace is defined - [Flags] - enum TraceBits - { - None = 0, - Write = 1, // write out - WriteBegin = 2, // begin to write out - WriteDone = 4, // done writing out - WriteWait = 8, // write thread waiting for buffer - Flush = 16, - Compress = 32, // async compress - Fill = 64, // filling buffers, when caller invokes Write() - Lifecycle = 128, // constructor/disposer - Session = 256, // Close/Reset - Synch = 512, // thread synchronization - WriterThread = 1024, // writer thread - } - - - - /// - /// Indicates whether the stream supports Seek operations. - /// - /// - /// Always returns false. - /// - public override bool CanSeek - { - get { return false; } - } - - - /// - /// Indicates whether the stream supports Read operations. - /// - /// - /// Always returns false. - /// - public override bool CanRead - { - get {return false;} - } - - /// - /// Indicates whether the stream supports Write operations. - /// - /// - /// Returns true if the provided stream is writable. - /// - public override bool CanWrite - { - get { return _outStream.CanWrite; } - } - - /// - /// Reading this property always throws a NotImplementedException. - /// - public override long Length - { - get { throw new NotImplementedException(); } - } - - /// - /// Reading or Writing this property always throws a NotImplementedException. - /// - public override long Position - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - /// - /// This method always throws a NotImplementedException. - /// - public override int Read(byte[] buffer, int offset, int count) - { - throw new NotImplementedException(); - } - - /// - /// This method always throws a NotImplementedException. - /// - public override long Seek(long offset, System.IO.SeekOrigin origin) - { - throw new NotImplementedException(); - } - - /// - /// This method always throws a NotImplementedException. - /// - public override void SetLength(long value) - { - throw new NotImplementedException(); - } - - } - -} - - diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/Tree.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/Tree.cs deleted file mode 100644 index 1db8c4f4..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/Tree.cs +++ /dev/null @@ -1,423 +0,0 @@ -// Tree.cs -// ------------------------------------------------------------------ -// -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. -// All rights reserved. -// -// This code module is part of DotNetZip, a zipfile class library. -// -// ------------------------------------------------------------------ -// -// This code is licensed under the Microsoft Public License. -// See the file License.txt for the license details. -// More info on: http://dotnetzip.codeplex.com -// -// ------------------------------------------------------------------ -// -// last saved (in emacs): -// Time-stamp: <2009-October-28 13:29:50> -// -// ------------------------------------------------------------------ -// -// This module defines classes for zlib compression and -// decompression. This code is derived from the jzlib implementation of -// zlib. In keeping with the license for jzlib, the copyright to that -// code is below. -// -// ------------------------------------------------------------------ -// -// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in -// the documentation and/or other materials provided with the distribution. -// -// 3. The names of the authors may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// ----------------------------------------------------------------------- -// -// This program is based on zlib-1.1.3; credit to authors -// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) -// and contributors of zlib. -// -// ----------------------------------------------------------------------- - - -using System; - -namespace Ionic.Zlib -{ - sealed class Tree - { - private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1); - - // extra bits for each length code - internal static readonly int[] ExtraLengthBits = new int[] - { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 - }; - - // extra bits for each distance code - internal static readonly int[] ExtraDistanceBits = new int[] - { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 - }; - - // extra bits for each bit length code - internal static readonly int[] extra_blbits = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; - - internal static readonly sbyte[] bl_order = new sbyte[]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - - // The lengths of the bit length codes are sent in order of decreasing - // probability, to avoid transmitting the lengths for unused bit - // length codes. - - internal const int Buf_size = 8 * 2; - - // see definition of array dist_code below - //internal const int DIST_CODE_LEN = 512; - - private static readonly sbyte[] _dist_code = new sbyte[] - { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, - 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 - }; - - internal static readonly sbyte[] LengthCode = new sbyte[] - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, - 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 - }; - - - internal static readonly int[] LengthBase = new int[] - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, - 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 - }; - - - internal static readonly int[] DistanceBase = new int[] - { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, - 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 - }; - - - /// - /// Map from a distance to a distance code. - /// - /// - /// No side effects. _dist_code[256] and _dist_code[257] are never used. - /// - internal static int DistanceCode(int dist) - { - return (dist < 256) - ? _dist_code[dist] - : _dist_code[256 + SharedUtils.URShift(dist, 7)]; - } - - internal short[] dyn_tree; // the dynamic tree - internal int max_code; // largest code with non zero frequency - internal StaticTree staticTree; // the corresponding static tree - - // Compute the optimal bit lengths for a tree and update the total bit length - // for the current block. - // IN assertion: the fields freq and dad are set, heap[heap_max] and - // above are the tree nodes sorted by increasing frequency. - // OUT assertions: the field len is set to the optimal bit length, the - // array bl_count contains the frequencies for each bit length. - // The length opt_len is updated; static_len is also updated if stree is - // not null. - internal void gen_bitlen(DeflateManager s) - { - short[] tree = dyn_tree; - short[] stree = staticTree.treeCodes; - int[] extra = staticTree.extraBits; - int base_Renamed = staticTree.extraBase; - int max_length = staticTree.maxLength; - int h; // heap index - int n, m; // iterate over the tree elements - int bits; // bit length - int xbits; // extra bits - short f; // frequency - int overflow = 0; // number of elements with bit length too large - - for (bits = 0; bits <= InternalConstants.MAX_BITS; bits++) - s.bl_count[bits] = 0; - - // In a first pass, compute the optimal bit lengths (which may - // overflow in the case of the bit length tree). - tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap - - for (h = s.heap_max + 1; h < HEAP_SIZE; h++) - { - n = s.heap[h]; - bits = tree[tree[n * 2 + 1] * 2 + 1] + 1; - if (bits > max_length) - { - bits = max_length; overflow++; - } - tree[n * 2 + 1] = (short) bits; - // We overwrite tree[n*2+1] which is no longer needed - - if (n > max_code) - continue; // not a leaf node - - s.bl_count[bits]++; - xbits = 0; - if (n >= base_Renamed) - xbits = extra[n - base_Renamed]; - f = tree[n * 2]; - s.opt_len += f * (bits + xbits); - if (stree != null) - s.static_len += f * (stree[n * 2 + 1] + xbits); - } - if (overflow == 0) - return ; - - // This happens for example on obj2 and pic of the Calgary corpus - // Find the first bit length which could increase: - do - { - bits = max_length - 1; - while (s.bl_count[bits] == 0) - bits--; - s.bl_count[bits]--; // move one leaf down the tree - s.bl_count[bits + 1] = (short) (s.bl_count[bits + 1] + 2); // move one overflow item as its brother - s.bl_count[max_length]--; - // The brother of the overflow item also moves one step up, - // but this does not affect bl_count[max_length] - overflow -= 2; - } - while (overflow > 0); - - for (bits = max_length; bits != 0; bits--) - { - n = s.bl_count[bits]; - while (n != 0) - { - m = s.heap[--h]; - if (m > max_code) - continue; - if (tree[m * 2 + 1] != bits) - { - s.opt_len = (int) (s.opt_len + ((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]); - tree[m * 2 + 1] = (short) bits; - } - n--; - } - } - } - - // Construct one Huffman tree and assigns the code bit strings and lengths. - // Update the total bit length for the current block. - // IN assertion: the field freq is set for all tree elements. - // OUT assertions: the fields len and code are set to the optimal bit length - // and corresponding code. The length opt_len is updated; static_len is - // also updated if stree is not null. The field max_code is set. - internal void build_tree(DeflateManager s) - { - short[] tree = dyn_tree; - short[] stree = staticTree.treeCodes; - int elems = staticTree.elems; - int n, m; // iterate over heap elements - int max_code = -1; // largest code with non zero frequency - int node; // new node being created - - // Construct the initial heap, with least frequent element in - // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - // heap[0] is not used. - s.heap_len = 0; - s.heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) - { - if (tree[n * 2] != 0) - { - s.heap[++s.heap_len] = max_code = n; - s.depth[n] = 0; - } - else - { - tree[n * 2 + 1] = 0; - } - } - - // The pkzip format requires that at least one distance code exists, - // and that at least one bit should be sent even if there is only one - // possible code. So to avoid special checks later on we force at least - // two codes of non zero frequency. - while (s.heap_len < 2) - { - node = s.heap[++s.heap_len] = (max_code < 2?++max_code:0); - tree[node * 2] = 1; - s.depth[node] = 0; - s.opt_len--; - if (stree != null) - s.static_len -= stree[node * 2 + 1]; - // node is 0 or 1 so it does not have extra bits - } - this.max_code = max_code; - - // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - // establish sub-heaps of increasing lengths: - - for (n = s.heap_len / 2; n >= 1; n--) - s.pqdownheap(tree, n); - - // Construct the Huffman tree by repeatedly combining the least two - // frequent nodes. - - node = elems; // next internal node of the tree - do - { - // n = node of least frequency - n = s.heap[1]; - s.heap[1] = s.heap[s.heap_len--]; - s.pqdownheap(tree, 1); - m = s.heap[1]; // m = node of next least frequency - - s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency - s.heap[--s.heap_max] = m; - - // Create a new node father of n and m - tree[node * 2] = unchecked((short) (tree[n * 2] + tree[m * 2])); - s.depth[node] = (sbyte) (System.Math.Max((byte) s.depth[n], (byte) s.depth[m]) + 1); - tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node; - - // and insert the new node in the heap - s.heap[1] = node++; - s.pqdownheap(tree, 1); - } - while (s.heap_len >= 2); - - s.heap[--s.heap_max] = s.heap[1]; - - // At this point, the fields freq and dad are set. We can now - // generate the bit lengths. - - gen_bitlen(s); - - // The field len is now set, we can generate the bit codes - gen_codes(tree, max_code, s.bl_count); - } - - // Generate the codes for a given tree and bit counts (which need not be - // optimal). - // IN assertion: the array bl_count contains the bit length statistics for - // the given tree and the field len is set for all tree elements. - // OUT assertion: the field code is set for all tree elements of non - // zero code length. - internal static void gen_codes(short[] tree, int max_code, short[] bl_count) - { - short[] next_code = new short[InternalConstants.MAX_BITS + 1]; // next code value for each bit length - short code = 0; // running code value - int bits; // bit index - int n; // code index - - // The distribution counts are first used to generate the code values - // without bit reversal. - for (bits = 1; bits <= InternalConstants.MAX_BITS; bits++) - unchecked { - next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1); - } - - // Check that the bit counts in bl_count are consistent. The last code - // must be all ones. - //Assert (code + bl_count[MAX_BITS]-1 == (1<>= 1; //SharedUtils.URShift(code, 1); - res <<= 1; - } - while (--len > 0); - return res >> 1; - } - } -} \ No newline at end of file diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/Zlib.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/Zlib.cs deleted file mode 100644 index 2692015a..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/Zlib.cs +++ /dev/null @@ -1,456 +0,0 @@ -// Zlib.cs -// ------------------------------------------------------------------ -// -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. -// All rights reserved. -// -// This code module is part of DotNetZip, a zipfile class library. -// -// ------------------------------------------------------------------ -// -// This code is licensed under the Microsoft Public License. -// See the file License.txt for the license details. -// More info on: http://dotnetzip.codeplex.com -// -// ------------------------------------------------------------------ -// -// last saved (in emacs): -// Time-stamp: <2009-November-07 05:26:55> -// -// ------------------------------------------------------------------ -// -// This module defines classes for ZLIB compression and -// decompression. This code is derived from the jzlib implementation of -// zlib, but significantly modified. The object model is not the same, -// and many of the behaviors are new or different. Nonetheless, in -// keeping with the license for jzlib, the copyright to that code is -// included below. -// -// ------------------------------------------------------------------ -// -// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in -// the documentation and/or other materials provided with the distribution. -// -// 3. The names of the authors may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// ----------------------------------------------------------------------- -// -// This program is based on zlib-1.1.3; credit to authors -// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) -// and contributors of zlib. -// -// ----------------------------------------------------------------------- - - - -using System; -using Interop=System.Runtime.InteropServices; - -namespace Ionic.Zlib -{ - - /// - /// The compression level to be used when using a DeflateStream or ZlibStream with CompressionMode.Compress. - /// - internal enum CompressionLevel - { - /// - /// None means that the data will be simply stored, with no change at all. - /// If you are producing ZIPs for use on Mac OSX, be aware that archives produced with CompressionLevel.None - /// cannot be opened with the default zip reader. Use a different CompressionLevel. - /// - None= 0, - /// - /// Same as None. - /// - Level0 = 0, - - /// - /// The fastest but least effective compression. - /// - BestSpeed = 1, - - /// - /// A synonym for BestSpeed. - /// - Level1 = 1, - - /// - /// A little slower, but better, than level 1. - /// - Level2 = 2, - - /// - /// A little slower, but better, than level 2. - /// - Level3 = 3, - - /// - /// A little slower, but better, than level 3. - /// - Level4 = 4, - - /// - /// A little slower than level 4, but with better compression. - /// - Level5 = 5, - - /// - /// The default compression level, with a good balance of speed and compression efficiency. - /// - Default = 6, - /// - /// A synonym for Default. - /// - Level6 = 6, - - /// - /// Pretty good compression! - /// - Level7 = 7, - - /// - /// Better compression than Level7! - /// - Level8 = 8, - - /// - /// The "best" compression, where best means greatest reduction in size of the input data stream. - /// This is also the slowest compression. - /// - BestCompression = 9, - - /// - /// A synonym for BestCompression. - /// - Level9 = 9, - } - - /// - /// Describes options for how the compression algorithm is executed. Different strategies - /// work better on different sorts of data. The strategy parameter can affect the compression - /// ratio and the speed of compression but not the correctness of the compresssion. - /// - internal enum CompressionStrategy - { - /// - /// The default strategy is probably the best for normal data. - /// - Default = 0, - - /// - /// The Filtered strategy is intended to be used most effectively with data produced by a - /// filter or predictor. By this definition, filtered data consists mostly of small - /// values with a somewhat random distribution. In this case, the compression algorithm - /// is tuned to compress them better. The effect of Filtered is to force more Huffman - /// coding and less string matching; it is a half-step between Default and HuffmanOnly. - /// - Filtered = 1, - - /// - /// Using HuffmanOnly will force the compressor to do Huffman encoding only, with no - /// string matching. - /// - HuffmanOnly = 2, - } - - - /// - /// An enum to specify the direction of transcoding - whether to compress or decompress. - /// - internal enum CompressionMode - { - /// - /// Used to specify that the stream should compress the data. - /// - Compress= 0, - /// - /// Used to specify that the stream should decompress the data. - /// - Decompress = 1, - } - - - /// - /// A general purpose exception class for exceptions in the Zlib library. - /// - [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000E")] - internal class ZlibException : System.Exception - { - /// - /// The ZlibException class captures exception information generated - /// by the Zlib library. - /// - public ZlibException() - : base() - { - } - - /// - /// This ctor collects a message attached to the exception. - /// - /// - public ZlibException(System.String s) - : base(s) - { - } - } - - - internal class SharedUtils - { - /// - /// Performs an unsigned bitwise right shift with the specified number - /// - /// Number to operate on - /// Ammount of bits to shift - /// The resulting number from the shift operation - public static int URShift(int number, int bits) - { - return (int)((uint)number >> bits); - } - -#if NOT - /// - /// Performs an unsigned bitwise right shift with the specified number - /// - /// Number to operate on - /// Ammount of bits to shift - /// The resulting number from the shift operation - public static long URShift(long number, int bits) - { - return (long) ((UInt64)number >> bits); - } -#endif - - /// - /// Reads a number of characters from the current source TextReader and writes - /// the data to the target array at the specified index. - /// - /// - /// The source TextReader to read from - /// Contains the array of characteres read from the source TextReader. - /// The starting index of the target array. - /// The maximum number of characters to read from the source TextReader. - /// - /// - /// The number of characters read. The number will be less than or equal to - /// count depending on the data available in the source TextReader. Returns -1 - /// if the end of the stream is reached. - /// - public static System.Int32 ReadInput(System.IO.TextReader sourceTextReader, byte[] target, int start, int count) - { - // Returns 0 bytes if not enough space in target - if (target.Length == 0) return 0; - - char[] charArray = new char[target.Length]; - int bytesRead = sourceTextReader.Read(charArray, start, count); - - // Returns -1 if EOF - if (bytesRead == 0) return -1; - - for (int index = start; index < start + bytesRead; index++) - target[index] = (byte)charArray[index]; - - return bytesRead; - } - - - internal static byte[] ToByteArray(System.String sourceString) - { - return System.Text.UTF8Encoding.UTF8.GetBytes(sourceString); - } - - - internal static char[] ToCharArray(byte[] byteArray) - { - return System.Text.UTF8Encoding.UTF8.GetChars(byteArray); - } - } - - internal static class InternalConstants - { - internal static readonly int MAX_BITS = 15; - internal static readonly int BL_CODES = 19; - internal static readonly int D_CODES = 30; - internal static readonly int LITERALS = 256; - internal static readonly int LENGTH_CODES = 29; - internal static readonly int L_CODES = (LITERALS + 1 + LENGTH_CODES); - - // Bit length codes must not exceed MAX_BL_BITS bits - internal static readonly int MAX_BL_BITS = 7; - - // repeat previous bit length 3-6 times (2 bits of repeat count) - internal static readonly int REP_3_6 = 16; - - // repeat a zero length 3-10 times (3 bits of repeat count) - internal static readonly int REPZ_3_10 = 17; - - // repeat a zero length 11-138 times (7 bits of repeat count) - internal static readonly int REPZ_11_138 = 18; - - } - - internal sealed class StaticTree - { - internal static readonly short[] lengthAndLiteralsTreeCodes = new short[] { - 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, - 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, - 2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, - 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, - 10, 8, 138, 8, 74, 8, 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, - 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, - 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8, - 22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, - 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, - 30, 8, 158, 8, 94, 8, 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, - 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, - 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, 241, 8, - 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, - 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, - 5, 8, 133, 8, 69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, - 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, - 13, 8, 141, 8, 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, 237, 8, - 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, - 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9, - 51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, - 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, - 43, 9, 299, 9, 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, 491, 9, - 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, - 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, 251, 9, 507, 9, - 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, - 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, - 23, 9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, - 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, - 15, 9, 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, 207, 9, 463, 9, - 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, - 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9, 223, 9, 479, 9, - 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, - 0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, - 8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, - 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, - 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8 - }; - - internal static readonly short[] distTreeCodes = new short[] { - 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, - 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, - 1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5, - 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 }; - - internal static readonly StaticTree Literals; - internal static readonly StaticTree Distances; - internal static readonly StaticTree BitLengths; - - internal short[] treeCodes; // static tree or null - internal int[] extraBits; // extra bits for each code or null - internal int extraBase; // base index for extra_bits - internal int elems; // max number of elements in the tree - internal int maxLength; // max bit length for the codes - - private StaticTree(short[] treeCodes, int[] extraBits, int extraBase, int elems, int maxLength) - { - this.treeCodes = treeCodes; - this.extraBits = extraBits; - this.extraBase = extraBase; - this.elems = elems; - this.maxLength = maxLength; - } - static StaticTree() - { - Literals = new StaticTree(lengthAndLiteralsTreeCodes, Tree.ExtraLengthBits, InternalConstants.LITERALS + 1, InternalConstants.L_CODES, InternalConstants.MAX_BITS); - Distances = new StaticTree(distTreeCodes, Tree.ExtraDistanceBits, 0, InternalConstants.D_CODES, InternalConstants.MAX_BITS); - BitLengths = new StaticTree(null, Tree.extra_blbits, 0, InternalConstants.BL_CODES, InternalConstants.MAX_BL_BITS); - } - } - - - - /// - /// Computes an Adler-32 checksum. - /// - /// - /// The Adler checksum is similar to a CRC checksum, but faster to compute, though less - /// reliable. It is used in producing RFC1950 compressed streams. The Adler checksum - /// is a required part of the "ZLIB" standard. Applications will almost never need to - /// use this class directly. - /// - internal sealed class Adler - { - // largest prime smaller than 65536 - private static readonly uint BASE = 65521; - // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 - private static readonly int NMAX = 5552; - - static internal uint Adler32(uint adler, byte[] buf, int index, int len) - { - if (buf == null) - return 1; - - uint s1 = (uint) (adler & 0xffff); - uint s2 = (uint) ((adler >> 16) & 0xffff); - - while (len > 0) - { - int k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) - { - //s1 += (buf[index++] & 0xff); s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - s1 += buf[index++]; s2 += s1; - k -= 16; - } - if (k != 0) - { - do - { - s1 += buf[index++]; - s2 += s1; - } - while (--k != 0); - } - s1 %= BASE; - s2 %= BASE; - } - return (uint)((s2 << 16) | s1); - } - - } - -} \ No newline at end of file diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibBaseStream.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibBaseStream.cs deleted file mode 100644 index add6bcb5..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibBaseStream.cs +++ /dev/null @@ -1,627 +0,0 @@ -// ZlibBaseStream.cs -// ------------------------------------------------------------------ -// -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. -// All rights reserved. -// -// This code module is part of DotNetZip, a zipfile class library. -// -// ------------------------------------------------------------------ -// -// This code is licensed under the Microsoft Public License. -// See the file License.txt for the license details. -// More info on: http://dotnetzip.codeplex.com -// -// ------------------------------------------------------------------ -// -// last saved (in emacs): -// Time-stamp: <2009-October-28 15:45:15> -// -// ------------------------------------------------------------------ -// -// This module defines the ZlibBaseStream class, which is an intnernal -// base class for DeflateStream, ZlibStream and GZipStream. -// -// ------------------------------------------------------------------ - -using System; -using System.IO; - -namespace Ionic.Zlib -{ - - internal enum ZlibStreamFlavor { ZLIB = 1950, DEFLATE = 1951, GZIP = 1952 } - - internal class ZlibBaseStream : System.IO.Stream - { - protected internal ZlibCodec _z = null; // deferred init... new ZlibCodec(); - - protected internal StreamMode _streamMode = StreamMode.Undefined; - protected internal FlushType _flushMode; - protected internal ZlibStreamFlavor _flavor; - protected internal CompressionMode _compressionMode; - protected internal CompressionLevel _level; - protected internal bool _leaveOpen; - protected internal byte[] _workingBuffer; - protected internal int _bufferSize = ZlibConstants.WorkingBufferSizeDefault; - protected internal byte[] _buf1 = new byte[1]; - - protected internal System.IO.Stream _stream; - protected internal CompressionStrategy Strategy = CompressionStrategy.Default; - - // workitem 7159 - Ionic.Zlib.CRC32 crc; - protected internal string _GzipFileName; - protected internal string _GzipComment; - protected internal DateTime _GzipMtime; - protected internal int _gzipHeaderByteCount; - - internal int Crc32 { get { if (crc == null) return 0; return crc.Crc32Result; } } - - public ZlibBaseStream(System.IO.Stream stream, - CompressionMode compressionMode, - CompressionLevel level, - ZlibStreamFlavor flavor, - bool leaveOpen) - : base() - { - this._flushMode = FlushType.None; - //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT]; - this._stream = stream; - this._leaveOpen = leaveOpen; - this._compressionMode = compressionMode; - this._flavor = flavor; - this._level = level; - // workitem 7159 - if (flavor == ZlibStreamFlavor.GZIP) - { - crc = new CRC32(); - } - } - - - protected internal bool _wantCompress - { - get - { - return (this._compressionMode == CompressionMode.Compress); - } - } - - private ZlibCodec z - { - get - { - if (_z == null) - { - bool wantRfc1950Header = (this._flavor == ZlibStreamFlavor.ZLIB); - _z = new ZlibCodec(); - if (this._compressionMode == CompressionMode.Decompress) - { - _z.InitializeInflate(wantRfc1950Header); - } - else - { - _z.Strategy = Strategy; - _z.InitializeDeflate(this._level, wantRfc1950Header); - } - } - return _z; - } - } - - - - private byte[] workingBuffer - { - get - { - if (_workingBuffer == null) - _workingBuffer = new byte[_bufferSize]; - return _workingBuffer; - } - } - - - - public override void Write(System.Byte[] buffer, int offset, int count) - { - // workitem 7159 - // calculate the CRC on the unccompressed data (before writing) - if (crc != null) - crc.SlurpBlock(buffer, offset, count); - - if (_streamMode == StreamMode.Undefined) - _streamMode = StreamMode.Writer; - else if (_streamMode != StreamMode.Writer) - throw new ZlibException("Cannot Write after Reading."); - - if (count == 0) - return; - - // first reference of z property will initialize the private var _z - z.InputBuffer = buffer; - _z.NextIn = offset; - _z.AvailableBytesIn = count; - bool done = false; - do - { - _z.OutputBuffer = workingBuffer; - _z.NextOut = 0; - _z.AvailableBytesOut = _workingBuffer.Length; - int rc = (_wantCompress) - ? _z.Deflate(_flushMode) - : _z.Inflate(_flushMode); - if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) - throw new ZlibException((_wantCompress ? "de" : "in") + "flating: " + _z.Message); - - //if (_workingBuffer.Length - _z.AvailableBytesOut > 0) - _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut); - - done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0; - - // If GZIP and de-compress, we're done when 8 bytes remain. - if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress) - done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0); - - } - while (!done); - } - - - - private void finish() - { - if (_z == null) return; - - if (_streamMode == StreamMode.Writer) - { - bool done = false; - do - { - _z.OutputBuffer = workingBuffer; - _z.NextOut = 0; - _z.AvailableBytesOut = _workingBuffer.Length; - int rc = (_wantCompress) - ? _z.Deflate(FlushType.Finish) - : _z.Inflate(FlushType.Finish); - - if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) - { - string verb = (_wantCompress ? "de" : "in") + "flating"; - if (_z.Message == null) - throw new ZlibException(String.Format("{0}: (rc = {1})", verb, rc)); - else - throw new ZlibException(verb + ": " + _z.Message); - } - - if (_workingBuffer.Length - _z.AvailableBytesOut > 0) - { - _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut); - } - - done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0; - // If GZIP and de-compress, we're done when 8 bytes remain. - if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress) - done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0); - - } - while (!done); - - Flush(); - - // workitem 7159 - if (_flavor == ZlibStreamFlavor.GZIP) - { - if (_wantCompress) - { - // Emit the GZIP trailer: CRC32 and size mod 2^32 - int c1 = crc.Crc32Result; - _stream.Write(BitConverter.GetBytes(c1), 0, 4); - int c2 = (Int32)(crc.TotalBytesRead & 0x00000000FFFFFFFF); - _stream.Write(BitConverter.GetBytes(c2), 0, 4); - } - else - { - throw new ZlibException("Writing with decompression is not supported."); - } - } - } - // workitem 7159 - else if (_streamMode == StreamMode.Reader) - { - if (_flavor == ZlibStreamFlavor.GZIP) - { - if (!_wantCompress) - { - // workitem 8501: handle edge case (decompress empty stream) - if (_z.TotalBytesOut == 0L) - return; - - // Read and potentially verify the GZIP trailer: CRC32 and size mod 2^32 - byte[] trailer = new byte[8]; - - // workitem 8679 - if (_z.AvailableBytesIn != 8) - { - // Make sure we have read to the end of the stream - Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, _z.AvailableBytesIn); - int bytesNeeded = 8 - _z.AvailableBytesIn; - int bytesRead = _stream.Read(trailer, - _z.AvailableBytesIn, - bytesNeeded); - if (bytesNeeded != bytesRead) - { - throw new ZlibException(String.Format("Protocol error. AvailableBytesIn={0}, expected 8", - _z.AvailableBytesIn + bytesRead)); - } - } - else - { - Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, trailer.Length); - } - - - Int32 crc32_expected = BitConverter.ToInt32(trailer, 0); - Int32 crc32_actual = crc.Crc32Result; - Int32 isize_expected = BitConverter.ToInt32(trailer, 4); - Int32 isize_actual = (Int32)(_z.TotalBytesOut & 0x00000000FFFFFFFF); - - if (crc32_actual != crc32_expected) - throw new ZlibException(String.Format("Bad CRC32 in GZIP stream. (actual({0:X8})!=expected({1:X8}))", crc32_actual, crc32_expected)); - - if (isize_actual != isize_expected) - throw new ZlibException(String.Format("Bad size in GZIP stream. (actual({0})!=expected({1}))", isize_actual, isize_expected)); - - } - else - { - throw new ZlibException("Reading with compression is not supported."); - } - } - } - } - - - private void end() - { - if (z == null) - return; - if (_wantCompress) - { - _z.EndDeflate(); - } - else - { - _z.EndInflate(); - } - _z = null; - } - - - public override void Close() - { - if (_stream == null) return; - try - { - finish(); - } - finally - { - end(); - if (!_leaveOpen) _stream.Close(); - _stream = null; - } - } - - public override void Flush() - { - _stream.Flush(); - } - - public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) - { - throw new NotImplementedException(); - //_outStream.Seek(offset, origin); - } - public override void SetLength(System.Int64 value) - { - _stream.SetLength(value); - } - - -#if NOT - public int Read() - { - if (Read(_buf1, 0, 1) == 0) - return 0; - // calculate CRC after reading - if (crc!=null) - crc.SlurpBlock(_buf1,0,1); - return (_buf1[0] & 0xFF); - } -#endif - - private bool nomoreinput = false; - - - - private string ReadZeroTerminatedString() - { - var list = new System.Collections.Generic.List(); - bool done = false; - do - { - // workitem 7740 - int n = _stream.Read(_buf1, 0, 1); - if (n != 1) - throw new ZlibException("Unexpected EOF reading GZIP header."); - else - { - if (_buf1[0] == 0) - done = true; - else - list.Add(_buf1[0]); - } - } while (!done); - byte[] a = list.ToArray(); - return GZipStream.iso8859dash1.GetString(a, 0, a.Length); - } - - - private int _ReadAndValidateGzipHeader() - { - int totalBytesRead = 0; - // read the header on the first read - byte[] header = new byte[10]; - int n = _stream.Read(header, 0, header.Length); - - // workitem 8501: handle edge case (decompress empty stream) - if (n == 0) - return 0; - - if (n != 10) - throw new ZlibException("Not a valid GZIP stream."); - - if (header[0] != 0x1F || header[1] != 0x8B || header[2] != 8) - throw new ZlibException("Bad GZIP header."); - - Int32 timet = BitConverter.ToInt32(header, 4); - _GzipMtime = GZipStream._unixEpoch.AddSeconds(timet); - totalBytesRead += n; - if ((header[3] & 0x04) == 0x04) - { - // read and discard extra field - n = _stream.Read(header, 0, 2); // 2-byte length field - totalBytesRead += n; - - Int16 extraLength = (Int16)(header[0] + header[1] * 256); - byte[] extra = new byte[extraLength]; - n = _stream.Read(extra, 0, extra.Length); - if (n != extraLength) - throw new ZlibException("Unexpected end-of-file reading GZIP header."); - totalBytesRead += n; - } - if ((header[3] & 0x08) == 0x08) - _GzipFileName = ReadZeroTerminatedString(); - if ((header[3] & 0x10) == 0x010) - _GzipComment = ReadZeroTerminatedString(); - if ((header[3] & 0x02) == 0x02) - Read(_buf1, 0, 1); // CRC16, ignore - - return totalBytesRead; - } - - - - public override System.Int32 Read(System.Byte[] buffer, System.Int32 offset, System.Int32 count) - { - // According to MS documentation, any implementation of the IO.Stream.Read function must: - // (a) throw an exception if offset & count reference an invalid part of the buffer, - // or if count < 0, or if buffer is null - // (b) return 0 only upon EOF, or if count = 0 - // (c) if not EOF, then return at least 1 byte, up to bytes - - if (_streamMode == StreamMode.Undefined) - { - if (!this._stream.CanRead) throw new ZlibException("The stream is not readable."); - // for the first read, set up some controls. - _streamMode = StreamMode.Reader; - // (The first reference to _z goes through the private accessor which - // may initialize it.) - z.AvailableBytesIn = 0; - if (_flavor == ZlibStreamFlavor.GZIP) - { - _gzipHeaderByteCount = _ReadAndValidateGzipHeader(); - // workitem 8501: handle edge case (decompress empty stream) - if (_gzipHeaderByteCount == 0) - return 0; - } - } - - if (_streamMode != StreamMode.Reader) - throw new ZlibException("Cannot Read after Writing."); - - if (count == 0) return 0; - if (nomoreinput && _wantCompress) return 0; // workitem 8557 - if (buffer == null) throw new ArgumentNullException("buffer"); - if (count < 0) throw new ArgumentOutOfRangeException("count"); - if (offset < buffer.GetLowerBound(0)) throw new ArgumentOutOfRangeException("offset"); - if ((offset + count) > buffer.GetLength(0)) throw new ArgumentOutOfRangeException("count"); - - int rc = 0; - - // set up the output of the deflate/inflate codec: - _z.OutputBuffer = buffer; - _z.NextOut = offset; - _z.AvailableBytesOut = count; - - // This is necessary in case _workingBuffer has been resized. (new byte[]) - // (The first reference to _workingBuffer goes through the private accessor which - // may initialize it.) - _z.InputBuffer = workingBuffer; - - do - { - // need data in _workingBuffer in order to deflate/inflate. Here, we check if we have any. - if ((_z.AvailableBytesIn == 0) && (!nomoreinput)) - { - // No data available, so try to Read data from the captive stream. - _z.NextIn = 0; - _z.AvailableBytesIn = _stream.Read(_workingBuffer, 0, _workingBuffer.Length); - if (_z.AvailableBytesIn == 0) - nomoreinput = true; - - } - // we have data in InputBuffer; now compress or decompress as appropriate - rc = (_wantCompress) - ? _z.Deflate(_flushMode) - : _z.Inflate(_flushMode); - - if (nomoreinput && (rc == ZlibConstants.Z_BUF_ERROR)) - return 0; - - if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) - throw new ZlibException(String.Format("{0}flating: rc={1} msg={2}", (_wantCompress ? "de" : "in"), rc, _z.Message)); - - if ((nomoreinput || rc == ZlibConstants.Z_STREAM_END) && (_z.AvailableBytesOut == count)) - break; // nothing more to read - } - //while (_z.AvailableBytesOut == count && rc == ZlibConstants.Z_OK); - while (_z.AvailableBytesOut > 0 && !nomoreinput && rc == ZlibConstants.Z_OK); - - - // workitem 8557 - // is there more room in output? - if (_z.AvailableBytesOut > 0) - { - if (rc == ZlibConstants.Z_OK && _z.AvailableBytesIn == 0) - { - // deferred - } - - // are we completely done reading? - if (nomoreinput) - { - // and in compression? - if (_wantCompress) - { - // no more input data available; therefore we flush to - // try to complete the read - rc = _z.Deflate(FlushType.Finish); - - if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) - throw new ZlibException(String.Format("Deflating: rc={0} msg={1}", rc, _z.Message)); - } - } - } - - - rc = (count - _z.AvailableBytesOut); - - // calculate CRC after reading - if (crc != null) - crc.SlurpBlock(buffer, offset, rc); - - return rc; - } - - - - public override System.Boolean CanRead - { - get { return this._stream.CanRead; } - } - - public override System.Boolean CanSeek - { - get { return this._stream.CanSeek; } - } - - public override System.Boolean CanWrite - { - get { return this._stream.CanWrite; } - } - - public override System.Int64 Length - { - get { return _stream.Length; } - } - - public override long Position - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - internal enum StreamMode - { - Writer, - Reader, - Undefined, - } - - - public static void CompressString(String s, Stream compressor) - { - byte[] uncompressed = System.Text.Encoding.UTF8.GetBytes(s); - using (compressor) - { - compressor.Write(uncompressed, 0, uncompressed.Length); - } - } - - public static void CompressBuffer(byte[] b, Stream compressor) - { - // workitem 8460 - using (compressor) - { - compressor.Write(b, 0, b.Length); - } - } - - public static String UncompressString(byte[] compressed, Stream decompressor) - { - // workitem 8460 - byte[] working = new byte[1024]; - var encoding = System.Text.Encoding.UTF8; - using (var output = new MemoryStream()) - { - using (decompressor) - { - int n; - while ((n = decompressor.Read(working, 0, working.Length)) != 0) - { - output.Write(working, 0, n); - } - } - - // reset to allow read from start - output.Seek(0, SeekOrigin.Begin); - var sr = new StreamReader(output, encoding); - return sr.ReadToEnd(); - } - } - - public static byte[] UncompressBuffer(byte[] compressed, Stream decompressor) - { - // workitem 8460 - byte[] working = new byte[1024]; - using (var output = new MemoryStream()) - { - using (decompressor) - { - int n; - while ((n = decompressor.Read(working, 0, working.Length)) != 0) - { - output.Write(working, 0, n); - } - } - return output.ToArray(); - } - } - - } - - -} diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibCodec.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibCodec.cs deleted file mode 100644 index 62f25460..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibCodec.cs +++ /dev/null @@ -1,717 +0,0 @@ -// ZlibCodec.cs -// ------------------------------------------------------------------ -// -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. -// All rights reserved. -// -// This code module is part of DotNetZip, a zipfile class library. -// -// ------------------------------------------------------------------ -// -// This code is licensed under the Microsoft Public License. -// See the file License.txt for the license details. -// More info on: http://dotnetzip.codeplex.com -// -// ------------------------------------------------------------------ -// -// last saved (in emacs): -// Time-stamp: <2009-November-03 15:40:51> -// -// ------------------------------------------------------------------ -// -// This module defines a Codec for ZLIB compression and -// decompression. This code extends code that was based the jzlib -// implementation of zlib, but this code is completely novel. The codec -// class is new, and encapsulates some behaviors that are new, and some -// that were present in other classes in the jzlib code base. In -// keeping with the license for jzlib, the copyright to the jzlib code -// is included below. -// -// ------------------------------------------------------------------ -// -// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in -// the documentation and/or other materials provided with the distribution. -// -// 3. The names of the authors may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// ----------------------------------------------------------------------- -// -// This program is based on zlib-1.1.3; credit to authors -// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) -// and contributors of zlib. -// -// ----------------------------------------------------------------------- - - -using System; -using Interop=System.Runtime.InteropServices; - -namespace Ionic.Zlib -{ - /// - /// Encoder and Decoder for ZLIB and DEFLATE (IETF RFC1950 and RFC1951). - /// - /// - /// - /// This class compresses and decompresses data according to the Deflate algorithm - /// and optionally, the ZLIB format, as documented in RFC 1950 - ZLIB and RFC 1951 - DEFLATE. - /// - [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000D")] - [Interop.ComVisible(true)] -#if !NETCF - [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)] -#endif - sealed internal class ZlibCodec - { - /// - /// The buffer from which data is taken. - /// - public byte[] InputBuffer; - - /// - /// An index into the InputBuffer array, indicating where to start reading. - /// - public int NextIn; - - /// - /// The number of bytes available in the InputBuffer, starting at NextIn. - /// - /// - /// Generally you should set this to InputBuffer.Length before the first Inflate() or Deflate() call. - /// The class will update this number as calls to Inflate/Deflate are made. - /// - public int AvailableBytesIn; - - /// - /// Total number of bytes read so far, through all calls to Inflate()/Deflate(). - /// - public long TotalBytesIn; - - /// - /// Buffer to store output data. - /// - public byte[] OutputBuffer; - - /// - /// An index into the OutputBuffer array, indicating where to start writing. - /// - public int NextOut; - - /// - /// The number of bytes available in the OutputBuffer, starting at NextOut. - /// - /// - /// Generally you should set this to OutputBuffer.Length before the first Inflate() or Deflate() call. - /// The class will update this number as calls to Inflate/Deflate are made. - /// - public int AvailableBytesOut; - - /// - /// Total number of bytes written to the output so far, through all calls to Inflate()/Deflate(). - /// - public long TotalBytesOut; - - /// - /// used for diagnostics, when something goes wrong! - /// - public System.String Message; - - internal DeflateManager dstate; - internal InflateManager istate; - - internal uint _Adler32; - - /// - /// The compression level to use in this codec. Useful only in compression mode. - /// - public CompressionLevel CompressLevel = CompressionLevel.Default; - - /// - /// The number of Window Bits to use. - /// - /// - /// This gauges the size of the sliding window, and hence the - /// compression effectiveness as well as memory consumption. It's best to just leave this - /// setting alone if you don't know what it is. The maximum value is 15 bits, which implies - /// a 32k window. - /// - public int WindowBits = ZlibConstants.WindowBitsDefault; - - /// - /// The compression strategy to use. - /// - /// - /// This is only effective in compression. The theory offered by ZLIB is that different - /// strategies could potentially produce significant differences in compression behavior - /// for different data sets. Unfortunately I don't have any good recommendations for how - /// to set it differently. When I tested changing the strategy I got minimally different - /// compression performance. It's best to leave this property alone if you don't have a - /// good feel for it. Or, you may want to produce a test harness that runs through the - /// different strategy options and evaluates them on different file types. If you do that, - /// let me know your results. - /// - public CompressionStrategy Strategy = CompressionStrategy.Default; - - - /// - /// The Adler32 checksum on the data transferred through the codec so far. You probably don't need to look at this. - /// - public int Adler32 { get { return (int)_Adler32; } } - - - /// - /// Create a ZlibCodec. - /// - /// - /// If you use this default constructor, you will later have to explicitly call - /// InitializeInflate() or InitializeDeflate() before using the ZlibCodec to compress - /// or decompress. - /// - public ZlibCodec() { } - - /// - /// Create a ZlibCodec that either compresses or decompresses. - /// - /// - /// Indicates whether the codec should compress (deflate) or decompress (inflate). - /// - public ZlibCodec(CompressionMode mode) - { - if (mode == CompressionMode.Compress) - { - int rc = InitializeDeflate(); - if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for deflate."); - } - else if (mode == CompressionMode.Decompress) - { - int rc = InitializeInflate(); - if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for inflate."); - } - else throw new ZlibException("Invalid ZlibStreamFlavor."); - } - - /// - /// Initialize the inflation state. - /// - /// - /// It is not necessary to call this before using the ZlibCodec to inflate data; - /// It is implicitly called when you call the constructor. - /// - /// Z_OK if everything goes well. - public int InitializeInflate() - { - return InitializeInflate(this.WindowBits); - } - - /// - /// Initialize the inflation state with an explicit flag to - /// govern the handling of RFC1950 header bytes. - /// - /// - /// - /// By default, the ZLIB header defined in RFC 1950 is expected. If - /// you want to read a zlib stream you should specify true for - /// expectRfc1950Header. If you have a deflate stream, you will want to specify - /// false. It is only necessary to invoke this initializer explicitly if you - /// want to specify false. - /// - /// - /// whether to expect an RFC1950 header byte - /// pair when reading the stream of data to be inflated. - /// - /// Z_OK if everything goes well. - public int InitializeInflate(bool expectRfc1950Header) - { - return InitializeInflate(this.WindowBits, expectRfc1950Header); - } - - /// - /// Initialize the ZlibCodec for inflation, with the specified number of window bits. - /// - /// The number of window bits to use. If you need to ask what that is, - /// then you shouldn't be calling this initializer. - /// Z_OK if all goes well. - public int InitializeInflate(int windowBits) - { - this.WindowBits = windowBits; - return InitializeInflate(windowBits, true); - } - - /// - /// Initialize the inflation state with an explicit flag to govern the handling of - /// RFC1950 header bytes. - /// - /// - /// - /// If you want to read a zlib stream you should specify true for - /// expectRfc1950Header. In this case, the library will expect to find a ZLIB - /// header, as defined in RFC - /// 1950, in the compressed stream. If you will be reading a DEFLATE or - /// GZIP stream, which does not have such a header, you will want to specify - /// false. - /// - /// - /// whether to expect an RFC1950 header byte pair when reading - /// the stream of data to be inflated. - /// The number of window bits to use. If you need to ask what that is, - /// then you shouldn't be calling this initializer. - /// Z_OK if everything goes well. - public int InitializeInflate(int windowBits, bool expectRfc1950Header) - { - this.WindowBits = windowBits; - if (dstate != null) throw new ZlibException("You may not call InitializeInflate() after calling InitializeDeflate()."); - istate = new InflateManager(expectRfc1950Header); - return istate.Initialize(this, windowBits); - } - - /// - /// Inflate the data in the InputBuffer, placing the result in the OutputBuffer. - /// - /// - /// You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and - /// AvailableBytesOut before calling this method. - /// - /// - /// - /// private void InflateBuffer() - /// { - /// int bufferSize = 1024; - /// byte[] buffer = new byte[bufferSize]; - /// ZlibCodec decompressor = new ZlibCodec(); - /// - /// Console.WriteLine("\n============================================"); - /// Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length); - /// MemoryStream ms = new MemoryStream(DecompressedBytes); - /// - /// int rc = decompressor.InitializeInflate(); - /// - /// decompressor.InputBuffer = CompressedBytes; - /// decompressor.NextIn = 0; - /// decompressor.AvailableBytesIn = CompressedBytes.Length; - /// - /// decompressor.OutputBuffer = buffer; - /// - /// // pass 1: inflate - /// do - /// { - /// decompressor.NextOut = 0; - /// decompressor.AvailableBytesOut = buffer.Length; - /// rc = decompressor.Inflate(FlushType.None); - /// - /// if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) - /// throw new Exception("inflating: " + decompressor.Message); - /// - /// ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut); - /// } - /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); - /// - /// // pass 2: finish and flush - /// do - /// { - /// decompressor.NextOut = 0; - /// decompressor.AvailableBytesOut = buffer.Length; - /// rc = decompressor.Inflate(FlushType.Finish); - /// - /// if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) - /// throw new Exception("inflating: " + decompressor.Message); - /// - /// if (buffer.Length - decompressor.AvailableBytesOut > 0) - /// ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut); - /// } - /// while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); - /// - /// decompressor.EndInflate(); - /// } - /// - /// - /// - /// The flush to use when inflating. - /// Z_OK if everything goes well. - public int Inflate(FlushType flush) - { - if (istate == null) - throw new ZlibException("No Inflate State!"); - return istate.Inflate(flush); - } - - - /// - /// Ends an inflation session. - /// - /// - /// Call this after successively calling Inflate(). This will cause all buffers to be flushed. - /// After calling this you cannot call Inflate() without a intervening call to one of the - /// InitializeInflate() overloads. - /// - /// Z_OK if everything goes well. - public int EndInflate() - { - if (istate == null) - throw new ZlibException("No Inflate State!"); - int ret = istate.End(); - istate = null; - return ret; - } - - /// - /// I don't know what this does! - /// - /// Z_OK if everything goes well. - public int SyncInflate() - { - if (istate == null) - throw new ZlibException("No Inflate State!"); - return istate.Sync(); - } - - /// - /// Initialize the ZlibCodec for deflation operation. - /// - /// - /// The codec will use the MAX window bits and the default level of compression. - /// - /// - /// - /// int bufferSize = 40000; - /// byte[] CompressedBytes = new byte[bufferSize]; - /// byte[] DecompressedBytes = new byte[bufferSize]; - /// - /// ZlibCodec compressor = new ZlibCodec(); - /// - /// compressor.InitializeDeflate(CompressionLevel.Default); - /// - /// compressor.InputBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress); - /// compressor.NextIn = 0; - /// compressor.AvailableBytesIn = compressor.InputBuffer.Length; - /// - /// compressor.OutputBuffer = CompressedBytes; - /// compressor.NextOut = 0; - /// compressor.AvailableBytesOut = CompressedBytes.Length; - /// - /// while (compressor.TotalBytesIn != TextToCompress.Length && compressor.TotalBytesOut < bufferSize) - /// { - /// compressor.Deflate(FlushType.None); - /// } - /// - /// while (true) - /// { - /// int rc= compressor.Deflate(FlushType.Finish); - /// if (rc == ZlibConstants.Z_STREAM_END) break; - /// } - /// - /// compressor.EndDeflate(); - /// - /// - /// - /// Z_OK if all goes well. You generally don't need to check the return code. - public int InitializeDeflate() - { - return _InternalInitializeDeflate(true); - } - - /// - /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel. - /// - /// - /// The codec will use the maximum window bits (15) and the specified - /// CompressionLevel. It will emit a ZLIB stream as it compresses. - /// - /// The compression level for the codec. - /// Z_OK if all goes well. - public int InitializeDeflate(CompressionLevel level) - { - this.CompressLevel = level; - return _InternalInitializeDeflate(true); - } - - - /// - /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, - /// and the explicit flag governing whether to emit an RFC1950 header byte pair. - /// - /// - /// The codec will use the maximum window bits (15) and the specified CompressionLevel. - /// If you want to generate a zlib stream, you should specify true for - /// wantRfc1950Header. In this case, the library will emit a ZLIB - /// header, as defined in RFC - /// 1950, in the compressed stream. - /// - /// The compression level for the codec. - /// whether to emit an initial RFC1950 byte pair in the compressed stream. - /// Z_OK if all goes well. - public int InitializeDeflate(CompressionLevel level, bool wantRfc1950Header) - { - this.CompressLevel = level; - return _InternalInitializeDeflate(wantRfc1950Header); - } - - - /// - /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel, - /// and the specified number of window bits. - /// - /// - /// The codec will use the specified number of window bits and the specified CompressionLevel. - /// - /// The compression level for the codec. - /// the number of window bits to use. If you don't know what this means, don't use this method. - /// Z_OK if all goes well. - public int InitializeDeflate(CompressionLevel level, int bits) - { - this.CompressLevel = level; - this.WindowBits = bits; - return _InternalInitializeDeflate(true); - } - - /// - /// Initialize the ZlibCodec for deflation operation, using the specified - /// CompressionLevel, the specified number of window bits, and the explicit flag - /// governing whether to emit an RFC1950 header byte pair. - /// - /// - /// The compression level for the codec. - /// whether to emit an initial RFC1950 byte pair in the compressed stream. - /// the number of window bits to use. If you don't know what this means, don't use this method. - /// Z_OK if all goes well. - public int InitializeDeflate(CompressionLevel level, int bits, bool wantRfc1950Header) - { - this.CompressLevel = level; - this.WindowBits = bits; - return _InternalInitializeDeflate(wantRfc1950Header); - } - - private int _InternalInitializeDeflate(bool wantRfc1950Header) - { - if (istate != null) throw new ZlibException("You may not call InitializeDeflate() after calling InitializeInflate()."); - dstate = new DeflateManager(); - dstate.WantRfc1950HeaderBytes = wantRfc1950Header; - - return dstate.Initialize(this, this.CompressLevel, this.WindowBits, this.Strategy); - } - - /// - /// Deflate one batch of data. - /// - /// - /// You must have set InputBuffer and OutputBuffer before calling this method. - /// - /// - /// - /// private void DeflateBuffer(CompressionLevel level) - /// { - /// int bufferSize = 1024; - /// byte[] buffer = new byte[bufferSize]; - /// ZlibCodec compressor = new ZlibCodec(); - /// - /// Console.WriteLine("\n============================================"); - /// Console.WriteLine("Size of Buffer to Deflate: {0} bytes.", UncompressedBytes.Length); - /// MemoryStream ms = new MemoryStream(); - /// - /// int rc = compressor.InitializeDeflate(level); - /// - /// compressor.InputBuffer = UncompressedBytes; - /// compressor.NextIn = 0; - /// compressor.AvailableBytesIn = UncompressedBytes.Length; - /// - /// compressor.OutputBuffer = buffer; - /// - /// // pass 1: deflate - /// do - /// { - /// compressor.NextOut = 0; - /// compressor.AvailableBytesOut = buffer.Length; - /// rc = compressor.Deflate(FlushType.None); - /// - /// if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) - /// throw new Exception("deflating: " + compressor.Message); - /// - /// ms.Write(compressor.OutputBuffer, 0, buffer.Length - compressor.AvailableBytesOut); - /// } - /// while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0); - /// - /// // pass 2: finish and flush - /// do - /// { - /// compressor.NextOut = 0; - /// compressor.AvailableBytesOut = buffer.Length; - /// rc = compressor.Deflate(FlushType.Finish); - /// - /// if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) - /// throw new Exception("deflating: " + compressor.Message); - /// - /// if (buffer.Length - compressor.AvailableBytesOut > 0) - /// ms.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut); - /// } - /// while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0); - /// - /// compressor.EndDeflate(); - /// - /// ms.Seek(0, SeekOrigin.Begin); - /// CompressedBytes = new byte[compressor.TotalBytesOut]; - /// ms.Read(CompressedBytes, 0, CompressedBytes.Length); - /// } - /// - /// - /// whether to flush all data as you deflate. Generally you will want to - /// use Z_NO_FLUSH here, in a series of calls to Deflate(), and then call EndDeflate() to - /// flush everything. - /// - /// Z_OK if all goes well. - public int Deflate(FlushType flush) - { - if (dstate == null) - throw new ZlibException("No Deflate State!"); - return dstate.Deflate(flush); - } - - /// - /// End a deflation session. - /// - /// - /// Call this after making a series of one or more calls to Deflate(). All buffers are flushed. - /// - /// Z_OK if all goes well. - public int EndDeflate() - { - if (dstate == null) - throw new ZlibException("No Deflate State!"); - // TODO: dinoch Tue, 03 Nov 2009 15:39 (test this) - //int ret = dstate.End(); - dstate = null; - return ZlibConstants.Z_OK; //ret; - } - - /// - /// Reset a codec for another deflation session. - /// - /// - /// Call this to reset the deflation state. For example if a thread is deflating - /// non-consecutive blocks, you can call Reset() after the Deflate(Sync) of the first - /// block and before the next Deflate(None) of the second block. - /// - /// Z_OK if all goes well. - public void ResetDeflate() - { - if (dstate == null) - throw new ZlibException("No Deflate State!"); - dstate.Reset(); - } - - - /// - /// Set the CompressionStrategy and CompressionLevel for a deflation session. - /// - /// the level of compression to use. - /// the strategy to use for compression. - /// Z_OK if all goes well. - public int SetDeflateParams(CompressionLevel level, CompressionStrategy strategy) - { - if (dstate == null) - throw new ZlibException("No Deflate State!"); - return dstate.SetParams(level, strategy); - } - - - /// - /// Set the dictionary to be used for either Inflation or Deflation. - /// - /// The dictionary bytes to use. - /// Z_OK if all goes well. - public int SetDictionary(byte[] dictionary) - { - if (istate != null) - return istate.SetDictionary(dictionary); - - if (dstate != null) - return dstate.SetDictionary(dictionary); - - throw new ZlibException("No Inflate or Deflate state!"); - } - - // Flush as much pending output as possible. All deflate() output goes - // through this function so some applications may wish to modify it - // to avoid allocating a large strm->next_out buffer and copying into it. - // (See also read_buf()). - internal void flush_pending() - { - int len = dstate.pendingCount; - - if (len > AvailableBytesOut) - len = AvailableBytesOut; - if (len == 0) - return; - - if (dstate.pending.Length <= dstate.nextPending || - OutputBuffer.Length <= NextOut || - dstate.pending.Length < (dstate.nextPending + len) || - OutputBuffer.Length < (NextOut + len)) - { - throw new ZlibException(String.Format("Invalid State. (pending.Length={0}, pendingCount={1})", - dstate.pending.Length, dstate.pendingCount)); - } - - Array.Copy(dstate.pending, dstate.nextPending, OutputBuffer, NextOut, len); - - NextOut += len; - dstate.nextPending += len; - TotalBytesOut += len; - AvailableBytesOut -= len; - dstate.pendingCount -= len; - if (dstate.pendingCount == 0) - { - dstate.nextPending = 0; - } - } - - // Read a new buffer from the current input stream, update the adler32 - // and total number of bytes read. All deflate() input goes through - // this function so some applications may wish to modify it to avoid - // allocating a large strm->next_in buffer and copying from it. - // (See also flush_pending()). - internal int read_buf(byte[] buf, int start, int size) - { - int len = AvailableBytesIn; - - if (len > size) - len = size; - if (len == 0) - return 0; - - AvailableBytesIn -= len; - - if (dstate.WantRfc1950HeaderBytes) - { - _Adler32 = Adler.Adler32(_Adler32, InputBuffer, NextIn, len); - } - Array.Copy(InputBuffer, NextIn, buf, start, len); - NextIn += len; - TotalBytesIn += len; - return len; - } - - } -} \ No newline at end of file diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibConstants.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibConstants.cs deleted file mode 100644 index d015b707..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibConstants.cs +++ /dev/null @@ -1,128 +0,0 @@ -// ZlibConstants.cs -// ------------------------------------------------------------------ -// -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. -// All rights reserved. -// -// This code module is part of DotNetZip, a zipfile class library. -// -// ------------------------------------------------------------------ -// -// This code is licensed under the Microsoft Public License. -// See the file License.txt for the license details. -// More info on: http://dotnetzip.codeplex.com -// -// ------------------------------------------------------------------ -// -// last saved (in emacs): -// Time-stamp: <2009-November-03 18:50:19> -// -// ------------------------------------------------------------------ -// -// This module defines constants used by the zlib class library. This -// code is derived from the jzlib implementation of zlib, but -// significantly modified. In keeping with the license for jzlib, the -// copyright to that code is included here. -// -// ------------------------------------------------------------------ -// -// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in -// the documentation and/or other materials provided with the distribution. -// -// 3. The names of the authors may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, -// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, -// INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// ----------------------------------------------------------------------- -// -// This program is based on zlib-1.1.3; credit to authors -// Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) -// and contributors of zlib. -// -// ----------------------------------------------------------------------- - - -using System; - -namespace Ionic.Zlib -{ - /// - /// A bunch of constants used in the Zlib interface. - /// - internal static class ZlibConstants - { - /// - /// The maximum number of window bits for the Deflate algorithm. - /// - public const int WindowBitsMax = 15; // 32K LZ77 window - - /// - /// The default number of window bits for the Deflate algorithm. - /// - public const int WindowBitsDefault = WindowBitsMax; - - /// - /// indicates everything is A-OK - /// - public const int Z_OK = 0; - - /// - /// Indicates that the last operation reached the end of the stream. - /// - public const int Z_STREAM_END = 1; - - /// - /// The operation ended in need of a dictionary. - /// - public const int Z_NEED_DICT = 2; - - /// - /// There was an error with the stream - not enough data, not open and readable, etc. - /// - public const int Z_STREAM_ERROR = -2; - - /// - /// There was an error with the data - not enough data, bad data, etc. - /// - public const int Z_DATA_ERROR = -3; - - /// - /// There was an error with the working buffer. - /// - public const int Z_BUF_ERROR = -5; - - /// - /// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes. - /// -#if NETCF - public const int WorkingBufferSizeDefault = 8192; -#else - public const int WorkingBufferSizeDefault = 16384; -#endif - /// - /// The minimum size of the working buffer used in the ZlibCodec class. Currently it is 128 bytes. - /// - public const int WorkingBufferSizeMin = 1024; - } - -} - diff --git a/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibStream.cs b/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibStream.cs deleted file mode 100644 index 0357c7ad..00000000 --- a/SubstrateCS/Vendor/DotNetZip/Zlib/ZlibStream.cs +++ /dev/null @@ -1,682 +0,0 @@ -// ZlibStream.cs -// ------------------------------------------------------------------ -// -// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. -// All rights reserved. -// -// This code module is part of DotNetZip, a zipfile class library. -// -// ------------------------------------------------------------------ -// -// This code is licensed under the Microsoft Public License. -// See the file License.txt for the license details. -// More info on: http://dotnetzip.codeplex.com -// -// ------------------------------------------------------------------ -// -// last saved (in emacs): -// Time-stamp: <2010-January-09 12:03:25> -// -// ------------------------------------------------------------------ -// -// This module defines the ZlibStream class, which is similar in idea to -// the System.IO.Compression.DeflateStream and -// System.IO.Compression.GZipStream classes in the .NET BCL. -// -// ------------------------------------------------------------------ - -using System; -using System.IO; - -namespace Ionic.Zlib -{ - - /// - /// Represents a Zlib stream for compression or decompression. - /// - /// - /// - /// - /// The ZlibStream is a Decorator on a . It adds ZLIB compression or decompression to any - /// stream. - /// - /// - /// Using this stream, applications can compress or decompress data via - /// stream Read() and Write() operations. Either compresssion or - /// decompression can occur through either reading or writing. The compression - /// format used is ZLIB, which is documented in IETF RFC 1950, "ZLIB Compressed - /// Data Format Specification version 3.3". This implementation of ZLIB always uses - /// DEFLATE as the compression method. (see IETF RFC 1951, "DEFLATE - /// Compressed Data Format Specification version 1.3.") - /// - /// - /// The ZLIB format allows for varying compression methods, window sizes, and dictionaries. - /// This implementation always uses the DEFLATE compression method, a preset dictionary, - /// and 15 window bits by default. - /// - /// - /// - /// This class is similar to , except that it adds the - /// RFC1950 header and trailer bytes to a compressed stream when compressing, or expects - /// the RFC1950 header and trailer bytes when decompressing. It is also similar to the - /// . - /// - /// - /// - /// - internal class ZlibStream : System.IO.Stream - { - internal ZlibBaseStream _baseStream; - bool _disposed; - - /// - /// Create a ZlibStream using the specified CompressionMode. - /// - /// - /// - /// - /// When mode is CompressionMode.Compress, the ZlibStream will use the - /// default compression level. The "captive" stream will be closed when the - /// ZlibStream is closed. - /// - /// - /// - /// - /// - /// This example uses a ZlibStream to compress a file, and writes the compressed - /// data to another file. - /// - /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) - /// { - /// using (var raw = System.IO.File.Create(fileToCompress + ".zlib")) - /// { - /// using (Stream compressor = new ZlibStream(raw, CompressionMode.Compress)) - /// { - /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; - /// int n; - /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) - /// { - /// compressor.Write(buffer, 0, n); - /// } - /// } - /// } - /// } - /// - /// - /// Using input As Stream = File.OpenRead(fileToCompress) - /// Using raw As FileStream = File.Create(fileToCompress & ".zlib") - /// Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress) - /// Dim buffer As Byte() = New Byte(4096) {} - /// Dim n As Integer = -1 - /// Do While (n <> 0) - /// If (n > 0) Then - /// compressor.Write(buffer, 0, n) - /// End If - /// n = input.Read(buffer, 0, buffer.Length) - /// Loop - /// End Using - /// End Using - /// End Using - /// - /// - /// - /// The stream which will be read or written. - /// Indicates whether the ZlibStream will compress or decompress. - public ZlibStream(System.IO.Stream stream, CompressionMode mode) - : this(stream, mode, CompressionLevel.Default, false) - { - } - - /// - /// Create a ZlibStream using the specified CompressionMode and - /// the specified CompressionLevel. - /// - /// - /// - /// - /// - /// When mode is CompressionMode.Decompress, the level parameter is ignored. - /// The "captive" stream will be closed when the ZlibStream is closed. - /// - /// - /// - /// - /// - /// This example uses a ZlibStream to compress data from a file, and writes the - /// compressed data to another file. - /// - /// - /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) - /// { - /// using (var raw = System.IO.File.Create(fileToCompress + ".zlib")) - /// { - /// using (Stream compressor = new ZlibStream(raw, - /// CompressionMode.Compress, - /// CompressionLevel.BestCompression)) - /// { - /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; - /// int n; - /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) - /// { - /// compressor.Write(buffer, 0, n); - /// } - /// } - /// } - /// } - /// - /// - /// - /// Using input As Stream = File.OpenRead(fileToCompress) - /// Using raw As FileStream = File.Create(fileToCompress & ".zlib") - /// Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression) - /// Dim buffer As Byte() = New Byte(4096) {} - /// Dim n As Integer = -1 - /// Do While (n <> 0) - /// If (n > 0) Then - /// compressor.Write(buffer, 0, n) - /// End If - /// n = input.Read(buffer, 0, buffer.Length) - /// Loop - /// End Using - /// End Using - /// End Using - /// - /// - /// - /// The stream to be read or written while deflating or inflating. - /// Indicates whether the ZlibStream will compress or decompress. - /// A tuning knob to trade speed for effectiveness. - public ZlibStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level) - : this(stream, mode, level, false) - { - } - - /// - /// Create a ZlibStream using the specified CompressionMode, and - /// explicitly specify whether the captive stream should be left open after - /// Deflation or Inflation. - /// - /// - /// - /// - /// - /// When mode is CompressionMode.Compress, the ZlibStream will use - /// the default compression level. - /// - /// - /// - /// This constructor allows the application to request that the captive stream - /// remain open after the deflation or inflation occurs. By default, after - /// Close() is called on the stream, the captive stream is also - /// closed. In some cases this is not desired, for example if the stream is a - /// that will be re-read after - /// compression. Specify true for the parameter to leave the stream - /// open. - /// - /// - /// - /// See the other overloads of this constructor for example code. - /// - /// - /// - /// - /// The stream which will be read or written. This is called the - /// "captive" stream in other places in this documentation. - /// Indicates whether the ZlibStream will compress or decompress. - /// true if the application would like the stream to remain - /// open after inflation/deflation. - public ZlibStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen) - : this(stream, mode, CompressionLevel.Default, leaveOpen) - { - } - - /// - /// Create a ZlibStream using the specified CompressionMode and - /// the specified CompressionLevel, and explicitly specify whether the - /// stream should be left open after Deflation or Inflation. - /// - /// - /// - /// - /// - /// This constructor allows the application to request that the captive stream - /// remain open after the deflation or inflation occurs. By default, after - /// Close() is called on the stream, the captive stream is also closed. In - /// some cases this is not desired, for example if the stream is a that will be re-read after compression. - /// Specify true for the parameter to leave the stream open. - /// - /// - /// - /// When mode is CompressionMode.Decompress, the level parameter is ignored. - /// - /// - /// - /// - /// - /// This example shows how to use a ZlibStream to compress the data from a file, - /// and store the result into another file. The filestream remains open to allow - /// additional data to be written to it. - /// - /// using (var output = System.IO.File.Create(fileToCompress + ".zlib")) - /// { - /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) - /// { - /// using (Stream compressor = new ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true)) - /// { - /// byte[] buffer = new byte[WORKING_BUFFER_SIZE]; - /// int n; - /// while ((n= input.Read(buffer, 0, buffer.Length)) != 0) - /// { - /// compressor.Write(buffer, 0, n); - /// } - /// } - /// } - /// // can write additional data to the output stream here - /// } - /// - /// - /// Using output As FileStream = File.Create(fileToCompress & ".zlib") - /// Using input As Stream = File.OpenRead(fileToCompress) - /// Using compressor As Stream = New ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True) - /// Dim buffer As Byte() = New Byte(4096) {} - /// Dim n As Integer = -1 - /// Do While (n <> 0) - /// If (n > 0) Then - /// compressor.Write(buffer, 0, n) - /// End If - /// n = input.Read(buffer, 0, buffer.Length) - /// Loop - /// End Using - /// End Using - /// ' can write additional data to the output stream here. - /// End Using - /// - /// - /// - /// The stream which will be read or written. - /// - /// Indicates whether the ZlibStream will compress or decompress. - /// - /// - /// true if the application would like the stream to remain open after inflation/deflation. - /// - /// - /// - /// A tuning knob to trade speed for effectiveness. This parameter is effective only when - /// mode is CompressionMode.Compress. - /// - public ZlibStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen) - { - _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.ZLIB, leaveOpen); - } - - #region Zlib properties - - /// - /// This property sets the flush behavior on the stream. - /// Sorry, though, not sure exactly how to describe all the various settings. - /// - virtual public FlushType FlushMode - { - get { return (this._baseStream._flushMode); } - set - { - if (_disposed) throw new ObjectDisposedException("ZlibStream"); - this._baseStream._flushMode = value; - } - } - - /// - /// The size of the working buffer for the compression codec. - /// - /// - /// - /// - /// The working buffer is used for all stream operations. The default size is - /// 1024 bytes. The minimum size is 128 bytes. You may get better performance - /// with a larger buffer. Then again, you might not. You would have to test - /// it. - /// - /// - /// - /// Set this before the first call to Read() or Write() on the - /// stream. If you try to set it afterwards, it will throw. - /// - /// - public int BufferSize - { - get - { - return this._baseStream._bufferSize; - } - set - { - if (_disposed) throw new ObjectDisposedException("ZlibStream"); - if (this._baseStream._workingBuffer != null) - throw new ZlibException("The working buffer is already set."); - if (value < ZlibConstants.WorkingBufferSizeMin) - throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin)); - this._baseStream._bufferSize = value; - } - } - - /// Returns the total number of bytes input so far. - virtual public long TotalIn - { - get { return this._baseStream._z.TotalBytesIn; } - } - - /// Returns the total number of bytes output so far. - virtual public long TotalOut - { - get { return this._baseStream._z.TotalBytesOut; } - } - - #endregion - - #region System.IO.Stream methods - - /// - /// Dispose the stream. - /// - /// - /// This may or may not result in a Close() call on the captive stream. - /// See the constructors that have a leaveOpen parameter for more information. - /// - protected override void Dispose(bool disposing) - { - try - { - if (!_disposed) - { - if (disposing && (this._baseStream != null)) - this._baseStream.Close(); - _disposed = true; - } - } - finally - { - base.Dispose(disposing); - } - } - - - /// - /// Indicates whether the stream can be read. - /// - /// - /// The return value depends on whether the captive stream supports reading. - /// - public override bool CanRead - { - get - { - if (_disposed) throw new ObjectDisposedException("ZlibStream"); - return _baseStream._stream.CanRead; - } - } - - /// - /// Indicates whether the stream supports Seek operations. - /// - /// - /// Always returns false. - /// - public override bool CanSeek - { - get { return false; } - } - - /// - /// Indicates whether the stream can be written. - /// - /// - /// The return value depends on whether the captive stream supports writing. - /// - public override bool CanWrite - { - get - { - if (_disposed) throw new ObjectDisposedException("ZlibStream"); - return _baseStream._stream.CanWrite; - } - } - - /// - /// Flush the stream. - /// - public override void Flush() - { - if (_disposed) throw new ObjectDisposedException("ZlibStream"); - _baseStream.Flush(); - } - - /// - /// Reading this property always throws a . - /// - public override long Length - { - get { throw new NotImplementedException(); } - } - - /// - /// The position of the stream pointer. - /// - /// - /// - /// Setting this property always throws a . Reading will return the total bytes - /// written out, if used in writing, or the total bytes read in, if used in - /// reading. The count may refer to compressed bytes or uncompressed bytes, - /// depending on how you've used the stream. - /// - public override long Position - { - get - { - if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer) - return this._baseStream._z.TotalBytesOut; - if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader) - return this._baseStream._z.TotalBytesIn; - return 0; - } - - set { throw new NotImplementedException(); } - } - - /// - /// Read data from the stream. - /// - /// - /// - /// - /// - /// If you wish to use the ZlibStream to compress data while reading, - /// you can create a ZlibStream with CompressionMode.Compress, - /// providing an uncompressed data stream. Then call Read() on that - /// ZlibStream, and the data read will be compressed. If you wish to - /// use the ZlibStream to decompress data while reading, you can create - /// a ZlibStream with CompressionMode.Decompress, providing a - /// readable compressed data stream. Then call Read() on that - /// ZlibStream, and the data will be decompressed as it is read. - /// - /// - /// - /// A ZlibStream can be used for Read() or Write(), but - /// not both. - /// - /// - /// - /// The buffer into which the read data should be placed. - /// the offset within that data array to put the first byte read. - /// the number of bytes to read. - public override int Read(byte[] buffer, int offset, int count) - { - if (_disposed) throw new ObjectDisposedException("ZlibStream"); - return _baseStream.Read(buffer, offset, count); - } - - /// - /// Calling this method always throws a . - /// - public override long Seek(long offset, System.IO.SeekOrigin origin) - { - throw new NotImplementedException(); - } - - /// - /// Calling this method always throws a . - /// - public override void SetLength(long value) - { - throw new NotImplementedException(); - } - - /// - /// Write data to the stream. - /// - /// - /// - /// - /// - /// If you wish to use the ZlibStream to compress data while writing, - /// you can create a ZlibStream with CompressionMode.Compress, - /// and a writable output stream. Then call Write() on that - /// ZlibStream, providing uncompressed data as input. The data sent to - /// the output stream will be the compressed form of the data written. If you - /// wish to use the ZlibStream to decompress data while writing, you - /// can create a ZlibStream with CompressionMode.Decompress, and a - /// writable output stream. Then call Write() on that stream, - /// providing previously compressed data. The data sent to the output stream - /// will be the decompressed form of the data written. - /// - /// - /// - /// A ZlibStream can be used for Read() or Write(), but not both. - /// - /// - /// The buffer holding data to write to the stream. - /// the offset within that data array to find the first byte to write. - /// the number of bytes to write. - public override void Write(byte[] buffer, int offset, int count) - { - if (_disposed) throw new ObjectDisposedException("ZlibStream"); - _baseStream.Write(buffer, offset, count); - } - #endregion - - - /// - /// Compress a string into a byte array using ZLIB. - /// - /// - /// - /// Uncompress it with . - /// - /// - /// - /// - /// - /// - /// A string to compress. The string will first be encoded - /// using UTF8, then compressed. - /// - /// - /// The string in compressed form - public static byte[] CompressString(String s) - { - using (var ms = new MemoryStream()) - { - Stream compressor = - new ZlibStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression); - ZlibBaseStream.CompressString(s, compressor); - return ms.ToArray(); - } - } - - - /// - /// Compress a byte array into a new byte array using ZLIB. - /// - /// - /// - /// Uncompress it with . - /// - /// - /// - /// - /// - /// - /// A buffer to compress. - /// - /// - /// The data in compressed form - public static byte[] CompressBuffer(byte[] b) - { - using (var ms = new MemoryStream()) - { - Stream compressor = - new ZlibStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression ); - - ZlibBaseStream.CompressBuffer(b, compressor); - return ms.ToArray(); - } - } - - - /// - /// Uncompress a ZLIB-compressed byte array into a single string. - /// - /// - /// - /// - /// - /// - /// A buffer containing ZLIB-compressed data. - /// - /// - /// The uncompressed string - public static String UncompressString(byte[] compressed) - { - using (var input = new MemoryStream(compressed)) - { - Stream decompressor = - new ZlibStream(input, CompressionMode.Decompress); - - return ZlibBaseStream.UncompressString(compressed, decompressor); - } - } - - - /// - /// Uncompress a ZLIB-compressed byte array into a byte array. - /// - /// - /// - /// - /// - /// - /// A buffer containing ZLIB-compressed data. - /// - /// - /// The data in uncompressed form - public static byte[] UncompressBuffer(byte[] compressed) - { - using (var input = new MemoryStream(compressed)) - { - Stream decompressor = - new ZlibStream( input, CompressionMode.Decompress ); - - return ZlibBaseStream.UncompressBuffer(compressed, decompressor); - } - } - - } - - -} \ No newline at end of file diff --git a/VERSION.md b/VERSION.md new file mode 100644 index 00000000..52329b6a --- /dev/null +++ b/VERSION.md @@ -0,0 +1,20 @@ + +#v2.0.0 + +##Changes: + +* Added Name IDs to blocks and items +* Updated Biome IDs +* Updated built in BlockInfo blocks +* Updated built in ItemInfo items +* Updated Level metadata +* Nuget +* Added unit tests + + +##Breaking Changes: + +* Entities and TileEntities have been moved to a separate library +* BlockInfo constructor now takes a nameId parameter. +* Setter functions on BlockInfo and ItemInfo have been changed to properties +* BlockInfoEx has been folded into BlockInfo, now check if TileEntityName is null instead of casting to BlockInfoEx \ No newline at end of file