diff --git a/MinecraftClient/AutoTimeout.cs b/MinecraftClient/AutoTimeout.cs
index f92d35fe..786be4db 100644
--- a/MinecraftClient/AutoTimeout.cs
+++ b/MinecraftClient/AutoTimeout.cs
@@ -1,7 +1,5 @@
using System;
-using System.Diagnostics;
using System.Threading;
-using System.Threading.Tasks;
namespace MinecraftClient
{
@@ -30,14 +28,15 @@ namespace MinecraftClient
/// Action to run
/// Maximum timeout
/// True if the action finished whithout timing out
- public static bool Perform(Action action, TimeSpan timeout) {
- Thread thread = new Thread(new ThreadStart(action));
+ public static bool Perform(Action action, TimeSpan timeout)
+ {
+ Thread thread = new(new ThreadStart(action));
thread.Start();
+
bool success = thread.Join(timeout);
if (!success)
thread.Interrupt();
- thread = null;
return success;
}
}
diff --git a/MinecraftClient/ChatBots/Alerts.cs b/MinecraftClient/ChatBots/Alerts.cs
index 0f9a04d7..c5b1402a 100644
--- a/MinecraftClient/ChatBots/Alerts.cs
+++ b/MinecraftClient/ChatBots/Alerts.cs
@@ -1,9 +1,5 @@
using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.IO;
-using static System.Net.WebRequestMethods;
namespace MinecraftClient.ChatBots
{
@@ -12,8 +8,8 @@ namespace MinecraftClient.ChatBots
///
public class Alerts : ChatBot
{
- private string[] dictionary = new string[0];
- private string[] excludelist = new string[0];
+ private string[] dictionary = Array.Empty();
+ private string[] excludelist = Array.Empty();
private bool logToFile = false;
///
diff --git a/MinecraftClient/ChatBots/AntiAFK.cs b/MinecraftClient/ChatBots/AntiAFK.cs
index d078aae5..f4604484 100644
--- a/MinecraftClient/ChatBots/AntiAFK.cs
+++ b/MinecraftClient/ChatBots/AntiAFK.cs
@@ -10,14 +10,14 @@ namespace MinecraftClient.ChatBots
public class AntiAFK : ChatBot
{
private int count;
- private string pingparam;
+ private readonly string pingparam;
private int timeping = 600;
private int timepingMax = -1;
private bool useTerrainHandling = false;
private bool previousSneakState = false;
private int walkRange = 5;
- private int walkRetries = 10;
- private Random random = new Random();
+ private readonly int walkRetries = 10;
+ private readonly Random random = new();
///
/// This bot sends a /ping command every X seconds in order to stay non-afk.
@@ -57,7 +57,7 @@ namespace MinecraftClient.ChatBots
else
{
// Handle the random range
- if (pingparam.Contains("-"))
+ if (pingparam.Contains('-'))
{
string[] parts = pingparam.Split("-");
@@ -85,10 +85,7 @@ namespace MinecraftClient.ChatBots
if (timepingMax != -1 && timeping > timepingMax)
{
- int temporary = timepingMax;
- timepingMax = timeping;
- timeping = temporary;
-
+ (timeping, timepingMax) = (timepingMax, timeping);
LogToConsole(Translations.TryGet("bot.antiafk.swapping"));
}
diff --git a/MinecraftClient/ChatBots/AutoAttack.cs b/MinecraftClient/ChatBots/AutoAttack.cs
index 55bc156d..f9c6e820 100644
--- a/MinecraftClient/ChatBots/AutoAttack.cs
+++ b/MinecraftClient/ChatBots/AutoAttack.cs
@@ -1,7 +1,7 @@
-using MinecraftClient.Mapping;
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
+using MinecraftClient.Mapping;
namespace MinecraftClient.ChatBots
{
@@ -10,22 +10,22 @@ namespace MinecraftClient.ChatBots
///
class AutoAttack : ChatBot
{
- private Dictionary entitiesToAttack = new Dictionary(); // mobs within attack range
+ private readonly Dictionary entitiesToAttack = new(); // mobs within attack range
private int attackCooldown = 6;
private int attackCooldownCounter = 6;
private Double attackSpeed = 4;
private Double attackCooldownSeconds;
- private bool overrideAttackSpeed = false;
- private int attackRange = 4;
+ private readonly bool overrideAttackSpeed = false;
+ private readonly int attackRange = 4;
private Double serverTPS;
private float health = 100;
- private bool singleMode = true;
- private bool priorityDistance = true;
- private InteractType interactMode;
- private bool attackHostile = true;
- private bool attackPassive = false;
- private string listMode = "blacklist";
- private List listedEntites = new();
+ private readonly bool singleMode = true;
+ private readonly bool priorityDistance = true;
+ private readonly InteractType interactMode;
+ private readonly bool attackHostile = true;
+ private readonly bool attackPassive = false;
+ private readonly string listMode = "blacklist";
+ private readonly List listedEntites = new();
public AutoAttack(
string mode, string priority, bool overrideAttackSpeed = false, double cooldownSeconds = 1, InteractType interaction = InteractType.Attack)
@@ -53,13 +53,13 @@ namespace MinecraftClient.ChatBots
else
{
this.overrideAttackSpeed = overrideAttackSpeed;
- this.attackCooldownSeconds = cooldownSeconds;
+ attackCooldownSeconds = cooldownSeconds;
attackCooldown = Convert.ToInt32(Math.Truncate(attackCooldownSeconds / 0.1) + 1);
}
}
- this.attackHostile = Settings.AutoAttack_Attack_Hostile;
- this.attackPassive = Settings.AutoAttack_Attack_Passive;
+ attackHostile = Settings.AutoAttack_Attack_Hostile;
+ attackPassive = Settings.AutoAttack_Attack_Passive;
if (Settings.AutoAttack_ListMode.Length > 0)
{
@@ -140,7 +140,7 @@ namespace MinecraftClient.ChatBots
if (entitiesToAttack.ContainsKey(priorityEntity))
{
// check entity distance and health again
- if (shouldAttackEntity(entitiesToAttack[priorityEntity]))
+ if (ShouldAttackEntity(entitiesToAttack[priorityEntity]))
{
InteractEntity(priorityEntity, interactMode); // hit the entity!
SendAnimation(Inventory.Hand.MainHand); // Arm animation
@@ -152,7 +152,7 @@ namespace MinecraftClient.ChatBots
foreach (KeyValuePair entity in entitiesToAttack)
{
// check that we are in range once again.
- if (shouldAttackEntity(entity.Value))
+ if (ShouldAttackEntity(entity.Value))
{
InteractEntity(entity.Key, interactMode); // hit the entity!
}
@@ -169,7 +169,7 @@ namespace MinecraftClient.ChatBots
public override void OnEntitySpawn(Entity entity)
{
- shouldAttackEntity(entity);
+ ShouldAttackEntity(entity);
}
public override void OnEntityDespawn(Entity entity)
@@ -209,7 +209,7 @@ namespace MinecraftClient.ChatBots
if (listedEntites.Count > 0)
{
bool inList = listedEntites.Contains(entity.Type);
- result = listMode.Equals("blacklist") ? (inList ? false : result) : (inList ? true : false);
+ result = listMode.Equals("blacklist") ? (!inList && result) : (inList);
}
return result;
@@ -217,7 +217,7 @@ namespace MinecraftClient.ChatBots
public override void OnEntityMove(Entity entity)
{
- shouldAttackEntity(entity);
+ ShouldAttackEntity(entity);
}
public override void OnHealthUpdate(float health, int food)
@@ -262,7 +262,7 @@ namespace MinecraftClient.ChatBots
///
/// The entity to handle
/// If the entity should be attacked
- public bool shouldAttackEntity(Entity entity)
+ public bool ShouldAttackEntity(Entity entity)
{
if (!IsAllowedToAttack(entity) || entity.Health <= 0)
return false;
diff --git a/MinecraftClient/ChatBots/AutoCraft.cs b/MinecraftClient/ChatBots/AutoCraft.cs
index 703a2fe9..a07bdf33 100644
--- a/MinecraftClient/ChatBots/AutoCraft.cs
+++ b/MinecraftClient/ChatBots/AutoCraft.cs
@@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using System.IO;
+using System.Linq;
using MinecraftClient.Inventory;
using MinecraftClient.Mapping;
@@ -16,23 +15,23 @@ namespace MinecraftClient.ChatBots
private bool craftingFailed = false;
private int inventoryInUse = -2;
private int index = 0;
- private Recipe recipeInUse;
- private List actionSteps = new List();
+ private Recipe? recipeInUse;
+ private readonly List actionSteps = new();
- private Location tableLocation = new Location();
+ private Location tableLocation = new();
private bool abortOnFailure = true;
private int updateDebounceValue = 2;
private int updateDebounce = 0;
- private int updateTimeoutValue = 10;
+ private readonly int updateTimeoutValue = 10;
private int updateTimeout = 0;
private string timeoutAction = "unspecified";
- private string configPath = @"autocraft\config.ini";
+ private readonly string configPath = @"autocraft\config.ini";
private string lastRecipe = ""; // Used in parsing recipe config
- private Dictionary recipes = new Dictionary();
+ private readonly Dictionary recipes = new();
- private void resetVar()
+ private void ResetVar()
{
craftingFailed = false;
waitingForTable = false;
@@ -123,9 +122,10 @@ namespace MinecraftClient.ChatBots
/// Materials needed and their position
///
/// position start with 1, from left to right, top to bottom
- public Dictionary Materials;
+ public Dictionary? Materials;
public Recipe() { }
+
public Recipe(Dictionary materials, ItemType resultItem, ContainerType type)
{
Materials = materials;
@@ -141,7 +141,7 @@ namespace MinecraftClient.ChatBots
/// so that it can be used in crafting table
public static Recipe ConvertToCraftingTable(Recipe recipe)
{
- if (recipe.CraftingAreaType == ContainerType.PlayerInventory)
+ if (recipe.CraftingAreaType == ContainerType.PlayerInventory && recipe.Materials != null)
{
if (recipe.Materials.ContainsKey(4))
{
@@ -202,7 +202,7 @@ namespace MinecraftClient.ChatBots
string name = args[1];
if (recipes.ContainsKey(name))
{
- resetVar();
+ ResetVar();
PrepareCrafting(recipes[name]);
return "";
}
@@ -221,32 +221,26 @@ namespace MinecraftClient.ChatBots
else return GetHelp();
}
- private string GetHelp()
+ private static string GetHelp()
{
return Translations.Get("bot.autoCraft.available_cmd", "load, list, reload, resetcfg, start, stop, help");
}
private string GetCommandHelp(string cmd)
{
- switch (cmd.ToLower())
+ return cmd.ToLower() switch
{
- case "load":
- return Translations.Get("bot.autocraft.help.load");
- case "list":
- return Translations.Get("bot.autocraft.help.list");
- case "reload":
- return Translations.Get("bot.autocraft.help.reload");
- case "resetcfg":
- return Translations.Get("bot.autocraft.help.resetcfg");
- case "start":
- return Translations.Get("bot.autocraft.help.start");
- case "stop":
- return Translations.Get("bot.autocraft.help.stop");
- case "help":
- return Translations.Get("bot.autocraft.help.help");
- default:
- return GetHelp();
- }
+#pragma warning disable format // @formatter:off
+ "load" => Translations.Get("bot.autocraft.help.load"),
+ "list" => Translations.Get("bot.autocraft.help.list"),
+ "reload" => Translations.Get("bot.autocraft.help.reload"),
+ "resetcfg" => Translations.Get("bot.autocraft.help.resetcfg"),
+ "start" => Translations.Get("bot.autocraft.help.start"),
+ "stop" => Translations.Get("bot.autocraft.help.stop"),
+ "help" => Translations.Get("bot.autocraft.help.help"),
+ _ => GetHelp(),
+#pragma warning restore format // @formatter:on
+ };
}
#region Config handling
@@ -312,7 +306,7 @@ namespace MinecraftClient.ChatBots
// local variable for use in parsing config
string section = "";
- Dictionary recipes = new Dictionary();
+ Dictionary recipes = new();
foreach (string l in content)
{
@@ -323,20 +317,20 @@ namespace MinecraftClient.ChatBots
if (line.Length <= 0)
continue;
- if (line[0] == '[' && line[line.Length - 1] == ']')
+ if (line[0] == '[' && line[^1] == ']')
{
- section = line.Substring(1, line.Length - 2).ToLower();
+ section = line[1..^1].ToLower();
continue;
}
string key = line.Split('=')[0].ToLower();
if (!(line.Length > (key.Length + 1)))
continue;
- string value = line.Substring(key.Length + 1);
+ string value = line[(key.Length + 1)..];
switch (section)
{
- case "recipe": parseRecipe(key, value); break;
- case "autocraft": parseMain(key, value); break;
+ case "recipe": ParseRecipe(key, value); break;
+ case "autocraft": ParseMain(key, value); break;
}
}
@@ -358,12 +352,12 @@ namespace MinecraftClient.ChatBots
}
}
-
+
}
#region Method for parsing different section of config
- private void parseMain(string key, string value)
+ private void ParseMain(string key, string value)
{
switch (key)
{
@@ -378,7 +372,7 @@ namespace MinecraftClient.ChatBots
else throw new Exception(Translations.Get("bot.autoCraft.exception.invalid_table", key));
break;
case "onfailure":
- abortOnFailure = value.ToLower() == "abort" ? true : false;
+ abortOnFailure = value.ToLower() == "abort";
break;
case "updatedebounce":
updateDebounceValue = Convert.ToInt32(value);
@@ -386,21 +380,21 @@ namespace MinecraftClient.ChatBots
}
}
- private void parseRecipe(string key, string value)
+ private void ParseRecipe(string key, string value)
{
if (key.StartsWith("slot"))
{
- int slot = Convert.ToInt32(key[key.Length - 1].ToString());
+ int slot = Convert.ToInt32(key[^1].ToString());
if (slot > 0 && slot < 10)
{
if (recipes.ContainsKey(lastRecipe))
{
- ItemType itemType;
- if (Enum.TryParse(value, true, out itemType))
+ if (Enum.TryParse(value, true, out ItemType itemType))
{
- if (recipes[lastRecipe].Materials != null && recipes[lastRecipe].Materials.Count > 0)
+ Dictionary? materials = recipes[lastRecipe].Materials;
+ if (materials != null && materials.Count > 0)
{
- recipes[lastRecipe].Materials.Add(slot, itemType);
+ materials.Add(slot, itemType);
}
else
{
@@ -450,8 +444,7 @@ namespace MinecraftClient.ChatBots
case "result":
if (recipes.ContainsKey(lastRecipe))
{
- ItemType itemType;
- if (Enum.TryParse(value, true, out itemType))
+ if (Enum.TryParse(value, true, out ItemType itemType))
{
recipes[lastRecipe].ResultItem = itemType;
}
@@ -487,7 +480,7 @@ namespace MinecraftClient.ChatBots
// After table opened, we need to wait for server to update table inventory items
waitingForUpdate = true;
inventoryInUse = inventoryId;
- PrepareCrafting(recipeInUse);
+ PrepareCrafting(recipeInUse!);
}
}
}
@@ -562,11 +555,14 @@ namespace MinecraftClient.ChatBots
}
}
- foreach (KeyValuePair slot in recipe.Materials)
+ if (recipe.Materials != null)
{
- // Steps for moving items from inventory to crafting area
- actionSteps.Add(new ActionStep(ActionType.LeftClick, inventoryInUse, slot.Value));
- actionSteps.Add(new ActionStep(ActionType.LeftClick, inventoryInUse, slot.Key));
+ foreach (KeyValuePair slot in recipe.Materials)
+ {
+ // Steps for moving items from inventory to crafting area
+ actionSteps.Add(new ActionStep(ActionType.LeftClick, inventoryInUse, slot.Value));
+ actionSteps.Add(new ActionStep(ActionType.LeftClick, inventoryInUse, slot.Key));
+ }
}
if (actionSteps.Count > 0)
{
@@ -626,15 +622,15 @@ namespace MinecraftClient.ChatBots
else
{
int[] slots = GetInventories()[step.InventoryID].SearchItem(step.ItemType);
- if (slots.Count() > 0)
+ if (slots.Length > 0)
{
int ignoredSlot;
- if (recipeInUse.CraftingAreaType == ContainerType.PlayerInventory)
+ if (recipeInUse!.CraftingAreaType == ContainerType.PlayerInventory)
ignoredSlot = 9;
else
ignoredSlot = 10;
slots = slots.Where(slot => slot >= ignoredSlot).ToArray();
- if (slots.Count() > 0)
+ if (slots.Length > 0)
WindowAction(step.InventoryID, slots[0], WindowActionType.LeftClick);
else
craftingFailed = true;
@@ -688,7 +684,6 @@ namespace MinecraftClient.ChatBots
}
HandleError();
}
-
}
///
diff --git a/MinecraftClient/ChatBots/AutoDrop.cs b/MinecraftClient/ChatBots/AutoDrop.cs
index cf3142f0..e101da54 100644
--- a/MinecraftClient/ChatBots/AutoDrop.cs
+++ b/MinecraftClient/ChatBots/AutoDrop.cs
@@ -1,8 +1,7 @@
-using MinecraftClient.Inventory;
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
+using MinecraftClient.Inventory;
namespace MinecraftClient.ChatBots
{
@@ -18,10 +17,10 @@ namespace MinecraftClient.ChatBots
private bool enable = true;
private int updateDebounce = 0;
- private int updateDebounceValue = 2;
+ private readonly int updateDebounceValue = 2;
private int inventoryUpdated = -1;
- private List itemList = new List();
+ private readonly List itemList = new();
public AutoDrop(string mode, string itemList)
{
@@ -40,17 +39,11 @@ namespace MinecraftClient.ChatBots
/// Item type array
private ItemType[] ItemListParser(string itemList)
{
- string trimed = new string(itemList.Where(c => !char.IsWhiteSpace(c)).ToArray());
- string[] list = trimed.Split(',');
- List result = new List();
- foreach (string t in list)
- {
- ItemType item;
- if (Enum.TryParse(t, true, out item))
- {
+ string trimed = new(itemList.Where(c => !char.IsWhiteSpace(c)).ToArray());
+ List result = new();
+ foreach (string t in trimed.Split(','))
+ if (Enum.TryParse(t, true, out ItemType item))
result.Add(item);
- }
- }
return result.ToArray();
}
@@ -71,8 +64,7 @@ namespace MinecraftClient.ChatBots
case "add":
if (args.Length >= 2)
{
- ItemType item;
- if (Enum.TryParse(args[1], true, out item))
+ if (Enum.TryParse(args[1], true, out ItemType item))
{
itemList.Add(item);
return Translations.Get("bot.autoDrop.added", item.ToString());
@@ -89,8 +81,7 @@ namespace MinecraftClient.ChatBots
case "remove":
if (args.Length >= 2)
{
- ItemType item;
- if (Enum.TryParse(args[1], true, out item))
+ if (Enum.TryParse(args[1], true, out ItemType item))
{
if (itemList.Contains(item))
{
@@ -109,7 +100,7 @@ namespace MinecraftClient.ChatBots
}
else
{
- return Translations.Get("cmd.inventory.help.usage") + ": remove - ";
+ return Translations.Get("cmd.inventory.help.usage") + ": remove
- ";
}
case "list":
if (itemList.Count > 0)
@@ -155,7 +146,7 @@ namespace MinecraftClient.ChatBots
}
}
- private string GetHelp()
+ private static string GetHelp()
{
return Translations.Get("general.available_cmd", "on, off, add, remove, list, mode");
}
diff --git a/MinecraftClient/ChatBots/AutoEat.cs b/MinecraftClient/ChatBots/AutoEat.cs
index 6e18d934..2866fe4a 100644
--- a/MinecraftClient/ChatBots/AutoEat.cs
+++ b/MinecraftClient/ChatBots/AutoEat.cs
@@ -1,8 +1,4 @@
using MinecraftClient.Inventory;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace MinecraftClient.ChatBots
{
@@ -10,7 +6,7 @@ namespace MinecraftClient.ChatBots
{
byte LastSlot = 0;
public static bool Eating = false;
- private int HungerThreshold = 6;
+ private readonly int HungerThreshold = 6;
private int DelayCounter = 0;
public AutoEat(int Threshold)
diff --git a/MinecraftClient/ChatBots/AutoFishing.cs b/MinecraftClient/ChatBots/AutoFishing.cs
index 38001e6c..4e11eada 100644
--- a/MinecraftClient/ChatBots/AutoFishing.cs
+++ b/MinecraftClient/ChatBots/AutoFishing.cs
@@ -1,9 +1,6 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using MinecraftClient.Mapping;
using MinecraftClient.Inventory;
+using MinecraftClient.Mapping;
namespace MinecraftClient.ChatBots
{
diff --git a/MinecraftClient/ChatBots/AutoRelog.cs b/MinecraftClient/ChatBots/AutoRelog.cs
index a56bc030..b6f5a6e6 100644
--- a/MinecraftClient/ChatBots/AutoRelog.cs
+++ b/MinecraftClient/ChatBots/AutoRelog.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Text;
namespace MinecraftClient.ChatBots
@@ -10,11 +8,11 @@ namespace MinecraftClient.ChatBots
///
public class AutoRelog : ChatBot
{
- private static Random random = new Random();
- private string[] dictionary = new string[0];
- private int attempts;
- private int delayMin;
- private int delayMax;
+ private static readonly Random random = new();
+ private string[] dictionary = Array.Empty();
+ private readonly int attempts;
+ private readonly int delayMin;
+ private readonly int delayMax;
///
/// This bot automatically re-join the server if kick message contains predefined string
@@ -100,7 +98,7 @@ namespace MinecraftClient.ChatBots
return false;
}
- private void LaunchDelayedReconnection(string msg)
+ private void LaunchDelayedReconnection(string? msg)
{
int delay = random.Next(delayMin, delayMax);
LogDebugToConsoleTranslated(String.IsNullOrEmpty(msg) ? "bot.autoRelog.reconnect_always" : "bot.autoRelog.reconnect", msg);
@@ -113,7 +111,7 @@ namespace MinecraftClient.ChatBots
{
if (Settings.AutoRelog_Enabled)
{
- AutoRelog bot = new AutoRelog(Settings.AutoRelog_Delay_Min, Settings.AutoRelog_Delay_Max, Settings.AutoRelog_Retries);
+ AutoRelog bot = new(Settings.AutoRelog_Delay_Min, Settings.AutoRelog_Delay_Max, Settings.AutoRelog_Retries);
bot.Initialize();
return bot.OnDisconnect(reason, message);
}
diff --git a/MinecraftClient/ChatBots/AutoRespond.cs b/MinecraftClient/ChatBots/AutoRespond.cs
index 7d17625f..2b0738b5 100644
--- a/MinecraftClient/ChatBots/AutoRespond.cs
+++ b/MinecraftClient/ChatBots/AutoRespond.cs
@@ -1,6 +1,6 @@
using System;
-using System.IO;
using System.Collections.Generic;
+using System.IO;
using System.Text;
using System.Text.RegularExpressions;
@@ -11,9 +11,9 @@ namespace MinecraftClient.ChatBots
///
class AutoRespond : ChatBot
{
- private string matchesFile;
- private bool matchColors;
- private List respondRules;
+ private readonly string matchesFile;
+ private readonly bool matchColors;
+ private List? respondRules;
private enum MessageType { Public, Private, Other };
///
@@ -31,13 +31,13 @@ namespace MinecraftClient.ChatBots
///
private class RespondRule
{
- private Regex regex;
- private string match;
- private string actionPublic;
- private string actionPrivate;
- private string actionOther;
- private bool ownersOnly;
- private TimeSpan cooldown;
+ private readonly Regex? regex;
+ private readonly string? match;
+ private readonly string? actionPublic;
+ private readonly string? actionPrivate;
+ private readonly string? actionOther;
+ private readonly bool ownersOnly;
+ private readonly TimeSpan cooldown;
private DateTime cooldownExpiration;
///
@@ -49,16 +49,16 @@ namespace MinecraftClient.ChatBots
/// Internal command to run for any other messages
/// Only match messages from bot owners
/// Minimal cooldown between two matches
- public RespondRule(Regex regex, string actionPublic, string actionPrivate, string actionOther, bool ownersOnly, TimeSpan cooldown)
+ public RespondRule(Regex regex, string? actionPublic, string? actionPrivate, string? actionOther, bool ownersOnly, TimeSpan cooldown)
{
this.regex = regex;
- this.match = null;
+ match = null;
this.actionPublic = actionPublic;
this.actionPrivate = actionPrivate;
this.actionOther = actionOther;
this.ownersOnly = ownersOnly;
this.cooldown = cooldown;
- this.cooldownExpiration = DateTime.MinValue;
+ cooldownExpiration = DateTime.MinValue;
}
///
@@ -69,16 +69,16 @@ namespace MinecraftClient.ChatBots
/// Internal command to run for private messages
/// Only match messages from bot owners
/// Minimal cooldown between two matches
- public RespondRule(string match, string actionPublic, string actionPrivate, string actionOther, bool ownersOnly, TimeSpan cooldown)
+ public RespondRule(string? match, string? actionPublic, string? actionPrivate, string? actionOther, bool ownersOnly, TimeSpan cooldown)
{
- this.regex = null;
+ regex = null;
this.match = match;
this.actionPublic = actionPublic;
this.actionPrivate = actionPrivate;
this.actionOther = actionOther;
this.ownersOnly = ownersOnly;
this.cooldown = cooldown;
- this.cooldownExpiration = DateTime.MinValue;
+ cooldownExpiration = DateTime.MinValue;
}
///
@@ -89,12 +89,12 @@ namespace MinecraftClient.ChatBots
/// Type of the message public/private message, or other message
/// Dictionary to populate with match variables in case of Regex match
/// Internal command to run as a response to this user, or null if no match has been detected
- public string Match(string username, string message, MessageType msgType, Dictionary localVars)
+ public string? Match(string username, string message, MessageType msgType, Dictionary localVars)
{
if (DateTime.Now < cooldownExpiration)
return null;
- string toSend = null;
+ string? toSend = null;
if (ownersOnly && (String.IsNullOrEmpty(username) || !Settings.Bots_Owners.Contains(username.ToLower())))
return null;
@@ -166,11 +166,11 @@ namespace MinecraftClient.ChatBots
{
if (File.Exists(matchesFile))
{
- Regex matchRegex = null;
- string matchString = null;
- string matchAction = null;
- string matchActionPrivate = null;
- string matchActionOther = null;
+ Regex? matchRegex = null;
+ string? matchString = null;
+ string? matchAction = null;
+ string? matchActionPrivate = null;
+ string? matchActionOther = null;
bool ownersOnly = false;
TimeSpan cooldown = TimeSpan.Zero;
respondRules = new List();
@@ -182,9 +182,9 @@ namespace MinecraftClient.ChatBots
string line = lineRAW.Split('#')[0].Trim();
if (line.Length > 0)
{
- if (line[0] == '[' && line[line.Length - 1] == ']')
+ if (line[0] == '[' && line[^1] == ']')
{
- switch (line.Substring(1, line.Length - 2).ToLower())
+ switch (line[1..^1].ToLower())
{
case "match":
CheckAddMatch(matchRegex, matchString, matchAction, matchActionPrivate, matchActionOther, ownersOnly, cooldown);
@@ -203,7 +203,7 @@ namespace MinecraftClient.ChatBots
string argName = line.Split('=')[0];
if (line.Length > (argName.Length + 1))
{
- string argValue = line.Substring(argName.Length + 1);
+ string argValue = line[(argName.Length + 1)..];
switch (argName.ToLower())
{
case "regex": matchRegex = new Regex(argValue); break;
@@ -236,7 +236,7 @@ namespace MinecraftClient.ChatBots
/// Action if the matching message is private
/// Only match messages from bot owners
/// Minimal cooldown between two matches
- private void CheckAddMatch(Regex matchRegex, string matchString, string matchAction, string matchActionPrivate, string matchActionOther, bool ownersOnly, TimeSpan cooldown)
+ private void CheckAddMatch(Regex? matchRegex, string? matchString, string? matchAction, string? matchActionPrivate, string? matchActionOther, bool ownersOnly, TimeSpan cooldown)
{
if (matchRegex != null || matchString != null || matchAction != null || matchActionPrivate != null || matchActionOther != null || ownersOnly || cooldown != TimeSpan.Zero)
{
@@ -248,7 +248,7 @@ namespace MinecraftClient.ChatBots
{
if (matchRegex != null || matchString != null)
{
- respondRules.Add(rule);
+ respondRules!.Add(rule);
LogDebugToConsoleTranslated("bot.autoRespond.loaded_match", rule);
}
else LogDebugToConsoleTranslated("bot.autoRespond.no_trigger", rule);
@@ -264,7 +264,7 @@ namespace MinecraftClient.ChatBots
public override void GetText(string text)
{
//Remove colour codes
- if (!this.matchColors)
+ if (!matchColors)
text = GetVerbatim(text);
//Get Message type
@@ -279,13 +279,13 @@ namespace MinecraftClient.ChatBots
//Do not process messages sent by the bot itself
if (msgType == MessageType.Other || sender != Settings.Username)
{
- foreach (RespondRule rule in respondRules)
+ foreach (RespondRule rule in respondRules!)
{
- Dictionary localVars = new Dictionary();
- string toPerform = rule.Match(sender, message, msgType, localVars);
+ Dictionary localVars = new();
+ string? toPerform = rule.Match(sender, message, msgType, localVars);
if (!String.IsNullOrEmpty(toPerform))
{
- string response = null;
+ string? response = null;
LogToConsoleTranslated("bot.autoRespond.match_run", toPerform);
PerformInternalCommand(toPerform, ref response, localVars);
if (!String.IsNullOrEmpty(response))
diff --git a/MinecraftClient/ChatBots/BotsCommand.cs b/MinecraftClient/ChatBots/BotsCommand.cs
index 309e3e0c..72913de3 100644
--- a/MinecraftClient/ChatBots/BotsCommand.cs
+++ b/MinecraftClient/ChatBots/BotsCommand.cs
@@ -1,7 +1,5 @@
-using MinecraftClient.Mapping;
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Text;
namespace MinecraftClient.Commands
@@ -12,11 +10,11 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "bots [list|unload ]"; } }
public override string CmdDesc { get { return "cmd.bots.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- string[] args = getArgs(command);
+ string[] args = GetArgs(command);
if (args.Length == 1)
{
diff --git a/MinecraftClient/ChatBots/ChatLog.cs b/MinecraftClient/ChatBots/ChatLog.cs
index 1eaffb08..cc2e81b5 100644
--- a/MinecraftClient/ChatBots/ChatLog.cs
+++ b/MinecraftClient/ChatBots/ChatLog.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using System.IO;
namespace MinecraftClient.ChatBots
@@ -13,13 +10,13 @@ namespace MinecraftClient.ChatBots
public class ChatLog : ChatBot
{
public enum MessageFilter { AllText, AllMessages, OnlyChat, OnlyWhispers, OnlyInternalCommands };
- private bool dateandtime;
- private bool saveOther = true;
- private bool saveChat = true;
- private bool savePrivate = true;
- private bool saveInternal = true;
- private string logfile;
- private object logfileLock = new object();
+ private readonly bool dateandtime;
+ private readonly bool saveOther = true;
+ private readonly bool saveChat = true;
+ private readonly bool savePrivate = true;
+ private readonly bool saveInternal = true;
+ private readonly string logfile;
+ private readonly object logfileLock = new();
///
/// This bot saves the messages received in the specified file, with some filters and date/time tagging.
@@ -70,15 +67,17 @@ namespace MinecraftClient.ChatBots
public static MessageFilter str2filter(string filtername)
{
- switch (Settings.ToLowerIfNeed(filtername))
+ return Settings.ToLowerIfNeed(filtername) switch
{
- case "all": return MessageFilter.AllText;
- case "messages": return MessageFilter.AllMessages;
- case "chat": return MessageFilter.OnlyChat;
- case "private": return MessageFilter.OnlyWhispers;
- case "internal": return MessageFilter.OnlyInternalCommands;
- default: return MessageFilter.AllText;
- }
+#pragma warning disable format // @formatter:off
+ "all" => MessageFilter.AllText,
+ "messages" => MessageFilter.AllMessages,
+ "chat" => MessageFilter.OnlyChat,
+ "private" => MessageFilter.OnlyWhispers,
+ "internal" => MessageFilter.OnlyInternalCommands,
+ _ => MessageFilter.AllText,
+#pragma warning restore format // @formatter:on
+ };
}
public override void GetText(string text)
@@ -89,37 +88,37 @@ namespace MinecraftClient.ChatBots
if (saveChat && IsChatMessage(text, ref message, ref sender))
{
- save("Chat " + sender + ": " + message);
+ Save("Chat " + sender + ": " + message);
}
else if (savePrivate && IsPrivateMessage(text, ref message, ref sender))
{
- save("Private " + sender + ": " + message);
+ Save("Private " + sender + ": " + message);
}
else if (saveOther)
{
- save("Other: " + text);
+ Save("Other: " + text);
}
}
- public override void OnInternalCommand(string commandName,string commandParams, string result)
+ public override void OnInternalCommand(string commandName, string commandParams, string result)
{
if (saveInternal)
{
- save(string.Format("Internal {0}({1}): {2}", commandName, commandParams, result));
+ Save(string.Format("Internal {0}({1}): {2}", commandName, commandParams, result));
}
}
- private void save(string tosave)
+ private void Save(string tosave)
{
if (dateandtime)
tosave = GetTimestamp() + ' ' + tosave;
lock (logfileLock)
{
- string directory = Path.GetDirectoryName(logfile);
+ string? directory = Path.GetDirectoryName(logfile);
if (!String.IsNullOrEmpty(directory) && !Directory.Exists(directory))
Directory.CreateDirectory(directory);
- FileStream stream = new FileStream(logfile, FileMode.OpenOrCreate);
- StreamWriter writer = new StreamWriter(stream);
+ FileStream stream = new(logfile, FileMode.OpenOrCreate);
+ StreamWriter writer = new(stream);
stream.Seek(0, SeekOrigin.End);
writer.WriteLine(tosave);
writer.Dispose();
diff --git a/MinecraftClient/ChatBots/FollowPlayer.cs b/MinecraftClient/ChatBots/FollowPlayer.cs
index 92af0b9c..e03eb253 100644
--- a/MinecraftClient/ChatBots/FollowPlayer.cs
+++ b/MinecraftClient/ChatBots/FollowPlayer.cs
@@ -8,8 +8,8 @@ namespace MinecraftClient.ChatBots
{
private string? _playerToFollow = null;
private int _updateCounter = 0;
- private int _updateLimit;
- private int _stopAtDistance;
+ private readonly int _updateLimit;
+ private readonly int _stopAtDistance;
private bool _unsafeEnabled = false;
public FollowPlayer(int updateLimit = 15, int stopAtDistance = 3)
@@ -112,7 +112,7 @@ namespace MinecraftClient.ChatBots
return;
// Stop at specified distance from plater (prevents pushing player around)
- double distance = Distance(entity.Location, GetCurrentLocation());
+ double distance = entity.Location.Distance(GetCurrentLocation());
if (distance < _stopAtDistance)
return;
@@ -154,14 +154,6 @@ namespace MinecraftClient.ChatBots
}
}
- private double Distance(Location location1, Location location2)
- {
- return Math.Sqrt(
- ((location1.X - location2.X) * (location1.X - location2.X)) +
- ((location1.Y - location2.Y) * (location1.Y - location2.Y)) +
- ((location1.Z - location2.Z) * (location1.Z - location2.Z)));
- }
-
private bool CanMoveThere(Location location)
{
ChunkColumn? chunkColumn = GetWorld().GetChunkColumn(location);
diff --git a/MinecraftClient/ChatBots/HangmanGame.cs b/MinecraftClient/ChatBots/HangmanGame.cs
index 49ec5ea1..c41324af 100644
--- a/MinecraftClient/ChatBots/HangmanGame.cs
+++ b/MinecraftClient/ChatBots/HangmanGame.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Text;
namespace MinecraftClient.ChatBots
@@ -12,14 +10,14 @@ namespace MinecraftClient.ChatBots
public class HangmanGame : ChatBot
{
private int vie = 0;
- private int vie_param = 10;
+ private readonly int vie_param = 10;
private int compteur = 0;
- private int compteur_param = 3000; //5 minutes
+ private readonly int compteur_param = 3000; //5 minutes
private bool running = false;
private bool[] discovered;
private string word = "";
private string letters = "";
- private bool English;
+ private readonly bool English;
///
/// Le jeu du Pendu / Hangman Game
@@ -29,6 +27,7 @@ namespace MinecraftClient.ChatBots
public HangmanGame(bool english)
{
English = english;
+ discovered = Array.Empty();
}
public override void Update()
@@ -61,7 +60,7 @@ namespace MinecraftClient.ChatBots
switch (message)
{
case "start":
- start();
+ Start();
break;
case "stop":
running = false;
@@ -108,11 +107,11 @@ namespace MinecraftClient.ChatBots
if (running)
{
- SendText(English ? ("Mysterious word: " + word_cached + " (lives : " + vie + ")")
- : ("Mot mystère : " + word_cached + " (vie : " + vie + ")"));
+ SendText(English ? ("Mysterious word: " + WordCached + " (lives : " + vie + ")")
+ : ("Mot mystère : " + WordCached + " (vie : " + vie + ")"));
}
- if (winner)
+ if (Winner)
{
SendText(English ? ("Congrats, " + username + '!') : ("Félicitations, " + username + " !"));
running = false;
@@ -124,22 +123,22 @@ namespace MinecraftClient.ChatBots
}
}
- private void start()
+ private void Start()
{
vie = vie_param;
running = true;
letters = "";
- word = chooseword();
+ word = Chooseword();
compteur = compteur_param;
discovered = new bool[word.Length];
SendText(English ? "Hangman v1.0 - By ORelio" : "Pendu v1.0 - Par ORelio");
- SendText(English ? ("Mysterious word: " + word_cached + " (lives : " + vie + ")")
- : ("Mot mystère : " + word_cached + " (vie : " + vie + ")"));
+ SendText(English ? ("Mysterious word: " + WordCached + " (lives : " + vie + ")")
+ : ("Mot mystère : " + WordCached + " (vie : " + vie + ")"));
SendText(English ? ("Try some letters ... :)") : ("Proposez une lettre ... :)"));
}
- private string chooseword()
+ private string Chooseword()
{
if (System.IO.File.Exists(English ? Settings.Hangman_FileWords_EN : Settings.Hangman_FileWords_FR))
{
@@ -153,7 +152,7 @@ namespace MinecraftClient.ChatBots
}
}
- private string word_cached
+ private string WordCached
{
get
{
@@ -170,7 +169,7 @@ namespace MinecraftClient.ChatBots
}
}
- private bool winner
+ private bool Winner
{
get
{
diff --git a/MinecraftClient/ChatBots/Mailer.cs b/MinecraftClient/ChatBots/Mailer.cs
index f22b82ba..8752d1fd 100644
--- a/MinecraftClient/ChatBots/Mailer.cs
+++ b/MinecraftClient/ChatBots/Mailer.cs
@@ -1,8 +1,8 @@
using System;
+using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
-using System.Collections.Generic;
namespace MinecraftClient.ChatBots
{
@@ -23,7 +23,7 @@ namespace MinecraftClient.ChatBots
/// Ignore list
public static IgnoreList FromFile(string filePath)
{
- IgnoreList ignoreList = new IgnoreList();
+ IgnoreList ignoreList = new();
foreach (string line in FileMonitor.ReadAllLinesWithRetries(filePath))
{
if (!line.StartsWith("#"))
@@ -42,7 +42,7 @@ namespace MinecraftClient.ChatBots
/// Path to destination file
public void SaveToFile(string filePath)
{
- List lines = new List();
+ List lines = new();
lines.Add("#Ignored Players");
foreach (string player in this)
lines.Add(player);
@@ -62,7 +62,7 @@ namespace MinecraftClient.ChatBots
/// Mail database
public static MailDatabase FromFile(string filePath)
{
- MailDatabase database = new MailDatabase();
+ MailDatabase database = new();
Dictionary> iniFileDict = INIFile.ParseFile(FileMonitor.ReadAllLinesWithRetries(filePath));
foreach (KeyValuePair> iniSection in iniFileDict)
{
@@ -83,17 +83,21 @@ namespace MinecraftClient.ChatBots
/// Path to destination file
public void SaveToFile(string filePath)
{
- Dictionary> iniFileDict = new Dictionary>();
+ Dictionary> iniFileDict = new();
int mailCount = 0;
foreach (Mail mail in this)
{
mailCount++;
- Dictionary iniSection = new Dictionary();
- iniSection["sender"] = mail.Sender;
- iniSection["recipient"] = mail.Recipient;
- iniSection["content"] = mail.Content;
- iniSection["timestamp"] = mail.DateSent.ToString();
- iniSection["anonymous"] = mail.Anonymous.ToString();
+ Dictionary iniSection = new()
+ {
+#pragma warning disable format // @formatter:off
+ ["sender"] = mail.Sender,
+ ["recipient"] = mail.Recipient,
+ ["content"] = mail.Content,
+ ["timestamp"] = mail.DateSent.ToString(),
+ ["anonymous"] = mail.Anonymous.ToString()
+#pragma warning restore format // @formatter:on
+ };
iniFileDict["mail" + mailCount] = iniSection;
}
FileMonitor.WriteAllLinesWithRetries(filePath, INIFile.Generate(iniFileDict, "Mail Database"));
@@ -105,24 +109,24 @@ namespace MinecraftClient.ChatBots
///
private class Mail
{
- private string sender;
- private string senderLower;
- private string recipient;
- private string recipientLower;
- private string message;
- private DateTime datesent;
+ private readonly string sender;
+ private readonly string senderLower;
+ private readonly string recipient;
+ private readonly string recipientLower;
+ private readonly string message;
+ private readonly DateTime datesent;
private bool delivered;
- private bool anonymous;
+ private readonly bool anonymous;
public Mail(string sender, string recipient, string message, bool anonymous, DateTime datesent)
{
this.sender = sender;
- this.senderLower = sender.ToLower();
+ senderLower = sender.ToLower();
this.recipient = recipient;
- this.recipientLower = recipient.ToLower();
+ recipientLower = recipient.ToLower();
this.message = message;
this.datesent = datesent;
- this.delivered = false;
+ delivered = false;
this.anonymous = anonymous;
}
@@ -132,9 +136,9 @@ namespace MinecraftClient.ChatBots
public string RecipientLowercase { get { return recipientLower; } }
public string Content { get { return message; } }
public DateTime DateSent { get { return datesent; } }
- public bool Delivered { get { return delivered; } }
+ public bool Delivered => delivered;
public bool Anonymous { get { return anonymous; } }
- public void setDelivered() { delivered = true; }
+ public void SetDelivered() { delivered = true; }
public override string ToString()
{
@@ -145,11 +149,11 @@ namespace MinecraftClient.ChatBots
// Internal variables
private int maxMessageLength = 0;
private DateTime nextMailSend = DateTime.Now;
- private MailDatabase mailDatabase = new MailDatabase();
- private IgnoreList ignoreList = new IgnoreList();
- private FileMonitor mailDbFileMonitor;
- private FileMonitor ignoreListFileMonitor;
- private object readWriteLock = new object();
+ private MailDatabase mailDatabase = new();
+ private IgnoreList ignoreList = new();
+ private FileMonitor? mailDbFileMonitor;
+ private FileMonitor? ignoreListFileMonitor;
+ private readonly object readWriteLock = new();
///
/// Initialization of the Mailer bot
@@ -207,8 +211,8 @@ namespace MinecraftClient.ChatBots
}
//Initialize file monitors. In case the bot needs to unload for some reason in the future, do not forget to .Dispose() them
- mailDbFileMonitor = new FileMonitor(Path.GetDirectoryName(Settings.Mailer_DatabaseFile), Path.GetFileName(Settings.Mailer_DatabaseFile), FileMonitorCallback);
- ignoreListFileMonitor = new FileMonitor(Path.GetDirectoryName(Settings.Mailer_IgnoreListFile), Path.GetFileName(Settings.Mailer_IgnoreListFile), FileMonitorCallback);
+ mailDbFileMonitor = new FileMonitor(Path.GetDirectoryName(Settings.Mailer_DatabaseFile)!, Path.GetFileName(Settings.Mailer_DatabaseFile), FileMonitorCallback);
+ ignoreListFileMonitor = new FileMonitor(Path.GetDirectoryName(Settings.Mailer_IgnoreListFile)!, Path.GetFileName(Settings.Mailer_IgnoreListFile), FileMonitorCallback);
RegisterChatBotCommand("mailer", Translations.Get("bot.mailer.cmd"), "mailer ", ProcessInternalCommand);
}
@@ -246,7 +250,7 @@ namespace MinecraftClient.ChatBots
&& mailDatabase.Count < Settings.Mailer_MaxDatabaseSize
&& mailDatabase.Where(mail => mail.SenderLowercase == usernameLower).Count() < Settings.Mailer_MaxMailsPerPlayer)
{
- Queue args = new Queue(Command.getArgs(message));
+ Queue args = new(Command.GetArgs(message));
if (args.Count >= 2)
{
bool anonymous = (command == "tellonym");
@@ -257,7 +261,7 @@ namespace MinecraftClient.ChatBots
{
if (message.Length <= maxMessageLength)
{
- Mail mail = new Mail(username, recipient, message, anonymous, DateTime.Now);
+ Mail mail = new(username, recipient, message, anonymous, DateTime.Now);
LogToConsoleTranslated("bot.mailer.saving", mail.ToString());
lock (readWriteLock)
{
@@ -291,12 +295,12 @@ namespace MinecraftClient.ChatBots
LogDebugToConsoleTranslated("bot.mailer.process_mails", DateTime.Now);
// Process at most 3 mails at a time to avoid spamming. Other mails will be processed on next mail send
- HashSet onlinePlayersLowercase = new HashSet(GetOnlinePlayers().Select(name => name.ToLower()));
+ HashSet onlinePlayersLowercase = new(GetOnlinePlayers().Select(name => name.ToLower()));
foreach (Mail mail in mailDatabase.Where(mail => !mail.Delivered && onlinePlayersLowercase.Contains(mail.RecipientLowercase)).Take(3))
{
string sender = mail.Anonymous ? "Anonymous" : mail.Sender;
SendPrivateMessage(mail.Recipient, sender + " mailed: " + mail.Content);
- mail.setDelivered();
+ mail.SetDelivered();
LogDebugToConsoleTranslated("bot.mailer.delivered", mail.ToString());
}
@@ -336,7 +340,7 @@ namespace MinecraftClient.ChatBots
switch (commandName)
{
case "getmails": // Sorry, I (ReinforceZwei) replaced "=" to "-" because it would affect the parsing of translation file (key=value)
- return Translations.Get("bot.mailer.cmd.getmails", string.Join("\n", mailDatabase));
+ return Translations.Get("bot.mailer.cmd.getmails", string.Join("\n", mailDatabase));
case "getignored":
return Translations.Get("bot.mailer.cmd.getignored", string.Join("\n", ignoreList));
diff --git a/MinecraftClient/ChatBots/Map.cs b/MinecraftClient/ChatBots/Map.cs
index a6793e1f..d84a1117 100644
--- a/MinecraftClient/ChatBots/Map.cs
+++ b/MinecraftClient/ChatBots/Map.cs
@@ -1,17 +1,17 @@
using System;
using System.Collections.Generic;
+using System.Drawing;
using System.IO;
using MinecraftClient.Mapping;
-using System.Drawing;
using MinecraftClient.Protocol.Handlers;
namespace MinecraftClient.ChatBots
{
class Map : ChatBot
{
- private string baseDirectory = @"Rendered_Maps";
+ private readonly string baseDirectory = @"Rendered_Maps";
- private Dictionary cachedMaps = new();
+ private readonly Dictionary cachedMaps = new();
private bool shouldResize = true;
private int resizeTo = 256;
private bool autoRenderOnUpdate = true;
@@ -40,7 +40,7 @@ namespace MinecraftClient.ChatBots
{
if (deleteAllOnExit)
{
- DirectoryInfo di = new DirectoryInfo(baseDirectory);
+ DirectoryInfo di = new(baseDirectory);
FileInfo[] files = di.GetFiles();
foreach (FileInfo file in files)
@@ -101,19 +101,20 @@ namespace MinecraftClient.ChatBots
if (columnsUpdated == 0 && cachedMaps.ContainsKey(mapid))
return;
- McMap map = new McMap();
-
- map.MapId = mapid;
- map.Scale = scale;
- map.TrackingPosition = trackingPosition;
- map.Locked = locked;
- map.MapIcons = icons;
- map.Width = rowsUpdated;
- map.Height = columnsUpdated;
- map.X = mapCoulmnX;
- map.Z = mapRowZ;
- map.Colors = colors;
- map.LastUpdated = DateTime.Now;
+ McMap map = new()
+ {
+ MapId = mapid,
+ Scale = scale,
+ TrackingPosition = trackingPosition,
+ Locked = locked,
+ MapIcons = icons,
+ Width = rowsUpdated,
+ Height = columnsUpdated,
+ X = mapCoulmnX,
+ Z = mapRowZ,
+ Colors = colors,
+ LastUpdated = DateTime.Now
+ };
if (!cachedMaps.ContainsKey(mapid))
{
@@ -139,7 +140,7 @@ namespace MinecraftClient.ChatBots
if (File.Exists(fileName))
File.Delete(fileName);
- Bitmap image = new Bitmap(map.Width, map.Height);
+ Bitmap image = new(map.Width, map.Height);
for (int x = 0; x < map.Width; ++x)
{
@@ -168,7 +169,7 @@ namespace MinecraftClient.ChatBots
}
private Bitmap ResizeBitmap(Bitmap sourceBMP, int width, int height)
{
- Bitmap result = new Bitmap(width, height);
+ Bitmap result = new(width, height);
using (Graphics g = Graphics.FromImage(result))
g.DrawImage(sourceBMP, 0, 0, width, height);
return result;
diff --git a/MinecraftClient/ChatBots/PlayerListLogger.cs b/MinecraftClient/ChatBots/PlayerListLogger.cs
index 0cf97194..b15d5f92 100644
--- a/MinecraftClient/ChatBots/PlayerListLogger.cs
+++ b/MinecraftClient/ChatBots/PlayerListLogger.cs
@@ -1,8 +1,6 @@
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Text;
-using static System.Net.Mime.MediaTypeNames;
namespace MinecraftClient.ChatBots
{
@@ -13,8 +11,8 @@ namespace MinecraftClient.ChatBots
public class PlayerListLogger : ChatBot
{
private int count;
- private int timeping;
- private string file;
+ private readonly int timeping;
+ private readonly string file;
///
/// This bot sends a /list command every X seconds and save the result.
@@ -35,24 +33,14 @@ namespace MinecraftClient.ChatBots
count++;
if (count == timeping)
{
- string[] playerList = GetOnlinePlayers();
-
- StringBuilder sb = new StringBuilder();
-
- for (int i = 0; i < playerList.Length; i++)
- {
- sb.Append(playerList[i]);
-
- // Do not add a comma after the last username
- if (i != playerList.Length - 1)
- sb.Append(", ");
- }
+ DateTime now = DateTime.Now;
LogDebugToConsole("Saving Player List");
- DateTime now = DateTime.Now;
- string TimeStamp = "[" + now.Year + '/' + now.Month + '/' + now.Day + ' ' + now.Hour + ':' + now.Minute + ']';
- System.IO.File.AppendAllText(file, TimeStamp + "\n" + sb.ToString() + "\n\n");
+ StringBuilder sb = new();
+ sb.AppendLine(string.Format("[{0}/{1}/{2} {3}:{4}]", now.Year, now.Month, now.Day, now.Hour, now.Minute));
+ sb.AppendLine(string.Join(", ", GetOnlinePlayers())).AppendLine();
+ System.IO.File.AppendAllText(file, sb.ToString());
count = 0;
}
diff --git a/MinecraftClient/ChatBots/Reload.cs b/MinecraftClient/ChatBots/Reload.cs
index 83a92a29..f4063db7 100644
--- a/MinecraftClient/ChatBots/Reload.cs
+++ b/MinecraftClient/ChatBots/Reload.cs
@@ -1,8 +1,4 @@
-using MinecraftClient.Mapping;
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace MinecraftClient.Commands
{
@@ -12,7 +8,7 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "reload"; } }
public override string CmdDesc { get { return "cmd.reload.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
handler.Log.Info(Translations.TryGet("cmd.reload.started"));
handler.ReloadSettings();
diff --git a/MinecraftClient/ChatBots/RemoteControl.cs b/MinecraftClient/ChatBots/RemoteControl.cs
index 988640f4..3baae1a1 100644
--- a/MinecraftClient/ChatBots/RemoteControl.cs
+++ b/MinecraftClient/ChatBots/RemoteControl.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace MinecraftClient.ChatBots
{
@@ -17,7 +14,7 @@ namespace MinecraftClient.ChatBots
string command = "", sender = "";
if (IsPrivateMessage(text, ref command, ref sender) && Settings.Bots_Owners.Contains(sender.ToLower().Trim()))
{
- string response = "";
+ string? response = "";
PerformInternalCommand(command, ref response);
response = GetVerbatim(response);
foreach (char disallowedChar in McClient.GetDisallowedChatCharacters())
diff --git a/MinecraftClient/ChatBots/ReplayCapture.cs b/MinecraftClient/ChatBots/ReplayCapture.cs
index 0685ba25..25ea1557 100644
--- a/MinecraftClient/ChatBots/ReplayCapture.cs
+++ b/MinecraftClient/ChatBots/ReplayCapture.cs
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using MinecraftClient.Protocol;
namespace MinecraftClient.ChatBots
@@ -11,15 +9,16 @@ namespace MinecraftClient.ChatBots
///
public class ReplayCapture : ChatBot
{
- private ReplayHandler replay;
- private int backupInterval = 3000; // Unit: second * 10
+ private ReplayHandler? replay;
+ private readonly int backupInterval = 3000; // Unit: second * 10
private int backupCounter = -1;
public ReplayCapture(int backupInterval)
{
if (backupInterval != -1)
this.backupInterval = backupInterval * 10;
- else this.backupInterval = -1;
+ else
+ this.backupInterval = -1;
}
public override void Initialize()
@@ -34,12 +33,12 @@ namespace MinecraftClient.ChatBots
public override void OnNetworkPacket(int packetID, List packetData, bool isLogin, bool isInbound)
{
- replay.AddPacket(packetID, packetData, isLogin, isInbound);
+ replay!.AddPacket(packetID, packetData, isLogin, isInbound);
}
public override void Update()
{
- if (backupInterval > 0 && replay.RecordRunning)
+ if (backupInterval > 0 && replay!.RecordRunning)
{
if (backupCounter <= 0)
{
@@ -52,7 +51,7 @@ namespace MinecraftClient.ChatBots
public override bool OnDisconnect(DisconnectReason reason, string message)
{
- replay.OnShutDown();
+ replay!.OnShutDown();
return base.OnDisconnect(reason, message);
}
@@ -60,7 +59,7 @@ namespace MinecraftClient.ChatBots
{
try
{
- if (replay.RecordRunning)
+ if (replay!.RecordRunning)
{
if (args.Length > 0)
{
diff --git a/MinecraftClient/ChatBots/Script.cs b/MinecraftClient/ChatBots/Script.cs
index 204d32be..84ee6483 100644
--- a/MinecraftClient/ChatBots/Script.cs
+++ b/MinecraftClient/ChatBots/Script.cs
@@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using Microsoft.CSharp;
-using System.CodeDom.Compiler;
-using System.Reflection;
using System.Diagnostics;
using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Threading;
namespace MinecraftClient.ChatBots
{
@@ -17,32 +14,32 @@ namespace MinecraftClient.ChatBots
public class Script : ChatBot
{
- private string file;
- private string[] lines = new string[0];
- private string[] args = new string[0];
+ private string? file;
+ private string[] lines = Array.Empty();
+ private string[] args = Array.Empty();
private int sleepticks = 10;
private int nextline = 0;
- private string owner;
+ private readonly string? owner;
private bool csharp;
- private Thread thread;
- private Dictionary localVars;
+ private Thread? thread;
+ private readonly Dictionary? localVars;
public Script(string filename)
{
ParseArguments(filename);
}
- public Script(string filename, string ownername, Dictionary localVars)
+ public Script(string filename, string? ownername, Dictionary? localVars)
: this(filename)
{
- this.owner = ownername;
+ owner = ownername;
this.localVars = localVars;
}
private void ParseArguments(string argstr)
{
- List args = new List();
- StringBuilder str = new StringBuilder();
+ List args = new();
+ StringBuilder str = new();
bool escape = false;
bool quotes = false;
@@ -115,9 +112,9 @@ namespace MinecraftClient.ChatBots
string caller = "Script";
try
{
- StackFrame frame = new StackFrame(1);
- MethodBase method = frame.GetMethod();
- Type type = method.DeclaringType;
+ StackFrame frame = new(1);
+ MethodBase method = frame.GetMethod()!;
+ Type type = method.DeclaringType!;
caller = type.Name;
}
catch { }
@@ -130,7 +127,7 @@ namespace MinecraftClient.ChatBots
public override void Initialize()
{
//Load the given file from the startup parameters
- if (LookForScript(ref file))
+ if (LookForScript(ref file!))
{
lines = System.IO.File.ReadAllLines(file, Encoding.UTF8);
csharp = file.EndsWith(".cs");
@@ -145,7 +142,7 @@ namespace MinecraftClient.ChatBots
if (!String.IsNullOrEmpty(owner))
SendPrivateMessage(owner, Translations.Get("bot.script.file_not_found", file));
-
+
UnloadBot(); //No need to keep the bot active
}
}
@@ -171,8 +168,10 @@ namespace MinecraftClient.ChatBots
SendPrivateMessage(owner, errorMessage);
LogToConsole(e.InnerException);
}
- });
- thread.Name = "MCC Script - " + file;
+ })
+ {
+ Name = "MCC Script - " + file
+ };
thread.Start();
}
@@ -204,7 +203,7 @@ namespace MinecraftClient.ChatBots
int ticks = 10;
try
{
- ticks = Convert.ToInt32(instruction_line.Substring(5, instruction_line.Length - 5));
+ ticks = Convert.ToInt32(instruction_line[5..]);
}
catch { }
sleepticks = ticks;
diff --git a/MinecraftClient/ChatBots/ScriptScheduler.cs b/MinecraftClient/ChatBots/ScriptScheduler.cs
index 089d7946..b30bb468 100644
--- a/MinecraftClient/ChatBots/ScriptScheduler.cs
+++ b/MinecraftClient/ChatBots/ScriptScheduler.cs
@@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using System.Globalization;
+using System.Text;
namespace MinecraftClient.ChatBots
{
@@ -14,7 +13,7 @@ namespace MinecraftClient.ChatBots
{
private class TaskDesc
{
- public string action = null;
+ public string? action = null;
public bool triggerOnFirstLogin = false;
public bool triggerOnLogin = false;
public bool triggerOnTime = false;
@@ -22,17 +21,17 @@ namespace MinecraftClient.ChatBots
public int triggerOnInterval_Interval = 0;
public int triggerOnInterval_Interval_Max = 0;
public int triggerOnInterval_Interval_Countdown = 0;
- public List triggerOnTime_Times = new List();
+ public List triggerOnTime_Times = new();
public bool triggerOnTime_alreadyTriggered = false;
}
private static bool firstlogin_done = false;
- private string tasksfile;
+ private readonly string tasksfile;
private bool serverlogin_done;
- private List tasks = new List();
+ private readonly List tasks = new();
private int verifytasks_timeleft = 10;
- private int verifytasks_delay = 10;
+ private readonly int verifytasks_delay = 10;
public ScriptScheduler(string tasksfile)
{
@@ -46,19 +45,19 @@ namespace MinecraftClient.ChatBots
if (System.IO.File.Exists(tasksfile))
{
LogDebugToConsoleTranslated("bot.scriptScheduler.loading", System.IO.Path.GetFullPath(tasksfile));
- TaskDesc current_task = null;
- String[] lines = System.IO.File.ReadAllLines(tasksfile, Encoding.UTF8);
+ TaskDesc? current_task = null;
+ string[] lines = System.IO.File.ReadAllLines(tasksfile, Encoding.UTF8);
foreach (string lineRAW in lines)
{
string line = lineRAW.Split('#')[0].Trim();
if (line.Length > 0)
{
- if (line[0] == '[' && line[line.Length - 1] == ']')
+ if (line[0] == '[' && line[^1] == ']')
{
- switch (line.Substring(1, line.Length - 2).ToLower())
+ switch (line[1..^1].ToLower())
{
case "task":
- checkAddTask(current_task);
+ CheckAddTask(current_task);
current_task = new TaskDesc(); //Create a blank task
break;
}
@@ -68,7 +67,7 @@ namespace MinecraftClient.ChatBots
string argName = line.Split('=')[0];
if (line.Length > (argName.Length + 1))
{
- string argValue = line.Substring(argName.Length + 1);
+ string argValue = line[(argName.Length + 1)..];
switch (argName.ToLower())
{
case "triggeronfirstlogin": current_task.triggerOnFirstLogin = Settings.str2bool(argValue); break;
@@ -77,21 +76,26 @@ namespace MinecraftClient.ChatBots
case "triggeroninterval": current_task.triggerOnInterval = Settings.str2bool(argValue); break;
case "timevalue": try { current_task.triggerOnTime_Times.Add(DateTime.ParseExact(argValue, "HH:mm", CultureInfo.InvariantCulture)); } catch { } break;
case "timeinterval":
- int interval = 1;
+ int interval;
int intervalMax = 0;
- if (argValue.Contains("-"))
+ if (argValue.Contains('-'))
{
string[] parts = argValue.Split("-");
-
if (parts.Length == 2)
{
- int.TryParse(parts[0].Trim(), out interval);
- int.TryParse(parts[1].Trim(), out intervalMax);
+ interval = int.Parse(parts[0].Trim());
+ intervalMax = int.Parse(parts[1].Trim());
+ }
+ else
+ {
+ interval = 1;
}
- else interval = 1;
}
- else int.TryParse(argValue, out interval);
+ else
+ {
+ interval = int.Parse(argValue);
+ }
current_task.triggerOnInterval_Interval = interval;
current_task.triggerOnInterval_Interval_Max = intervalMax;
@@ -104,7 +108,7 @@ namespace MinecraftClient.ChatBots
}
}
}
- checkAddTask(current_task);
+ CheckAddTask(current_task);
}
else
{
@@ -113,7 +117,7 @@ namespace MinecraftClient.ChatBots
}
}
- private void checkAddTask(TaskDesc current_task)
+ private void CheckAddTask(TaskDesc? current_task)
{
//Check if we built a valid task before adding it
if (current_task != null)
@@ -166,7 +170,7 @@ namespace MinecraftClient.ChatBots
{
task.triggerOnTime_alreadyTriggered = true;
LogDebugToConsoleTranslated("bot.scriptScheduler.running_time", task.action);
- PerformInternalCommand(task.action);
+ PerformInternalCommand(task.action!);
}
}
}
@@ -186,7 +190,7 @@ namespace MinecraftClient.ChatBots
task.triggerOnInterval_Interval_Countdown = time;
LogDebugToConsoleTranslated("bot.scriptScheduler.running_inverval", task.action);
- PerformInternalCommand(task.action);
+ PerformInternalCommand(task.action!);
}
else task.triggerOnInterval_Interval_Countdown--;
}
@@ -199,7 +203,7 @@ namespace MinecraftClient.ChatBots
if (task.triggerOnLogin || (firstlogin_done == false && task.triggerOnFirstLogin))
{
LogDebugToConsoleTranslated("bot.scriptScheduler.running_login", task.action);
- PerformInternalCommand(task.action);
+ PerformInternalCommand(task.action!);
}
}
diff --git a/MinecraftClient/ChatBots/TestBot.cs b/MinecraftClient/ChatBots/TestBot.cs
index c531e85b..b9ac86a2 100644
--- a/MinecraftClient/ChatBots/TestBot.cs
+++ b/MinecraftClient/ChatBots/TestBot.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace MinecraftClient.ChatBots
+namespace MinecraftClient.ChatBots
{
///
/// Example of message receiving.
diff --git a/MinecraftClient/Command.cs b/MinecraftClient/Command.cs
index 62909f62..627542c6 100644
--- a/MinecraftClient/Command.cs
+++ b/MinecraftClient/Command.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Text;
namespace MinecraftClient
@@ -50,12 +49,12 @@ namespace MinecraftClient
/// Return a list of aliases for this command.
/// Override this method if you wish to put aliases to the command
///
- public virtual IEnumerable getCMDAliases() { return new string[0]; }
+ public virtual IEnumerable GetCMDAliases() { return Array.Empty(); }
///
/// Check if at least one argument has been passed to the command
///
- public static bool hasArg(string command)
+ public static bool HasArg(string command)
{
int first_space = command.IndexOf(' ');
return (first_space > 0 && first_space < command.Length - 1);
@@ -65,30 +64,25 @@ namespace MinecraftClient
/// Extract the argument string from the command
///
/// Argument or "" if no argument
- public static string getArg(string command)
+ public static string GetArg(string command)
{
- if (hasArg(command))
- {
- return command.Substring(command.IndexOf(' ') + 1);
- }
- else return "";
+ if (HasArg(command))
+ return command[(command.IndexOf(' ') + 1)..];
+ else
+ return string.Empty;
}
///
/// Extract the arguments as a string array from the command
///
/// Argument array or empty array if no arguments
- public static string[] getArgs(string command)
+ public static string[] GetArgs(string command)
{
- string[] args = getArg(command).Split(' ', StringSplitOptions.RemoveEmptyEntries);
- if (args.Length == 1 && args[0] == "")
- {
- return new string[] { };
- }
+ string[] args = GetArg(command).Split(' ', StringSplitOptions.RemoveEmptyEntries);
+ if (args.Length == 1 && args[0] == string.Empty)
+ return Array.Empty();
else
- {
return args;
- }
}
///
@@ -97,7 +91,7 @@ namespace MinecraftClient
///
/// Provided arguments as a string
/// All extracted arguments in a string list
- public static List parseCommandLine(string cmdLine)
+ public static List ParseCommandLine(string cmdLine)
{
var args = new List();
if (string.IsNullOrWhiteSpace(cmdLine)) return args;
@@ -107,7 +101,7 @@ namespace MinecraftClient
for (int i = 0; i < cmdLine.Length; i++)
{
- if ((cmdLine[i] == '"' && i > 0 && cmdLine[i-1] != '\\') || (cmdLine[i] == '"' && i == 0))
+ if ((cmdLine[i] == '"' && i > 0 && cmdLine[i - 1] != '\\') || (cmdLine[i] == '"' && i == 0))
{
if (inQuotedArg)
{
@@ -136,7 +130,7 @@ namespace MinecraftClient
{
if (cmdLine[i] == '\\' && cmdLine[i + 1] == '\"')
{
- currentArg.Append("\"");
+ currentArg.Append('"');
i += 1;
}
else
diff --git a/MinecraftClient/Commands/Animation.cs b/MinecraftClient/Commands/Animation.cs
index 463958f1..cdfa8ad7 100644
--- a/MinecraftClient/Commands/Animation.cs
+++ b/MinecraftClient/Commands/Animation.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -11,11 +8,11 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "animation "; } }
public override string CmdDesc { get { return "cmd.animation.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- string[] args = getArgs(command);
+ string[] args = GetArgs(command);
if (args.Length > 0)
{
if (args[0] == "mainhand" || args[0] == "0")
diff --git a/MinecraftClient/Commands/Bed.cs b/MinecraftClient/Commands/Bed.cs
index 37936fd5..3bffd887 100644
--- a/MinecraftClient/Commands/Bed.cs
+++ b/MinecraftClient/Commands/Bed.cs
@@ -12,9 +12,9 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "bed leave|sleep |sleep "; } }
public override string CmdDesc { get { return "cmd.bed.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- string[] args = getArgs(command);
+ string[] args = GetArgs(command);
if (args.Length >= 1)
{
diff --git a/MinecraftClient/Commands/ChangeSlot.cs b/MinecraftClient/Commands/ChangeSlot.cs
index 814d75e9..f278cac7 100644
--- a/MinecraftClient/Commands/ChangeSlot.cs
+++ b/MinecraftClient/Commands/ChangeSlot.cs
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace MinecraftClient.Commands
{
@@ -11,17 +9,17 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "changeslot <1-9>"; } }
public override string CmdDesc { get { return "cmd.changeSlot.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
if (!handler.GetInventoryEnabled())
return Translations.Get("extra.inventory_required");
- if (hasArg(command))
+ if (HasArg(command))
{
short slot;
try
{
- slot = Convert.ToInt16(getArg(command));
+ slot = Convert.ToInt16(GetArg(command));
}
catch (FormatException)
{
@@ -29,9 +27,9 @@ namespace MinecraftClient.Commands
}
if (slot >= 1 && slot <= 9)
{
- if (handler.ChangeSlot(slot-=1))
+ if (handler.ChangeSlot(slot -= 1))
{
- return Translations.Get("cmd.changeSlot.changed", (slot+=1));
+ return Translations.Get("cmd.changeSlot.changed", (slot += 1));
}
else
{
diff --git a/MinecraftClient/Commands/Chunk.cs b/MinecraftClient/Commands/Chunk.cs
index ed876502..8939efc6 100644
--- a/MinecraftClient/Commands/Chunk.cs
+++ b/MinecraftClient/Commands/Chunk.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Text;
using MinecraftClient.Mapping;
@@ -14,9 +13,9 @@ namespace MinecraftClient.Commands
public override string Run(McClient handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- string[] args = getArgs(command);
+ string[] args = GetArgs(command);
if (args.Length > 0)
{
if (args[0] == "status")
@@ -29,7 +28,7 @@ namespace MinecraftClient.Commands
StringBuilder sb = new();
- sb.Append(getChunkLoadingStatus(handler.GetWorld()));
+ sb.Append(World.GetChunkLoadingStatus(handler.GetWorld()));
sb.Append('\n');
sb.Append(String.Format("Current location:{0}, chunk: ({1}, {2}).\n", current, current.ChunkX, current.ChunkZ));
@@ -135,7 +134,7 @@ namespace MinecraftClient.Commands
// \ud83d\udd33: 🔳, \ud83d\udfe8: 🟨, \ud83d\udfe9: 🟩, \u25A1: â–¡, \u25A3: â–£, \u25A0: â–
- string[] chunkStatusStr = Settings.EnableEmoji ?
+ string[] chunkStatusStr = Settings.EnableEmoji ?
new string[] { "\ud83d\udd33", "\ud83d\udfe8", "\ud83d\udfe9" } : new string[] { "\u25A1", "\u25A3", "\u25A0" };
// Output
@@ -177,7 +176,7 @@ namespace MinecraftClient.Commands
ChunkColumn? chunkColumn = world[chunkX, chunkZ];
if (chunkColumn != null)
chunkColumn.FullyLoaded = false;
- return (chunkColumn == null) ? "Fail: chunk dosen't exist!" :
+ return (chunkColumn == null) ? "Fail: chunk dosen't exist!" :
String.Format("Successfully marked chunk ({0}, {1}) as loading.", chunkX, chunkZ);
}
else
@@ -194,7 +193,7 @@ namespace MinecraftClient.Commands
ChunkColumn? chunkColumn = world[chunkX, chunkZ];
if (chunkColumn != null)
chunkColumn.FullyLoaded = true;
- return (chunkColumn == null) ? "Fail: chunk dosen't exist!" :
+ return (chunkColumn == null) ? "Fail: chunk dosen't exist!" :
String.Format("Successfully marked chunk ({0}, {1}) as loaded.", chunkX, chunkZ);
}
else
@@ -220,11 +219,11 @@ namespace MinecraftClient.Commands
else
return GetCmdDescTranslated();
}
- else
+ else
return GetCmdDescTranslated();
}
- private Tuple? ParseChunkPos(string[] args)
+ private static Tuple? ParseChunkPos(string[] args)
{
try
{
@@ -249,19 +248,5 @@ namespace MinecraftClient.Commands
return null;
}
}
-
- private string getChunkLoadingStatus(World world)
- {
- double chunkLoadedRatio;
- if (world.chunkCnt == 0)
- chunkLoadedRatio = 0;
- else
- chunkLoadedRatio = (world.chunkCnt - world.chunkLoadNotCompleted) / (double)world.chunkCnt;
-
- string status = Translations.Get("cmd.move.chunk_loading_status",
- chunkLoadedRatio, world.chunkCnt - world.chunkLoadNotCompleted, world.chunkCnt);
-
- return status;
- }
}
}
diff --git a/MinecraftClient/Commands/Connect.cs b/MinecraftClient/Commands/Connect.cs
index f8fac928..ca95c81a 100644
--- a/MinecraftClient/Commands/Connect.cs
+++ b/MinecraftClient/Commands/Connect.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -11,11 +8,11 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "connect [account]"; } }
public override string CmdDesc { get { return "cmd.connect.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient? handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- string[] args = getArgs(command);
+ string[] args = GetArgs(command);
if (args.Length > 1)
{
if (!Settings.SetAccount(args[1]))
diff --git a/MinecraftClient/Commands/Debug.cs b/MinecraftClient/Commands/Debug.cs
index 11c122fc..c08404e0 100644
--- a/MinecraftClient/Commands/Debug.cs
+++ b/MinecraftClient/Commands/Debug.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -11,11 +8,11 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "debug [on|off]"; } }
public override string CmdDesc { get { return "cmd.debug.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- Settings.DebugMessages = (getArg(command).ToLower() == "on");
+ Settings.DebugMessages = (GetArg(command).ToLower() == "on");
}
else Settings.DebugMessages = !Settings.DebugMessages;
return Translations.Get(Settings.DebugMessages ? "cmd.debug.state_on" : "cmd.debug.state_off");
diff --git a/MinecraftClient/Commands/Dig.cs b/MinecraftClient/Commands/Dig.cs
index 6f297720..9438d1bc 100644
--- a/MinecraftClient/Commands/Dig.cs
+++ b/MinecraftClient/Commands/Dig.cs
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using MinecraftClient.Mapping;
namespace MinecraftClient.Commands
@@ -12,12 +10,12 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "dig "; } }
public override string CmdDesc { get { return "cmd.dig.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
if (!handler.GetTerrainEnabled())
return Translations.Get("extra.terrainandmovement_required");
- string[] args = getArgs(command);
+ string[] args = GetArgs(command);
if (args.Length == 0)
{
(bool hasBlock, Location blockLoc, Block block) = RaycastHelper.RaycastBlock(handler, 4.5, false);
diff --git a/MinecraftClient/Commands/DropItem.cs b/MinecraftClient/Commands/DropItem.cs
index db1da5e5..54f93254 100644
--- a/MinecraftClient/Commands/DropItem.cs
+++ b/MinecraftClient/Commands/DropItem.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
using MinecraftClient.Inventory;
namespace MinecraftClient.Commands
@@ -14,17 +13,16 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "/dropitem "; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
if (!handler.GetInventoryEnabled())
{
return Translations.Get("extra.inventory_required");
}
- if (hasArg(command))
+ if (HasArg(command))
{
- string arg = getArg(command);
- ItemType itemType;
- if (Enum.TryParse(arg, true, out itemType))
+ string arg = GetArg(command);
+ if (Enum.TryParse(arg, true, out ItemType itemType))
{
int inventoryId;
var inventories = handler.GetInventories();
diff --git a/MinecraftClient/Commands/Entitycmd.cs b/MinecraftClient/Commands/Entitycmd.cs
index 8aebdaf1..767f7134 100644
--- a/MinecraftClient/Commands/Entitycmd.cs
+++ b/MinecraftClient/Commands/Entitycmd.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Drawing;
using MinecraftClient.Inventory;
using MinecraftClient.Mapping;
@@ -12,17 +11,16 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "entity "; } }
public override string CmdDesc { get { return ""; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
if (handler.GetEntityHandlingEnabled())
{
- string[] args = getArgs(command);
+ string[] args = GetArgs(command);
if (args.Length >= 1)
{
try
{
- int entityID = 0;
- int.TryParse(args[0], out entityID);
+ int entityID = int.Parse(args[0]);
if (entityID != 0)
{
if (handler.GetEntities().ContainsKey(entityID))
@@ -44,8 +42,8 @@ namespace MinecraftClient.Commands
float health = entity.Health;
int latency = entity.Latency;
Item item = entity.Item;
- string nickname = entity.Name;
- string customname = entity.CustomName;
+ string? nickname = entity.Name;
+ string? customname = entity.CustomName;
EntityPose pose = entity.Pose;
EntityType type = entity.Type;
double distance = Math.Round(entity.Location.Distance(handler.GetCurrentLocation()), 2);
@@ -66,7 +64,7 @@ namespace MinecraftClient.Commands
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.latency]): {0}", latency);
else if (type == EntityType.Item || type == EntityType.ItemFrame || type == Mapping.EntityType.EyeOfEnder || type == Mapping.EntityType.Egg || type == Mapping.EntityType.EnderPearl || type == Mapping.EntityType.Potion || type == Mapping.EntityType.Fireball || type == Mapping.EntityType.FireworkRocket)
{
- string displayName = item.DisplayName;
+ string? displayName = item.DisplayName;
if (String.IsNullOrEmpty(displayName))
done += Translations.Replace("\n [MCC] ([cmd.entityCmd.item]): {0} x{1}", item.Type, item.Count);
else
@@ -100,8 +98,7 @@ namespace MinecraftClient.Commands
}
else
{
- EntityType interacttype = EntityType.Player;
- Enum.TryParse(args[0], out interacttype);
+ EntityType interacttype = Enum.Parse(args[0]);
string actionst = "cmd.entityCmd.attacked";
int actioncount = 0;
foreach (var entity2 in handler.GetEntities())
@@ -134,15 +131,17 @@ namespace MinecraftClient.Commands
else
{
Dictionary entities = handler.GetEntities();
- List response = new List();
- response.Add(Translations.Get("cmd.entityCmd.entities"));
+ List response = new()
+ {
+ Translations.Get("cmd.entityCmd.entities")
+ };
foreach (var entity2 in entities)
{
int id = entity2.Key;
float health = entity2.Value.Health;
int latency = entity2.Value.Latency;
- string nickname = entity2.Value.Name;
- string customname = entity2.Value.CustomName;
+ string? nickname = entity2.Value.Name;
+ string? customname = entity2.Value.CustomName;
EntityPose pose = entity2.Value.Pose;
EntityType type = entity2.Value.Type;
Item item = entity2.Value.Item;
diff --git a/MinecraftClient/Commands/ExecIf.cs b/MinecraftClient/Commands/ExecIf.cs
index df2c9e37..474c1c50 100644
--- a/MinecraftClient/Commands/ExecIf.cs
+++ b/MinecraftClient/Commands/ExecIf.cs
@@ -11,11 +11,11 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "execif ---> "; } }
public override string CmdDesc { get { return "cmd.execif.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- string commandsString = getArg(command);
+ string commandsString = GetArg(command);
if (!commandsString.Contains("--->"))
return GetCmdDescTranslated();
@@ -41,44 +41,41 @@ namespace MinecraftClient.Commands
var result = interpreter.Eval(expressionText);
- if (result != null)
+ bool shouldExec = result;
+
+ /*if (result is bool)
+ shouldExec = (bool)result;
+ else if (result is string)
+ shouldExec = !string.IsNullOrEmpty((string)result) && ((string)result).Trim().Contains("true", StringComparison.OrdinalIgnoreCase);
+ else if (result is int)
+ shouldExec = (int)result > 0;
+ else if (result is double)
+ shouldExec = (double)result > 0;
+ else if (result is float)
+ shouldExec = (float)result > 0;
+ else if (result is Int16)
+ shouldExec = (Int16)result > 0;
+ else if (result is Int32)
+ shouldExec = (Int32)result > 0;
+ else if (result is Int64)
+ shouldExec = (Int64)result > 0;
+ */
+
+ handler.Log.Debug("[Execif] Result Type: " + result.GetType().Name);
+
+ if (shouldExec)
{
- bool shouldExec = result;
+ string? output = "";
+ handler.PerformInternalCommand(resultCommand, ref output);
- /*if (result is bool)
- shouldExec = (bool)result;
- else if (result is string)
- shouldExec = !string.IsNullOrEmpty((string)result) && ((string)result).Trim().Contains("true", StringComparison.OrdinalIgnoreCase);
- else if (result is int)
- shouldExec = (int)result > 0;
- else if (result is double)
- shouldExec = (double)result > 0;
- else if (result is float)
- shouldExec = (float)result > 0;
- else if (result is Int16)
- shouldExec = (Int16)result > 0;
- else if (result is Int32)
- shouldExec = (Int32)result > 0;
- else if (result is Int64)
- shouldExec = (Int64)result > 0;
- */
-
- handler.Log.Debug("[Execif] Result Type: " + result.GetType().Name);
-
- if (shouldExec)
- {
- string output = "";
- handler.PerformInternalCommand(resultCommand, ref output);
-
- if (string.IsNullOrEmpty(output))
- handler.Log.Debug(Translations.TryGet("cmd.execif.executed_no_output", expressionText, resultCommand));
- else handler.Log.Debug(Translations.TryGet("cmd.execif.executed", expressionText, resultCommand, output));
-
- return "";
- }
+ if (string.IsNullOrEmpty(output))
+ handler.Log.Debug(Translations.TryGet("cmd.execif.executed_no_output", expressionText, resultCommand));
+ else handler.Log.Debug(Translations.TryGet("cmd.execif.executed", expressionText, resultCommand, output));
return "";
}
+
+ return "";
}
catch (Exception e)
{
@@ -86,8 +83,6 @@ namespace MinecraftClient.Commands
handler.Log.Error(Translations.TryGet("cmd.execif.error", e.Message));
return "";
}
-
- return GetCmdDescTranslated();
}
return GetCmdDescTranslated();
diff --git a/MinecraftClient/Commands/ExecMulti.cs b/MinecraftClient/Commands/ExecMulti.cs
index a7ad217f..a329da10 100644
--- a/MinecraftClient/Commands/ExecMulti.cs
+++ b/MinecraftClient/Commands/ExecMulti.cs
@@ -10,11 +10,11 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "execmulti -> -> -> ..."; } }
public override string CmdDesc { get { return "cmd.execmulti.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- string commandsString = getArg(command);
+ string commandsString = GetArg(command);
if (commandsString.Contains("execmulti", StringComparison.OrdinalIgnoreCase) || commandsString.Contains("execif", StringComparison.OrdinalIgnoreCase))
return Translations.TryGet("cmd.execmulti.prevent");
@@ -25,16 +25,17 @@ namespace MinecraftClient.Commands
foreach (string cmd in commands)
{
- string output = "";
+ string? output = "";
handler.PerformInternalCommand(cmd, ref output);
string log = Translations.TryGet(
"cmd.execmulti.executed", cmd,
string.IsNullOrEmpty(output) ? Translations.TryGet("cmd.execmulti.no_result") : Translations.TryGet("cmd.execmulti.result", output));
- if (output.Contains("unknown command", StringComparison.OrdinalIgnoreCase))
+ if (output != null && output.Contains("unknown command", StringComparison.OrdinalIgnoreCase))
handler.Log.Error(log);
- else handler.Log.Info(log);
+ else
+ handler.Log.Info(log);
}
return "";
diff --git a/MinecraftClient/Commands/Exit.cs b/MinecraftClient/Commands/Exit.cs
index 8a442786..7bca6496 100644
--- a/MinecraftClient/Commands/Exit.cs
+++ b/MinecraftClient/Commands/Exit.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -11,13 +8,13 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "exit"; } }
public override string CmdDesc { get { return "cmd.exit.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient? handler, string command, Dictionary? localVars)
{
Program.Exit();
return "";
}
- public override IEnumerable getCMDAliases()
+ public override IEnumerable GetCMDAliases()
{
return new string[] { "quit" };
}
diff --git a/MinecraftClient/Commands/Health.cs b/MinecraftClient/Commands/Health.cs
index 95e084c1..68af9b32 100644
--- a/MinecraftClient/Commands/Health.cs
+++ b/MinecraftClient/Commands/Health.cs
@@ -1,7 +1,4 @@
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace MinecraftClient.Commands
{
@@ -11,7 +8,7 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "health"; } }
public override string CmdDesc { get { return "cmd.health.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
return Translations.Get("cmd.health.response", handler.GetHealth(), handler.GetSaturation(), handler.GetLevel(), handler.GetTotalExperience());
}
diff --git a/MinecraftClient/Commands/Inventory.cs b/MinecraftClient/Commands/Inventory.cs
index 5821df68..58d7997e 100644
--- a/MinecraftClient/Commands/Inventory.cs
+++ b/MinecraftClient/Commands/Inventory.cs
@@ -16,7 +16,7 @@ namespace MinecraftClient.Commands
{
if (handler.GetInventoryEnabled())
{
- string[] args = getArgs(command);
+ string[] args = GetArgs(command);
if (args.Length >= 1)
{
int inventoryId;
@@ -117,7 +117,7 @@ namespace MinecraftClient.Commands
{
inventory.Items.Values
.ToList()
- .FindAll(item => item.Type == parsedItemType && (shouldUseItemCount ? item.Count == itemCount : true))
+ .FindAll(item => item.Type == parsedItemType && (!shouldUseItemCount || item.Count == itemCount))
.ForEach(item =>
{
if (!foundItems.ContainsKey(inventory.ID))
@@ -183,7 +183,7 @@ namespace MinecraftClient.Commands
response.Append(Translations.Get("cmd.inventory.inventory"));
response.AppendLine(String.Format(" #{0} - {1}§8", inventoryId, inventory.Title));
- string asciiArt = inventory.Type.GetAsciiArt();
+ string? asciiArt = inventory.Type.GetAsciiArt();
if (asciiArt != null && Settings.DisplayInventoryLayout)
response.AppendLine(asciiArt);
diff --git a/MinecraftClient/Commands/List.cs b/MinecraftClient/Commands/List.cs
index 7cc4575c..f261d670 100644
--- a/MinecraftClient/Commands/List.cs
+++ b/MinecraftClient/Commands/List.cs
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace MinecraftClient.Commands
{
@@ -11,7 +9,7 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "list"; } }
public override string CmdDesc { get { return "cmd.list.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
return Translations.Get("cmd.list.players", String.Join(", ", handler.GetOnlinePlayers()));
}
diff --git a/MinecraftClient/Commands/Log.cs b/MinecraftClient/Commands/Log.cs
index 9c0daf1e..412e401b 100644
--- a/MinecraftClient/Commands/Log.cs
+++ b/MinecraftClient/Commands/Log.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -11,11 +8,11 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "log "; } }
public override string CmdDesc { get { return "cmd.log.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- ConsoleIO.WriteLogLine(getArg(command));
+ ConsoleIO.WriteLogLine(GetArg(command));
return "";
}
else return GetCmdDescTranslated();
diff --git a/MinecraftClient/Commands/Look.cs b/MinecraftClient/Commands/Look.cs
index 433f53a7..2f6488b2 100644
--- a/MinecraftClient/Commands/Look.cs
+++ b/MinecraftClient/Commands/Look.cs
@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Net.Http.Headers;
-using System.Text;
using MinecraftClient.Mapping;
namespace MinecraftClient.Commands
@@ -13,11 +10,11 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "look "; } }
public override string CmdDesc { get { return "cmd.look.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
if (handler.GetTerrainEnabled())
{
- string[] args = getArgs(command);
+ string[] args = GetArgs(command);
if (args.Length == 0)
{
const double maxDistance = 8.0;
@@ -33,7 +30,7 @@ namespace MinecraftClient.Commands
}
else if (args.Length == 1)
{
- string dirStr = getArg(command).Trim().ToLower();
+ string dirStr = GetArg(command).Trim().ToLower();
Direction direction;
switch (dirStr)
{
@@ -53,8 +50,8 @@ namespace MinecraftClient.Commands
{
try
{
- float yaw = Single.Parse(args[0]);
- float pitch = Single.Parse(args[1]);
+ float yaw = float.Parse(args[0]);
+ float pitch = float.Parse(args[1]);
handler.UpdateLocation(handler.GetCurrentLocation(), yaw, pitch);
return Translations.Get("cmd.look.at", yaw.ToString("0.00"), pitch.ToString("0.00"));
diff --git a/MinecraftClient/Commands/Move.cs b/MinecraftClient/Commands/Move.cs
index edd95ccd..6bc6e1fb 100644
--- a/MinecraftClient/Commands/Move.cs
+++ b/MinecraftClient/Commands/Move.cs
@@ -11,9 +11,9 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "move [-f]"; } }
public override string CmdDesc { get { return "walk or start walking. \"-f\": force unsafe movements like falling or touching fire"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- List args = getArgs(command.ToLower()).ToList();
+ List args = GetArgs(command.ToLower()).ToList();
bool takeRisk = false;
if (args.Count < 1)
@@ -21,7 +21,7 @@ namespace MinecraftClient.Commands
string desc = GetCmdDescTranslated();
if (handler.GetTerrainEnabled())
- handler.Log.Info(getChunkLoadingStatus(handler.GetWorld()));
+ handler.Log.Info(World.GetChunkLoadingStatus(handler.GetWorld()));
return desc;
}
@@ -65,7 +65,7 @@ namespace MinecraftClient.Commands
case "south": direction = Direction.South; break;
case "center":
Location current = handler.GetCurrentLocation();
- Location currentCenter = new Location(Math.Floor(current.X) + 0.5, current.Y, Math.Floor(current.Z) + 0.5);
+ Location currentCenter = new(Math.Floor(current.X) + 0.5, current.Y, Math.Floor(current.Z) + 0.5);
handler.MoveTo(currentCenter, allowDirectTeleport: true);
return Translations.Get("cmd.move.walk", currentCenter, current);
case "get": return handler.GetCurrentLocation().ToString();
@@ -81,7 +81,7 @@ namespace MinecraftClient.Commands
{
if (handler.MoveTo(goal, allowUnsafe: takeRisk))
return Translations.Get("cmd.move.moving", args[0]);
- else
+ else
return takeRisk ? Translations.Get("cmd.move.dir_fail") : Translations.Get("cmd.move.suggestforce");
}
else return Translations.Get("cmd.move.dir_fail");
@@ -113,19 +113,5 @@ namespace MinecraftClient.Commands
}
else return Translations.Get("extra.terrainandmovement_required");
}
-
- private string getChunkLoadingStatus(World world)
- {
- double chunkLoadedRatio;
- if (world.chunkCnt == 0)
- chunkLoadedRatio = 0;
- else
- chunkLoadedRatio = (world.chunkCnt - world.chunkLoadNotCompleted) / (double)world.chunkCnt;
-
- string status = Translations.Get("cmd.move.chunk_loading_status",
- chunkLoadedRatio, world.chunkCnt - world.chunkLoadNotCompleted, world.chunkCnt);
-
- return status;
- }
}
}
diff --git a/MinecraftClient/Commands/Reco.cs b/MinecraftClient/Commands/Reco.cs
index 4119130c..46beebbb 100644
--- a/MinecraftClient/Commands/Reco.cs
+++ b/MinecraftClient/Commands/Reco.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -11,9 +8,9 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "reco [account]"; } }
public override string CmdDesc { get { return "cmd.reco.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient? handler, string command, Dictionary? localVars)
{
- string[] args = getArgs(command);
+ string[] args = GetArgs(command);
if (args.Length > 0)
{
if (!Settings.SetAccount(args[0]))
diff --git a/MinecraftClient/Commands/Respawn.cs b/MinecraftClient/Commands/Respawn.cs
index aece669c..3ff718fd 100644
--- a/MinecraftClient/Commands/Respawn.cs
+++ b/MinecraftClient/Commands/Respawn.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -11,7 +8,7 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "respawn"; } }
public override string CmdDesc { get { return "cmd.respawn.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
handler.SendRespawnPacket();
return Translations.Get("cmd.respawn.done");
diff --git a/MinecraftClient/Commands/Script.cs b/MinecraftClient/Commands/Script.cs
index 61145398..e7e233c5 100644
--- a/MinecraftClient/Commands/Script.cs
+++ b/MinecraftClient/Commands/Script.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -11,11 +8,11 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "script "; } }
public override string CmdDesc { get { return "cmd.script.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- handler.BotLoad(new ChatBots.Script(getArg(command), null, localVars));
+ handler.BotLoad(new ChatBots.Script(GetArg(command), null, localVars));
return "";
}
else return GetCmdDescTranslated();
diff --git a/MinecraftClient/Commands/Send.cs b/MinecraftClient/Commands/Send.cs
index 945ec94d..55977740 100644
--- a/MinecraftClient/Commands/Send.cs
+++ b/MinecraftClient/Commands/Send.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -11,11 +8,11 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "send "; } }
public override string CmdDesc { get { return "cmd.send.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- handler.SendText(getArg(command));
+ handler.SendText(GetArg(command));
return "";
}
else return GetCmdDescTranslated();
diff --git a/MinecraftClient/Commands/Set.cs b/MinecraftClient/Commands/Set.cs
index a58541c8..9f6ccd78 100644
--- a/MinecraftClient/Commands/Set.cs
+++ b/MinecraftClient/Commands/Set.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -11,14 +8,14 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "set varname=value"; } }
public override string CmdDesc { get { return "cmd.set.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- string[] temp = getArg(command).Split('=');
+ string[] temp = GetArg(command).Split('=');
if (temp.Length > 1)
{
- if (Settings.SetVar(temp[0], getArg(command).Substring(temp[0].Length + 1)))
+ if (Settings.SetVar(temp[0], GetArg(command).Substring(temp[0].Length + 1)))
{
return ""; //Success
}
diff --git a/MinecraftClient/Commands/SetRnd.cs b/MinecraftClient/Commands/SetRnd.cs
index ea4f0b84..6ee7bfb8 100644
--- a/MinecraftClient/Commands/SetRnd.cs
+++ b/MinecraftClient/Commands/SetRnd.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Text;
namespace MinecraftClient.Commands
{
@@ -9,16 +8,16 @@ namespace MinecraftClient.Commands
public override string CmdName { get { return "setrnd"; } }
public override string CmdUsage { get { return Translations.Get("cmd.setrnd.format"); } }
public override string CmdDesc { get { return "cmd.setrnd.desc"; } }
- private static readonly Random rand = new Random();
+ private static readonly Random rand = new();
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
- if (hasArg(command))
+ if (HasArg(command))
{
- string[] args = getArg(command).Split(' ');
+ string[] args = GetArg(command).Split(' ');
- if (args.Length > 1)
- {
+ if (args.Length > 1)
+ {
// detect "to" keyword in string
if (args.Length == 2 && args[1].Contains("to"))
{
@@ -28,7 +27,7 @@ namespace MinecraftClient.Commands
// try to extract the two numbers from the string
try
{
- num1 = Convert.ToInt32(args[1].Substring(0, args[1].IndexOf('t')));
+ num1 = Convert.ToInt32(args[1][..args[1].IndexOf('t')]);
num2 = Convert.ToInt32(args[1].Substring(args[1].IndexOf('o') + 1, args[1].Length - 1 - args[1].IndexOf('o')));
}
catch (Exception)
@@ -38,11 +37,7 @@ namespace MinecraftClient.Commands
// switch the values if they were entered in the wrong way
if (num2 < num1)
- {
- int temp = num1;
- num1 = num2;
- num2 = temp;
- }
+ (num2, num1) = (num1, num2);
// create a variable or set it to num1 <= varlue < num2
if (Settings.SetVar(args[0], rand.Next(num1, num2)))
@@ -54,10 +49,10 @@ namespace MinecraftClient.Commands
else
{
// extract all arguments of the command
- string argString = command.Substring(8 + command.Split(' ')[1].Length);
+ string argString = command[(8 + command.Split(' ')[1].Length)..];
// process all arguments similar to regular terminals with quotes and escaping
- List values = parseCommandLine(argString);
+ List values = ParseCommandLine(argString);
// create a variable or set it to one of the values
if (values.Count > 0 && Settings.SetVar(args[0], values[rand.Next(0, values.Count)]))
diff --git a/MinecraftClient/Commands/Sneak.cs b/MinecraftClient/Commands/Sneak.cs
index 1ba6a94a..1c8dbf17 100644
--- a/MinecraftClient/Commands/Sneak.cs
+++ b/MinecraftClient/Commands/Sneak.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -12,14 +9,14 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "Sneak"; } }
public override string CmdDesc { get { return "cmd.sneak.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
if (sneaking)
{
var result = handler.SendEntityAction(Protocol.EntityActionType.StopSneaking);
if (result)
sneaking = false;
- return Translations.Get(result ? "cmd.sneak.off" : "general.fail");
+ return Translations.Get(result ? "cmd.sneak.off" : "general.fail");
}
else
{
@@ -28,7 +25,6 @@ namespace MinecraftClient.Commands
sneaking = true;
return Translations.Get(result ? "cmd.sneak.on" : "general.fail");
}
-
}
}
}
\ No newline at end of file
diff --git a/MinecraftClient/Commands/Tps.cs b/MinecraftClient/Commands/Tps.cs
index 356eb752..9aaafc5c 100644
--- a/MinecraftClient/Commands/Tps.cs
+++ b/MinecraftClient/Commands/Tps.cs
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace MinecraftClient.Commands
{
@@ -11,7 +9,7 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "tps"; } }
public override string CmdDesc { get { return "cmd.tps.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
var tps = Math.Round(handler.GetServerTPS(), 2);
string color;
@@ -19,7 +17,8 @@ namespace MinecraftClient.Commands
color = "§c"; // Red
else if (tps < 15)
color = "§e"; // Yellow
- else color = "§a"; // Green
+ else
+ color = "§a"; // Green
return Translations.Get("cmd.tps.current") + ": " + color + tps;
}
}
diff --git a/MinecraftClient/Commands/UseItem.cs b/MinecraftClient/Commands/UseItem.cs
index c2ffa966..497633d2 100644
--- a/MinecraftClient/Commands/UseItem.cs
+++ b/MinecraftClient/Commands/UseItem.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Commands
{
@@ -11,7 +8,7 @@ namespace MinecraftClient.Commands
public override string CmdUsage { get { return "useitem"; } }
public override string CmdDesc { get { return "cmd.useitem.desc"; } }
- public override string Run(McClient handler, string command, Dictionary localVars)
+ public override string Run(McClient handler, string command, Dictionary? localVars)
{
if (handler.GetInventoryEnabled())
{
diff --git a/MinecraftClient/Commands/Useblock.cs b/MinecraftClient/Commands/Useblock.cs
index f35ac385..05284afd 100644
--- a/MinecraftClient/Commands/Useblock.cs
+++ b/MinecraftClient/Commands/Useblock.cs
@@ -1,8 +1,5 @@
-using MinecraftClient.Mapping;
-using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using MinecraftClient.Mapping;
namespace MinecraftClient.Commands
{
@@ -16,9 +13,9 @@ namespace MinecraftClient.Commands
{
if (!handler.GetTerrainEnabled())
return Translations.Get("extra.terrainandmovement_required");
- else if (hasArg(command))
+ else if (HasArg(command))
{
- string[] args = getArgs(command);
+ string[] args = GetArgs(command);
if (args.Length >= 3)
{
Location block = Location.Parse(handler.GetCurrentLocation(), args[0], args[1], args[2]).ToFloor();
diff --git a/MinecraftClient/ConsoleIO.cs b/MinecraftClient/ConsoleIO.cs
index a1f06d1d..13b55989 100644
--- a/MinecraftClient/ConsoleIO.cs
+++ b/MinecraftClient/ConsoleIO.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Text;
-using System.Threading;
namespace MinecraftClient
{
@@ -14,7 +12,7 @@ namespace MinecraftClient
///
public static class ConsoleIO
{
- private static IAutoComplete autocomplete_engine;
+ private static IAutoComplete? autocomplete_engine;
///
/// Reset the IO mechanism and clear all buffers
@@ -77,8 +75,8 @@ namespace MinecraftClient
public static string ReadLine()
{
if (BasicIO)
- return Console.ReadLine();
- else
+ return Console.ReadLine() ?? String.Empty;
+ else
return ConsoleInteractive.ConsoleReader.RequestImmediateInput();
}
@@ -87,7 +85,7 @@ namespace MinecraftClient
///
public static void DebugReadInput()
{
- ConsoleKeyInfo k = new ConsoleKeyInfo();
+ ConsoleKeyInfo k;
while (true)
{
k = Console.ReadKey(true);
@@ -119,14 +117,11 @@ namespace MinecraftClient
///
public static void WriteLineFormatted(string str, bool acceptnewlines = false, bool? displayTimestamp = null)
{
- StringBuilder output = new StringBuilder();
-
+ StringBuilder output = new();
+
if (!String.IsNullOrEmpty(str))
{
- if (displayTimestamp == null)
- {
- displayTimestamp = EnableTimestamps;
- }
+ displayTimestamp ??= EnableTimestamps;
if (displayTimestamp.Value)
{
int hour = DateTime.Now.Hour, minute = DateTime.Now.Minute, second = DateTime.Now.Second;
@@ -183,10 +178,10 @@ namespace MinecraftClient
public static void AutocompleteHandler(object? sender, ConsoleKey e)
{
if (e != ConsoleKey.Tab) return;
-
+
if (autocomplete_engine == null)
return;
-
+
var buffer = ConsoleInteractive.ConsoleReader.GetBufferContent();
autocomplete_engine.AutoComplete(buffer.Text[..buffer.CursorPosition]);
}
diff --git a/MinecraftClient/Crypto/AesCfb8Stream.cs b/MinecraftClient/Crypto/AesCfb8Stream.cs
index aac0443d..f653546c 100644
--- a/MinecraftClient/Crypto/AesCfb8Stream.cs
+++ b/MinecraftClient/Crypto/AesCfb8Stream.cs
@@ -1,12 +1,9 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Security.Cryptography;
-using System.IO;
using System.Collections.Concurrent;
+using System.IO;
using System.Runtime.CompilerServices;
+using System.Security.Cryptography;
+using System.Threading.Tasks;
namespace MinecraftClient.Crypto
{
@@ -19,8 +16,8 @@ namespace MinecraftClient.Crypto
private bool inStreamEnded = false;
- private byte[] ReadStreamIV = new byte[16];
- private byte[] WriteStreamIV = new byte[16];
+ private readonly byte[] ReadStreamIV = new byte[16];
+ private readonly byte[] WriteStreamIV = new byte[16];
public Stream BaseStream { get; set; }
diff --git a/MinecraftClient/Crypto/CryptoHandler.cs b/MinecraftClient/Crypto/CryptoHandler.cs
index 5728835a..963c5dbc 100644
--- a/MinecraftClient/Crypto/CryptoHandler.cs
+++ b/MinecraftClient/Crypto/CryptoHandler.cs
@@ -1,9 +1,7 @@
using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
using System.Security.Cryptography;
-using System.IO;
+using System.Text;
namespace MinecraftClient.Crypto
{
@@ -13,7 +11,7 @@ namespace MinecraftClient.Crypto
public static class CryptoHandler
{
- public static byte[]? ClientAESPrivateKey = null;
+ public static byte[]? ClientAESPrivateKey;
///
/// Get a cryptographic service for encrypting data using the server's RSA public key
@@ -21,21 +19,21 @@ namespace MinecraftClient.Crypto
/// Byte array containing the encoded key
/// Returns the corresponding RSA Crypto Service
- public static RSACryptoServiceProvider DecodeRSAPublicKey(byte[] x509key)
+ public static RSACryptoServiceProvider? DecodeRSAPublicKey(byte[] x509key)
{
/* Code from StackOverflow no. 18091460 */
byte[] SeqOID = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
- System.IO.MemoryStream ms = new System.IO.MemoryStream(x509key);
- System.IO.BinaryReader reader = new System.IO.BinaryReader(ms);
+ System.IO.MemoryStream ms = new(x509key);
+ System.IO.BinaryReader reader = new(ms);
if (reader.ReadByte() == 0x30)
ReadASNLength(reader); //skip the size
else
return null;
- int identifierSize = 0; //total length of Object Identifier section
+ int identifierSize; //total length of Object Identifier section
if (reader.ReadByte() == 0x30)
identifierSize = ReadASNLength(reader);
else
@@ -78,10 +76,12 @@ namespace MinecraftClient.Crypto
byte[] exponent = new byte[exponentSize];
reader.Read(exponent, 0, exponent.Length);
- RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
- RSAParameters RSAKeyInfo = new RSAParameters();
- RSAKeyInfo.Modulus = modulus;
- RSAKeyInfo.Exponent = exponent;
+ RSACryptoServiceProvider RSA = new();
+ RSAParameters RSAKeyInfo = new()
+ {
+ Modulus = modulus,
+ Exponent = exponent
+ };
RSA.ImportParameters(RSAKeyInfo);
return RSA;
}
@@ -120,8 +120,9 @@ namespace MinecraftClient.Crypto
public static byte[] GenerateAESPrivateKey()
{
- AesManaged AES = new AesManaged();
- AES.KeySize = 128; AES.GenerateKey();
+ Aes AES = Aes.Create();
+ AES.KeySize = 128;
+ AES.GenerateKey();
return AES.Key;
}
@@ -133,9 +134,9 @@ namespace MinecraftClient.Crypto
/// Secret key chosen by the client
/// Returns the corresponding SHA-1 hex hash
- public static string getServerHash(string serverID, byte[] PublicKey, byte[] SecretKey)
+ public static string GetServerHash(string serverID, byte[] PublicKey, byte[] SecretKey)
{
- byte[] hash = digest(new byte[][] { Encoding.GetEncoding("iso-8859-1").GetBytes(serverID), SecretKey, PublicKey });
+ byte[] hash = Digest(new byte[][] { Encoding.GetEncoding("iso-8859-1").GetBytes(serverID), SecretKey, PublicKey });
bool negative = (hash[0] & 0x80) == 0x80;
if (negative) { hash = TwosComplementLittleEndian(hash); }
string result = GetHexString(hash).TrimStart('0');
@@ -149,13 +150,13 @@ namespace MinecraftClient.Crypto
/// array of byte arrays to hash
/// Returns the hashed data
- private static byte[] digest(byte[][] tohash)
+ private static byte[] Digest(byte[][] tohash)
{
- SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
+ SHA1 sha1 = SHA1.Create();
for (int i = 0; i < tohash.Length; i++)
sha1.TransformBlock(tohash[i], 0, tohash[i].Length, tohash[i], 0);
- sha1.TransformFinalBlock(new byte[] { }, 0, 0);
- return sha1.Hash;
+ sha1.TransformFinalBlock(Array.Empty(), 0, 0);
+ return sha1.Hash!;
}
///
diff --git a/MinecraftClient/FileMonitor.cs b/MinecraftClient/FileMonitor.cs
index 23c29b8e..378bb6b6 100644
--- a/MinecraftClient/FileMonitor.cs
+++ b/MinecraftClient/FileMonitor.cs
@@ -11,8 +11,8 @@ namespace MinecraftClient
///
public class FileMonitor : IDisposable
{
- private Tuple? monitor = null;
- private Tuple? polling = null;
+ private readonly Tuple? monitor = null;
+ private readonly Tuple? polling = null;
///
/// Create a new FileMonitor and start monitoring
@@ -24,7 +24,7 @@ namespace MinecraftClient
{
if (Settings.DebugMessages)
{
- string callerClass = new System.Diagnostics.StackFrame(1).GetMethod().DeclaringType.Name;
+ string callerClass = new System.Diagnostics.StackFrame(1).GetMethod()!.DeclaringType!.Name;
ConsoleIO.WriteLineFormatted(Translations.Get("filemonitor.init", callerClass, Path.Combine(folder, filename)));
}
@@ -42,14 +42,14 @@ namespace MinecraftClient
{
if (Settings.DebugMessages)
{
- string callerClass = new System.Diagnostics.StackFrame(1).GetMethod().DeclaringType.Name;
+ string callerClass = new System.Diagnostics.StackFrame(1).GetMethod()!.DeclaringType!.Name;
ConsoleIO.WriteLineFormatted(Translations.Get("filemonitor.fail", callerClass));
}
monitor = null;
var cancellationTokenSource = new CancellationTokenSource();
polling = new Tuple(new Thread(() => PollingThread(folder, filename, handler, cancellationTokenSource.Token)), cancellationTokenSource);
- polling.Item1.Name = String.Format("{0} Polling thread: {1}", this.GetType().Name, Path.Combine(folder, filename));
+ polling.Item1.Name = String.Format("{0} Polling thread: {1}", GetType().Name, Path.Combine(folder, filename));
polling.Item1.Start();
}
}
@@ -94,7 +94,7 @@ namespace MinecraftClient
/// Last write time, or DateTime.MinValue if the file does not exist
private DateTime GetLastWrite(string path)
{
- FileInfo fileInfo = new FileInfo(path);
+ FileInfo fileInfo = new(path);
if (fileInfo.Exists)
{
return fileInfo.LastWriteTime;
@@ -110,11 +110,10 @@ namespace MinecraftClient
/// Encoding (default is UTF8)
/// Thrown when failing to read the file despite multiple retries
/// All lines
- public static string[] ReadAllLinesWithRetries(string filePath, int maxTries = 3, Encoding encoding = null)
+ public static string[] ReadAllLinesWithRetries(string filePath, int maxTries = 3, Encoding? encoding = null)
{
int attempt = 0;
- if (encoding == null)
- encoding = Encoding.UTF8;
+ encoding ??= Encoding.UTF8;
while (true)
{
try
@@ -138,11 +137,10 @@ namespace MinecraftClient
/// The lines to write to the file
/// Maximum read attempts
/// Encoding (default is UTF8)
- public static void WriteAllLinesWithRetries(string filePath, IEnumerable lines, int maxTries = 3, Encoding encoding = null)
+ public static void WriteAllLinesWithRetries(string filePath, IEnumerable lines, int maxTries = 3, Encoding? encoding = null)
{
int attempt = 0;
- if (encoding == null)
- encoding = Encoding.UTF8;
+ encoding ??= Encoding.UTF8;
while (true)
{
try
diff --git a/MinecraftClient/INIFile.cs b/MinecraftClient/INIFile.cs
index 712bc205..2dd8c719 100644
--- a/MinecraftClient/INIFile.cs
+++ b/MinecraftClient/INIFile.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
using System.Text;
namespace MinecraftClient
@@ -42,9 +41,9 @@ namespace MinecraftClient
string line = lineRaw.Split('#')[0].Trim();
if (line.Length > 0 && line[0] != ';')
{
- if (line[0] == '[' && line[line.Length - 1] == ']')
+ if (line[0] == '[' && line[^1] == ']')
{
- iniSection = line.Substring(1, line.Length - 2);
+ iniSection = line[1..^1];
if (lowerCase)
iniSection = iniSection.ToLower();
}
@@ -55,7 +54,7 @@ namespace MinecraftClient
argName = argName.ToLower();
if (line.Length > (argName.Length + 1))
{
- string argValue = line.Substring(argName.Length + 1);
+ string argValue = line[(argName.Length + 1)..];
if (!iniContents.ContainsKey(iniSection))
iniContents[iniSection] = new Dictionary();
iniContents[iniSection][argName] = argValue;
@@ -73,7 +72,7 @@ namespace MinecraftClient
/// Data to put into the file
/// INI file description, inserted as a comment on first line of the INI file
/// Automatically change first char of section and keys to uppercase
- public static void WriteFile(string iniFile, Dictionary> contents, string description = null, bool autoCase = true)
+ public static void WriteFile(string iniFile, Dictionary> contents, string? description = null, bool autoCase = true)
{
File.WriteAllLines(iniFile, Generate(contents, description, autoCase), Encoding.UTF8);
}
@@ -85,9 +84,9 @@ namespace MinecraftClient
/// INI file description, inserted as a comment on first line of the INI file
/// Automatically change first char of section and keys to uppercase
/// Lines of the INI file
- public static string[] Generate(Dictionary> contents, string description = null, bool autoCase = true)
+ public static string[] Generate(Dictionary> contents, string? description = null, bool autoCase = true)
{
- List lines = new List();
+ List lines = new();
if (!String.IsNullOrWhiteSpace(description))
lines.Add('#' + description);
foreach (var section in contents)
@@ -96,10 +95,10 @@ namespace MinecraftClient
lines.Add("");
if (!String.IsNullOrEmpty(section.Key))
{
- lines.Add("[" + (autoCase ? char.ToUpper(section.Key[0]) + section.Key.Substring(1) : section.Key) + ']');
+ lines.Add("[" + (autoCase ? char.ToUpper(section.Key[0]) + section.Key[1..] : section.Key) + ']');
foreach (var item in section.Value)
if (!String.IsNullOrEmpty(item.Key))
- lines.Add((autoCase ? char.ToUpper(item.Key[0]) + item.Key.Substring(1) : item.Key) + '=' + item.Value);
+ lines.Add((autoCase ? char.ToUpper(item.Key[0]) + item.Key[1..] : item.Key) + '=' + item.Value);
}
}
return lines.ToArray();
diff --git a/MinecraftClient/Inventory/Container.cs b/MinecraftClient/Inventory/Container.cs
index b39892b6..35a438b3 100644
--- a/MinecraftClient/Inventory/Container.cs
+++ b/MinecraftClient/Inventory/Container.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Inventory
{
@@ -23,7 +20,7 @@ namespace MinecraftClient.Inventory
///
/// title of container
///
- public string Title;
+ public string? Title;
///
/// state of container
@@ -35,11 +32,6 @@ namespace MinecraftClient.Inventory
///
public Dictionary Items;
- ///
- /// Create an empty container
- ///
- public Container() { }
-
///
/// Create an empty container with ID, Type and Title
///
@@ -61,7 +53,7 @@ namespace MinecraftClient.Inventory
/// Container Type
/// Container Title
/// Container Items (key: slot ID, value: item info)
- public Container(int id, ContainerType type, string title, Dictionary items)
+ public Container(int id, ContainerType type, string? title, Dictionary items)
{
ID = id;
Type = type;
@@ -130,33 +122,33 @@ namespace MinecraftClient.Inventory
public static ContainerType GetContainerType(int typeID)
{
// https://wiki.vg/Inventory didn't state the inventory ID, assume that list start with 0
- switch (typeID)
+ return typeID switch
{
- case 0: return ContainerType.Generic_9x1;
- case 1: return ContainerType.Generic_9x2;
- case 2: return ContainerType.Generic_9x3;
- case 3: return ContainerType.Generic_9x4;
- case 4: return ContainerType.Generic_9x5;
- case 5: return ContainerType.Generic_9x6;
- case 6: return ContainerType.Generic_3x3;
- case 7: return ContainerType.Anvil;
- case 8: return ContainerType.Beacon;
- case 9: return ContainerType.BlastFurnace;
- case 10: return ContainerType.BrewingStand;
- case 11: return ContainerType.Crafting;
- case 12: return ContainerType.Enchantment;
- case 13: return ContainerType.Furnace;
- case 14: return ContainerType.Grindstone;
- case 15: return ContainerType.Hopper;
- case 16: return ContainerType.Lectern;
- case 17: return ContainerType.Loom;
- case 18: return ContainerType.Merchant;
- case 19: return ContainerType.ShulkerBox;
- case 20: return ContainerType.Smoker;
- case 21: return ContainerType.Cartography;
- case 22: return ContainerType.Stonecutter;
- default: return ContainerType.Unknown;
- }
+ 0 => ContainerType.Generic_9x1,
+ 1 => ContainerType.Generic_9x2,
+ 2 => ContainerType.Generic_9x3,
+ 3 => ContainerType.Generic_9x4,
+ 4 => ContainerType.Generic_9x5,
+ 5 => ContainerType.Generic_9x6,
+ 6 => ContainerType.Generic_3x3,
+ 7 => ContainerType.Anvil,
+ 8 => ContainerType.Beacon,
+ 9 => ContainerType.BlastFurnace,
+ 10 => ContainerType.BrewingStand,
+ 11 => ContainerType.Crafting,
+ 12 => ContainerType.Enchantment,
+ 13 => ContainerType.Furnace,
+ 14 => ContainerType.Grindstone,
+ 15 => ContainerType.Hopper,
+ 16 => ContainerType.Lectern,
+ 17 => ContainerType.Loom,
+ 18 => ContainerType.Merchant,
+ 19 => ContainerType.ShulkerBox,
+ 20 => ContainerType.Smoker,
+ 21 => ContainerType.Cartography,
+ 22 => ContainerType.Stonecutter,
+ _ => ContainerType.Unknown,
+ };
}
///
@@ -166,7 +158,7 @@ namespace MinecraftClient.Inventory
/// An array of slot ID
public int[] SearchItem(ItemType itemType)
{
- List result = new List();
+ List result = new();
if (Items != null)
{
foreach (var item in Items)
@@ -185,7 +177,7 @@ namespace MinecraftClient.Inventory
/// Also depending on the container type, some empty slots cannot be used e.g. armor slots. This might cause issues.
public int[] GetEmpytSlots()
{
- List result = new List();
+ List result = new();
for (int i = 0; i < Type.SlotCount(); i++)
{
result.Add(i);
diff --git a/MinecraftClient/Inventory/ContainerType.cs b/MinecraftClient/Inventory/ContainerType.cs
index 1bb101d6..76d05416 100644
--- a/MinecraftClient/Inventory/ContainerType.cs
+++ b/MinecraftClient/Inventory/ContainerType.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace MinecraftClient.Inventory
+namespace MinecraftClient.Inventory
{
// For MC 1.14 after ONLY
public enum ContainerType
@@ -57,22 +52,24 @@ namespace MinecraftClient.Inventory
{
public static ContainerType ToNew(ContainerTypeOld type)
{
- switch (type)
+ return type switch
{
- case ContainerTypeOld.CONTAINER: return ContainerType.Unknown;
- case ContainerTypeOld.CHEST: return ContainerType.Generic_9x3;
- case ContainerTypeOld.CRAFTING_TABLE: return ContainerType.Crafting;
- case ContainerTypeOld.FURNACE: return ContainerType.Furnace;
- case ContainerTypeOld.DISPENSER: return ContainerType.Generic_3x3;
- case ContainerTypeOld.ENCHANTING_TABLE: return ContainerType.Enchantment;
- case ContainerTypeOld.BREWING_STAND: return ContainerType.BrewingStand;
- case ContainerTypeOld.VILLAGER: return ContainerType.Merchant;
- case ContainerTypeOld.HOPPER: return ContainerType.Hopper;
- case ContainerTypeOld.DROPPER: return ContainerType.Generic_3x3;
- case ContainerTypeOld.SHULKER_BOX: return ContainerType.ShulkerBox;
- case ContainerTypeOld.ENTITYHORSE: return ContainerType.Unknown;
- default: return ContainerType.Unknown;
- }
+#pragma warning disable format // @formatter:off
+ ContainerTypeOld.CONTAINER => ContainerType.Unknown,
+ ContainerTypeOld.CHEST => ContainerType.Generic_9x3,
+ ContainerTypeOld.CRAFTING_TABLE => ContainerType.Crafting,
+ ContainerTypeOld.FURNACE => ContainerType.Furnace,
+ ContainerTypeOld.DISPENSER => ContainerType.Generic_3x3,
+ ContainerTypeOld.ENCHANTING_TABLE => ContainerType.Enchantment,
+ ContainerTypeOld.BREWING_STAND => ContainerType.BrewingStand,
+ ContainerTypeOld.VILLAGER => ContainerType.Merchant,
+ ContainerTypeOld.HOPPER => ContainerType.Hopper,
+ ContainerTypeOld.DROPPER => ContainerType.Generic_3x3,
+ ContainerTypeOld.SHULKER_BOX => ContainerType.ShulkerBox,
+ ContainerTypeOld.ENTITYHORSE => ContainerType.Unknown,
+ _ => ContainerType.Unknown,
+#pragma warning restore format // @formatter:on
+ };
}
}
}
diff --git a/MinecraftClient/Inventory/ContainerTypeExtensions.cs b/MinecraftClient/Inventory/ContainerTypeExtensions.cs
index 373bbb15..166693e9 100644
--- a/MinecraftClient/Inventory/ContainerTypeExtensions.cs
+++ b/MinecraftClient/Inventory/ContainerTypeExtensions.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace MinecraftClient.Inventory
+namespace MinecraftClient.Inventory
{
public static class ContainerTypeExtensions
{
@@ -14,31 +9,33 @@ namespace MinecraftClient.Inventory
/// Slot count of the container
public static int SlotCount(this ContainerType c)
{
- switch (c)
+ return c switch
{
- case ContainerType.PlayerInventory: return 46;
- case ContainerType.Generic_9x3: return 63;
- case ContainerType.Generic_9x6: return 90;
- case ContainerType.Generic_3x3: return 45;
- case ContainerType.Crafting: return 46;
- case ContainerType.BlastFurnace: return 39;
- case ContainerType.Furnace: return 39;
- case ContainerType.Smoker: return 39;
- case ContainerType.Enchantment: return 38;
- case ContainerType.BrewingStand: return 41;
- case ContainerType.Merchant: return 39;
- case ContainerType.Beacon: return 37;
- case ContainerType.Anvil: return 39;
- case ContainerType.Hopper: return 41;
- case ContainerType.ShulkerBox: return 63;
- case ContainerType.Loom: return 40;
- case ContainerType.Stonecutter: return 38;
- case ContainerType.Lectern: return 37;
- case ContainerType.Cartography: return 39;
- case ContainerType.Grindstone: return 39;
- case ContainerType.Unknown: return 0;
- default: return 0;
- }
+#pragma warning disable format // @formatter:off
+ ContainerType.PlayerInventory => 46,
+ ContainerType.Generic_9x3 => 63,
+ ContainerType.Generic_9x6 => 90,
+ ContainerType.Generic_3x3 => 45,
+ ContainerType.Crafting => 46,
+ ContainerType.BlastFurnace => 39,
+ ContainerType.Furnace => 39,
+ ContainerType.Smoker => 39,
+ ContainerType.Enchantment => 38,
+ ContainerType.BrewingStand => 41,
+ ContainerType.Merchant => 39,
+ ContainerType.Beacon => 37,
+ ContainerType.Anvil => 39,
+ ContainerType.Hopper => 41,
+ ContainerType.ShulkerBox => 63,
+ ContainerType.Loom => 40,
+ ContainerType.Stonecutter => 38,
+ ContainerType.Lectern => 37,
+ ContainerType.Cartography => 39,
+ ContainerType.Grindstone => 39,
+ ContainerType.Unknown => 0,
+ _ => 0,
+#pragma warning restore format // @formatter:on
+ };
}
///
@@ -46,33 +43,40 @@ namespace MinecraftClient.Inventory
///
///
/// ASCII art representation or NULL if not implemented for this container type
- public static string GetAsciiArt(this ContainerType c)
+ public static string? GetAsciiArt(this ContainerType c)
{
- switch (c)
+ return c switch
{
- case ContainerType.PlayerInventory: return DefaultConfigResource.ContainerType_PlayerInventory;
- case ContainerType.Generic_9x3: return DefaultConfigResource.ContainerType_Generic_9x3;
- case ContainerType.Generic_9x6: return DefaultConfigResource.ContainerType_Generic_9x6;
- case ContainerType.Generic_3x3: return DefaultConfigResource.ContainerType_Generic_3x3;
- case ContainerType.Crafting: return DefaultConfigResource.ContainerType_Crafting;
- case ContainerType.BlastFurnace: return DefaultConfigResource.ContainerType_Furnace;
- case ContainerType.Furnace: return DefaultConfigResource.ContainerType_Furnace;
- case ContainerType.Smoker: return DefaultConfigResource.ContainerType_Furnace;
- case ContainerType.Enchantment: return null;
- case ContainerType.BrewingStand: return DefaultConfigResource.ContainerType_BrewingStand;
- case ContainerType.Merchant: return null;
- case ContainerType.Beacon: return null;
- case ContainerType.Anvil: return null;
- case ContainerType.Hopper: return DefaultConfigResource.ContainerType_Hopper;
- case ContainerType.ShulkerBox: return DefaultConfigResource.ContainerType_Generic_9x3;
- case ContainerType.Loom: return null;
- case ContainerType.Stonecutter: return null;
- case ContainerType.Lectern: return null;
- case ContainerType.Cartography: return null;
- case ContainerType.Grindstone: return DefaultConfigResource.ContainerType_Grindstone;
- case ContainerType.Unknown: return null;
- default: return null;
- }
+#pragma warning disable format // @formatter:off
+ ContainerType.PlayerInventory => DefaultConfigResource.ContainerType_PlayerInventory,
+ ContainerType.Generic_9x3 => DefaultConfigResource.ContainerType_Generic_9x3,
+ ContainerType.Generic_9x6 => DefaultConfigResource.ContainerType_Generic_9x6,
+ ContainerType.Generic_3x3 => DefaultConfigResource.ContainerType_Generic_3x3,
+ ContainerType.Crafting => DefaultConfigResource.ContainerType_Crafting,
+ ContainerType.BlastFurnace => DefaultConfigResource.ContainerType_Furnace,
+ ContainerType.Furnace => DefaultConfigResource.ContainerType_Furnace,
+ ContainerType.Smoker => DefaultConfigResource.ContainerType_Furnace,
+ ContainerType.Enchantment => null,
+ ContainerType.BrewingStand => DefaultConfigResource.ContainerType_BrewingStand,
+ ContainerType.Merchant => null,
+ ContainerType.Beacon => null,
+ ContainerType.Anvil => null,
+ ContainerType.Hopper => DefaultConfigResource.ContainerType_Hopper,
+ ContainerType.ShulkerBox => DefaultConfigResource.ContainerType_Generic_9x3,
+ ContainerType.Loom => null,
+ ContainerType.Stonecutter => null,
+ ContainerType.Lectern => null,
+ ContainerType.Cartography => null,
+ ContainerType.Grindstone => DefaultConfigResource.ContainerType_Grindstone,
+ ContainerType.Unknown => null,
+ ContainerType.Generic_9x1 => null,
+ ContainerType.Generic_9x2 => null,
+ ContainerType.Generic_9x4 => null,
+ ContainerType.Generic_9x5 => null,
+ ContainerType.SmightingTable => null,
+ _ => null,
+#pragma warning restore format // @formatter:on
+ };
}
}
}
diff --git a/MinecraftClient/Inventory/Effects.cs b/MinecraftClient/Inventory/Effects.cs
index a5f3c194..5ab62ee4 100644
--- a/MinecraftClient/Inventory/Effects.cs
+++ b/MinecraftClient/Inventory/Effects.cs
@@ -1,9 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
namespace MinecraftClient.Inventory
{
///
diff --git a/MinecraftClient/Inventory/Item.cs b/MinecraftClient/Inventory/Item.cs
index 628c4936..cfe4201e 100644
--- a/MinecraftClient/Inventory/Item.cs
+++ b/MinecraftClient/Inventory/Item.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Text;
+using System.Linq;
namespace MinecraftClient.Inventory
{
@@ -33,9 +33,9 @@ namespace MinecraftClient.Inventory
/// Item Metadata
public Item(ItemType itemType, int count, Dictionary? nbt)
{
- this.Type = itemType;
- this.Count = count;
- this.NBT = nbt;
+ Type = itemType;
+ Count = count;
+ NBT = nbt;
}
///
@@ -53,50 +53,46 @@ namespace MinecraftClient.Inventory
///
/// Retrieve item display name from NBT properties. NULL if no display name is defined.
///
- public string DisplayName
+ public string? DisplayName
{
get
{
if (NBT != null && NBT.ContainsKey("display"))
{
- var displayProperties = NBT["display"] as Dictionary;
- if (displayProperties != null && displayProperties.ContainsKey("Name"))
+ if (NBT["display"] is Dictionary displayProperties && displayProperties.ContainsKey("Name"))
{
- string displayName = displayProperties["Name"] as string;
+ string? displayName = displayProperties["Name"] as string;
if (!String.IsNullOrEmpty(displayName))
- return MinecraftClient.Protocol.ChatParser.ParseText(displayProperties["Name"].ToString());
+ return MinecraftClient.Protocol.ChatParser.ParseText(displayProperties["Name"].ToString() ?? string.Empty);
}
}
return null;
}
}
-
+
///
/// Retrieve item lores from NBT properties. Returns null if no lores is defined.
///
- public string[] Lores
+ public string[]? Lores
{
get
{
- List lores = new List();
+ List lores = new();
if (NBT != null && NBT.ContainsKey("display"))
{
- var displayProperties = NBT["display"] as Dictionary;
- if (displayProperties != null && displayProperties.ContainsKey("Lore"))
+ if (NBT["display"] is Dictionary displayProperties && displayProperties.ContainsKey("Lore"))
{
- object[] displayName = displayProperties["Lore"] as object[];
- foreach (string st in displayName)
- {
- string str = MinecraftClient.Protocol.ChatParser.ParseText(st.ToString());
- lores.Add(str);
- }
+ object[] displayName = (object[])displayProperties["Lore"];
+ lores.AddRange(from string st in displayName
+ let str = MinecraftClient.Protocol.ChatParser.ParseText(st.ToString())
+ select str);
return lores.ToArray();
}
}
return null;
}
}
-
+
///
/// Retrieve item damage from NBT properties. Returns 0 if no damage is defined.
///
@@ -109,7 +105,7 @@ namespace MinecraftClient.Inventory
object damage = NBT["Damage"];
if (damage != null)
{
- return int.Parse(damage.ToString());
+ return int.Parse(damage.ToString() ?? string.Empty);
}
}
return 0;
@@ -118,18 +114,18 @@ namespace MinecraftClient.Inventory
public override string ToString()
{
- StringBuilder sb = new StringBuilder();
+ StringBuilder sb = new();
+
sb.AppendFormat("x{0,-2} {1}", Count, Type.ToString());
- string displayName = DisplayName;
+
+ string? displayName = DisplayName;
if (!String.IsNullOrEmpty(displayName))
- {
sb.AppendFormat(" - {0}§8", displayName);
- }
+
int damage = Damage;
if (damage != 0)
- {
sb.AppendFormat(" | {0}: {1}", Translations.Get("cmd.inventory.damage"), damage);
- }
+
return sb.ToString();
}
}
diff --git a/MinecraftClient/Inventory/ItemMovingHelper.cs b/MinecraftClient/Inventory/ItemMovingHelper.cs
index 08c9d5bd..07b1e686 100644
--- a/MinecraftClient/Inventory/ItemMovingHelper.cs
+++ b/MinecraftClient/Inventory/ItemMovingHelper.cs
@@ -1,8 +1,5 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Text;
namespace MinecraftClient.Inventory
{
@@ -11,8 +8,8 @@ namespace MinecraftClient.Inventory
///
public class ItemMovingHelper
{
- private Container c;
- private McClient mc;
+ private readonly Container c;
+ private readonly McClient mc;
///
/// Create a helper that contains useful methods to move item around in container
@@ -35,7 +32,7 @@ namespace MinecraftClient.Inventory
/// Dest slot
/// Dest slot's container (only if dest slot is in other container)
/// True if success or false if Failed
- public bool MoveTo(int source, int dest, Container destContainer = null)
+ public bool MoveTo(int source, int dest, Container? destContainer = null)
{
// Condition: source has item and dest has no item
if (ValidateSlots(source, dest, destContainer) &&
@@ -53,7 +50,7 @@ namespace MinecraftClient.Inventory
/// Slot 2
/// Slot2 container (only if slot2 is in other container)
/// True if success or False if Failed
- public bool Swap(int slot1, int slot2, Container destContainer = null)
+ public bool Swap(int slot1, int slot2, Container? destContainer = null)
{
// Condition: Both slot1 and slot2 has item
if (ValidateSlots(slot1, slot2, destContainer) &&
@@ -79,7 +76,7 @@ namespace MinecraftClient.Inventory
{
if (!HasItem(source))
return false;
- List availableSlots = new List(slots.Count());
+ List availableSlots = new(slots.Count());
// filter out different item type or non-empty slots (they will be ignored silently)
foreach (var slot in slots)
if (ItemTypeEqual(source, slot) || !HasItem(slot))
@@ -126,7 +123,7 @@ namespace MinecraftClient.Inventory
/// Slot 2
/// Second container (only if slot2 is in other container)
/// The compare result
- private bool ValidateSlots(int s1, int s2, Container s2Container = null)
+ private bool ValidateSlots(int s1, int s2, Container? s2Container = null)
{
if (s2Container == null)
return (s1 != s2 && s1 < c.Type.SlotCount() && s2 < c.Type.SlotCount());
@@ -140,10 +137,9 @@ namespace MinecraftClient.Inventory
/// Slot ID
/// Specify another contianer (only if the slot is in other container)
/// True if has item
- private bool HasItem(int slot, Container c = null)
+ private bool HasItem(int slot, Container? c = null)
{
- if (c == null)
- c = this.c;
+ c ??= this.c;
return c.Items.ContainsKey(slot);
}
@@ -154,7 +150,7 @@ namespace MinecraftClient.Inventory
///
/// Second container (only if slot2 is in other container)
/// True if they are equal
- private bool ItemTypeEqual(int slot1, int slot2, Container s2Container = null)
+ private bool ItemTypeEqual(int slot1, int slot2, Container? s2Container = null)
{
if (s2Container == null)
{
diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette.cs
index 74de67b8..84f04bfa 100644
--- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette.cs
+++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette.cs
@@ -1,14 +1,11 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes
{
public abstract class ItemPalette
{
protected abstract Dictionary GetDict();
- private readonly Dictionary DictReverse = new Dictionary();
+ private readonly Dictionary DictReverse = new();
public ItemPalette()
{
diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette115.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette115.cs
index d69e143f..0ca43415 100644
--- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette115.cs
+++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette115.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes
@@ -9,7 +8,7 @@ namespace MinecraftClient.Inventory.ItemPalettes
///
public class ItemPalette115 : ItemPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static ItemPalette115()
{
diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1161.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1161.cs
index 0b0504c2..a953ec2a 100644
--- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1161.cs
+++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1161.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes
@@ -9,7 +8,7 @@ namespace MinecraftClient.Inventory.ItemPalettes
///
public class ItemPalette1161 : ItemPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static ItemPalette1161()
{
diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1162.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1162.cs
index aa674f45..b2094614 100644
--- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette1162.cs
+++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette1162.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes
@@ -9,7 +8,7 @@ namespace MinecraftClient.Inventory.ItemPalettes
///
public class ItemPalette1162 : ItemPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static ItemPalette1162()
{
diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette117.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette117.cs
index 35d903ab..92715541 100644
--- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette117.cs
+++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette117.cs
@@ -1,11 +1,10 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes
{
public class ItemPalette117 : ItemPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static ItemPalette117()
{
diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette118.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette118.cs
index d8e1d61d..a37a61a6 100644
--- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette118.cs
+++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette118.cs
@@ -1,11 +1,10 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes
{
public class ItemPalette118 : ItemPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static ItemPalette118()
{
diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPalette119.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPalette119.cs
index c0540f4a..48a9a6ea 100644
--- a/MinecraftClient/Inventory/ItemPalettes/ItemPalette119.cs
+++ b/MinecraftClient/Inventory/ItemPalettes/ItemPalette119.cs
@@ -1,11 +1,10 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Inventory.ItemPalettes
{
public class ItemPalette119 : ItemPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static ItemPalette119()
{
diff --git a/MinecraftClient/Inventory/ItemPalettes/ItemPaletteGenerator.cs b/MinecraftClient/Inventory/ItemPalettes/ItemPaletteGenerator.cs
index c58dd57e..eed9b844 100644
--- a/MinecraftClient/Inventory/ItemPalettes/ItemPaletteGenerator.cs
+++ b/MinecraftClient/Inventory/ItemPalettes/ItemPaletteGenerator.cs
@@ -1,8 +1,4 @@
using MinecraftClient.Protocol;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace MinecraftClient.Inventory.ItemPalettes
{
@@ -18,8 +14,8 @@ namespace MinecraftClient.Inventory.ItemPalettes
{
DataTypeGenerator.GenerateEnumWithPalette(
registriesJsonFile,
- "minecraft:item",
- "ItemType",
+ "minecraft:item",
+ "ItemType",
"MinecraftClient.Inventory",
"ItemPalette",
"MinecraftClient.Inventory.ItemPalettes");
diff --git a/MinecraftClient/Inventory/ItemTypeExtensions.cs b/MinecraftClient/Inventory/ItemTypeExtensions.cs
index 5c1c8ac4..7f3e5f75 100644
--- a/MinecraftClient/Inventory/ItemTypeExtensions.cs
+++ b/MinecraftClient/Inventory/ItemTypeExtensions.cs
@@ -1,7 +1,5 @@
using System;
-using System.Collections.Generic;
using System.Linq;
-using System.Text;
namespace MinecraftClient.Inventory
{
diff --git a/MinecraftClient/Inventory/VillagerTrade.cs b/MinecraftClient/Inventory/VillagerTrade.cs
index 4e1948b4..70246cab 100644
--- a/MinecraftClient/Inventory/VillagerTrade.cs
+++ b/MinecraftClient/Inventory/VillagerTrade.cs
@@ -7,7 +7,7 @@
{
public Item InputItem1;
public Item OutputItem;
- public Item InputItem2;
+ public Item? InputItem2;
public bool TradeDisabled;
public int NumberOfTradeUses;
public int MaximumNumberOfTradeUses;
@@ -16,18 +16,18 @@
public float PriceMultiplier;
public int Demand;
- public VillagerTrade(Item inputItem1, Item outputItem, Item inputItem2, bool tradeDisabled, int numberOfTradeUses, int maximumNumberOfTradeUses, int xp, int specialPrice, float priceMultiplier, int demand)
+ public VillagerTrade(Item inputItem1, Item outputItem, Item? inputItem2, bool tradeDisabled, int numberOfTradeUses, int maximumNumberOfTradeUses, int xp, int specialPrice, float priceMultiplier, int demand)
{
- this.InputItem1 = inputItem1;
- this.OutputItem = outputItem;
- this.InputItem2 = inputItem2;
- this.TradeDisabled = tradeDisabled;
- this.NumberOfTradeUses = numberOfTradeUses;
- this.MaximumNumberOfTradeUses = maximumNumberOfTradeUses;
- this.Xp = xp;
- this.SpecialPrice = specialPrice;
- this.PriceMultiplier = priceMultiplier;
- this.Demand = demand;
+ InputItem1 = inputItem1;
+ OutputItem = outputItem;
+ InputItem2 = inputItem2;
+ TradeDisabled = tradeDisabled;
+ NumberOfTradeUses = numberOfTradeUses;
+ MaximumNumberOfTradeUses = maximumNumberOfTradeUses;
+ Xp = xp;
+ SpecialPrice = specialPrice;
+ PriceMultiplier = priceMultiplier;
+ Demand = demand;
}
}
}
diff --git a/MinecraftClient/Inventory/WindowActionType.cs b/MinecraftClient/Inventory/WindowActionType.cs
index f25aea84..a0b9d904 100644
--- a/MinecraftClient/Inventory/WindowActionType.cs
+++ b/MinecraftClient/Inventory/WindowActionType.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace MinecraftClient.Inventory
+namespace MinecraftClient.Inventory
{
///
/// Represents mouse interactions with an inventory window
diff --git a/MinecraftClient/Json.cs b/MinecraftClient/Json.cs
index 1904f494..06722166 100644
--- a/MinecraftClient/Json.cs
+++ b/MinecraftClient/Json.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.Text;
namespace MinecraftClient
@@ -27,7 +26,7 @@ namespace MinecraftClient
public class JSONData
{
public enum DataType { Object, Array, String };
- private DataType type;
+ private readonly DataType type;
public DataType Type { get { return type; } }
public Dictionary Properties;
public List DataArray;
@@ -137,9 +136,20 @@ namespace MinecraftClient
break;
//Number
- case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '.':
+ case '-':
data = new JSONData(JSONData.DataType.String);
- StringBuilder sb = new StringBuilder();
+ StringBuilder sb = new();
while ((toparse[cursorpos] >= '0' && toparse[cursorpos] <= '9') || toparse[cursorpos] == '.' || toparse[cursorpos] == '-')
{
sb.Append(toparse[cursorpos]);
diff --git a/MinecraftClient/Logger/FileLogLogger.cs b/MinecraftClient/Logger/FileLogLogger.cs
index 6dab993f..f065ed83 100644
--- a/MinecraftClient/Logger/FileLogLogger.cs
+++ b/MinecraftClient/Logger/FileLogLogger.cs
@@ -1,16 +1,13 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using System.IO;
namespace MinecraftClient.Logger
{
public class FileLogLogger : FilteredLogger
{
- private string logFile;
- private bool prependTimestamp;
- private object logFileLock = new object();
+ private readonly string logFile;
+ private readonly bool prependTimestamp;
+ private readonly object logFileLock = new();
public FileLogLogger(string file, bool prependTimestamp = false)
{
@@ -34,13 +31,13 @@ namespace MinecraftClient.Logger
if (prependTimestamp)
msg = GetTimestamp() + ' ' + msg;
- string directory = Path.GetDirectoryName(logFile);
+ string? directory = Path.GetDirectoryName(logFile);
if (!String.IsNullOrEmpty(directory) && !Directory.Exists(directory))
Directory.CreateDirectory(directory);
lock (logFileLock)
{
- FileStream stream = new FileStream(logFile, FileMode.OpenOrCreate);
- StreamWriter writer = new StreamWriter(stream);
+ FileStream stream = new(logFile, FileMode.OpenOrCreate);
+ StreamWriter writer = new(stream);
stream.Seek(0, SeekOrigin.End);
writer.WriteLine(msg);
writer.Dispose();
diff --git a/MinecraftClient/Logger/FilteredLogger.cs b/MinecraftClient/Logger/FilteredLogger.cs
index 288d75f2..d3878f89 100644
--- a/MinecraftClient/Logger/FilteredLogger.cs
+++ b/MinecraftClient/Logger/FilteredLogger.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
namespace MinecraftClient.Logger
{
@@ -12,9 +8,9 @@ namespace MinecraftClient.Logger
protected bool ShouldDisplay(FilterChannel channel, string msg)
{
- Regex regexToUse = null;
+ Regex? regexToUse = null;
// Convert to bool for XOR later. Whitelist = 0, Blacklist = 1
- bool filterMode = Settings.FilterMode == Settings.FilterModeEnum.Blacklist ? true : false;
+ bool filterMode = Settings.FilterMode == Settings.FilterModeEnum.Blacklist;
switch (channel)
{
case FilterChannel.Chat: regexToUse = Settings.ChatFilter; break;
diff --git a/MinecraftClient/Logger/ILogger.cs b/MinecraftClient/Logger/ILogger.cs
index 98b810d2..ba3f143f 100644
--- a/MinecraftClient/Logger/ILogger.cs
+++ b/MinecraftClient/Logger/ILogger.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace MinecraftClient.Logger
+namespace MinecraftClient.Logger
{
public interface ILogger
{
diff --git a/MinecraftClient/Logger/LoggerBase.cs b/MinecraftClient/Logger/LoggerBase.cs
index 1ea31c6d..8569bfc9 100644
--- a/MinecraftClient/Logger/LoggerBase.cs
+++ b/MinecraftClient/Logger/LoggerBase.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace MinecraftClient.Logger
+namespace MinecraftClient.Logger
{
///
/// Abstract class providing basic implementation of the ILogger interface
@@ -30,7 +25,7 @@ namespace MinecraftClient.Logger
public void Chat(object msg)
{
- Chat(msg.ToString());
+ Chat(msg.ToString() ?? string.Empty);
}
public abstract void Debug(string msg);
@@ -42,7 +37,7 @@ namespace MinecraftClient.Logger
public void Debug(object msg)
{
- Debug(msg.ToString());
+ Debug(msg.ToString() ?? string.Empty);
}
public abstract void Error(string msg);
@@ -54,7 +49,7 @@ namespace MinecraftClient.Logger
public void Error(object msg)
{
- Error(msg.ToString());
+ Error(msg.ToString() ?? string.Empty);
}
public abstract void Info(string msg);
@@ -66,7 +61,7 @@ namespace MinecraftClient.Logger
public void Info(object msg)
{
- Info(msg.ToString());
+ Info(msg.ToString() ?? string.Empty);
}
public abstract void Warn(string msg);
@@ -78,12 +73,12 @@ namespace MinecraftClient.Logger
public void Warn(object msg)
{
- Warn(msg.ToString());
+ Warn(msg.ToString() ?? string.Empty);
}
protected virtual void Log(object msg)
{
- ConsoleIO.WriteLineFormatted(msg.ToString());
+ ConsoleIO.WriteLineFormatted(msg.ToString() ?? string.Empty);
}
protected virtual void Log(string msg)
diff --git a/MinecraftClient/Mapping/Block.cs b/MinecraftClient/Mapping/Block.cs
index 5aa1f382..595356ab 100644
--- a/MinecraftClient/Mapping/Block.cs
+++ b/MinecraftClient/Mapping/Block.cs
@@ -1,8 +1,5 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Runtime.CompilerServices;
-using System.Text;
using MinecraftClient.Mapping.BlockPalettes;
namespace MinecraftClient.Mapping
@@ -18,7 +15,7 @@ namespace MinecraftClient.Mapping
/// Get or set global block ID to Material mapping
/// The global Palette is a concept introduced with Minecraft 1.13
///
- public static BlockPalette Palette { get; set; }
+ public static BlockPalette Palette { get; set; } = new Palette112();
///
/// Storage for block ID and metadata, as ushort for compatibility, performance and lower memory footprint
@@ -45,13 +42,13 @@ namespace MinecraftClient.Mapping
if (Palette.IdHasMetadata)
{
if (value > (ushort.MaxValue >> 4) || value < 0)
- throw new ArgumentOutOfRangeException("value", "Invalid block ID. Accepted range: 0-4095");
+ throw new ArgumentOutOfRangeException(nameof(value), "Invalid block ID. Accepted range: 0-4095");
blockIdAndMeta = (ushort)(value << 4 | BlockMeta);
}
else
{
if (value > ushort.MaxValue || value < 0)
- throw new ArgumentOutOfRangeException("value", "Invalid block ID. Accepted range: 0-65535");
+ throw new ArgumentOutOfRangeException(nameof(value), "Invalid block ID. Accepted range: 0-65535");
blockIdAndMeta = (ushort)value;
}
}
@@ -100,9 +97,9 @@ namespace MinecraftClient.Mapping
{
if (!Palette.IdHasMetadata)
throw new InvalidOperationException("Current global Palette does not support block Metadata");
- this.blockIdAndMeta = 0;
- this.BlockId = type;
- this.BlockMeta = metadata;
+ blockIdAndMeta = 0;
+ BlockId = type;
+ BlockMeta = metadata;
}
///
@@ -112,7 +109,7 @@ namespace MinecraftClient.Mapping
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public Block(ushort typeAndMeta)
{
- this.blockIdAndMeta = typeAndMeta;
+ blockIdAndMeta = typeAndMeta;
}
///
diff --git a/MinecraftClient/Mapping/BlockPalettes/BlockPalette.cs b/MinecraftClient/Mapping/BlockPalettes/BlockPalette.cs
index 9b8611b6..a3cd7986 100644
--- a/MinecraftClient/Mapping/BlockPalettes/BlockPalette.cs
+++ b/MinecraftClient/Mapping/BlockPalettes/BlockPalette.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes
{
diff --git a/MinecraftClient/Mapping/BlockPalettes/BlockPaletteGenerator.cs b/MinecraftClient/Mapping/BlockPalettes/BlockPaletteGenerator.cs
index 831b3abe..57675b5f 100644
--- a/MinecraftClient/Mapping/BlockPalettes/BlockPaletteGenerator.cs
+++ b/MinecraftClient/Mapping/BlockPalettes/BlockPaletteGenerator.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.IO;
+using System.Linq;
using System.Text;
namespace MinecraftClient.Mapping.BlockPalettes
@@ -42,13 +42,13 @@ namespace MinecraftClient.Mapping.BlockPalettes
/// output path for material.cs
/// java -cp minecraft_server.jar net.minecraft.data.Main --reports
/// state => block name mappings
- public static void JsonToClass(string blocksJsonFile, string outputClass, string outputEnum = null)
+ public static void JsonToClass(string blocksJsonFile, string outputClass, string? outputEnum = null)
{
- string outputPalettePath = Path.Combine(Path.GetDirectoryName(blocksJsonFile), outputClass + "XXX.cs");
- string outputEnumPath = Path.Combine(Path.GetDirectoryName(blocksJsonFile), outputEnum + "XXX.cs");
+ string outputPalettePath = Path.Combine(Path.GetDirectoryName(blocksJsonFile)!, outputClass + "XXX.cs");
+ string outputEnumPath = Path.Combine(Path.GetDirectoryName(blocksJsonFile)!, outputEnum + "XXX.cs");
- HashSet knownStates = new HashSet();
- Dictionary> blocks = new Dictionary>();
+ HashSet knownStates = new();
+ Dictionary> blocks = new();
Json.JSONData palette = Json.ParseJson(File.ReadAllText(blocksJsonFile, Encoding.UTF8));
foreach (KeyValuePair item in palette.Properties)
@@ -76,17 +76,16 @@ namespace MinecraftClient.Mapping.BlockPalettes
}
}
- HashSet materials = new HashSet();
- List outFile = new List();
+ HashSet materials = new();
+ List outFile = new();
outFile.AddRange(new[] {
- "using System;",
"using System.Collections.Generic;",
"",
"namespace MinecraftClient.Mapping.BlockPalettes",
"{",
" public class PaletteXXX : BlockPalette",
" {",
- " private static Dictionary materials = new Dictionary();",
+ " private static readonly Dictionary materials = new();",
"",
" static PaletteXXX()",
" {",
@@ -103,7 +102,7 @@ namespace MinecraftClient.Mapping.BlockPalettes
if (idList.Count > 1)
{
idList.Sort();
- Queue idQueue = new Queue(idList);
+ Queue idQueue = new(idList);
while (idQueue.Count > 0)
{
diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette112.cs b/MinecraftClient/Mapping/BlockPalettes/Palette112.cs
index 7afc42ad..02dde423 100644
--- a/MinecraftClient/Mapping/BlockPalettes/Palette112.cs
+++ b/MinecraftClient/Mapping/BlockPalettes/Palette112.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes
@@ -11,7 +10,7 @@ namespace MinecraftClient.Mapping.BlockPalettes
///
public class Palette112 : BlockPalette
{
- private static Dictionary materials = new Dictionary()
+ private static readonly Dictionary materials = new()
{
{ 0, Material.Air },
{ 1, Material.Stone },
diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette113.cs b/MinecraftClient/Mapping/BlockPalettes/Palette113.cs
index b0e2006d..55be9672 100644
--- a/MinecraftClient/Mapping/BlockPalettes/Palette113.cs
+++ b/MinecraftClient/Mapping/BlockPalettes/Palette113.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes
@@ -9,7 +8,7 @@ namespace MinecraftClient.Mapping.BlockPalettes
///
public class Palette113 : BlockPalette
{
- private static Dictionary materials = new Dictionary();
+ private static readonly Dictionary materials = new();
static Palette113()
{
diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette114.cs b/MinecraftClient/Mapping/BlockPalettes/Palette114.cs
index b44b20d6..b21e0830 100644
--- a/MinecraftClient/Mapping/BlockPalettes/Palette114.cs
+++ b/MinecraftClient/Mapping/BlockPalettes/Palette114.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes
@@ -9,7 +8,7 @@ namespace MinecraftClient.Mapping.BlockPalettes
///
public class Palette114 : BlockPalette
{
- private static Dictionary materials = new Dictionary();
+ private static readonly Dictionary materials = new();
static Palette114()
{
diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette115.cs b/MinecraftClient/Mapping/BlockPalettes/Palette115.cs
index e84fbd11..b43a1ce9 100644
--- a/MinecraftClient/Mapping/BlockPalettes/Palette115.cs
+++ b/MinecraftClient/Mapping/BlockPalettes/Palette115.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes
@@ -9,7 +8,7 @@ namespace MinecraftClient.Mapping.BlockPalettes
///
public class Palette115 : BlockPalette
{
- private static Dictionary materials = new Dictionary();
+ private static readonly Dictionary materials = new();
static Palette115()
{
diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette116.cs b/MinecraftClient/Mapping/BlockPalettes/Palette116.cs
index 1d63b6b4..3b2524f5 100644
--- a/MinecraftClient/Mapping/BlockPalettes/Palette116.cs
+++ b/MinecraftClient/Mapping/BlockPalettes/Palette116.cs
@@ -1,11 +1,10 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes
{
public class Palette116 : BlockPalette
{
- private static Dictionary materials = new Dictionary();
+ private static readonly Dictionary materials = new();
static Palette116()
{
diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette117.cs b/MinecraftClient/Mapping/BlockPalettes/Palette117.cs
index 826b630e..ff0358d1 100644
--- a/MinecraftClient/Mapping/BlockPalettes/Palette117.cs
+++ b/MinecraftClient/Mapping/BlockPalettes/Palette117.cs
@@ -1,11 +1,10 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes
{
public class Palette117 : BlockPalette
{
- private static Dictionary materials = new Dictionary();
+ private static readonly Dictionary materials = new();
static Palette117()
{
diff --git a/MinecraftClient/Mapping/BlockPalettes/Palette119.cs b/MinecraftClient/Mapping/BlockPalettes/Palette119.cs
index 88521065..ab276fee 100644
--- a/MinecraftClient/Mapping/BlockPalettes/Palette119.cs
+++ b/MinecraftClient/Mapping/BlockPalettes/Palette119.cs
@@ -1,11 +1,10 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.BlockPalettes
{
public class Palette119 : BlockPalette
{
- private static Dictionary materials = new Dictionary();
+ private static readonly Dictionary materials = new();
static Palette119()
{
diff --git a/MinecraftClient/Mapping/Chunk.cs b/MinecraftClient/Mapping/Chunk.cs
index 90ef604e..4041343b 100644
--- a/MinecraftClient/Mapping/Chunk.cs
+++ b/MinecraftClient/Mapping/Chunk.cs
@@ -1,9 +1,5 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Runtime.CompilerServices;
-using System.Text;
-using System.Threading;
namespace MinecraftClient.Mapping
{
diff --git a/MinecraftClient/Mapping/ChunkColumn.cs b/MinecraftClient/Mapping/ChunkColumn.cs
index 5e40c954..38f37c63 100644
--- a/MinecraftClient/Mapping/ChunkColumn.cs
+++ b/MinecraftClient/Mapping/ChunkColumn.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
namespace MinecraftClient.Mapping
{
diff --git a/MinecraftClient/Mapping/CommandBlockFlags.cs b/MinecraftClient/Mapping/CommandBlockFlags.cs
index 5807222e..9241fa61 100644
--- a/MinecraftClient/Mapping/CommandBlockFlags.cs
+++ b/MinecraftClient/Mapping/CommandBlockFlags.cs
@@ -1,8 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
namespace MinecraftClient.Mapping
{
///
diff --git a/MinecraftClient/Mapping/CommandBlockMode.cs b/MinecraftClient/Mapping/CommandBlockMode.cs
index 6d4aba67..9dd492ce 100644
--- a/MinecraftClient/Mapping/CommandBlockMode.cs
+++ b/MinecraftClient/Mapping/CommandBlockMode.cs
@@ -1,8 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
namespace MinecraftClient.Mapping
{
///
diff --git a/MinecraftClient/Mapping/Dimension.cs b/MinecraftClient/Mapping/Dimension.cs
index d260ce71..3aea6744 100644
--- a/MinecraftClient/Mapping/Dimension.cs
+++ b/MinecraftClient/Mapping/Dimension.cs
@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
namespace MinecraftClient.Mapping
{
@@ -120,7 +117,7 @@ namespace MinecraftClient.Mapping
///
public Dimension()
{
- this.Name = "minecraft:overworld";
+ Name = "minecraft:overworld";
}
///
@@ -130,73 +127,66 @@ namespace MinecraftClient.Mapping
/// The dimension type (NBT Tag Compound)
public Dimension(string name, Dictionary nbt)
{
- if (name == null)
- throw new ArgumentNullException("name");
- if (nbt == null)
- throw new ArgumentNullException("nbt Data");
+ Name = name ?? throw new ArgumentNullException(nameof(name));
- this.Name = name;
+ if (nbt == null)
+ throw new ArgumentNullException(nameof(nbt));
if (nbt.ContainsKey("piglin_safe"))
- this.piglinSafe = 1 == (byte)nbt["piglin_safe"];
+ piglinSafe = Convert.ToBoolean(nbt["piglin_safe"]);
if (nbt.ContainsKey("monster_spawn_light_level"))
{
try
{
var monsterSpawnLightLevelObj = nbt["monster_spawn_light_level"];
- if (monsterSpawnLightLevelObj.GetType() == typeof(int))
- this.monsterSpawnMinLightLevel = this.monsterSpawnMaxLightLevel = (int)monsterSpawnLightLevelObj;
- else
+ try
+ {
+ monsterSpawnMinLightLevel = monsterSpawnMaxLightLevel = Convert.ToInt32(monsterSpawnLightLevelObj);
+ }
+ catch (Exception)
{
var inclusive = (Dictionary)(((Dictionary)monsterSpawnLightLevelObj)["value"]);
- this.monsterSpawnMinLightLevel = (int)inclusive["min_inclusive"];
- this.monsterSpawnMaxLightLevel = (int)inclusive["max_inclusive"];
+ monsterSpawnMinLightLevel = Convert.ToInt32(inclusive["min_inclusive"]);
+ monsterSpawnMaxLightLevel = Convert.ToInt32(inclusive["max_inclusive"]);
}
}
catch (KeyNotFoundException) { }
}
if (nbt.ContainsKey("monster_spawn_block_light_limit"))
- this.monsterSpawnBlockLightLimit = (int)nbt["monster_spawn_block_light_limit"];
+ monsterSpawnBlockLightLimit = Convert.ToInt32(nbt["monster_spawn_block_light_limit"]);
if (nbt.ContainsKey("natural"))
- this.natural = 1 == (byte)nbt["natural"];
+ natural = Convert.ToBoolean(nbt["natural"]);
if (nbt.ContainsKey("ambient_light"))
- this.ambientLight = (float)nbt["ambient_light"];
+ ambientLight = (float)Convert.ToDouble(nbt["ambient_light"]);
if (nbt.ContainsKey("fixed_time"))
- this.fixedTime = (long)nbt["fixed_time"];
+ fixedTime = Convert.ToInt64(nbt["fixed_time"]);
if (nbt.ContainsKey("infiniburn"))
- this.infiniburn = (string)nbt["infiniburn"];
+ infiniburn = Convert.ToString(nbt["infiniburn"]) ?? string.Empty;
if (nbt.ContainsKey("respawn_anchor_works"))
- this.respawnAnchorWorks = 1 == (byte)nbt["respawn_anchor_works"];
+ respawnAnchorWorks = Convert.ToBoolean(nbt["respawn_anchor_works"]);
if (nbt.ContainsKey("has_skylight"))
- this.hasSkylight = 1 == (byte)nbt["has_skylight"];
+ hasSkylight = Convert.ToBoolean(nbt["has_skylight"]);
if (nbt.ContainsKey("bed_works"))
- this.bedWorks = 1 == (byte)nbt["bed_works"];
+ bedWorks = Convert.ToBoolean(nbt["bed_works"]);
if (nbt.ContainsKey("effects"))
- this.effects = (string)nbt["effects"];
+ effects = Convert.ToString(nbt["effects"]) ?? string.Empty;
if (nbt.ContainsKey("has_raids"))
- this.hasRaids = 1 == (byte)nbt["has_raids"];
+ hasRaids = Convert.ToBoolean(nbt["has_raids"]);
if (nbt.ContainsKey("min_y"))
- this.minY = (int)nbt["min_y"];
+ minY = Convert.ToInt32(nbt["min_y"]);
if (nbt.ContainsKey("height"))
- this.height = (int)nbt["height"];
+ height = Convert.ToInt32(nbt["height"]);
if (nbt.ContainsKey("min_y") && nbt.ContainsKey("height"))
- this.maxY = this.minY + this.height;
+ maxY = minY + height;
if (nbt.ContainsKey("logical_height") && nbt["logical_height"].GetType() != typeof(byte))
- this.logicalHeight = (int)nbt["logical_height"];
+ logicalHeight = Convert.ToInt32(nbt["logical_height"]);
if (nbt.ContainsKey("coordinate_scale"))
- {
- var coordinateScaleObj = nbt["coordinate_scale"];
- if (coordinateScaleObj.GetType() == typeof(float))
- this.coordinateScale = (float)coordinateScaleObj;
- else
- this.coordinateScale = (double)coordinateScaleObj;
- }
+ coordinateScale = Convert.ToDouble(nbt["coordinate_scale"]);
if (nbt.ContainsKey("ultrawarm"))
- this.ultrawarm = 1 == (byte)nbt["ultrawarm"];
+ ultrawarm = Convert.ToBoolean(nbt["ultrawarm"]);
if (nbt.ContainsKey("has_ceiling"))
- this.hasCeiling = 1 == (byte)nbt["has_ceiling"];
+ hasCeiling = Convert.ToBoolean(nbt["has_ceiling"]);
}
-
}
}
diff --git a/MinecraftClient/Mapping/Direction.cs b/MinecraftClient/Mapping/Direction.cs
index 209d97e2..9f3ed7fe 100644
--- a/MinecraftClient/Mapping/Direction.cs
+++ b/MinecraftClient/Mapping/Direction.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace MinecraftClient.Mapping
+namespace MinecraftClient.Mapping
{
///
/// Represents a unit movement in the world
diff --git a/MinecraftClient/Mapping/Entity.cs b/MinecraftClient/Mapping/Entity.cs
index e32f43e8..bd19247b 100644
--- a/MinecraftClient/Mapping/Entity.cs
+++ b/MinecraftClient/Mapping/Entity.cs
@@ -23,12 +23,12 @@ namespace MinecraftClient.Mapping
/// Nickname of the entity if it is a player.
///
public string? Name;
-
+
///
/// CustomName of the entity.
///
- public string CustomNameJson;
-
+ public string? CustomNameJson;
+
///
/// IsCustomNameVisible of the entity.
///
@@ -37,8 +37,8 @@ namespace MinecraftClient.Mapping
///
/// CustomName of the entity.
///
- public string CustomName;
-
+ public string? CustomName;
+
///
/// Latency of the entity if it is a player.
///
@@ -77,21 +77,21 @@ namespace MinecraftClient.Mapping
/// Health of the entity
///
public float Health;
-
+
///
/// Item of the entity if ItemFrame or Item
///
public Item Item;
-
+
///
/// Entity pose in the Minecraft world
///
public EntityPose Pose;
-
+
///
/// Entity metadata
///
- public Dictionary Metadata;
+ public Dictionary? Metadata;
///
/// Entity equipment
@@ -107,11 +107,11 @@ namespace MinecraftClient.Mapping
public Entity(int ID, EntityType type, Location location)
{
this.ID = ID;
- this.Type = type;
- this.Location = location;
- this.Health = 1.0f;
- this.Equipment = new Dictionary();
- this.Item = new Item(ItemType.Air, 0, null);
+ Type = type;
+ Location = location;
+ Health = 1.0f;
+ Equipment = new Dictionary();
+ Item = new Item(ItemType.Air, 0, null);
}
///
@@ -123,14 +123,14 @@ namespace MinecraftClient.Mapping
public Entity(int ID, EntityType type, Location location, byte yaw, byte pitch, int objectData)
{
this.ID = ID;
- this.Type = type;
- this.Location = location;
- this.Health = 1.0f;
- this.Equipment = new Dictionary();
- this.Item = new Item(ItemType.Air, 0, null);
- this.Yaw = yaw * (1 / 256) * 360; // to angle in 360 degree
- this.Pitch = pitch * (1 / 256) * 360;
- this.ObjectData = objectData;
+ Type = type;
+ Location = location;
+ Health = 1.0f;
+ Equipment = new Dictionary();
+ Item = new Item(ItemType.Air, 0, null);
+ Yaw = yaw * (1 / 256) * 360; // to angle in 360 degree
+ Pitch = pitch * (1 / 256) * 360;
+ ObjectData = objectData;
}
///
@@ -144,15 +144,15 @@ namespace MinecraftClient.Mapping
public Entity(int ID, EntityType type, Location location, Guid uuid, string? name, byte yaw, byte pitch)
{
this.ID = ID;
- this.Type = type;
- this.Location = location;
- this.UUID = uuid;
- this.Name = name;
- this.Health = 1.0f;
- this.Equipment = new Dictionary();
- this.Item = new Item(ItemType.Air, 0, null);
- this.Yaw = yaw * (1 / 256) * 360; // to angle in 360 degree
- this.Pitch = pitch * (1 / 256) * 360;
+ Type = type;
+ Location = location;
+ UUID = uuid;
+ Name = name;
+ Health = 1.0f;
+ Equipment = new Dictionary();
+ Item = new Item(ItemType.Air, 0, null);
+ Yaw = yaw * (1 / 256) * 360; // to angle in 360 degree
+ Pitch = pitch * (1 / 256) * 360;
}
}
}
diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette.cs
index df7abd5d..d1e30c16 100644
--- a/MinecraftClient/Mapping/EntityPalettes/EntityPalette.cs
+++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes
{
@@ -17,7 +14,7 @@ namespace MinecraftClient.Mapping.EntityPalettes
/// Get mapping dictionary for pre-1.14 non-living entities.
///
/// Palette dictionary for non-living entities (pre-1.14)
- protected virtual Dictionary GetDictNonLiving()
+ protected virtual Dictionary? GetDictNonLiving()
{
return null;
}
@@ -30,7 +27,7 @@ namespace MinecraftClient.Mapping.EntityPalettes
public EntityType FromId(int id, bool living)
{
Dictionary entityTypes = GetDict();
- Dictionary entityTypesNonLiving = GetDictNonLiving();
+ Dictionary? entityTypesNonLiving = GetDictNonLiving();
if (entityTypesNonLiving != null && !living)
{
diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette112.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette112.cs
index 322dff54..15d0dcd4 100644
--- a/MinecraftClient/Mapping/EntityPalettes/EntityPalette112.cs
+++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette112.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes
{
diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette113.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette113.cs
index 5d66bf37..cc1b1654 100644
--- a/MinecraftClient/Mapping/EntityPalettes/EntityPalette113.cs
+++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette113.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes
diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette114.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette114.cs
index b0140581..a908cc1f 100644
--- a/MinecraftClient/Mapping/EntityPalettes/EntityPalette114.cs
+++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette114.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes
@@ -9,7 +8,7 @@ namespace MinecraftClient.Mapping.EntityPalettes
///
public class EntityPalette114 : EntityPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static EntityPalette114()
{
diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette115.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette115.cs
index 4d242f93..d8f67560 100644
--- a/MinecraftClient/Mapping/EntityPalettes/EntityPalette115.cs
+++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette115.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes
@@ -9,7 +8,7 @@ namespace MinecraftClient.Mapping.EntityPalettes
///
public class EntityPalette115 : EntityPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static EntityPalette115()
{
diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette1161.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1161.cs
index 494fedd2..7aa83ea4 100644
--- a/MinecraftClient/Mapping/EntityPalettes/EntityPalette1161.cs
+++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1161.cs
@@ -1,11 +1,10 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes
{
public class EntityPalette1161 : EntityPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static EntityPalette1161()
{
diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette1162.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1162.cs
index 6fc9be32..fcb00cd6 100644
--- a/MinecraftClient/Mapping/EntityPalettes/EntityPalette1162.cs
+++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette1162.cs
@@ -1,11 +1,10 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes
{
public class EntityPalette1162 : EntityPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static EntityPalette1162()
{
diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette117.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette117.cs
index 65d9272a..ce292066 100644
--- a/MinecraftClient/Mapping/EntityPalettes/EntityPalette117.cs
+++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette117.cs
@@ -1,11 +1,10 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes
{
public class EntityPalette117 : EntityPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static EntityPalette117()
{
diff --git a/MinecraftClient/Mapping/EntityPalettes/EntityPalette119.cs b/MinecraftClient/Mapping/EntityPalettes/EntityPalette119.cs
index b85059cc..51f87e18 100644
--- a/MinecraftClient/Mapping/EntityPalettes/EntityPalette119.cs
+++ b/MinecraftClient/Mapping/EntityPalettes/EntityPalette119.cs
@@ -1,11 +1,10 @@
-using System;
using System.Collections.Generic;
namespace MinecraftClient.Mapping.EntityPalettes
{
public class EntityPalette119 : EntityPalette
{
- private static Dictionary mappings = new Dictionary();
+ private static readonly Dictionary mappings = new();
static EntityPalette119()
{
diff --git a/MinecraftClient/Mapping/EntityTypeExtensions.cs b/MinecraftClient/Mapping/EntityTypeExtensions.cs
index b022394b..e6546d22 100644
--- a/MinecraftClient/Mapping/EntityTypeExtensions.cs
+++ b/MinecraftClient/Mapping/EntityTypeExtensions.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace MinecraftClient.Mapping
+namespace MinecraftClient.Mapping
{
public static class EntityTypeExtensions
{
diff --git a/MinecraftClient/Mapping/InteractType.cs b/MinecraftClient/Mapping/InteractType.cs
index 02876e8f..f54a1014 100644
--- a/MinecraftClient/Mapping/InteractType.cs
+++ b/MinecraftClient/Mapping/InteractType.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MinecraftClient.Mapping
+namespace MinecraftClient.Mapping
{
public enum InteractType
{
diff --git a/MinecraftClient/Mapping/Location.cs b/MinecraftClient/Mapping/Location.cs
index 5852e6c6..069fdf32 100644
--- a/MinecraftClient/Mapping/Location.cs
+++ b/MinecraftClient/Mapping/Location.cs
@@ -1,8 +1,5 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Runtime.CompilerServices;
-using System.Text;
namespace MinecraftClient.Mapping
{
@@ -159,7 +156,7 @@ namespace MinecraftClient.Mapping
/// New location
public Location ToFloor()
{
- return new Location(Math.Floor(this.X), Math.Floor(this.Y), Math.Floor(this.Z));
+ return new Location(Math.Floor(X), Math.Floor(Y), Math.Floor(Z));
}
///
@@ -168,7 +165,7 @@ namespace MinecraftClient.Mapping
/// New location
public Location ToCenter()
{
- return new Location(Math.Floor(this.X) + 0.5, this.Y, Math.Floor(this.Z) + 0.5);
+ return new Location(Math.Floor(X) + 0.5, Y, Math.Floor(Z) + 0.5);
}
///
@@ -273,15 +270,15 @@ namespace MinecraftClient.Mapping
///
/// Object to compare to
/// TRUE if the locations are equals
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
if (obj == null)
return false;
- if (obj is Location)
+ if (obj is Location location)
{
- return ((int)this.X) == ((int)((Location)obj).X)
- && ((int)this.Y) == ((int)((Location)obj).Y)
- && ((int)this.Z) == ((int)((Location)obj).Z);
+ return ((int)X) == ((int)location.X)
+ && ((int)Y) == ((int)location.Y)
+ && ((int)Z) == ((int)location.Z);
}
return false;
}
@@ -293,6 +290,11 @@ namespace MinecraftClient.Mapping
/// Second location to compare
/// TRUE if the locations are equals
public static bool operator ==(Location loc1, Location loc2)
+ {
+ return loc1.Equals(loc2);
+ }
+
+ public static bool operator ==(Location? loc1, Location? loc2)
{
if (loc1 == null && loc2 == null)
return true;
@@ -308,6 +310,11 @@ namespace MinecraftClient.Mapping
/// Second location to compare
/// TRUE if the locations are equals
public static bool operator !=(Location loc1, Location loc2)
+ {
+ return !loc1.Equals(loc2);
+ }
+
+ public static bool operator !=(Location? loc1, Location? loc2)
{
if (loc1 == null && loc2 == null)
return false;
diff --git a/MinecraftClient/Mapping/MapIcon.cs b/MinecraftClient/Mapping/MapIcon.cs
index 155f1b97..3862b8db 100644
--- a/MinecraftClient/Mapping/MapIcon.cs
+++ b/MinecraftClient/Mapping/MapIcon.cs
@@ -1,11 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using MinecraftClient.Protocol.Handlers;
-
-namespace MinecraftClient.Mapping
+namespace MinecraftClient.Mapping
{
public class MapIcon
{
diff --git a/MinecraftClient/Mapping/MapIconType.cs b/MinecraftClient/Mapping/MapIconType.cs
index 68a1e307..125527e5 100644
--- a/MinecraftClient/Mapping/MapIconType.cs
+++ b/MinecraftClient/Mapping/MapIconType.cs
@@ -1,10 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MinecraftClient.Mapping
+namespace MinecraftClient.Mapping
{
public enum MapIconType
{
diff --git a/MinecraftClient/Mapping/Material2Tool.cs b/MinecraftClient/Mapping/Material2Tool.cs
index f2259d0f..d94315ab 100644
--- a/MinecraftClient/Mapping/Material2Tool.cs
+++ b/MinecraftClient/Mapping/Material2Tool.cs
@@ -1,5 +1,5 @@
-using MinecraftClient.Inventory;
-using System.Collections.Generic;
+using System.Collections.Generic;
+using MinecraftClient.Inventory;
namespace MinecraftClient.Mapping
{
@@ -8,7 +8,7 @@ namespace MinecraftClient.Mapping
// Made with the following ressources: https://minecraft.fandom.com/wiki/Breaking
// Sorted in alphabetical order.
// Minable by Any Pickaxe.
- private static readonly List pickaxeTier0 = new List()
+ private static readonly List pickaxeTier0 = new()
{
Material.ActivatorRail,
Material.Andesite,
@@ -281,7 +281,7 @@ namespace MinecraftClient.Mapping
Material.YellowTerracotta,
};
// Minable by Stone, iron, diamond, netherite.
- private static readonly List pickaxeTier1 = new List()
+ private static readonly List pickaxeTier1 = new()
{
Material.CopperOre,
Material.CopperBlock,
@@ -329,7 +329,7 @@ namespace MinecraftClient.Mapping
Material.WeatheredCutCopper,
};
// Minable by Iron, diamond, netherite.
- private static readonly List pickaxeTier2 = new List()
+ private static readonly List pickaxeTier2 = new()
{
Material.DeepslateDiamondOre,
Material.DeepslateEmeraldOre,
@@ -345,7 +345,7 @@ namespace MinecraftClient.Mapping
Material.RedstoneOre,
};
// Minable by Diamond, Netherite.
- private static readonly List pickaxeTier3 = new List()
+ private static readonly List pickaxeTier3 = new()
{
Material.AncientDebris,
Material.CryingObsidian,
@@ -355,7 +355,7 @@ namespace MinecraftClient.Mapping
};
// Every shovel can mine every block (speed difference).
- private static readonly List shovel = new List()
+ private static readonly List shovel = new()
{
Material.BlackConcretePowder,
Material.BlueConcretePowder,
@@ -393,7 +393,7 @@ namespace MinecraftClient.Mapping
Material.YellowConcretePowder,
};
// Every axe can mine every block (speed difference).
- private static readonly List axe = new List()
+ private static readonly List axe = new()
{
Material.AcaciaButton,
Material.AcaciaDoor,
@@ -578,7 +578,7 @@ namespace MinecraftClient.Mapping
Material.YellowWallBanner,
};
// Every block a shear can mine.
- private static readonly List shears = new List()
+ private static readonly List shears = new()
{
Material.AcaciaLeaves,
Material.AzaleaLeaves,
@@ -607,7 +607,7 @@ namespace MinecraftClient.Mapping
Material.YellowWool,
};
// Every block that is mined with a sword.
- private static readonly List sword = new List()
+ private static readonly List sword = new()
{
Material.Bamboo,
Material.Cobweb,
@@ -620,7 +620,7 @@ namespace MinecraftClient.Mapping
Material.InfestedStoneBricks,
};
// Every block that can be mined with a hoe.
- private static readonly List hoe = new List()
+ private static readonly List hoe = new()
{
Material.AcaciaLeaves,
Material.BirchLeaves,
@@ -639,14 +639,14 @@ namespace MinecraftClient.Mapping
Material.WetSponge,
};
// Liquids
- private static readonly List bucket = new List()
+ private static readonly List bucket = new()
{
Material.Lava,
Material.Water
};
// Unbreakable Blocks
- private static readonly List unbreakable = new List()
+ private static readonly List unbreakable = new()
{
Material.Air,
Material.Barrier,
@@ -773,7 +773,7 @@ namespace MinecraftClient.Mapping
ItemType.Bucket,
};
}
- else { return new ItemType[0]; }
+ else { return System.Array.Empty(); }
}
public static bool IsUnbreakable(Material block) { return unbreakable.Contains(block); }
diff --git a/MinecraftClient/Mapping/MaterialExtensions.cs b/MinecraftClient/Mapping/MaterialExtensions.cs
index f1b9129a..a3ff5592 100644
--- a/MinecraftClient/Mapping/MaterialExtensions.cs
+++ b/MinecraftClient/Mapping/MaterialExtensions.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-namespace MinecraftClient.Mapping
+namespace MinecraftClient.Mapping
{
///
/// Defines extension methods for the Material enumeration
diff --git a/MinecraftClient/Mapping/Movement.cs b/MinecraftClient/Mapping/Movement.cs
index 21811c8d..04cecd0e 100644
--- a/MinecraftClient/Mapping/Movement.cs
+++ b/MinecraftClient/Mapping/Movement.cs
@@ -23,7 +23,7 @@ namespace MinecraftClient.Mapping
{
if (Settings.GravityEnabled)
{
- Location onFoots = new Location(location.X, Math.Floor(location.Y), location.Z);
+ Location onFoots = new(location.X, Math.Floor(location.Y), location.Z);
Location belowFoots = Move(location, Direction.Down);
if (location.Y > Math.Truncate(location.Y) + 0.0001)
{
@@ -94,7 +94,7 @@ namespace MinecraftClient.Mapping
{
//Use MC-Like falling algorithm
double Y = start.Y;
- Queue fallSteps = new Queue();
+ Queue fallSteps = new();
fallSteps.Enqueue(start);
double motionPrev = motionY;
motionY -= 0.08D;
@@ -102,7 +102,7 @@ namespace MinecraftClient.Mapping
Y += motionY;
if (Y < goal.Y)
return new Queue(new[] { goal });
- else
+ else
return new Queue(new[] { new Location(start.X, Y, start.Z) });
}
else
@@ -120,7 +120,7 @@ namespace MinecraftClient.Mapping
movementSteps.Enqueue(start + step * i);
return movementSteps;
}
- else
+ else
return new Queue(new[] { goal });
}
}
@@ -142,7 +142,7 @@ namespace MinecraftClient.Mapping
/// A list of locations, or null if calculation failed
public static Queue? CalculatePath(World world, Location start, Location goal, bool allowUnsafe, int maxOffset, int minOffset, TimeSpan timeout)
{
- CancellationTokenSource cts = new CancellationTokenSource();
+ CancellationTokenSource cts = new();
Task?> pathfindingTask = Task.Factory.StartNew(() => Movement.CalculatePath(world, start, goal, allowUnsafe, maxOffset, minOffset, cts.Token));
pathfindingTask.Wait(timeout);
if (!pathfindingTask.IsCompleted)
@@ -171,7 +171,7 @@ namespace MinecraftClient.Mapping
{
// This is a bad configuration
if (minOffset > maxOffset)
- throw new ArgumentException("minOffset must be lower or equal to maxOffset", "minOffset");
+ throw new ArgumentException("minOffset must be lower or equal to maxOffset", nameof(minOffset));
// Round start coordinates for easier calculation
Location startLower = start.ToFloor();
@@ -184,18 +184,18 @@ namespace MinecraftClient.Mapping
///---///
// Prepare variables and datastructures for A*
///---///
-
+
// Dictionary that contains the relation between all coordinates and resolves the final path
- Dictionary CameFrom = new Dictionary();
+ Dictionary CameFrom = new();
// Create a Binary Heap for all open positions => Allows fast access to Nodes with lowest scores
- BinaryHeap openSet = new BinaryHeap();
+ BinaryHeap openSet = new();
// Dictionary to keep track of the G-Score of every location
- Dictionary gScoreDict = new Dictionary();
+ Dictionary gScoreDict = new();
// Set start values for variables
openSet.Insert(0, (int)startLower.DistanceSquared(goalLower), startLower);
gScoreDict[startLower] = 0;
- BinaryHeap.Node current = null;
+ BinaryHeap.Node? current = null;
///---///
// Start of A*
@@ -239,7 +239,7 @@ namespace MinecraftClient.Mapping
}
//// Goal could not be reached. Set the path to the closest location if close enough
- if (current != null && (maxOffset == int.MaxValue || openSet.MinH_ScoreNode.H_score <= maxOffset))
+ if (current != null && openSet.MinH_ScoreNode != null && (maxOffset == int.MaxValue || openSet.MinH_ScoreNode.H_score <= maxOffset))
return ReconstructPath(CameFrom, openSet.MinH_ScoreNode.Location, start, goal);
else
return null;
@@ -306,17 +306,17 @@ namespace MinecraftClient.Mapping
public Node(int g_score, int h_score, Location loc)
{
- this.G_score = g_score;
- this.H_score = h_score;
+ G_score = g_score;
+ H_score = h_score;
Location = loc;
}
}
// List which contains all nodes in form of a Binary Heap
- private List heapList;
+ private readonly List heapList;
// Hashset for quick checks of locations included in the heap
- private HashSet locationList;
- public Node MinH_ScoreNode;
+ private readonly HashSet locationList;
+ public Node? MinH_ScoreNode;
public BinaryHeap()
{
@@ -337,7 +337,7 @@ namespace MinecraftClient.Mapping
int i = heapList.Count;
// Temporarily save the node created with the parameters to allow comparisons
- Node newNode = new Node(newG_Score, newH_Score, loc);
+ Node newNode = new(newG_Score, newH_Score, loc);
// Add new note to the end of the list
heapList.Add(newNode);
@@ -384,7 +384,7 @@ namespace MinecraftClient.Mapping
locationList.Remove(rootNode.Location);
// Temporarirly store the last item's value.
- Node lastNode = heapList[heapList.Count - 1];
+ Node lastNode = heapList[^1];
// Remove the last value.
heapList.RemoveAt(heapList.Count - 1);
@@ -524,7 +524,7 @@ namespace MinecraftClient.Mapping
public static bool IsSafe(World world, Location location)
{
return
- //No block that can harm the player
+ //No block that can harm the player
!world.GetBlock(location).Type.CanHarmPlayers()
&& !world.GetBlock(Move(location, Direction.Up)).Type.CanHarmPlayers()
&& !world.GetBlock(Move(location, Direction.Down)).Type.CanHarmPlayers()
@@ -640,7 +640,7 @@ namespace MinecraftClient.Mapping
return Move(Direction.North) + Move(Direction.West);
default:
- throw new ArgumentException("Unknown direction", "direction");
+ throw new ArgumentException("Unknown direction", nameof(direction));
}
}
diff --git a/MinecraftClient/Mapping/World.cs b/MinecraftClient/Mapping/World.cs
index ffe231ab..0e9a3241 100644
--- a/MinecraftClient/Mapping/World.cs
+++ b/MinecraftClient/Mapping/World.cs
@@ -2,8 +2,6 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
-using System.Threading;
namespace MinecraftClient.Mapping
{
@@ -23,7 +21,7 @@ namespace MinecraftClient.Mapping
///
private static Dimension curDimension = new();
- private static Dictionary dimensionList = new();
+ private static readonly Dictionary dimensionList = new();
///
/// Chunk data parsing progress
@@ -62,10 +60,11 @@ namespace MinecraftClient.Mapping
public static void StoreDimensionList(Dictionary registryCodec)
{
var dimensionListNbt = (object[])(((Dictionary)registryCodec["minecraft:dimension_type"])["value"]);
- foreach (Dictionary dimensionNbt in dimensionListNbt)
+ foreach (var (dimensionName, dimensionType) in from Dictionary dimensionNbt in dimensionListNbt
+ let dimensionName = (string)dimensionNbt["name"]
+ let dimensionType = (Dictionary)dimensionNbt["element"]
+ select (dimensionName, dimensionType))
{
- string dimensionName = (string)dimensionNbt["name"];
- Dictionary dimensionType = (Dictionary)dimensionNbt["element"];
StoreOneDimension(dimensionName, dimensionType);
}
}
@@ -78,7 +77,7 @@ namespace MinecraftClient.Mapping
public static void StoreOneDimension(string dimensionName, Dictionary dimensionType)
{
if (dimensionList.ContainsKey(dimensionName))
- dimensionList.Remove(dimensionName);
+ dimensionList.Remove(dimensionName);
dimensionList.Add(dimensionName, new Dimension(dimensionName, dimensionType));
}
@@ -170,16 +169,16 @@ namespace MinecraftClient.Mapping
/// Block matching the specified block type
public List FindBlock(Location from, Material block, int radiusx, int radiusy, int radiusz)
{
- Location minPoint = new Location(from.X - radiusx, from.Y - radiusy, from.Z - radiusz);
- Location maxPoint = new Location(from.X + radiusx, from.Y + radiusy, from.Z + radiusz);
- List list = new List { };
+ Location minPoint = new(from.X - radiusx, from.Y - radiusy, from.Z - radiusz);
+ Location maxPoint = new(from.X + radiusx, from.Y + radiusy, from.Z + radiusz);
+ List list = new() { };
for (double x = minPoint.X; x <= maxPoint.X; x++)
{
for (double y = minPoint.Y; y <= maxPoint.Y; y++)
{
for (double z = minPoint.Z; z <= maxPoint.Z; z++)
{
- Location doneloc = new Location(x, y, z);
+ Location doneloc = new(x, y, z);
Block doneblock = GetBlock(doneloc);
Material blockType = doneblock.Type;
if (blockType == block)
@@ -218,5 +217,19 @@ namespace MinecraftClient.Mapping
chunkCnt = 0;
chunkLoadNotCompleted = 0;
}
+
+ public static string GetChunkLoadingStatus(World world)
+ {
+ double chunkLoadedRatio;
+ if (world.chunkCnt == 0)
+ chunkLoadedRatio = 0;
+ else
+ chunkLoadedRatio = (world.chunkCnt - world.chunkLoadNotCompleted) / (double)world.chunkCnt;
+
+ string status = Translations.Get("cmd.move.chunk_loading_status",
+ chunkLoadedRatio, world.chunkCnt - world.chunkLoadNotCompleted, world.chunkCnt);
+
+ return status;
+ }
}
}
diff --git a/MinecraftClient/McClient.cs b/MinecraftClient/McClient.cs
index 73213fbf..a8fed3b9 100644
--- a/MinecraftClient/McClient.cs
+++ b/MinecraftClient/McClient.cs
@@ -1,21 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
using System.Net.Sockets;
+using System.Text;
using System.Threading;
-using System.IO;
-using System.Net;
using MinecraftClient.ChatBots;
-using MinecraftClient.Protocol;
-using MinecraftClient.Proxy;
-using MinecraftClient.Protocol.Handlers.Forge;
-using MinecraftClient.Mapping;
using MinecraftClient.Inventory;
using MinecraftClient.Logger;
+using MinecraftClient.Mapping;
+using MinecraftClient.Protocol;
+using MinecraftClient.Protocol.Handlers.Forge;
using MinecraftClient.Protocol.Keys;
-using MinecraftClient.Protocol.Session;
using MinecraftClient.Protocol.Message;
+using MinecraftClient.Protocol.Session;
+using MinecraftClient.Proxy;
namespace MinecraftClient
{
@@ -32,15 +30,15 @@ namespace MinecraftClient
private static bool commandsLoaded = false;
- private Queue chatQueue = new();
+ private readonly Queue chatQueue = new();
private static DateTime nextMessageSendTime = DateTime.MinValue;
- private Queue threadTasks = new();
- private object threadTasksLock = new();
+ private readonly Queue threadTasks = new();
+ private readonly object threadTasksLock = new();
private readonly List bots = new();
private static readonly List botsOnHold = new();
- private static Dictionary inventories = new();
+ private static readonly Dictionary inventories = new();
private readonly Dictionary> registeredBotPluginChannels = new();
private readonly List registeredServerPluginChannels = new();
@@ -51,10 +49,10 @@ namespace MinecraftClient
private bool inventoryHandlingRequested = false;
private bool entityHandlingEnabled;
- private object locationLock = new();
+ private readonly object locationLock = new();
private bool locationReceived = false;
- private World world = new();
- private Queue steps;
+ private readonly World world = new();
+ private Queue? steps;
private Queue? path;
private Location location;
private float? _yaw; // Used for calculation ONLY!!! Doesn't reflect the client yaw
@@ -66,16 +64,16 @@ namespace MinecraftClient
public int currentMovementSpeed = 4;
private int sequenceId; // User for player block synchronization (Aka. digging, placing blocks, etc..)
- private string host;
- private int port;
- private int protocolversion;
- private string username;
+ private readonly string host;
+ private readonly int port;
+ private readonly int protocolversion;
+ private readonly string username;
private Guid uuid;
private string uuidStr;
- private string sessionid;
- private PlayerKeyPair? playerKeyPair;
+ private readonly string sessionid;
+ private readonly PlayerKeyPair? playerKeyPair;
private DateTime lastKeepAlive;
- private object lastKeepAliveLock = new();
+ private readonly object lastKeepAliveLock = new();
private int respawnTicks = 0;
private int gamemode = 0;
private bool isSupportPreviewsChat;
@@ -90,7 +88,7 @@ namespace MinecraftClient
private byte CurrentSlot = 0;
// Entity handling
- private Dictionary entities = new();
+ private readonly Dictionary entities = new();
// server TPS
private long lastAge = 0;
@@ -98,7 +96,7 @@ namespace MinecraftClient
private double serverTPS = 0;
private double averageTPS = 20;
private const int maxSamples = 5;
- private List tpsSamples = new(maxSamples);
+ private readonly List tpsSamples = new(maxSamples);
private double sampleSum = 0;
// ChatBot OnNetworkPacket event
@@ -125,12 +123,12 @@ namespace MinecraftClient
public int GetGamemode() { return gamemode; }
public bool GetNetworkPacketCaptureEnabled() { return networkPacketCaptureEnabled; }
public int GetProtocolVersion() { return protocolversion; }
- public ILogger GetLogger() { return this.Log; }
+ public ILogger GetLogger() { return Log; }
public int GetPlayerEntityID() { return playerEntityID; }
public List GetLoadedChatBots() { return new List(bots); }
- TcpClient client;
- IMinecraftCom handler;
+ readonly TcpClient client;
+ readonly IMinecraftCom handler;
CancellationTokenSource? cmdprompt = null;
Tuple? timeoutdetector = null;
@@ -152,18 +150,17 @@ namespace MinecraftClient
inventoryHandlingEnabled = Settings.InventoryHandling;
entityHandlingEnabled = Settings.EntityHandling;
- bool retry = false;
- this.sessionid = session.ID;
- if (!Guid.TryParse(session.PlayerID, out this.uuid))
- this.uuid = Guid.Empty;
- this.uuidStr = session.PlayerID;
- this.username = session.PlayerName;
- this.host = server_ip;
+ sessionid = session.ID;
+ if (!Guid.TryParse(session.PlayerID, out uuid))
+ uuid = Guid.Empty;
+ uuidStr = session.PlayerID;
+ username = session.PlayerName;
+ host = server_ip;
this.port = port;
this.protocolversion = protocolversion;
this.playerKeyPair = playerKeyPair;
- this.Log = Settings.LogToFile
+ Log = Settings.LogToFile
? new FileLogLogger(Settings.ExpandVars(Settings.LogFile), Settings.PrependTimestamp)
: new FilteredLogger();
Log.DebugEnabled = Settings.DebugMessages;
@@ -183,7 +180,7 @@ namespace MinecraftClient
try
{
- client = ProxyHandler.newTcpClient(host, port);
+ client = ProxyHandler.NewTcpClient(host, port);
client.ReceiveBufferSize = 1024 * 1024;
client.ReceiveTimeout = Settings.Timeout * 1000; // Default: 30 seconds
handler = Protocol.ProtocolHandler.GetProtocolHandler(client, protocolversion, forgeInfo, this);
@@ -225,45 +222,47 @@ namespace MinecraftClient
else
{
Log.Error(Translations.Get("error.login_failed"));
- retry = true;
+ goto Retry;
}
}
catch (Exception e)
{
Log.Error(e.GetType().Name + ": " + e.Message);
Log.Error(Translations.Get("error.join"));
- retry = true;
+ goto Retry;
}
}
catch (SocketException e)
{
Log.Error(e.Message);
Log.Error(Translations.Get("error.connect"));
- retry = true;
+ goto Retry;
}
- if (retry)
+ return;
+
+ Retry:
+ if (timeoutdetector != null)
{
- if (timeoutdetector != null)
- {
- timeoutdetector.Item2.Cancel();
- timeoutdetector = null;
- }
- if (ReconnectionAttemptsLeft > 0)
- {
- Log.Info(Translations.Get("mcc.reconnect", ReconnectionAttemptsLeft));
- Thread.Sleep(5000);
- ReconnectionAttemptsLeft--;
- Program.Restart();
- }
- else if (command == null && Settings.interactiveMode)
- {
- ConsoleInteractive.ConsoleReader.StopReadThread();
- ConsoleInteractive.ConsoleReader.MessageReceived -= ConsoleReaderOnMessageReceived;
- ConsoleInteractive.ConsoleReader.OnKeyInput -= ConsoleIO.AutocompleteHandler;
- Program.HandleFailure();
- }
+ timeoutdetector.Item2.Cancel();
+ timeoutdetector = null;
}
+ if (ReconnectionAttemptsLeft > 0)
+ {
+ Log.Info(Translations.Get("mcc.reconnect", ReconnectionAttemptsLeft));
+ Thread.Sleep(5000);
+ ReconnectionAttemptsLeft--;
+ Program.Restart();
+ }
+ else if (command == null && Settings.interactiveMode)
+ {
+ ConsoleInteractive.ConsoleReader.StopReadThread();
+ ConsoleInteractive.ConsoleReader.MessageReceived -= ConsoleReaderOnMessageReceived;
+ ConsoleInteractive.ConsoleReader.OnKeyInput -= ConsoleIO.AutocompleteHandler;
+ Program.HandleFailure();
+ }
+
+ throw new Exception("Initialization failed.");
}
///
@@ -502,7 +501,7 @@ namespace MinecraftClient
}
//Process AutoRelog last to make sure other bots can perform their cleanup tasks first (issue #1517)
- List onDisconnectBotList = bots.Where(bot => !(bot is AutoRelog)).ToList();
+ List onDisconnectBotList = bots.Where(bot => bot is not AutoRelog).ToList();
onDisconnectBotList.AddRange(bots.Where(bot => bot is AutoRelog));
foreach (ChatBot bot in onDisconnectBotList)
@@ -513,7 +512,7 @@ namespace MinecraftClient
}
catch (Exception e)
{
- if (!(e is ThreadAbortException))
+ if (e is not ThreadAbortException)
{
Log.Warn("OnDisconnect: Got error from " + bot.ToString() + ": " + e.ToString());
}
@@ -576,13 +575,13 @@ namespace MinecraftClient
{
if (Settings.internalCmdChar == ' ' || text[0] == Settings.internalCmdChar)
{
- string response_msg = "";
- string command = Settings.internalCmdChar == ' ' ? text : text.Substring(1);
+ string? response_msg = "";
+ string command = Settings.internalCmdChar == ' ' ? text : text[1..];
if (!PerformInternalCommand(Settings.ExpandVars(command), ref response_msg, Settings.GetVariables()) && Settings.internalCmdChar == '/')
{
SendText(text);
}
- else if (response_msg.Length > 0)
+ else if (!String.IsNullOrEmpty(response_msg))
{
Log.Info(response_msg);
}
@@ -641,16 +640,16 @@ namespace MinecraftClient
/// May contain a confirmation or error message after processing the command, or "" otherwise.
/// Local variables passed along with the command
/// TRUE if the command was indeed an internal MCC command
- public bool PerformInternalCommand(string command, ref string response_msg, Dictionary? localVars = null)
+ public bool PerformInternalCommand(string command, ref string? response_msg, Dictionary? localVars = null)
{
/* Process the provided command */
string command_name = command.Split(' ')[0].ToLower();
if (command_name == "help")
{
- if (Command.hasArg(command))
+ if (Command.HasArg(command))
{
- string help_cmdname = Command.getArgs(command)[0].ToLower();
+ string help_cmdname = Command.GetArgs(command)[0].ToLower();
if (help_cmdname == "help")
{
response_msg = Translations.Get("icmd.help");
@@ -671,13 +670,13 @@ namespace MinecraftClient
{
try
{
- bot.OnInternalCommand(command_name, string.Join(" ", Command.getArgs(command)), response_msg);
+ bot.OnInternalCommand(command_name, string.Join(" ", Command.GetArgs(command)), response_msg);
}
catch (Exception e)
{
- if (!(e is ThreadAbortException))
+ if (e is not ThreadAbortException)
{
- Log.Warn(Translations.Get("icmd.error", bot.ToString(), e.ToString()));
+ Log.Warn(Translations.Get("icmd.error", bot.ToString() ?? string.Empty, e.ToString()));
}
else throw; //ThreadAbortException should not be caught
}
@@ -705,10 +704,10 @@ namespace MinecraftClient
{
try
{
- Command cmd = (Command)Activator.CreateInstance(type);
+ Command cmd = (Command)Activator.CreateInstance(type)!;
cmds[Settings.ToLowerIfNeed(cmd.CmdName)] = cmd;
cmd_names.Add(Settings.ToLowerIfNeed(cmd.CmdName));
- foreach (string alias in cmd.getCMDAliases())
+ foreach (string alias in cmd.GetCMDAliases())
cmds[Settings.ToLowerIfNeed(alias)] = cmd;
}
catch (Exception e)
@@ -773,7 +772,7 @@ namespace MinecraftClient
}
else
{
- TaskWithResult taskWithResult = new TaskWithResult(task);
+ TaskWithResult taskWithResult = new(task);
lock (threadTasksLock)
{
threadTasks.Enqueue(taskWithResult.ExecuteSynchronously);
@@ -813,7 +812,7 @@ namespace MinecraftClient
{
get
{
- int callingThreadId = Thread.CurrentThread.ManagedThreadId;
+ int callingThreadId = Environment.CurrentManagedThreadId;
if (handler != null)
{
return handler.GetNetMainThreadId() != callingThreadId;
@@ -845,7 +844,7 @@ namespace MinecraftClient
bots.Add(b);
if (init)
DispatchBotEvent(bot => bot.Initialize(), new ChatBot[] { b });
- if (this.handler != null)
+ if (handler != null)
DispatchBotEvent(bot => bot.AfterGameJoined(), new ChatBot[] { b });
Settings.SingleCommand = "";
}
@@ -1109,7 +1108,7 @@ namespace MinecraftClient
/// Dictionay of online players, key is UUID, value is Player name
public Dictionary GetOnlinePlayersWithUUID()
{
- Dictionary uuid2Player = new Dictionary();
+ Dictionary uuid2Player = new();
lock (onlinePlayers)
{
foreach (Guid key in onlinePlayers.Keys)
@@ -1165,7 +1164,7 @@ namespace MinecraftClient
else
{
// Calculate path through pathfinding. Path contains a list of 1-block movement that will be divided into steps
- path = Movement.CalculatePath(world, this.location, goal, allowUnsafe, maxOffset, minOffset, timeout ?? TimeSpan.FromSeconds(5));
+ path = Movement.CalculatePath(world, location, goal, allowUnsafe, maxOffset, minOffset, timeout ?? TimeSpan.FromSeconds(5));
return path != null;
}
}
@@ -1241,8 +1240,10 @@ namespace MinecraftClient
}
else
{
- List bots = new List();
- bots.Add(bot);
+ List bots = new()
+ {
+ bot
+ };
registeredBotPluginChannels[channel] = bots;
SendPluginChannelMessage("REGISTER", Encoding.UTF8.GetBytes(channel), true);
}
@@ -1315,7 +1316,7 @@ namespace MinecraftClient
/// TRUE if the item was successfully used
public bool UseItemOnHand()
{
- return InvokeOnMainThread(() => handler.SendUseItem(0, this.sequenceId));
+ return InvokeOnMainThread(() => handler.SendUseItem(0, sequenceId));
}
///
@@ -1324,7 +1325,7 @@ namespace MinecraftClient
/// TRUE if the item was successfully used
public bool UseItemOnLeftHand()
{
- return InvokeOnMainThread(() => handler.SendUseItem(1, this.sequenceId));
+ return InvokeOnMainThread(() => handler.SendUseItem(1, sequenceId));
}
///
@@ -1437,9 +1438,7 @@ namespace MinecraftClient
else
{
// Swap two items
- var itemTmp = playerInventory.Items[-1];
- playerInventory.Items[-1] = inventory.Items[slotId];
- inventory.Items[slotId] = itemTmp;
+ (inventory.Items[slotId], playerInventory.Items[-1]) = (playerInventory.Items[-1], inventory.Items[slotId]);
}
}
else
@@ -1494,16 +1493,14 @@ namespace MinecraftClient
else
{
// Swap two items
- var itemTmp = playerInventory.Items[-1];
- playerInventory.Items[-1] = inventory.Items[slotId];
- inventory.Items[slotId] = itemTmp;
+ (inventory.Items[slotId], playerInventory.Items[-1]) = (playerInventory.Items[-1], inventory.Items[slotId]);
}
}
else
{
// Drop 1 item count from cursor
- var itemTmp = playerInventory.Items[-1];
- var itemClone = new Item(itemTmp.Type, 1, itemTmp.NBT);
+ Item itemTmp = playerInventory.Items[-1];
+ Item itemClone = new(itemTmp.Type, 1, itemTmp.NBT);
inventory.Items[slotId] = itemClone;
playerInventory.Items[-1].Count--;
}
@@ -1871,7 +1868,7 @@ namespace MinecraftClient
break;
case ContainerType.Lectern:
return false;
- break;
+ // break;
case ContainerType.Loom:
if (slotId >= 0 && slotId <= 3)
{
@@ -2213,7 +2210,7 @@ namespace MinecraftClient
/// TRUE if successfully placed
public bool PlaceBlock(Location location, Direction blockFace, Hand hand = Hand.MainHand)
{
- return InvokeOnMainThread(() => handler.SendPlayerBlockPlacement((int)hand, location, blockFace, this.sequenceId));
+ return InvokeOnMainThread(() => handler.SendPlayerBlockPlacement((int)hand, location, blockFace, sequenceId));
}
///
@@ -2239,9 +2236,9 @@ namespace MinecraftClient
// Send dig start and dig end, will need to wait for server response to know dig result
// See https://wiki.vg/How_to_Write_a_Client#Digging for more details
- return handler.SendPlayerDigging(0, location, blockFace, this.sequenceId)
+ return handler.SendPlayerDigging(0, location, blockFace, sequenceId)
&& (!swingArms || DoAnimation((int)Hand.MainHand))
- && handler.SendPlayerDigging(2, location, blockFace, this.sequenceId);
+ && handler.SendPlayerDigging(2, location, blockFace, sequenceId);
}
///
@@ -2364,11 +2361,11 @@ namespace MinecraftClient
}
catch (Exception e)
{
- if (!(e is ThreadAbortException))
+ if (e is not ThreadAbortException)
{
//Retrieve parent method name to determine which event caused the exception
- System.Diagnostics.StackFrame frame = new System.Diagnostics.StackFrame(1);
- System.Reflection.MethodBase method = frame.GetMethod();
+ System.Diagnostics.StackFrame frame = new(1);
+ System.Reflection.MethodBase method = frame.GetMethod()!;
string parentMethodName = method.Name;
//Display a meaningful error message to help debugging the ChatBot
@@ -2464,7 +2461,7 @@ namespace MinecraftClient
/// Current goal of movement. Location.Zero if not set.
public Location GetCurrentMovementGoal()
{
- return ClientIsMoving() ? Location.Zero : path.Last();
+ return (ClientIsMoving() || path == null) ? Location.Zero : path.Last();
}
///
@@ -2529,8 +2526,8 @@ namespace MinecraftClient
/// Pitch to look at
public void UpdateLocation(Location location, float yaw, float pitch)
{
- this._yaw = yaw;
- this._pitch = pitch;
+ _yaw = yaw;
+ _pitch = pitch;
UpdateLocation(location, false);
}
@@ -2586,7 +2583,7 @@ namespace MinecraftClient
case Direction.South:
break;
default:
- throw new ArgumentException(Translations.Get("exception.unknown_direction"), "direction");
+ throw new ArgumentException(Translations.Get("exception.unknown_direction"), nameof(direction));
}
UpdateLocation(location, yaw, pitch);
@@ -2694,7 +2691,7 @@ namespace MinecraftClient
/// Window ID
/// Slot ID
/// Item (may be null for empty slot)
- public void OnSetSlot(byte inventoryID, short slotID, Item item, int stateId)
+ public void OnSetSlot(byte inventoryID, short slotID, Item? item, int stateId)
{
if (inventories.ContainsKey(inventoryID))
inventories[inventoryID].StateID = stateId;
@@ -2751,8 +2748,8 @@ namespace MinecraftClient
if (player.Name == username)
{
// 1.19+ offline server is possible to return different uuid
- this.uuid = player.Uuid;
- this.uuidStr = player.Uuid.ToString().Replace("-", string.Empty);
+ uuid = player.Uuid;
+ uuidStr = player.Uuid.ToString().Replace("-", string.Empty);
}
lock (onlinePlayers)
@@ -2860,7 +2857,7 @@ namespace MinecraftClient
/// Entity ID
/// Equipment slot. 0: main hand, 1: off hand, 2–5: armor slot (2: boots, 3: leggings, 4: chestplate, 5: helmet)
/// Item)
- public void OnEntityEquipment(int entityid, int slot, Item item)
+ public void OnEntityEquipment(int entityid, int slot, Item? item)
{
if (entities.ContainsKey(entityid))
{
@@ -2889,7 +2886,7 @@ namespace MinecraftClient
if (onlinePlayers.ContainsKey(uuid))
{
string playerName = onlinePlayers[uuid].Name;
- if (playerName == this.username)
+ if (playerName == username)
this.gamemode = gamemode;
DispatchBotEvent(bot => bot.OnGamemodeUpdate(playerName, uuid, gamemode));
}
@@ -2944,7 +2941,7 @@ namespace MinecraftClient
{
if (entities.ContainsKey(EntityID))
{
- Location location = new Location(X, Y, Z);
+ Location location = new(X, Y, Z);
entities[EntityID].Location = location;
DispatchBotEvent(bot => bot.OnEntityMove(entities[EntityID]));
}
@@ -3200,13 +3197,13 @@ namespace MinecraftClient
}
if (metadata.TryGetValue(2, out object? nameObj) && nameObj != null && nameObj.GetType() == typeof(string))
{
- string name = nameObj.ToString()!;
+ string name = nameObj.ToString() ?? string.Empty;
entity.CustomNameJson = name;
entity.CustomName = ChatParser.ParseText(name);
}
if (metadata.TryGetValue(3, out object? nameVisableObj) && nameVisableObj != null && nameVisableObj.GetType() == typeof(bool))
{
- entity.IsCustomNameVisible = bool.Parse(nameVisableObj.ToString()!);
+ entity.IsCustomNameVisible = bool.Parse(nameVisableObj.ToString() ?? string.Empty);
}
DispatchBotEvent(bot => bot.OnEntityMetadata(entity, metadata));
}
@@ -3271,7 +3268,7 @@ namespace MinecraftClient
/// Indicates if the server previews chat
public void OnServerDataRecived(bool hasMotd, string motd, bool hasIcon, string iconBase64, bool previewsChat)
{
- this.isSupportPreviewsChat = previewsChat;
+ isSupportPreviewsChat = previewsChat;
}
///
@@ -3280,7 +3277,7 @@ namespace MinecraftClient
/// Indicates if the server previews chat
public void OnChatPreviewSettingUpdate(bool previewsChat)
{
- this.isSupportPreviewsChat = previewsChat;
+ isSupportPreviewsChat = previewsChat;
}
///
diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj
index 794364ff..7148da0b 100644
--- a/MinecraftClient/MinecraftClient.csproj
+++ b/MinecraftClient/MinecraftClient.csproj
@@ -1,4 +1,4 @@
-
+
net6.0
Exe
@@ -18,6 +18,11 @@
MinecraftClient.Program
+
+
+
+
+
@@ -28,16 +33,16 @@
-
+
+
-
+
-
- all
-
-
+
+ NU1701
+
diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs
index 14281da5..2eedb89a 100644
--- a/MinecraftClient/Program.cs
+++ b/MinecraftClient/Program.cs
@@ -1,22 +1,20 @@
using System;
-using System.IO;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
-using System.Text;
-using MinecraftClient.Protocol;
using System.Reflection;
using System.Runtime.InteropServices;
+using System.Text;
using System.Threading;
-using MinecraftClient.Protocol.Handlers.Forge;
-using MinecraftClient.Protocol.Session;
-using MinecraftClient.Mapping.EntityPalettes;
-using MinecraftClient.Mapping.BlockPalettes;
-using MinecraftClient.Inventory.ItemPalettes;
-using MinecraftClient.WinAPI;
-using MinecraftClient.Protocol.Keys;
-using System.Security.Cryptography;
-using System.Xml.Linq;
using System.Threading.Tasks;
+using MinecraftClient.Inventory.ItemPalettes;
+using MinecraftClient.Mapping.BlockPalettes;
+using MinecraftClient.Mapping.EntityPalettes;
+using MinecraftClient.Protocol;
+using MinecraftClient.Protocol.Handlers.Forge;
+using MinecraftClient.Protocol.Keys;
+using MinecraftClient.Protocol.Session;
+using MinecraftClient.WinAPI;
namespace MinecraftClient
{
@@ -36,13 +34,13 @@ namespace MinecraftClient
///
static class Program
{
- private static McClient client;
- public static string[] startupargs;
+ private static McClient? client;
+ public static string[]? startupargs;
public const string Version = MCHighestVersion;
public const string MCLowestVersion = "1.4.6";
public const string MCHighestVersion = "1.19.2";
- public static readonly string BuildInfo = null;
+ public static readonly string? BuildInfo = null;
private static Tuple? offlinePrompt = null;
private static bool useMcVersionOnce = false;
@@ -77,14 +75,14 @@ namespace MinecraftClient
//Setup ConsoleIO
ConsoleIO.LogPrefix = "§8[MCC] ";
- if (args.Length >= 1 && args[args.Length - 1] == "BasicIO" || args.Length >= 1 && args[args.Length - 1] == "BasicIO-NoColor")
+ if (args.Length >= 1 && args[^1] == "BasicIO" || args.Length >= 1 && args[^1] == "BasicIO-NoColor")
{
- if (args.Length >= 1 && args[args.Length - 1] == "BasicIO-NoColor")
+ if (args.Length >= 1 && args[^1] == "BasicIO-NoColor")
{
ConsoleIO.BasicIO_NoColor = true;
}
ConsoleIO.BasicIO = true;
- args = args.Where(o => !Object.ReferenceEquals(o, args[args.Length - 1])).ToArray();
+ args = args.Where(o => !Object.ReferenceEquals(o, args[^1])).ToArray();
}
if (!ConsoleIO.BasicIO)
@@ -150,10 +148,10 @@ namespace MinecraftClient
{
if (argument.StartsWith("--") && !argument.Contains("--generate"))
{
- if (!argument.Contains("="))
+ if (!argument.Contains('='))
throw new ArgumentException(Translations.Get("error.setting.argument_syntax", argument));
- string[] argParts = argument.Substring(2).Split('=');
+ string[] argParts = argument[2..].Split('=');
string argName = argParts[0].Trim();
string argValue = argParts[1].Replace("\"", "").Trim();
@@ -269,7 +267,7 @@ namespace MinecraftClient
// Do NOT use Program.Exit() as creating new Thread cause program to freeze
if (client != null) { client.Disconnect(); ConsoleIO.Reset(); }
if (offlinePrompt != null) { offlinePrompt.Item2.Cancel(); offlinePrompt = null; ConsoleIO.Reset(); }
- if (Settings.playerHeadAsIcon) { ConsoleIcon.revertToMCCIcon(); }
+ if (Settings.playerHeadAsIcon) { ConsoleIcon.RevertToMCCIcon(); }
});
@@ -293,7 +291,7 @@ namespace MinecraftClient
///
private static void InitializeClient()
{
- SessionToken session = new SessionToken();
+ SessionToken session = new();
PlayerKeyPair? playerKeyPair = null;
ProtocolHandler.LoginResult result = ProtocolHandler.LoginResult.LoginRequired;
@@ -390,12 +388,12 @@ namespace MinecraftClient
Console.Title = Settings.ExpandVars(Settings.ConsoleTitle);
if (Settings.playerHeadAsIcon)
- ConsoleIcon.setPlayerIconAsync(Settings.Username);
+ ConsoleIcon.SetPlayerIconAsync(Settings.Username);
if (Settings.DebugMessages)
Translations.WriteLine("debug.session_id", session.ID);
- List availableWorlds = new List();
+ List availableWorlds = new();
if (Settings.MinecraftRealmsEnabled && !String.IsNullOrEmpty(session.ID))
availableWorlds = ProtocolHandler.RealmsListWorlds(Settings.Username, session.PlayerID, session.ID);
@@ -412,9 +410,8 @@ namespace MinecraftClient
HandleFailure(Translations.Get("error.realms.access_denied"), false, ChatBot.DisconnectReason.LoginRejected);
return;
}
- int worldIndex = 0;
string worldId = addressInput.Split(':')[1];
- if (!availableWorlds.Contains(worldId) && int.TryParse(worldId, out worldIndex) && worldIndex < availableWorlds.Count)
+ if (!availableWorlds.Contains(worldId) && int.TryParse(worldId, out int worldIndex) && worldIndex < availableWorlds.Count)
worldId = availableWorlds[worldIndex];
if (availableWorlds.Contains(worldId))
{
@@ -508,7 +505,11 @@ namespace MinecraftClient
if (Settings.ConsoleTitle != "")
Console.Title = Settings.ExpandVars(Settings.ConsoleTitle);
}
- catch (NotSupportedException) { HandleFailure(Translations.Get("error.unsupported"), true); }
+ catch (NotSupportedException)
+ {
+ HandleFailure(Translations.Get("error.unsupported"), true);
+ }
+ catch (Exception) { }
}
else HandleFailure(Translations.Get("error.determine"), true);
}
@@ -516,18 +517,20 @@ namespace MinecraftClient
{
string failureMessage = Translations.Get("error.login");
string failureReason = "";
- switch (result)
+ failureReason = result switch
{
- case ProtocolHandler.LoginResult.AccountMigrated: failureReason = "error.login.migrated"; break;
- case ProtocolHandler.LoginResult.ServiceUnavailable: failureReason = "error.login.server"; break;
- case ProtocolHandler.LoginResult.WrongPassword: failureReason = "error.login.blocked"; break;
- case ProtocolHandler.LoginResult.InvalidResponse: failureReason = "error.login.response"; break;
- case ProtocolHandler.LoginResult.NotPremium: failureReason = "error.login.premium"; break;
- case ProtocolHandler.LoginResult.OtherError: failureReason = "error.login.network"; break;
- case ProtocolHandler.LoginResult.SSLError: failureReason = "error.login.ssl"; break;
- case ProtocolHandler.LoginResult.UserCancel: failureReason = "error.login.cancel"; break;
- default: failureReason = "error.login.unknown"; break;
- }
+#pragma warning disable format // @formatter:off
+ ProtocolHandler.LoginResult.AccountMigrated => "error.login.migrated",
+ ProtocolHandler.LoginResult.ServiceUnavailable => "error.login.server",
+ ProtocolHandler.LoginResult.WrongPassword => "error.login.blocked",
+ ProtocolHandler.LoginResult.InvalidResponse => "error.login.response",
+ ProtocolHandler.LoginResult.NotPremium => "error.login.premium",
+ ProtocolHandler.LoginResult.OtherError => "error.login.network",
+ ProtocolHandler.LoginResult.SSLError => "error.login.ssl",
+ ProtocolHandler.LoginResult.UserCancel => "error.login.cancel",
+ _ => "error.login.unknown",
+#pragma warning restore format // @formatter:on
+ };
failureMessage += Translations.Get(failureReason);
HandleFailure(failureMessage, false, ChatBot.DisconnectReason.LoginRejected);
}
@@ -572,7 +575,7 @@ namespace MinecraftClient
{
if (client != null) { client.Disconnect(); ConsoleIO.Reset(); }
if (offlinePrompt != null) { offlinePrompt.Item2.Cancel(); offlinePrompt.Item1.Join(); offlinePrompt = null; ConsoleIO.Reset(); }
- if (Settings.playerHeadAsIcon) { ConsoleIcon.revertToMCCIcon(); }
+ if (Settings.playerHeadAsIcon) { ConsoleIcon.RevertToMCCIcon(); }
Environment.Exit(exitcode);
})).Start();
}
@@ -584,7 +587,7 @@ namespace MinecraftClient
/// Error message to display and optionally pass to AutoRelog bot
/// Specify if the error is related to an incompatible or unkown server version
/// If set, the error message will be processed by the AutoRelog bot
- public static void HandleFailure(string errorMessage = null, bool versionError = false, ChatBots.AutoRelog.DisconnectReason? disconnectReason = null)
+ public static void HandleFailure(string? errorMessage = null, bool versionError = false, ChatBots.AutoRelog.DisconnectReason? disconnectReason = null)
{
if (!String.IsNullOrEmpty(errorMessage))
{
@@ -643,7 +646,7 @@ namespace MinecraftClient
if (Settings.internalCmdChar != ' '
&& command[0] == Settings.internalCmdChar)
- command = command.Substring(1);
+ command = command[1..];
if (command.StartsWith("reco"))
{
@@ -722,7 +725,7 @@ namespace MinecraftClient
/// Namespace to process
/// Assembly to use. Default is Assembly.GetExecutingAssembly()
///
- public static Type[] GetTypesInNamespace(string nameSpace, Assembly assembly = null)
+ public static Type[] GetTypesInNamespace(string nameSpace, Assembly? assembly = null)
{
if (assembly == null) { assembly = Assembly.GetExecutingAssembly(); }
return assembly.GetTypes().Where(t => String.Equals(t.Namespace, nameSpace, StringComparison.Ordinal)).ToArray();
@@ -733,12 +736,10 @@ namespace MinecraftClient
///
static Program()
{
- AssemblyConfigurationAttribute attribute
- = typeof(Program)
+ if (typeof(Program)
.Assembly
.GetCustomAttributes(typeof(System.Reflection.AssemblyConfigurationAttribute), false)
- .FirstOrDefault() as AssemblyConfigurationAttribute;
- if (attribute != null)
+ .FirstOrDefault() is AssemblyConfigurationAttribute attribute)
BuildInfo = attribute.Configuration;
}
}
diff --git a/MinecraftClient/Properties/AssemblyInfo.cs b/MinecraftClient/Properties/AssemblyInfo.cs
index 81eee9c1..99b66052 100644
--- a/MinecraftClient/Properties/AssemblyInfo.cs
+++ b/MinecraftClient/Properties/AssemblyInfo.cs
@@ -1,5 +1,4 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
diff --git a/MinecraftClient/Protocol/DataTypeGenerator.cs b/MinecraftClient/Protocol/DataTypeGenerator.cs
index f0070523..039ae477 100644
--- a/MinecraftClient/Protocol/DataTypeGenerator.cs
+++ b/MinecraftClient/Protocol/DataTypeGenerator.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using System.IO;
+using System.Linq;
namespace MinecraftClient.Protocol
{
@@ -22,7 +22,7 @@ namespace MinecraftClient.Protocol
{
Json.JSONData rawJson = Json.ParseJson(File.ReadAllText(registriesJsonFile));
Json.JSONData rawRegistry = rawJson.Properties[jsonRegistryName].Properties["entries"];
- Dictionary registry = new Dictionary();
+ Dictionary registry = new();
foreach (KeyValuePair entry in rawRegistry.Properties)
{
@@ -32,7 +32,7 @@ namespace MinecraftClient.Protocol
string entryName = String.Concat(
entry.Key.Replace("minecraft:", "")
.Split('_')
- .Select(word => char.ToUpper(word[0]) + word.Substring(1))
+ .Select(word => char.ToUpper(word[0]) + word[1..])
);
if (registry.ContainsKey(entryId))
@@ -53,7 +53,7 @@ namespace MinecraftClient.Protocol
/// Output enum namespace, e.g. MinecraftClient.Inventory
public static void GenerateEnum(string registriesJsonFile, string jsonRegistryName, string outputEnum, string enumNamespace)
{
- List outputEnumLines = new List();
+ List outputEnumLines = new();
outputEnumLines.AddRange(new[] {
"namespace " + enumNamespace,
@@ -71,7 +71,7 @@ namespace MinecraftClient.Protocol
"}"
});
- string outputEnumPath = Path.Combine(Path.GetDirectoryName(registriesJsonFile), outputEnum + "XXX.cs");
+ string outputEnumPath = Path.Combine(Path.GetDirectoryName(registriesJsonFile)!, outputEnum + "XXX.cs");
File.WriteAllLines(outputEnumPath, outputEnumLines);
}
@@ -86,8 +86,8 @@ namespace MinecraftClient.Protocol
/// Palette namespace, e.g. MinecraftClient.EntityPalettes
public static void GenerateEnumWithPalette(string registriesJsonFile, string jsonRegistryName, string outputEnum, string enumNamespace, string outputPalette, string paletteNamespace)
{
- List outputEnumLines = new List();
- List outputPaletteLines = new List();
+ List outputEnumLines = new();
+ List outputPaletteLines = new();
outputEnumLines.AddRange(new[] {
"namespace " + enumNamespace,
@@ -97,14 +97,13 @@ namespace MinecraftClient.Protocol
});
outputPaletteLines.AddRange(new[] {
- "using System;",
"using System.Collections.Generic;",
"",
"namespace " + paletteNamespace,
"{",
" public class " + outputPalette + "XXX : " + outputPalette,
" {",
- " private static Dictionary mappings = new Dictionary();",
+ " private static readonly Dictionary mappings = new();",
"",
" static " + outputPalette + "XXX()",
" {",
@@ -134,8 +133,8 @@ namespace MinecraftClient.Protocol
"}"
});
- string outputEnumPath = Path.Combine(Path.GetDirectoryName(registriesJsonFile), outputEnum + "XXX.cs");
- string outputPalettePath = Path.Combine(Path.GetDirectoryName(registriesJsonFile), outputPalette + "XXX.cs");
+ string outputEnumPath = Path.Combine(Path.GetDirectoryName(registriesJsonFile)!, outputEnum + "XXX.cs");
+ string outputPalettePath = Path.Combine(Path.GetDirectoryName(registriesJsonFile)!, outputPalette + "XXX.cs");
File.WriteAllLines(outputEnumPath, outputEnumLines);
File.WriteAllLines(outputPalettePath, outputPaletteLines);
diff --git a/MinecraftClient/Protocol/EntityActionType.cs b/MinecraftClient/Protocol/EntityActionType.cs
index bda20370..b7191ded 100644
--- a/MinecraftClient/Protocol/EntityActionType.cs
+++ b/MinecraftClient/Protocol/EntityActionType.cs
@@ -1,8 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
namespace MinecraftClient.Protocol
{
public enum EntityActionType
diff --git a/MinecraftClient/Protocol/GuidExtensions.cs b/MinecraftClient/Protocol/GuidExtensions.cs
index f148c2af..c5ce2645 100644
--- a/MinecraftClient/Protocol/GuidExtensions.cs
+++ b/MinecraftClient/Protocol/GuidExtensions.cs
@@ -1,7 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace MinecraftClient.Protocol
{
diff --git a/MinecraftClient/Protocol/Handlers/Compression/CRC32.cs b/MinecraftClient/Protocol/Handlers/Compression/CRC32.cs
deleted file mode 100644
index 97593b91..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/CRC32.cs
+++ /dev/null
@@ -1,814 +0,0 @@
-// CRC32.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2011 Dino Chiesa.
-// 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: <2011-August-02 18:25:54>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the CRC32 class, which can do the CRC32 algorithm, using
-// arbitrary starting polynomials, and bit reversal. The bit reversal is what
-// distinguishes this CRC-32 used in BZip2 from the CRC-32 that is used in PKZIP
-// files, or GZIP files. This class does both.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using Interop = System.Runtime.InteropServices;
-
-namespace Ionic.Crc
-{
- ///
- /// Computes a CRC-32. The CRC-32 algorithm is parameterized - you
- /// can set the polynomial and enable or disable bit
- /// reversal. This can be used for GZIP, BZip2, or 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
- public class CRC32
- {
- ///
- /// Indicates the total number of bytes applied to the CRC.
- ///
- public Int64 TotalBytesRead
- {
- get
- {
- return _TotalBytesRead;
- }
- }
-
- ///
- /// Indicates the current CRC for all blocks slurped in.
- ///
- public Int32 Crc32Result
- {
- get
- {
- return unchecked((Int32)(~_register));
- }
- }
-
- ///
- /// 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 Exception("The input stream must not be null.");
-
- unchecked
- {
- 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)(~_register);
- }
- }
-
-
- ///
- /// Get the CRC32 for the given (word,byte) combo. This is a
- /// computation defined by PKzip for PKZIP 2.0 (weak) encryption.
- ///
- /// 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 Exception("The data buffer must not be null.");
-
- // bzip algorithm
- for (int i = 0; i < count; i++)
- {
- int x = offset + i;
- byte b = block[x];
- if (this.reverseBits)
- {
- UInt32 temp = (_register >> 24) ^ b;
- _register = (_register << 8) ^ crc32Table[temp];
- }
- else
- {
- UInt32 temp = (_register & 0x000000FF) ^ b;
- _register = (_register >> 8) ^ crc32Table[temp];
- }
- }
- _TotalBytesRead += count;
- }
-
-
- ///
- /// Process one byte in the CRC.
- ///
- /// the byte to include into the CRC .
- public void UpdateCRC(byte b)
- {
- if (this.reverseBits)
- {
- UInt32 temp = (_register >> 24) ^ b;
- _register = (_register << 8) ^ crc32Table[temp];
- }
- else
- {
- UInt32 temp = (_register & 0x000000FF) ^ b;
- _register = (_register >> 8) ^ crc32Table[temp];
- }
- }
-
- ///
- /// Process a run of N identical bytes into the CRC.
- ///
- ///
- ///
- /// This method serves as an optimization for updating the CRC when a
- /// run of identical bytes is found. Rather than passing in a buffer of
- /// length n, containing all identical bytes b, this method accepts the
- /// byte value and the length of the (virtual) buffer - the length of
- /// the run.
- ///
- ///
- /// the byte to include into the CRC.
- /// the number of times that byte should be repeated.
- public void UpdateCRC(byte b, int n)
- {
- while (n-- > 0)
- {
- if (this.reverseBits)
- {
- uint temp = (_register >> 24) ^ b;
- _register = (_register << 8) ^ crc32Table[(temp >= 0)
- ? temp
- : (temp + 256)];
- }
- else
- {
- UInt32 temp = (_register & 0x000000FF) ^ b;
- _register = (_register >> 8) ^ crc32Table[(temp >= 0)
- ? temp
- : (temp + 256)];
-
- }
- }
- }
-
-
-
- private static uint ReverseBits(uint data)
- {
- unchecked
- {
- uint ret = data;
- ret = (ret & 0x55555555) << 1 | (ret >> 1) & 0x55555555;
- ret = (ret & 0x33333333) << 2 | (ret >> 2) & 0x33333333;
- ret = (ret & 0x0F0F0F0F) << 4 | (ret >> 4) & 0x0F0F0F0F;
- ret = (ret << 24) | ((ret & 0xFF00) << 8) | ((ret >> 8) & 0xFF00) | (ret >> 24);
- return ret;
- }
- }
-
- private static byte ReverseBits(byte data)
- {
- unchecked
- {
- uint u = (uint)data * 0x00020202;
- uint m = 0x01044010;
- uint s = u & m;
- uint t = (u << 2) & (m << 1);
- return (byte)((0x01001001 * (s + t)) >> 24);
- }
- }
-
-
-
- private void GenerateLookupTable()
- {
- crc32Table = new UInt32[256];
- unchecked
- {
- UInt32 dwCrc;
- byte i = 0;
- do
- {
- dwCrc = i;
- for (byte j = 8; j > 0; j--)
- {
- if ((dwCrc & 1) == 1)
- {
- dwCrc = (dwCrc >> 1) ^ dwPolynomial;
- }
- else
- {
- dwCrc >>= 1;
- }
- }
- if (reverseBits)
- {
- crc32Table[ReverseBits(i)] = ReverseBits(dwCrc);
- }
- else
- {
- crc32Table[i] = dwCrc;
- }
- i++;
- } while (i!=0);
- }
-
-#if VERBOSE
- Console.WriteLine();
- Console.WriteLine("private static readonly UInt32[] crc32Table = {");
- for (int i = 0; i < crc32Table.Length; i+=4)
- {
- Console.Write(" ");
- for (int j=0; j < 4; j++)
- {
- Console.Write(" 0x{0:X8}U,", crc32Table[i+j]);
- }
- Console.WriteLine();
- }
- Console.WriteLine("};");
- Console.WriteLine();
-#endif
- }
-
-
- 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= ~_register;
- uint crc2= (uint) crc;
-
- // put operator for one zero bit in odd
- odd[0] = this.dwPolynomial; // 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;
-
- _register= ~crc1;
-
- //return (int) crc1;
- return;
- }
-
-
- ///
- /// Create an instance of the CRC32 class using the default settings: no
- /// bit reversal, and a polynomial of 0xEDB88320.
- ///
- public CRC32() : this(false)
- {
- }
-
- ///
- /// Create an instance of the CRC32 class, specifying whether to reverse
- /// data bits or not.
- ///
- ///
- /// specify true if the instance should reverse data bits.
- ///
- ///
- ///
- /// In the CRC-32 used by BZip2, the bits are reversed. Therefore if you
- /// want a CRC32 with compatibility with BZip2, you should pass true
- /// here. In the CRC-32 used by GZIP and PKZIP, the bits are not
- /// reversed; Therefore if you want a CRC32 with compatibility with
- /// those, you should pass false.
- ///
- ///
- public CRC32(bool reverseBits) :
- this( unchecked((int)0xEDB88320), reverseBits)
- {
- }
-
-
- ///
- /// Create an instance of the CRC32 class, specifying the polynomial and
- /// whether to reverse data bits or not.
- ///
- ///
- /// The polynomial to use for the CRC, expressed in the reversed (LSB)
- /// format: the highest ordered bit in the polynomial value is the
- /// coefficient of the 0th power; the second-highest order bit is the
- /// coefficient of the 1 power, and so on. Expressed this way, the
- /// polynomial for the CRC-32C used in IEEE 802.3, is 0xEDB88320.
- ///
- ///
- /// specify true if the instance should reverse data bits.
- ///
- ///
- ///
- ///
- /// In the CRC-32 used by BZip2, the bits are reversed. Therefore if you
- /// want a CRC32 with compatibility with BZip2, you should pass true
- /// here for the reverseBits parameter. In the CRC-32 used by
- /// GZIP and PKZIP, the bits are not reversed; Therefore if you want a
- /// CRC32 with compatibility with those, you should pass false for the
- /// reverseBits parameter.
- ///
- ///
- public CRC32(int polynomial, bool reverseBits)
- {
- this.reverseBits = reverseBits;
- this.dwPolynomial = (uint) polynomial;
- this.GenerateLookupTable();
- }
-
- ///
- /// Reset the CRC-32 class - clear the CRC "remainder register."
- ///
- ///
- ///
- /// Use this when employing a single instance of this class to compute
- /// multiple, distinct CRCs on multiple, distinct data blocks.
- ///
- ///
- public void Reset()
- {
- _register = 0xFFFFFFFFU;
- }
-
- // private member vars
- private UInt32 dwPolynomial;
- private Int64 _TotalBytesRead;
- private bool reverseBits;
- private UInt32[] crc32Table;
- private const int BUFFER_SIZE = 8192;
- private UInt32 _register = 0xFFFFFFFFU;
- }
-
-
- ///
- /// 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.
- ///
- ///
- public 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;
-
- ///
- /// The default constructor.
- ///
- ///
- ///
- /// Instances returned from this constructor will leave the underlying
- /// stream open upon Close(). The stream uses the default CRC32
- /// algorithm, which implies a polynomial of 0xEDB88320.
- ///
- ///
- /// The underlying stream
- public CrcCalculatorStream(System.IO.Stream stream)
- : this(true, CrcCalculatorStream.UnsetLengthLimit, stream, null)
- {
- }
-
- ///
- /// The constructor allows the caller to specify how to handle the
- /// underlying stream at close.
- ///
- ///
- ///
- /// The stream uses the default CRC32 algorithm, which implies a
- /// polynomial of 0xEDB88320.
- ///
- ///
- /// 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, null)
- {
- }
-
- ///
- /// A constructor allowing the specification of the length of the stream
- /// to read.
- ///
- ///
- ///
- /// The stream uses the default CRC32 algorithm, which implies a
- /// polynomial of 0xEDB88320.
- ///
- ///
- /// 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, null)
- {
- 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 stream uses the default CRC32 algorithm, which implies a
- /// polynomial of 0xEDB88320.
- ///
- ///
- /// 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, null)
- {
- 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(), and the CRC32 instance to use.
- ///
- ///
- ///
- /// The stream uses the specified CRC32 instance, which allows the
- /// application to specify how the CRC gets calculated.
- ///
- ///
- /// The underlying stream
- /// The length of the stream to slurp
- /// true to leave the underlying stream
- /// open upon close of the CrcCalculatorStream; false otherwise.
- /// the CRC32 instance to use to calculate the CRC32
- public CrcCalculatorStream(System.IO.Stream stream, Int64 length, bool leaveOpen,
- CRC32 crc32)
- : this(leaveOpen, length, stream, crc32)
- {
- 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, CRC32 crc32)
- : base()
- {
- _innerStream = stream;
- _Crc32 = crc32 ?? new CRC32();
- _lengthLimit = length;
- _leaveOpen = 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; }
- }
-
- ///
- /// Provides the current CRC for all blocks slurped in.
- ///
- ///
- ///
- /// The running total of the CRC is kept as data is written or read
- /// through the stream. read this property after all reads or writes to
- /// get an accurate CRC for the entire stream.
- ///
- ///
- public Int32 Crc
- {
- get { return _Crc32.Crc32Result; }
- }
-
- ///
- /// Indicates whether the underlying stream will be left open when the
- /// CrcCalculatorStream is Closed.
- ///
- ///
- ///
- /// Set this at any point before calling .
- ///
- ///
- 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.
- ///
- ///
- ///
- /// Always returns false.
- ///
- ///
- public override bool CanSeek
- {
- get { return false; }
- }
-
- ///
- /// Indicates whether the stream supports writing.
- ///
- public override bool CanWrite
- {
- get { return _innerStream.CanWrite; }
- }
-
- ///
- /// Flush the stream.
- ///
- public override void Flush()
- {
- _innerStream.Flush();
- }
-
- ///
- /// Returns the length of the underlying stream.
- ///
- public override long Length
- {
- get
- {
- if (_lengthLimit == CrcCalculatorStream.UnsetLengthLimit)
- return _innerStream.Length;
- else return _lengthLimit;
- }
- }
-
- ///
- /// The getter for this property returns the total bytes read.
- /// If you use the setter, it will throw
- /// .
- ///
- public override long Position
- {
- get { return _Crc32.TotalBytesRead; }
- set { throw new NotSupportedException(); }
- }
-
- ///
- /// Seeking is not supported on this stream. This method always throws
- ///
- ///
- /// N/A
- /// N/A
- /// N/A
- public override long Seek(long offset, System.IO.SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
-
- ///
- /// This method always throws
- ///
- ///
- /// N/A
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
-
-
- void IDisposable.Dispose()
- {
- Close();
- }
-
- ///
- /// Closes the stream.
- ///
- public override void Close()
- {
- base.Close();
- if (!_leaveOpen)
- _innerStream.Close();
- }
-
- }
-
-}
\ No newline at end of file
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Deflate.cs b/MinecraftClient/Protocol/Handlers/Compression/Deflate.cs
deleted file mode 100644
index 96722507..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Deflate.cs
+++ /dev/null
@@ -1,1879 +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: <2011-August-03 19:52:15>
-//
-// ------------------------------------------------------------------
-//
-// 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
-{
-
- 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));
- }
- if (_codec.AvailableBytesOut == 0)
- {
- _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)];
- throw new ZlibException("OutputBuffer is full (AvailableBytesOut == 0)");
- }
-
- 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)
- {
- 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 nothing.
-
- // _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/MinecraftClient/Protocol/Handlers/Compression/DeflateStream.cs b/MinecraftClient/Protocol/Handlers/Compression/DeflateStream.cs
deleted file mode 100644
index 05362d41..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/DeflateStream.cs
+++ /dev/null
@@ -1,740 +0,0 @@
-// DeflateStream.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2010 Dino Chiesa.
-// 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: <2011-July-31 14:48:11>
-//
-// ------------------------------------------------------------------
-//
-// 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.
- ///
- ///
- ///
- ///
- ///
- ///
- public 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.
- ///
- ///
- /// Application code won't call this code directly. This method may be
- /// invoked in two distinct scenarios. If disposing == true, the method
- /// has been called directly or indirectly by a user's code, for example
- /// via the public Dispose() method. In this case, both managed and
- /// unmanaged resources can be referenced and disposed. If disposing ==
- /// false, the method has been called by the runtime from inside the
- /// object finalizer and this method should not reference other objects;
- /// in that case only unmanaged resources must be referenced or
- /// disposed.
- ///
- ///
- ///
- /// true if the Dispose method was invoked by user code.
- ///
- 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 (RFC 1951).
- ///
- ///
- ///
- /// Uncompress it with .
- ///
- ///
- /// DeflateStream.UncompressString(byte[])
- /// DeflateStream.CompressBuffer(byte[])
- /// GZipStream.CompressString(string)
- /// ZlibStream.CompressString(string)
- ///
- ///
- /// 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 .
- ///
- ///
- /// DeflateStream.CompressString(string)
- /// DeflateStream.UncompressBuffer(byte[])
- /// GZipStream.CompressBuffer(byte[])
- /// ZlibStream.CompressBuffer(byte[])
- ///
- ///
- /// 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.
- ///
- ///
- /// DeflateStream.CompressString(String)
- /// DeflateStream.UncompressBuffer(byte[])
- /// GZipStream.UncompressString(byte[])
- /// ZlibStream.UncompressString(byte[])
- ///
- ///
- /// A buffer containing DEFLATE-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.
- ///
- ///
- /// DeflateStream.CompressBuffer(byte[])
- /// DeflateStream.UncompressString(byte[])
- /// GZipStream.UncompressBuffer(byte[])
- /// ZlibStream.UncompressBuffer(byte[])
- ///
- ///
- /// 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/MinecraftClient/Protocol/Handlers/Compression/GZipStream.cs b/MinecraftClient/Protocol/Handlers/Compression/GZipStream.cs
deleted file mode 100644
index 745e0963..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/GZipStream.cs
+++ /dev/null
@@ -1,1033 +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: <2011-August-08 18:14:39>
-//
-// ------------------------------------------------------------------
-//
-// 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.
- ///
- ///
- ///
- ///
- ///
- ///
- public 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.
- ///
- virtual public 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.
- 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 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.
- ///
- ///
- /// This method may be invoked in two distinct scenarios. If disposing
- /// == true, the method has been called directly or indirectly by a
- /// user's code, for example via the public Dispose() method. In this
- /// case, both managed and unmanaged resources can be referenced and
- /// disposed. If disposing == false, the method has been called by the
- /// runtime from inside the object finalizer and this method should not
- /// reference other objects; in that case only unmanaged resources must
- /// be referenced or disposed.
- ///
- ///
- ///
- /// indicates whether the Dispose method was invoked by user code.
- ///
- 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);
-#if SILVERLIGHT || NETCF
- internal static readonly System.Text.Encoding iso8859dash1 = new Ionic.Encoding.Iso8859Dash1Encoding();
-#else
- internal static readonly System.Text.Encoding iso8859dash1 = System.Text.Encoding.GetEncoding("iso-8859-1");
-#endif
-
-
- 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/MinecraftClient/Protocol/Handlers/Compression/InfTree.cs b/MinecraftClient/Protocol/Handlers/Compression/InfTree.cs
deleted file mode 100644
index 416b143a..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/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;
-using System.Runtime.CompilerServices;
-
-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.
- [MethodImpl(MethodImplOptions.AggressiveOptimization)]
- 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/MinecraftClient/Protocol/Handlers/Compression/ParallelDeflateOutputStream.cs b/MinecraftClient/Protocol/Handlers/Compression/ParallelDeflateOutputStream.cs
deleted file mode 100644
index f7514159..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/ParallelDeflateOutputStream.cs
+++ /dev/null
@@ -1,1386 +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: <2011-July-31 14:49:40>
-//
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 by Dino Chiesa
-// 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
-//
-// ------------------------------------------------------------------
-
-using System;
-using System.Collections.Generic;
-using System.Threading;
-using Ionic.Zlib;
-using System.IO;
-
-
-namespace Ionic.Zlib
-{
- internal class WorkItem
- {
- public byte[] buffer;
- public byte[] compressed;
- public int crc;
- public int index;
- public int ordinal;
- public int inputBytesAvailable;
- public int compressedBytesAvailable;
- public ZlibCodec compressor;
-
- public WorkItem(int size,
- Ionic.Zlib.CompressionLevel compressLevel,
- CompressionStrategy strategy,
- int ix)
- {
- this.buffer= new byte[size];
- // alloc 5 bytes overhead for every block (margin of safety= 2)
- int n = size + ((size / 32768)+1) * 5 * 2;
- this.compressed = new byte[n];
- this.compressor = new ZlibCodec();
- this.compressor.InitializeDeflate(compressLevel, false);
- this.compressor.OutputBuffer = this.compressed;
- this.compressor.InputBuffer = this.buffer;
- this.index = ix;
- }
- }
-
- ///
- /// A class for compressing streams using the
- /// Deflate algorithm with multiple threads.
- ///
- ///
- ///
- ///
- /// This class performs DEFLATE compression 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 class is for compression only, and 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 associated to using the thread
- /// pool.
- ///
- ///
- ///
- ///
- public class ParallelDeflateOutputStream : System.IO.Stream
- {
-
- private static readonly int IO_BUFFER_SIZE_DEFAULT = 64 * 1024; // 128k
- private static readonly int BufferPairsPerCore = 4;
-
- private System.Collections.Generic.List _pool;
- private bool _leaveOpen;
- private bool emitting;
- private System.IO.Stream _outStream;
- private int _maxBufferPairs;
- private int _bufferSize = IO_BUFFER_SIZE_DEFAULT;
- private AutoResetEvent _newlyCompressedBlob;
- //private ManualResetEvent _writingDone;
- //private ManualResetEvent _sessionReset;
- private object _outputLock = new object();
- private bool _isClosed;
- private bool _firstWriteDone;
- private int _currentlyFilling;
- private int _lastFilled;
- private int _lastWritten;
- private int _latestCompressed;
- private int _Crc32;
- private Ionic.Crc.CRC32 _runningCrc;
- private object _latestLock = new object();
- private System.Collections.Generic.Queue _toWrite;
- private System.Collections.Generic.Queue _toFill;
- private Int64 _totalBytesProcessed;
- private Ionic.Zlib.CompressionLevel _compressLevel;
- private volatile Exception _pendingException;
- private bool _handlingException;
- 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.Session |
- TraceBits.Compress |
- TraceBits.WriteTake |
- TraceBits.WriteEnter |
- TraceBits.EmitEnter |
- TraceBits.EmitDone |
- TraceBits.EmitLock |
- TraceBits.EmitSkip |
- TraceBits.EmitBegin;
-
- ///
- /// 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());
- _outStream = stream;
- _compressLevel= level;
- Strategy = strategy;
- _leaveOpen = leaveOpen;
- this.MaxBufferPairs = 16; // default
- }
-
-
- ///
- /// The ZLIB strategy to be used during compression.
- ///
- ///
- public CompressionStrategy Strategy
- {
- get;
- private set;
- }
-
- ///
- /// The maximum number of buffer pairs to use.
- ///
- ///
- ///
- ///
- /// This property sets an upper limit on the number of memory buffer
- /// pairs to create. The implementation of this stream allocates
- /// multiple buffers to facilitate parallel compression. As each buffer
- /// fills up, this stream uses
- /// ThreadPool.QueueUserWorkItem()
- /// to compress those buffers in a background threadpool thread. After a
- /// buffer is compressed, it is re-ordered and written to the output
- /// stream.
- ///
- ///
- ///
- /// A higher number of buffer pairs enables a higher degree of
- /// parallelism, which tends to increase the speed of compression on
- /// multi-cpu computers. On the other hand, a higher number of buffer
- /// pairs also implies a larger memory consumption, more active worker
- /// threads, and a higher cpu utilization for any compression. This
- /// property enables the application to limit its memory consumption and
- /// CPU utilization behavior depending on requirements.
- ///
- ///
- ///
- /// For each compression "task" that occurs in parallel, there are 2
- /// buffers allocated: one for input and one for output. This property
- /// sets a limit for the number of pairs. The total amount of storage
- /// space allocated for buffering will then be (N*S*2), where N is the
- /// number of buffer pairs, S is the size of each buffer (). By default, DotNetZip allocates 4 buffer
- /// pairs per CPU core, so if your machine has 4 cores, and you retain
- /// the default buffer size of 128k, then the
- /// ParallelDeflateOutputStream will use 4 * 4 * 2 * 128kb of buffer
- /// memory in total, or 4mb, in blocks of 128kb. If you then set this
- /// property to 8, then the number will be 8 * 2 * 128kb of buffer
- /// memory, or 2mb.
- ///
- ///
- ///
- /// CPU utilization will also go up with additional buffers, because a
- /// larger number of buffer pairs allows a larger number of background
- /// threads to compress in parallel. If you find that parallel
- /// compression is consuming too much memory or CPU, you can adjust this
- /// value downward.
- ///
- ///
- ///
- /// The default value is 16. Different values may deliver better or
- /// worse results, depending on your priorities and the dynamic
- /// performance characteristics of your storage and compute resources.
- ///
- ///
- ///
- /// This property is not the number of buffer pairs to use; it is an
- /// upper limit. An illustration: Suppose you have an application that
- /// uses the default value of this property (which is 16), and it runs
- /// on a machine with 2 CPU cores. In that case, DotNetZip will allocate
- /// 4 buffer pairs per CPU core, for a total of 8 pairs. The upper
- /// limit specified by this property has no effect.
- ///
- ///
- ///
- /// 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 MaxBufferPairs
- {
- get
- {
- return _maxBufferPairs;
- }
- set
- {
- if (value < 4)
- throw new ArgumentException("MaxBufferPairs",
- "Value must be 4 or greater.");
- _maxBufferPairs = value;
- }
- }
-
- ///
- /// 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 may 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*S*2), where N is the number of buffer pairs, and S is the size of
- /// each buffer (this property). There are 2 buffers used by the
- /// compressor, one for input and one for output. By default, DotNetZip
- /// allocates 4 buffer pairs per CPU core, so if your machine has 4
- /// cores, then the number of buffer pairs used will be 16. If you
- /// accept the default value of this property, 128k, then the
- /// ParallelDeflateOutputStream will use 16 * 2 * 128kb of buffer memory
- /// in total, or 4mb, in blocks of 128kb. If you set this property to
- /// 64kb, then the number will be 16 * 2 * 64kb of buffer memory, or
- /// 2mb.
- ///
- ///
- ///
- public int BufferSize
- {
- get { return _bufferSize;}
- set
- {
- if (value < 1024)
- throw new ArgumentOutOfRangeException("BufferSize",
- "BufferSize must be greater than 1024 bytes");
- _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()
- {
- _toWrite = new Queue();
- _toFill = new Queue();
- _pool = new System.Collections.Generic.List();
- int nTasks = BufferPairsPerCore * Environment.ProcessorCount;
- nTasks = Math.Min(nTasks, _maxBufferPairs);
- for(int i=0; i < nTasks; i++)
- {
- _pool.Add(new WorkItem(_bufferSize, _compressLevel, Strategy, i));
- _toFill.Enqueue(i);
- }
-
- _newlyCompressedBlob = new AutoResetEvent(false);
- _runningCrc = new Ionic.Crc.CRC32();
- _currentlyFilling = -1;
- _lastFilled = -1;
- _lastWritten = -1;
- _latestCompressed = -1;
- }
-
-
-
-
- ///
- /// 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)
- {
- bool mustWait = false;
-
- // This method does this:
- // 0. handles any pending exceptions
- // 1. write any buffers that are ready to be written,
- // 2. fills a work buffer; when full, flip state to 'Filled',
- // 3. if more data to be written, goto step 1
-
- if (_isClosed)
- throw new InvalidOperationException();
-
- // dispense any exceptions that occurred on the BG threads
- if (_pendingException != null)
- {
- _handlingException = true;
- var pe = _pendingException;
- _pendingException = null;
- throw pe;
- }
-
- if (count == 0) return;
-
- if (!_firstWriteDone)
- {
- // Want to do this on first Write, first session, and not in the
- // constructor. We want to allow MaxBufferPairs to
- // change after construction, but before first Write.
- _InitializePoolOfWorkItems();
- _firstWriteDone = true;
- }
-
-
- do
- {
- // may need to make buffers available
- EmitPendingBuffers(false, mustWait);
-
- mustWait = false;
- // use current buffer, or get a new buffer to fill
- int ix = -1;
- if (_currentlyFilling >= 0)
- {
- ix = _currentlyFilling;
- TraceOutput(TraceBits.WriteTake,
- "Write notake wi({0}) lf({1})",
- ix,
- _lastFilled);
- }
- else
- {
- TraceOutput(TraceBits.WriteTake, "Write take?");
- if (_toFill.Count == 0)
- {
- // no available buffers, so... need to emit
- // compressed buffers.
- mustWait = true;
- continue;
- }
-
- ix = _toFill.Dequeue();
- TraceOutput(TraceBits.WriteTake,
- "Write take wi({0}) lf({1})",
- ix,
- _lastFilled);
- ++_lastFilled; // TODO: consider rollover?
- }
-
- WorkItem workitem = _pool[ix];
-
- int limit = ((workitem.buffer.Length - workitem.inputBytesAvailable) > count)
- ? count
- : (workitem.buffer.Length - workitem.inputBytesAvailable);
-
- workitem.ordinal = _lastFilled;
-
- TraceOutput(TraceBits.Write,
- "Write lock wi({0}) ord({1}) iba({2})",
- workitem.index,
- workitem.ordinal,
- workitem.inputBytesAvailable
- );
-
- // copy from the provided buffer to our workitem, starting at
- // the tail end of whatever data we might have in there currently.
- Buffer.BlockCopy(buffer,
- offset,
- workitem.buffer,
- workitem.inputBytesAvailable,
- limit);
-
- count -= limit;
- offset += limit;
- workitem.inputBytesAvailable += limit;
- if (workitem.inputBytesAvailable == workitem.buffer.Length)
- {
- // 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.
- TraceOutput(TraceBits.Write,
- "Write QUWI wi({0}) ord({1}) iba({2}) nf({3})",
- workitem.index,
- workitem.ordinal,
- workitem.inputBytesAvailable );
-
- if (!ThreadPool.QueueUserWorkItem( _DeflateOne, workitem ))
- throw new Exception("Cannot enqueue workitem");
-
- _currentlyFilling = -1; // will get a new buffer next time
- }
- else
- _currentlyFilling = ix;
-
- if (count > 0)
- TraceOutput(TraceBits.WriteEnter, "Write more");
- }
- while (count > 0); // until no more to write
-
- TraceOutput(TraceBits.WriteEnter, "Write exit");
- return;
- }
-
-
-
- private void _FlushFinish()
- {
- // After writing a series of compressed buffers, each one closed
- // with Flush.Sync, we now write the final one as Flush.Finish,
- // and then stop.
- byte[] buffer = new byte[128];
- var 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.EmitBegin,
- "Emit begin flush bytes({0})",
- buffer.Length - compressor.AvailableBytesOut);
-
- _outStream.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut);
-
- TraceOutput(TraceBits.EmitDone,
- "Emit done flush");
- }
-
- compressor.EndDeflate();
-
- _Crc32 = _runningCrc.Crc32Result;
- }
-
-
- private void _Flush(bool lastInput)
- {
- if (_isClosed)
- throw new InvalidOperationException();
-
- if (emitting) return;
-
- // compress any partial buffer
- if (_currentlyFilling >= 0)
- {
- WorkItem workitem = _pool[_currentlyFilling];
- _DeflateOne(workitem);
- _currentlyFilling = -1; // get a new buffer next Write()
- }
-
- if (lastInput)
- {
- EmitPendingBuffers(true, false);
- _FlushFinish();
- }
- else
- {
- EmitPendingBuffers(false, false);
- }
- }
-
-
-
- ///
- /// Flush the stream.
- ///
- public override void Flush()
- {
- if (_pendingException != null)
- {
- _handlingException = true;
- var pe = _pendingException;
- _pendingException = null;
- throw pe;
- }
- if (_handlingException)
- return;
-
- _Flush(false);
- }
-
-
- ///
- /// 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 (_pendingException != null)
- {
- _handlingException = true;
- var pe = _pendingException;
- _pendingException = null;
- throw pe;
- }
-
- if (_handlingException)
- return;
-
- if (_isClosed) return;
-
- _Flush(true);
-
- if (!_leaveOpen)
- _outStream.Close();
-
- _isClosed= true;
- }
-
-
-
- // 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());
- Close();
- _pool = null;
- Dispose(true);
- }
-
-
-
- /// The Dispose method
- ///
- /// indicates whether the Dispose method was invoked by user code.
- ///
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
- }
-
-
- ///
- /// 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.
- ///
- ///
- ///
- /// The new output stream for this era.
- ///
- ///
- ///
- ///
- /// 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;
-
- // reset all status
- _toWrite.Clear();
- _toFill.Clear();
- foreach (var workitem in _pool)
- {
- _toFill.Enqueue(workitem.index);
- workitem.ordinal = -1;
- }
-
- _firstWriteDone = false;
- _totalBytesProcessed = 0L;
- _runningCrc = new Ionic.Crc.CRC32();
- _isClosed= false;
- _currentlyFilling = -1;
- _lastFilled = -1;
- _lastWritten = -1;
- _latestCompressed = -1;
- _outStream = stream;
- }
-
-
-
-
- private void EmitPendingBuffers(bool doAll, bool mustWait)
- {
- // When combining parallel deflation with a ZipSegmentedStream, it's
- // possible for the ZSS to throw from within this method. In that
- // case, Close/Dispose will be called on this stream, if this stream
- // is employed within a using or try/finally pair as required. But
- // this stream is unaware of the pending exception, so the Close()
- // method invokes this method AGAIN. This can lead to a deadlock.
- // Therefore, failfast if re-entering.
-
- if (emitting) return;
- emitting = true;
- if (doAll || mustWait)
- _newlyCompressedBlob.WaitOne();
-
- do
- {
- int firstSkip = -1;
- int millisecondsToWait = doAll ? 200 : (mustWait ? -1 : 0);
- int nextToWrite = -1;
-
- do
- {
- if (Monitor.TryEnter(_toWrite, millisecondsToWait))
- {
- nextToWrite = -1;
- try
- {
- if (_toWrite.Count > 0)
- nextToWrite = _toWrite.Dequeue();
- }
- finally
- {
- Monitor.Exit(_toWrite);
- }
-
- if (nextToWrite >= 0)
- {
- WorkItem workitem = _pool[nextToWrite];
- if (workitem.ordinal != _lastWritten + 1)
- {
- // out of order. requeue and try again.
- TraceOutput(TraceBits.EmitSkip,
- "Emit skip wi({0}) ord({1}) lw({2}) fs({3})",
- workitem.index,
- workitem.ordinal,
- _lastWritten,
- firstSkip);
-
- lock(_toWrite)
- {
- _toWrite.Enqueue(nextToWrite);
- }
-
- if (firstSkip == nextToWrite)
- {
- // We went around the list once.
- // None of the items in the list is the one we want.
- // Now wait for a compressor to signal again.
- _newlyCompressedBlob.WaitOne();
- firstSkip = -1;
- }
- else if (firstSkip == -1)
- firstSkip = nextToWrite;
-
- continue;
- }
-
- firstSkip = -1;
-
- TraceOutput(TraceBits.EmitBegin,
- "Emit begin wi({0}) ord({1}) cba({2})",
- workitem.index,
- workitem.ordinal,
- workitem.compressedBytesAvailable);
-
- _outStream.Write(workitem.compressed, 0, workitem.compressedBytesAvailable);
- _runningCrc.Combine(workitem.crc, workitem.inputBytesAvailable);
- _totalBytesProcessed += workitem.inputBytesAvailable;
- workitem.inputBytesAvailable = 0;
-
- TraceOutput(TraceBits.EmitDone,
- "Emit done wi({0}) ord({1}) cba({2}) mtw({3})",
- workitem.index,
- workitem.ordinal,
- workitem.compressedBytesAvailable,
- millisecondsToWait);
-
- _lastWritten = workitem.ordinal;
- _toFill.Enqueue(workitem.index);
-
- // don't wait next time through
- if (millisecondsToWait == -1) millisecondsToWait = 0;
- }
- }
- else
- nextToWrite = -1;
-
- } while (nextToWrite >= 0);
-
- } while (doAll && (_lastWritten != _latestCompressed));
-
- emitting = false;
- }
-
-
-
-#if OLD
- 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");
- }
-#endif
-
-
-
-
- private void _DeflateOne(Object wi)
- {
- // compress one buffer
- WorkItem workitem = (WorkItem) wi;
- try
- {
- int myItem = workitem.index;
- Ionic.Crc.CRC32 crc = new Ionic.Crc.CRC32();
-
- // calc CRC on the buffer
- crc.SlurpBlock(workitem.buffer, 0, workitem.inputBytesAvailable);
-
- // deflate it
- DeflateOneSegment(workitem);
-
- // update status
- workitem.crc = crc.Crc32Result;
- TraceOutput(TraceBits.Compress,
- "Compress wi({0}) ord({1}) len({2})",
- workitem.index,
- workitem.ordinal,
- workitem.compressedBytesAvailable
- );
-
- lock(_latestLock)
- {
- if (workitem.ordinal > _latestCompressed)
- _latestCompressed = workitem.ordinal;
- }
- lock (_toWrite)
- {
- _toWrite.Enqueue(workitem.index);
- }
- _newlyCompressedBlob.Set();
- }
- 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();
-#if !SILVERLIGHT
- Console.ForegroundColor = (ConsoleColor) (tid % 8 + 8);
-#endif
- Console.Write("{0:000} PDOS ", tid);
- Console.WriteLine(format, varParams);
-#if !SILVERLIGHT
- Console.ResetColor();
-#endif
- }
- }
- }
-
-
- // used only when Trace is defined
- [Flags]
- enum TraceBits : uint
- {
- None = 0,
- NotUsed1 = 1,
- EmitLock = 2,
- EmitEnter = 4, // enter _EmitPending
- EmitBegin = 8, // begin to write out
- EmitDone = 16, // done writing out
- EmitSkip = 32, // writer skipping a workitem
- EmitAll = 58, // All Emit flags
- Flush = 64,
- Lifecycle = 128, // constructor/disposer
- Session = 256, // Close/Reset
- Synch = 512, // thread synchronization
- Instance = 1024, // instance settings
- Compress = 2048, // compress task
- Write = 4096, // filling buffers, when caller invokes Write()
- WriteEnter = 8192, // upon entry to Write()
- WriteTake = 16384, // on _toFill.Take()
- All = 0xffffffff,
- }
-
-
-
- ///
- /// 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 NotSupportedException.
- ///
- public override long Length
- {
- get { throw new NotSupportedException(); }
- }
-
- ///
- /// Returns the current position of the output stream.
- ///
- ///
- ///
- /// Because the output gets written by a background thread,
- /// the value may change asynchronously. Setting this
- /// property always throws a NotSupportedException.
- ///
- ///
- public override long Position
- {
- get { return _outStream.Position; }
- set { throw new NotSupportedException(); }
- }
-
- ///
- /// This method always throws a NotSupportedException.
- ///
- ///
- /// The buffer into which data would be read, IF THIS METHOD
- /// ACTUALLY DID ANYTHING.
- ///
- ///
- /// The offset within that data array at which to insert the
- /// data that is read, IF THIS METHOD ACTUALLY DID
- /// ANYTHING.
- ///
- ///
- /// The number of bytes to write, IF THIS METHOD ACTUALLY DID
- /// ANYTHING.
- ///
- /// nothing.
- public override int Read(byte[] buffer, int offset, int count)
- {
- throw new NotSupportedException();
- }
-
- ///
- /// This method always throws a NotSupportedException.
- ///
- ///
- /// The offset to seek to....
- /// IF THIS METHOD ACTUALLY DID ANYTHING.
- ///
- ///
- /// The reference specifying how to apply the offset.... IF
- /// THIS METHOD ACTUALLY DID ANYTHING.
- ///
- /// nothing. It always throws.
- public override long Seek(long offset, System.IO.SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
-
- ///
- /// This method always throws a NotSupportedException.
- ///
- ///
- /// The new value for the stream length.... IF
- /// THIS METHOD ACTUALLY DID ANYTHING.
- ///
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
-
- }
-
-}
-
-
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Tree.cs b/MinecraftClient/Protocol/Handlers/Compression/Tree.cs
deleted file mode 100644
index 1db8c4f4..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/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/MinecraftClient/Protocol/Handlers/Compression/Zip/ComHelper.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ComHelper.cs
deleted file mode 100644
index 385cef27..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ComHelper.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-// ComHelper.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa.
-// 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: <2011-June-13 17:04:06>
-//
-// ------------------------------------------------------------------
-//
-// This module defines a COM Helper class.
-//
-// Created: Tue, 08 Sep 2009 22:03
-//
-
-using Interop=System.Runtime.InteropServices;
-
-namespace Ionic.Zip
-{
- ///
- /// This class exposes a set of COM-accessible wrappers for static
- /// methods available on the ZipFile class. You don't need this
- /// class unless you are using DotNetZip from a COM environment.
- ///
- [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000F")]
- [System.Runtime.InteropServices.ComVisible(true)]
-#if !NETCF
- [System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDispatch)]
-#endif
-
- public class ComHelper
- {
- ///
- /// A wrapper for ZipFile.IsZipFile(string)
- ///
- /// The filename to of the zip file to check.
- /// true if the file contains a valid zip file.
- public bool IsZipFile(string filename)
- {
- return ZipFile.IsZipFile(filename);
- }
-
- ///
- /// A wrapper for ZipFile.IsZipFile(string, bool)
- ///
- ///
- /// We cannot use "overloaded" Method names in COM interop.
- /// So, here, we use a unique name.
- ///
- /// The filename to of the zip file to check.
- /// true if the file contains a valid zip file.
- public bool IsZipFileWithExtract(string filename)
- {
- return ZipFile.IsZipFile(filename, true);
- }
-
-#if !NETCF
- ///
- /// A wrapper for ZipFile.CheckZip(string)
- ///
- /// The filename to of the zip file to check.
- ///
- /// true if the named zip file checks OK. Otherwise, false.
- public bool CheckZip(string filename)
- {
- return ZipFile.CheckZip(filename);
- }
-
- ///
- /// A COM-friendly wrapper for the static method .
- ///
- ///
- /// The filename to of the zip file to check.
- ///
- /// The password to check.
- ///
- /// true if the named zip file checks OK. Otherwise, false.
- public bool CheckZipPassword(string filename, string password)
- {
- return ZipFile.CheckZipPassword(filename, password);
- }
-
- ///
- /// A wrapper for ZipFile.FixZipDirectory(string)
- ///
- /// The filename to of the zip file to fix.
- public void FixZipDirectory(string filename)
- {
- ZipFile.FixZipDirectory(filename);
- }
-#endif
-
- ///
- /// A wrapper for ZipFile.LibraryVersion
- ///
- ///
- /// the version number on the DotNetZip assembly, formatted as a string.
- ///
- public string GetZipLibraryVersion()
- {
- return ZipFile.LibraryVersion.ToString();
- }
-
- }
-}
\ No newline at end of file
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/EncryptionAlgorithm.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/EncryptionAlgorithm.cs
deleted file mode 100644
index 66b4f40f..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/EncryptionAlgorithm.cs
+++ /dev/null
@@ -1,135 +0,0 @@
-// EncryptionAlgorithm.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa
-// 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-21 17:24:45>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the EncryptionAgorithm enum
-//
-//
-// ------------------------------------------------------------------
-
-
-namespace Ionic.Zip
-{
- ///
- /// An enum that provides the various encryption algorithms supported by this
- /// library.
- ///
- ///
- ///
- ///
- ///
- /// PkzipWeak implies the use of Zip 2.0 encryption, which is known to be
- /// weak and subvertible.
- ///
- ///
- ///
- /// A note on interoperability: Values of PkzipWeak and None are
- /// specified in PKWARE's zip
- /// specification, and are considered to be "standard". Zip archives
- /// produced using these options will be interoperable with many other zip tools
- /// and libraries, including Windows Explorer.
- ///
- ///
- ///
- /// Values of WinZipAes128 and WinZipAes256 are not part of the Zip
- /// specification, but rather imply the use of a vendor-specific extension from
- /// WinZip. If you want to produce interoperable Zip archives, do not use these
- /// values. For example, if you produce a zip archive using WinZipAes256, you
- /// will be able to open it in Windows Explorer on Windows XP and Vista, but you
- /// will not be able to extract entries; trying this will lead to an "unspecified
- /// error". For this reason, some people have said that a zip archive that uses
- /// WinZip's AES encryption is not actually a zip archive at all. A zip archive
- /// produced this way will be readable with the WinZip tool (Version 11 and
- /// beyond).
- ///
- ///
- ///
- /// There are other third-party tools and libraries, both commercial and
- /// otherwise, that support WinZip's AES encryption. These will be able to read
- /// AES-encrypted zip archives produced by DotNetZip, and conversely applications
- /// that use DotNetZip to read zip archives will be able to read AES-encrypted
- /// archives produced by those tools or libraries. Consult the documentation for
- /// those other tools and libraries to find out if WinZip's AES encryption is
- /// supported.
- ///
- ///
- ///
- /// In case you care: According to the WinZip specification, the
- /// actual AES key used is derived from the via an
- /// algorithm that complies with RFC 2898, using an iteration
- /// count of 1000. The algorithm is sometimes referred to as PBKDF2, which stands
- /// for "Password Based Key Derivation Function #2".
- ///
- ///
- ///
- /// A word about password strength and length: The AES encryption technology is
- /// very good, but any system is only as secure as the weakest link. If you want
- /// to secure your data, be sure to use a password that is hard to guess. To make
- /// it harder to guess (increase its "entropy"), you should make it longer. If
- /// you use normal characters from an ASCII keyboard, a password of length 20 will
- /// be strong enough that it will be impossible to guess. For more information on
- /// that, I'd encourage you to read this
- /// article.
- ///
- ///
- ///
- /// The WinZip AES algorithms are not supported with the version of DotNetZip that
- /// runs on the .NET Compact Framework. This is because .NET CF lacks the
- /// HMACSHA1 class that is required for producing the archive.
- ///
- ///
- public enum EncryptionAlgorithm
- {
- ///
- /// No encryption at all.
- ///
- None = 0,
-
- ///
- /// Traditional or Classic pkzip encryption.
- ///
- PkzipWeak,
-
-#if AESCRYPTO
- ///
- /// WinZip AES encryption (128 key bits).
- ///
- WinZipAes128,
-
- ///
- /// WinZip AES encryption (256 key bits).
- ///
- WinZipAes256,
-#endif
-
- ///
- /// An encryption algorithm that is not supported by DotNetZip.
- ///
- Unsupported = 4,
-
-
- // others... not implemented (yet?)
- }
-
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/Events.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/Events.cs
deleted file mode 100644
index e51ff78f..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/Events.cs
+++ /dev/null
@@ -1,684 +0,0 @@
-// Events.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2006, 2007, 2008, 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: <2011-August-06 12:26:24>
-//
-// ------------------------------------------------------------------
-//
-// This module defines events used by the ZipFile class.
-//
-//
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Ionic.Zip
-{
- ///
- /// Delegate in which the application writes the ZipEntry content for the named entry.
- ///
- ///
- /// The name of the entry that must be written.
- /// The stream to which the entry data should be written.
- ///
- ///
- /// When you add an entry and specify a WriteDelegate, via , the application
- /// code provides the logic that writes the entry data directly into the zip file.
- ///
- ///
- ///
- ///
- /// This example shows how to define a WriteDelegate that obtains a DataSet, and then
- /// writes the XML for the DataSet into the zip archive. There's no need to
- /// save the XML to a disk file first.
- ///
- ///
- /// private void WriteEntry (String filename, Stream output)
- /// {
- /// DataSet ds1 = ObtainDataSet();
- /// ds1.WriteXml(output);
- /// }
- ///
- /// private void Run()
- /// {
- /// using (var zip = new ZipFile())
- /// {
- /// zip.AddEntry(zipEntryName, WriteEntry);
- /// zip.Save(zipFileName);
- /// }
- /// }
- ///
- ///
- ///
- /// Private Sub WriteEntry (ByVal filename As String, ByVal output As Stream)
- /// DataSet ds1 = ObtainDataSet()
- /// ds1.WriteXml(stream)
- /// End Sub
- ///
- /// Public Sub Run()
- /// Using zip = New ZipFile
- /// zip.AddEntry(zipEntryName, New WriteDelegate(AddressOf WriteEntry))
- /// zip.Save(zipFileName)
- /// End Using
- /// End Sub
- ///
- ///
- ///
- public delegate void WriteDelegate(string entryName, System.IO.Stream stream);
-
-
- ///
- /// Delegate in which the application opens the stream, just-in-time, for the named entry.
- ///
- ///
- ///
- /// The name of the ZipEntry that the application should open the stream for.
- ///
- ///
- ///
- /// When you add an entry via , the application code provides the logic that
- /// opens and closes the stream for the given ZipEntry.
- ///
- ///
- ///
- public delegate System.IO.Stream OpenDelegate(string entryName);
-
- ///
- /// Delegate in which the application closes the stream, just-in-time, for the named entry.
- ///
- ///
- ///
- /// The name of the ZipEntry that the application should close the stream for.
- ///
- ///
- /// The stream to be closed.
- ///
- ///
- /// When you add an entry via , the application code provides the logic that
- /// opens and closes the stream for the given ZipEntry.
- ///
- ///
- ///
- public delegate void CloseDelegate(string entryName, System.IO.Stream stream);
-
- ///
- /// Delegate for the callback by which the application tells the
- /// library the CompressionLevel to use for a file.
- ///
- ///
- ///
- ///
- /// Using this callback, the application can, for example, specify that
- /// previously-compressed files (.mp3, .png, .docx, etc) should use a
- /// CompressionLevel of None, or can set the compression level based
- /// on any other factor.
- ///
- ///
- ///
- public delegate Ionic.Zlib.CompressionLevel SetCompressionCallback(string localFileName, string fileNameInArchive);
-
- ///
- /// In an EventArgs type, indicates which sort of progress event is being
- /// reported.
- ///
- ///
- /// There are events for reading, events for saving, and events for
- /// extracting. This enumeration allows a single EventArgs type to be sued to
- /// describe one of multiple subevents. For example, a SaveProgress event is
- /// invoked before, after, and during the saving of a single entry. The value
- /// of an enum with this type, specifies which event is being triggered. The
- /// same applies to Extraction, Reading and Adding events.
- ///
- public enum ZipProgressEventType
- {
- ///
- /// Indicates that a Add() operation has started.
- ///
- Adding_Started,
-
- ///
- /// Indicates that an individual entry in the archive has been added.
- ///
- Adding_AfterAddEntry,
-
- ///
- /// Indicates that a Add() operation has completed.
- ///
- Adding_Completed,
-
- ///
- /// Indicates that a Read() operation has started.
- ///
- Reading_Started,
-
- ///
- /// Indicates that an individual entry in the archive is about to be read.
- ///
- Reading_BeforeReadEntry,
-
- ///
- /// Indicates that an individual entry in the archive has just been read.
- ///
- Reading_AfterReadEntry,
-
- ///
- /// Indicates that a Read() operation has completed.
- ///
- Reading_Completed,
-
- ///
- /// The given event reports the number of bytes read so far
- /// during a Read() operation.
- ///
- Reading_ArchiveBytesRead,
-
- ///
- /// Indicates that a Save() operation has started.
- ///
- Saving_Started,
-
- ///
- /// Indicates that an individual entry in the archive is about to be written.
- ///
- Saving_BeforeWriteEntry,
-
- ///
- /// Indicates that an individual entry in the archive has just been saved.
- ///
- Saving_AfterWriteEntry,
-
- ///
- /// Indicates that a Save() operation has completed.
- ///
- Saving_Completed,
-
- ///
- /// Indicates that the zip archive has been created in a
- /// temporary location during a Save() operation.
- ///
- Saving_AfterSaveTempArchive,
-
- ///
- /// Indicates that the temporary file is about to be renamed to the final archive
- /// name during a Save() operation.
- ///
- Saving_BeforeRenameTempArchive,
-
- ///
- /// Indicates that the temporary file is has just been renamed to the final archive
- /// name during a Save() operation.
- ///
- Saving_AfterRenameTempArchive,
-
- ///
- /// Indicates that the self-extracting archive has been compiled
- /// during a Save() operation.
- ///
- Saving_AfterCompileSelfExtractor,
-
- ///
- /// The given event is reporting the number of source bytes that have run through the compressor so far
- /// during a Save() operation.
- ///
- Saving_EntryBytesRead,
-
- ///
- /// Indicates that an entry is about to be extracted.
- ///
- Extracting_BeforeExtractEntry,
-
- ///
- /// Indicates that an entry has just been extracted.
- ///
- Extracting_AfterExtractEntry,
-
- ///
- /// Indicates that extraction of an entry would overwrite an existing
- /// filesystem file. You must use
- ///
- /// ExtractExistingFileAction.InvokeExtractProgressEvent in the call
- /// to ZipEntry.Extract() in order to receive this event.
- ///
- Extracting_ExtractEntryWouldOverwrite,
-
- ///
- /// The given event is reporting the number of bytes written so far for
- /// the current entry during an Extract() operation.
- ///
- Extracting_EntryBytesWritten,
-
- ///
- /// Indicates that an ExtractAll operation is about to begin.
- ///
- Extracting_BeforeExtractAll,
-
- ///
- /// Indicates that an ExtractAll operation has completed.
- ///
- Extracting_AfterExtractAll,
-
- ///
- /// Indicates that an error has occurred while saving a zip file.
- /// This generally means the file cannot be opened, because it has been
- /// removed, or because it is locked by another process. It can also
- /// mean that the file cannot be Read, because of a range lock conflict.
- ///
- Error_Saving,
- }
-
-
- ///
- /// Provides information about the progress of a save, read, or extract operation.
- /// This is a base class; you will probably use one of the classes derived from this one.
- ///
- public class ZipProgressEventArgs : EventArgs
- {
- private int _entriesTotal;
- private bool _cancel;
- private ZipEntry _latestEntry;
- private ZipProgressEventType _flavor;
- private String _archiveName;
- private Int64 _bytesTransferred;
- private Int64 _totalBytesToTransfer;
-
-
- internal ZipProgressEventArgs() { }
-
- internal ZipProgressEventArgs(string archiveName, ZipProgressEventType flavor)
- {
- this._archiveName = archiveName;
- this._flavor = flavor;
- }
-
- ///
- /// The total number of entries to be saved or extracted.
- ///
- public int EntriesTotal
- {
- get { return _entriesTotal; }
- set { _entriesTotal = value; }
- }
-
- ///
- /// The name of the last entry saved or extracted.
- ///
- public ZipEntry CurrentEntry
- {
- get { return _latestEntry; }
- set { _latestEntry = value; }
- }
-
- ///
- /// In an event handler, set this to cancel the save or extract
- /// operation that is in progress.
- ///
- public bool Cancel
- {
- get { return _cancel; }
- set { _cancel = _cancel || value; }
- }
-
- ///
- /// The type of event being reported.
- ///
- public ZipProgressEventType EventType
- {
- get { return _flavor; }
- set { _flavor = value; }
- }
-
- ///
- /// Returns the archive name associated to this event.
- ///
- public String ArchiveName
- {
- get { return _archiveName; }
- set { _archiveName = value; }
- }
-
-
- ///
- /// The number of bytes read or written so far for this entry.
- ///
- public Int64 BytesTransferred
- {
- get { return _bytesTransferred; }
- set { _bytesTransferred = value; }
- }
-
-
-
- ///
- /// Total number of bytes that will be read or written for this entry.
- /// This number will be -1 if the value cannot be determined.
- ///
- public Int64 TotalBytesToTransfer
- {
- get { return _totalBytesToTransfer; }
- set { _totalBytesToTransfer = value; }
- }
- }
-
-
-
- ///
- /// Provides information about the progress of a Read operation.
- ///
- public class ReadProgressEventArgs : ZipProgressEventArgs
- {
-
- internal ReadProgressEventArgs() { }
-
- private ReadProgressEventArgs(string archiveName, ZipProgressEventType flavor)
- : base(archiveName, flavor)
- { }
-
- internal static ReadProgressEventArgs Before(string archiveName, int entriesTotal)
- {
- var x = new ReadProgressEventArgs(archiveName, ZipProgressEventType.Reading_BeforeReadEntry);
- x.EntriesTotal = entriesTotal;
- return x;
- }
-
- internal static ReadProgressEventArgs After(string archiveName, ZipEntry entry, int entriesTotal)
- {
- var x = new ReadProgressEventArgs(archiveName, ZipProgressEventType.Reading_AfterReadEntry);
- x.EntriesTotal = entriesTotal;
- x.CurrentEntry = entry;
- return x;
- }
-
- internal static ReadProgressEventArgs Started(string archiveName)
- {
- var x = new ReadProgressEventArgs(archiveName, ZipProgressEventType.Reading_Started);
- return x;
- }
-
- internal static ReadProgressEventArgs ByteUpdate(string archiveName, ZipEntry entry, Int64 bytesXferred, Int64 totalBytes)
- {
- var x = new ReadProgressEventArgs(archiveName, ZipProgressEventType.Reading_ArchiveBytesRead);
- x.CurrentEntry = entry;
- x.BytesTransferred = bytesXferred;
- x.TotalBytesToTransfer = totalBytes;
- return x;
- }
-
- internal static ReadProgressEventArgs Completed(string archiveName)
- {
- var x = new ReadProgressEventArgs(archiveName, ZipProgressEventType.Reading_Completed);
- return x;
- }
-
- }
-
-
- ///
- /// Provides information about the progress of a Add operation.
- ///
- public class AddProgressEventArgs : ZipProgressEventArgs
- {
- internal AddProgressEventArgs() { }
-
- private AddProgressEventArgs(string archiveName, ZipProgressEventType flavor)
- : base(archiveName, flavor)
- { }
-
- internal static AddProgressEventArgs AfterEntry(string archiveName, ZipEntry entry, int entriesTotal)
- {
- var x = new AddProgressEventArgs(archiveName, ZipProgressEventType.Adding_AfterAddEntry);
- x.EntriesTotal = entriesTotal;
- x.CurrentEntry = entry;
- return x;
- }
-
- internal static AddProgressEventArgs Started(string archiveName)
- {
- var x = new AddProgressEventArgs(archiveName, ZipProgressEventType.Adding_Started);
- return x;
- }
-
- internal static AddProgressEventArgs Completed(string archiveName)
- {
- var x = new AddProgressEventArgs(archiveName, ZipProgressEventType.Adding_Completed);
- return x;
- }
-
- }
-
- ///
- /// Provides information about the progress of a save operation.
- ///
- public class SaveProgressEventArgs : ZipProgressEventArgs
- {
- private int _entriesSaved;
-
- ///
- /// Constructor for the SaveProgressEventArgs.
- ///
- /// the name of the zip archive.
- /// whether this is before saving the entry, or after
- /// The total number of entries in the zip archive.
- /// Number of entries that have been saved.
- /// The entry involved in the event.
- internal SaveProgressEventArgs(string archiveName, bool before, int entriesTotal, int entriesSaved, ZipEntry entry)
- : base(archiveName, (before) ? ZipProgressEventType.Saving_BeforeWriteEntry : ZipProgressEventType.Saving_AfterWriteEntry)
- {
- this.EntriesTotal = entriesTotal;
- this.CurrentEntry = entry;
- this._entriesSaved = entriesSaved;
- }
-
- internal SaveProgressEventArgs() { }
-
- internal SaveProgressEventArgs(string archiveName, ZipProgressEventType flavor)
- : base(archiveName, flavor)
- { }
-
-
- internal static SaveProgressEventArgs ByteUpdate(string archiveName, ZipEntry entry, Int64 bytesXferred, Int64 totalBytes)
- {
- var x = new SaveProgressEventArgs(archiveName, ZipProgressEventType.Saving_EntryBytesRead);
- x.ArchiveName = archiveName;
- x.CurrentEntry = entry;
- x.BytesTransferred = bytesXferred;
- x.TotalBytesToTransfer = totalBytes;
- return x;
- }
-
- internal static SaveProgressEventArgs Started(string archiveName)
- {
- var x = new SaveProgressEventArgs(archiveName, ZipProgressEventType.Saving_Started);
- return x;
- }
-
- internal static SaveProgressEventArgs Completed(string archiveName)
- {
- var x = new SaveProgressEventArgs(archiveName, ZipProgressEventType.Saving_Completed);
- return x;
- }
-
- ///
- /// Number of entries saved so far.
- ///
- public int EntriesSaved
- {
- get { return _entriesSaved; }
- }
- }
-
-
- ///
- /// Provides information about the progress of the extract operation.
- ///
- public class ExtractProgressEventArgs : ZipProgressEventArgs
- {
- private int _entriesExtracted;
- private string _target;
-
- ///
- /// Constructor for the ExtractProgressEventArgs.
- ///
- /// the name of the zip archive.
- /// whether this is before saving the entry, or after
- /// The total number of entries in the zip archive.
- /// Number of entries that have been extracted.
- /// The entry involved in the event.
- /// The location to which entries are extracted.
- internal ExtractProgressEventArgs(string archiveName, bool before, int entriesTotal, int entriesExtracted, ZipEntry entry, string extractLocation)
- : base(archiveName, (before) ? ZipProgressEventType.Extracting_BeforeExtractEntry : ZipProgressEventType.Extracting_AfterExtractEntry)
- {
- this.EntriesTotal = entriesTotal;
- this.CurrentEntry = entry;
- this._entriesExtracted = entriesExtracted;
- this._target = extractLocation;
- }
-
- internal ExtractProgressEventArgs(string archiveName, ZipProgressEventType flavor)
- : base(archiveName, flavor)
- { }
-
- internal ExtractProgressEventArgs()
- { }
-
-
- internal static ExtractProgressEventArgs BeforeExtractEntry(string archiveName, ZipEntry entry, string extractLocation)
- {
- var x = new ExtractProgressEventArgs
- {
- ArchiveName = archiveName,
- EventType = ZipProgressEventType.Extracting_BeforeExtractEntry,
- CurrentEntry = entry,
- _target = extractLocation,
- };
- return x;
- }
-
- internal static ExtractProgressEventArgs ExtractExisting(string archiveName, ZipEntry entry, string extractLocation)
- {
- var x = new ExtractProgressEventArgs
- {
- ArchiveName = archiveName,
- EventType = ZipProgressEventType.Extracting_ExtractEntryWouldOverwrite,
- CurrentEntry = entry,
- _target = extractLocation,
- };
- return x;
- }
-
- internal static ExtractProgressEventArgs AfterExtractEntry(string archiveName, ZipEntry entry, string extractLocation)
- {
- var x = new ExtractProgressEventArgs
- {
- ArchiveName = archiveName,
- EventType = ZipProgressEventType.Extracting_AfterExtractEntry,
- CurrentEntry = entry,
- _target = extractLocation,
- };
- return x;
- }
-
- internal static ExtractProgressEventArgs ExtractAllStarted(string archiveName, string extractLocation)
- {
- var x = new ExtractProgressEventArgs(archiveName, ZipProgressEventType.Extracting_BeforeExtractAll);
- x._target = extractLocation;
- return x;
- }
-
- internal static ExtractProgressEventArgs ExtractAllCompleted(string archiveName, string extractLocation)
- {
- var x = new ExtractProgressEventArgs(archiveName, ZipProgressEventType.Extracting_AfterExtractAll);
- x._target = extractLocation;
- return x;
- }
-
-
- internal static ExtractProgressEventArgs ByteUpdate(string archiveName, ZipEntry entry, Int64 bytesWritten, Int64 totalBytes)
- {
- var x = new ExtractProgressEventArgs(archiveName, ZipProgressEventType.Extracting_EntryBytesWritten);
- x.ArchiveName = archiveName;
- x.CurrentEntry = entry;
- x.BytesTransferred = bytesWritten;
- x.TotalBytesToTransfer = totalBytes;
- return x;
- }
-
-
-
- ///
- /// Number of entries extracted so far. This is set only if the
- /// EventType is Extracting_BeforeExtractEntry or Extracting_AfterExtractEntry, and
- /// the Extract() is occurring witin the scope of a call to ExtractAll().
- ///
- public int EntriesExtracted
- {
- get { return _entriesExtracted; }
- }
-
- ///
- /// Returns the extraction target location, a filesystem path.
- ///
- public String ExtractLocation
- {
- get { return _target; }
- }
-
- }
-
-
-
- ///
- /// Provides information about the an error that occurred while zipping.
- ///
- public class ZipErrorEventArgs : ZipProgressEventArgs
- {
- private Exception _exc;
- private ZipErrorEventArgs() { }
- internal static ZipErrorEventArgs Saving(string archiveName, ZipEntry entry, Exception exception)
- {
- var x = new ZipErrorEventArgs
- {
- EventType = ZipProgressEventType.Error_Saving,
- ArchiveName = archiveName,
- CurrentEntry = entry,
- _exc = exception
- };
- return x;
- }
-
- ///
- /// Returns the exception that occurred, if any.
- ///
- public Exception @Exception
- {
- get { return _exc; }
- }
-
- ///
- /// Returns the name of the file that caused the exception, if any.
- ///
- public String FileName
- {
- get { return CurrentEntry.LocalFileName; }
- }
- }
-
-
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/Exceptions.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/Exceptions.cs
deleted file mode 100644
index 9f67077e..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/Exceptions.cs
+++ /dev/null
@@ -1,300 +0,0 @@
-// Exceptions.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2008, 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: <2011-July-12 12:19:10>
-//
-// ------------------------------------------------------------------
-//
-// This module defines exceptions used in the class library.
-//
-
-
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-#if !NETCF
-using System.Runtime.Serialization;
-#endif
-
-namespace Ionic.Zip
-{
- /////
- ///// Base exception type for all custom exceptions in the Zip library. It acts as a marker class.
- /////
- //[AttributeUsage(AttributeTargets.Class)]
- //public class ZipExceptionAttribute : Attribute { }
-
-
-
- ///
- /// Issued when an ZipEntry.ExtractWithPassword() method is invoked
- /// with an incorrect password.
- ///
-#if !SILVERLIGHT
- [Serializable]
-#endif
- [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000B")]
- public class BadPasswordException : ZipException
- {
- ///
- /// Default ctor.
- ///
- public BadPasswordException() { }
-
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The message in the exception.
- public BadPasswordException(String message)
- : base(message)
- { }
-
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The message in the exception.
- /// The innerException for this exception.
- public BadPasswordException(String message, Exception innerException)
- : base(message, innerException)
- {
- }
-
-
-#if ! (NETCF || SILVERLIGHT)
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The serialization info for the exception.
- /// The streaming context from which to deserialize.
- protected BadPasswordException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- { }
-#endif
-
- }
-
- ///
- /// Indicates that a read was attempted on a stream, and bad or incomplete data was
- /// received.
- ///
-#if !SILVERLIGHT
- [Serializable]
-#endif
- [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000A")]
- public class BadReadException : ZipException
- {
- ///
- /// Default ctor.
- ///
- public BadReadException() { }
-
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The message in the exception.
- public BadReadException(String message)
- : base(message)
- { }
-
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The message in the exception.
- /// The innerException for this exception.
- public BadReadException(String message, Exception innerException)
- : base(message, innerException)
- {
- }
-
-#if ! (NETCF || SILVERLIGHT)
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The serialization info for the exception.
- /// The streaming context from which to deserialize.
- protected BadReadException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- { }
-#endif
-
- }
-
-
-
- ///
- /// Issued when an CRC check fails upon extracting an entry from a zip archive.
- ///
-#if !SILVERLIGHT
- [Serializable]
-#endif
- [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00009")]
- public class BadCrcException : ZipException
- {
- ///
- /// Default ctor.
- ///
- public BadCrcException() { }
-
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The message in the exception.
- public BadCrcException(String message)
- : base(message)
- { }
-
-
-#if ! (NETCF || SILVERLIGHT)
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The serialization info for the exception.
- /// The streaming context from which to deserialize.
- protected BadCrcException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- { }
-#endif
-
- }
-
-
- ///
- /// Issued when errors occur saving a self-extracting archive.
- ///
-#if !SILVERLIGHT
- [Serializable]
-#endif
- [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00008")]
- public class SfxGenerationException : ZipException
- {
- ///
- /// Default ctor.
- ///
- public SfxGenerationException() { }
-
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The message in the exception.
- public SfxGenerationException(String message)
- : base(message)
- { }
-
-#if ! (NETCF || SILVERLIGHT)
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The serialization info for the exception.
- /// The streaming context from which to deserialize.
- protected SfxGenerationException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- { }
-#endif
-
- }
-
-
- ///
- /// Indicates that an operation was attempted on a ZipFile which was not possible
- /// given the state of the instance. For example, if you call Save() on a ZipFile
- /// which has no filename set, you can get this exception.
- ///
-#if !SILVERLIGHT
- [Serializable]
-#endif
- [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00007")]
- public class BadStateException : ZipException
- {
- ///
- /// Default ctor.
- ///
- public BadStateException() { }
-
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The message in the exception.
- public BadStateException(String message)
- : base(message)
- { }
-
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The message in the exception.
- /// The innerException for this exception.
- public BadStateException(String message, Exception innerException)
- : base(message, innerException)
- {}
-
-#if ! (NETCF || SILVERLIGHT)
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The serialization info for the exception.
- /// The streaming context from which to deserialize.
- protected BadStateException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- { }
-#endif
-
- }
-
- ///
- /// Base class for all exceptions defined by and throw by the Zip library.
- ///
-#if !SILVERLIGHT
- [Serializable]
-#endif
- [System.Runtime.InteropServices.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00006")]
- public class ZipException : Exception
- {
- ///
- /// Default ctor.
- ///
- public ZipException() { }
-
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The message in the exception.
- public ZipException(String message) : base(message) { }
-
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The message in the exception.
- /// The innerException for this exception.
- public ZipException(String message, Exception innerException)
- : base(message, innerException)
- { }
-
-#if ! (NETCF || SILVERLIGHT)
- ///
- /// Come on, you know how exceptions work. Why are you looking at this documentation?
- ///
- /// The serialization info for the exception.
- /// The streaming context from which to deserialize.
- protected ZipException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- { }
-#endif
-
- }
-
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ExtractExistingFileAction.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ExtractExistingFileAction.cs
deleted file mode 100644
index 2de229fd..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ExtractExistingFileAction.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-// ExtractExistingFileAction.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa
-// 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-August-25 08:44:37>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the ExtractExistingFileAction enum
-//
-//
-// ------------------------------------------------------------------
-
-
-namespace Ionic.Zip
-{
-
- ///
- /// An enum for the options when extracting an entry would overwrite an existing file.
- ///
- ///
- ///
- ///
- /// This enum describes the actions that the library can take when an
- /// Extract() or ExtractWithPassword() method is called to extract an
- /// entry to a filesystem, and the extraction would overwrite an existing filesystem
- /// file.
- ///
- ///
- ///
- public enum ExtractExistingFileAction
- {
- ///
- /// Throw an exception when extraction would overwrite an existing file. (For
- /// COM clients, this is a 0 (zero).)
- ///
- Throw,
-
- ///
- /// When extraction would overwrite an existing file, overwrite the file silently.
- /// The overwrite will happen even if the target file is marked as read-only.
- /// (For COM clients, this is a 1.)
- ///
- OverwriteSilently,
-
- ///
- /// When extraction would overwrite an existing file, don't overwrite the file, silently.
- /// (For COM clients, this is a 2.)
- ///
- DoNotOverwrite,
-
- ///
- /// When extraction would overwrite an existing file, invoke the ExtractProgress
- /// event, using an event type of . In
- /// this way, the application can decide, just-in-time, whether to overwrite the
- /// file. For example, a GUI application may wish to pop up a dialog to allow
- /// the user to choose. You may want to examine the property before making
- /// the decision. If, after your processing in the Extract progress event, you
- /// want to NOT extract the file, set
- /// on the ZipProgressEventArgs.CurrentEntry to DoNotOverwrite.
- /// If you do want to extract the file, set ZipEntry.ExtractExistingFile
- /// to OverwriteSilently. If you want to cancel the Extraction, set
- /// ZipProgressEventArgs.Cancel to true. Cancelling differs from using
- /// DoNotOverwrite in that a cancel will not extract any further entries, if
- /// there are any. (For COM clients, the value of this enum is a 3.)
- ///
- InvokeExtractProgressEvent,
- }
-
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/FileSelector.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/FileSelector.cs
deleted file mode 100644
index 874eb1b5..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/FileSelector.cs
+++ /dev/null
@@ -1,1608 +0,0 @@
-//#define SelectorTrace
-
-// FileSelector.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2008-2011 Dino Chiesa.
-// 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: <2011-August-05 11:03:11>
-//
-// ------------------------------------------------------------------
-//
-// This module implements a "file selector" that finds files based on a
-// set of inclusion criteria, including filename, size, file time, and
-// potentially file attributes. The criteria are given in a string with
-// a simple expression language. Examples:
-//
-// find all .txt files:
-// name = *.txt
-//
-// shorthand for the above
-// *.txt
-//
-// all files modified after January 1st, 2009
-// mtime > 2009-01-01
-//
-// All .txt files modified after the first of the year
-// name = *.txt AND mtime > 2009-01-01
-//
-// All .txt files modified after the first of the year, or any file with the archive bit set
-// (name = *.txt AND mtime > 2009-01-01) or (attribtues = A)
-//
-// All .txt files or any file greater than 1mb in size
-// (name = *.txt or size > 1mb)
-//
-// and so on.
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-using System.Text;
-using System.Reflection;
-using System.ComponentModel;
-using System.Text.RegularExpressions;
-using System.Collections.Generic;
-#if SILVERLIGHT
-using System.Linq;
-#endif
-
-namespace Ionic
-{
-
- ///
- /// Enumerates the options for a logical conjunction. This enum is intended for use
- /// internally by the FileSelector class.
- ///
- internal enum LogicalConjunction
- {
- NONE,
- AND,
- OR,
- XOR,
- }
-
- internal enum WhichTime
- {
- atime,
- mtime,
- ctime,
- }
-
-
- internal enum ComparisonOperator
- {
- [Description(">")]
- GreaterThan,
- [Description(">=")]
- GreaterThanOrEqualTo,
- [Description("<")]
- LesserThan,
- [Description("<=")]
- LesserThanOrEqualTo,
- [Description("=")]
- EqualTo,
- [Description("!=")]
- NotEqualTo
- }
-
-
- internal abstract partial class SelectionCriterion
- {
- internal virtual bool Verbose
- {
- get;set;
- }
- internal abstract bool Evaluate(string filename);
-
- [System.Diagnostics.Conditional("SelectorTrace")]
- protected static void CriterionTrace(string format, params object[] args)
- {
- //System.Console.WriteLine(" " + format, args);
- }
- }
-
-
- internal partial class SizeCriterion : SelectionCriterion
- {
- internal ComparisonOperator Operator;
- internal Int64 Size;
-
- public override String ToString()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append("size ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(Size.ToString());
- return sb.ToString();
- }
-
- internal override bool Evaluate(string filename)
- {
- System.IO.FileInfo fi = new System.IO.FileInfo(filename);
- CriterionTrace("SizeCriterion::Evaluate('{0}' [{1}])",
- filename, this.ToString());
- return _Evaluate(fi.Length);
- }
-
- private bool _Evaluate(Int64 Length)
- {
- bool result = false;
- switch (Operator)
- {
- case ComparisonOperator.GreaterThanOrEqualTo:
- result = Length >= Size;
- break;
- case ComparisonOperator.GreaterThan:
- result = Length > Size;
- break;
- case ComparisonOperator.LesserThanOrEqualTo:
- result = Length <= Size;
- break;
- case ComparisonOperator.LesserThan:
- result = Length < Size;
- break;
- case ComparisonOperator.EqualTo:
- result = Length == Size;
- break;
- case ComparisonOperator.NotEqualTo:
- result = Length != Size;
- break;
- default:
- throw new ArgumentException("Operator");
- }
- return result;
- }
-
- }
-
-
-
- internal partial class TimeCriterion : SelectionCriterion
- {
- internal ComparisonOperator Operator;
- internal WhichTime Which;
- internal DateTime Time;
-
- public override String ToString()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append(Which.ToString()).Append(" ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(Time.ToString("yyyy-MM-dd-HH:mm:ss"));
- return sb.ToString();
- }
-
- internal override bool Evaluate(string filename)
- {
- DateTime x;
- switch (Which)
- {
- case WhichTime.atime:
- x = System.IO.File.GetLastAccessTime(filename).ToUniversalTime();
- break;
- case WhichTime.mtime:
- x = System.IO.File.GetLastWriteTime(filename).ToUniversalTime();
- break;
- case WhichTime.ctime:
- x = System.IO.File.GetCreationTime(filename).ToUniversalTime();
- break;
- default:
- throw new ArgumentException("Operator");
- }
- CriterionTrace("TimeCriterion({0},{1})= {2}", filename, Which.ToString(), x);
- return _Evaluate(x);
- }
-
-
- private bool _Evaluate(DateTime x)
- {
- bool result = false;
- switch (Operator)
- {
- case ComparisonOperator.GreaterThanOrEqualTo:
- result = (x >= Time);
- break;
- case ComparisonOperator.GreaterThan:
- result = (x > Time);
- break;
- case ComparisonOperator.LesserThanOrEqualTo:
- result = (x <= Time);
- break;
- case ComparisonOperator.LesserThan:
- result = (x < Time);
- break;
- case ComparisonOperator.EqualTo:
- result = (x == Time);
- break;
- case ComparisonOperator.NotEqualTo:
- result = (x != Time);
- break;
- default:
- throw new ArgumentException("Operator");
- }
-
- CriterionTrace("TimeCriterion: {0}", result);
- return result;
- }
- }
-
-
-
- internal partial class NameCriterion : SelectionCriterion
- {
- private Regex _re;
- private String _regexString;
- internal ComparisonOperator Operator;
- private string _MatchingFileSpec;
- internal virtual string MatchingFileSpec
- {
- set
- {
- // workitem 8245
- if (Directory.Exists(value))
- {
- _MatchingFileSpec = ".\\" + value + "\\*.*";
- }
- else
- {
- _MatchingFileSpec = value;
- }
-
- _regexString = "^" +
- Regex.Escape(_MatchingFileSpec)
- .Replace(@"\\\*\.\*", @"\\([^\.]+|.*\.[^\\\.]*)")
- .Replace(@"\.\*", @"\.[^\\\.]*")
- .Replace(@"\*", @".*")
- //.Replace(@"\*", @"[^\\\.]*") // ill-conceived
- .Replace(@"\?", @"[^\\\.]")
- + "$";
-
- CriterionTrace("NameCriterion regexString({0})", _regexString);
-
- _re = new Regex(_regexString, RegexOptions.IgnoreCase);
- }
- }
-
-
- public override String ToString()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append("name ").Append(EnumUtil.GetDescription(Operator))
- .Append(" '")
- .Append(_MatchingFileSpec)
- .Append("'");
- return sb.ToString();
- }
-
-
- internal override bool Evaluate(string filename)
- {
- CriterionTrace("NameCriterion::Evaluate('{0}' pattern[{1}])",
- filename, _MatchingFileSpec);
- return _Evaluate(filename);
- }
-
- private bool _Evaluate(string fullpath)
- {
- CriterionTrace("NameCriterion::Evaluate({0})", fullpath);
- // No slash in the pattern implicitly means recurse, which means compare to
- // filename only, not full path.
- String f = (_MatchingFileSpec.IndexOf('\\') == -1)
- ? System.IO.Path.GetFileName(fullpath)
- : fullpath; // compare to fullpath
-
- bool result = _re.IsMatch(f);
-
- if (Operator != ComparisonOperator.EqualTo)
- result = !result;
- return result;
- }
- }
-
-
- internal partial class TypeCriterion : SelectionCriterion
- {
- private char ObjectType; // 'D' = Directory, 'F' = File
- internal ComparisonOperator Operator;
- internal string AttributeString
- {
- get
- {
- return ObjectType.ToString();
- }
- set
- {
- if (value.Length != 1 ||
- (value[0]!='D' && value[0]!='F'))
- throw new ArgumentException("Specify a single character: either D or F");
- ObjectType = value[0];
- }
- }
-
- public override String ToString()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append("type ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(AttributeString);
- return sb.ToString();
- }
-
- internal override bool Evaluate(string filename)
- {
- CriterionTrace("TypeCriterion::Evaluate({0})", filename);
-
- bool result = (ObjectType == 'D')
- ? Directory.Exists(filename)
- : File.Exists(filename);
-
- if (Operator != ComparisonOperator.EqualTo)
- result = !result;
- return result;
- }
- }
-
-
-#if !SILVERLIGHT
- internal partial class AttributesCriterion : SelectionCriterion
- {
- private FileAttributes _Attributes;
- internal ComparisonOperator Operator;
- internal string AttributeString
- {
- get
- {
- string result = "";
- if ((_Attributes & FileAttributes.Hidden) != 0)
- result += "H";
- if ((_Attributes & FileAttributes.System) != 0)
- result += "S";
- if ((_Attributes & FileAttributes.ReadOnly) != 0)
- result += "R";
- if ((_Attributes & FileAttributes.Archive) != 0)
- result += "A";
- if ((_Attributes & FileAttributes.ReparsePoint) != 0)
- result += "L";
- if ((_Attributes & FileAttributes.NotContentIndexed) != 0)
- result += "I";
- return result;
- }
-
- set
- {
- _Attributes = FileAttributes.Normal;
- foreach (char c in value.ToUpper())
- {
- switch (c)
- {
- case 'H':
- if ((_Attributes & FileAttributes.Hidden) != 0)
- throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
- _Attributes |= FileAttributes.Hidden;
- break;
-
- case 'R':
- if ((_Attributes & FileAttributes.ReadOnly) != 0)
- throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
- _Attributes |= FileAttributes.ReadOnly;
- break;
-
- case 'S':
- if ((_Attributes & FileAttributes.System) != 0)
- throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
- _Attributes |= FileAttributes.System;
- break;
-
- case 'A':
- if ((_Attributes & FileAttributes.Archive) != 0)
- throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
- _Attributes |= FileAttributes.Archive;
- break;
-
- case 'I':
- if ((_Attributes & FileAttributes.NotContentIndexed) != 0)
- throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
- _Attributes |= FileAttributes.NotContentIndexed;
- break;
-
- case 'L':
- if ((_Attributes & FileAttributes.ReparsePoint) != 0)
- throw new ArgumentException(String.Format("Repeated flag. ({0})", c), "value");
- _Attributes |= FileAttributes.ReparsePoint;
- break;
-
- default:
- throw new ArgumentException(value);
- }
- }
- }
- }
-
-
- public override String ToString()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append("attributes ").Append(EnumUtil.GetDescription(Operator)).Append(" ").Append(AttributeString);
- return sb.ToString();
- }
-
- private bool _EvaluateOne(FileAttributes fileAttrs, FileAttributes criterionAttrs)
- {
- bool result = false;
- if ((_Attributes & criterionAttrs) == criterionAttrs)
- result = ((fileAttrs & criterionAttrs) == criterionAttrs);
- else
- result = true;
- return result;
- }
-
-
-
- internal override bool Evaluate(string filename)
- {
- // workitem 10191
- if (Directory.Exists(filename))
- {
- // Directories don't have file attributes, so the result
- // of an evaluation is always NO. This gets negated if
- // the operator is NotEqualTo.
- return (Operator != ComparisonOperator.EqualTo);
- }
-#if NETCF
- FileAttributes fileAttrs = NetCfFile.GetAttributes(filename);
-#else
- FileAttributes fileAttrs = System.IO.File.GetAttributes(filename);
-#endif
-
- return _Evaluate(fileAttrs);
- }
-
- private bool _Evaluate(FileAttributes fileAttrs)
- {
- bool result = _EvaluateOne(fileAttrs, FileAttributes.Hidden);
- if (result)
- result = _EvaluateOne(fileAttrs, FileAttributes.System);
- if (result)
- result = _EvaluateOne(fileAttrs, FileAttributes.ReadOnly);
- if (result)
- result = _EvaluateOne(fileAttrs, FileAttributes.Archive);
- if (result)
- result = _EvaluateOne(fileAttrs, FileAttributes.NotContentIndexed);
- if (result)
- result = _EvaluateOne(fileAttrs, FileAttributes.ReparsePoint);
-
- if (Operator != ComparisonOperator.EqualTo)
- result = !result;
-
- return result;
- }
- }
-#endif
-
-
- internal partial class CompoundCriterion : SelectionCriterion
- {
- internal LogicalConjunction Conjunction;
- internal SelectionCriterion Left;
-
- private SelectionCriterion _Right;
- internal SelectionCriterion Right
- {
- get { return _Right; }
- set
- {
- _Right = value;
- if (value == null)
- Conjunction = LogicalConjunction.NONE;
- else if (Conjunction == LogicalConjunction.NONE)
- Conjunction = LogicalConjunction.AND;
- }
- }
-
-
- internal override bool Evaluate(string filename)
- {
- bool result = Left.Evaluate(filename);
- switch (Conjunction)
- {
- case LogicalConjunction.AND:
- if (result)
- result = Right.Evaluate(filename);
- break;
- case LogicalConjunction.OR:
- if (!result)
- result = Right.Evaluate(filename);
- break;
- case LogicalConjunction.XOR:
- result ^= Right.Evaluate(filename);
- break;
- default:
- throw new ArgumentException("Conjunction");
- }
- return result;
- }
-
-
- public override String ToString()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append("(")
- .Append((Left != null) ? Left.ToString() : "null")
- .Append(" ")
- .Append(Conjunction.ToString())
- .Append(" ")
- .Append((Right != null) ? Right.ToString() : "null")
- .Append(")");
- return sb.ToString();
- }
- }
-
-
-
- ///
- /// FileSelector encapsulates logic that selects files from a source - a zip file
- /// or the filesystem - based on a set of criteria. This class is used internally
- /// by the DotNetZip library, in particular for the AddSelectedFiles() methods.
- /// This class can also be used independently of the zip capability in DotNetZip.
- ///
- ///
- ///
- ///
- ///
- /// The FileSelector class is used internally by the ZipFile class for selecting
- /// files for inclusion into the ZipFile, when the method, or one of
- /// its overloads, is called. It's also used for the methods. Typically, an
- /// application that creates or manipulates Zip archives will not directly
- /// interact with the FileSelector class.
- ///
- ///
- ///
- /// Some applications may wish to use the FileSelector class directly, to
- /// select files from disk volumes based on a set of criteria, without creating or
- /// querying Zip archives. The file selection criteria include: a pattern to
- /// match the filename; the last modified, created, or last accessed time of the
- /// file; the size of the file; and the attributes of the file.
- ///
- ///
- ///
- /// Consult the documentation for
- /// for more information on specifying the selection criteria.
- ///
- ///
- ///
- public partial class FileSelector
- {
- internal SelectionCriterion _Criterion;
-
-#if NOTUSED
- ///
- /// The default constructor.
- ///
- ///
- /// Typically, applications won't use this constructor. Instead they'll
- /// call the constructor that accepts a selectionCriteria string. If you
- /// use this constructor, you'll want to set the SelectionCriteria
- /// property on the instance before calling SelectFiles().
- ///
- protected FileSelector() { }
-#endif
- ///
- /// Constructor that allows the caller to specify file selection criteria.
- ///
- ///
- ///
- ///
- /// This constructor allows the caller to specify a set of criteria for
- /// selection of files.
- ///
- ///
- ///
- /// See for a description of
- /// the syntax of the selectionCriteria string.
- ///
- ///
- ///
- /// By default the FileSelector will traverse NTFS Reparse Points. To
- /// change this, use FileSelector(String, bool).
- ///
- ///
- ///
- /// The criteria for file selection.
- public FileSelector(String selectionCriteria)
- : this(selectionCriteria, true)
- {
- }
-
- ///
- /// Constructor that allows the caller to specify file selection criteria.
- ///
- ///
- ///
- ///
- /// This constructor allows the caller to specify a set of criteria for
- /// selection of files.
- ///
- ///
- ///
- /// See for a description of
- /// the syntax of the selectionCriteria string.
- ///
- ///
- ///
- /// The criteria for file selection.
- ///
- /// whether to traverse NTFS reparse points (junctions).
- ///
- public FileSelector(String selectionCriteria, bool traverseDirectoryReparsePoints)
- {
- if (!String.IsNullOrEmpty(selectionCriteria))
- _Criterion = _ParseCriterion(selectionCriteria);
- TraverseReparsePoints = traverseDirectoryReparsePoints;
- }
-
-
-
- ///
- /// The string specifying which files to include when retrieving.
- ///
- ///
- ///
- ///
- /// Specify the criteria in statements of 3 elements: a noun, an operator,
- /// and a value. Consider the string "name != *.doc" . The noun is
- /// "name". The operator is "!=", implying "Not Equal". The value is
- /// "*.doc". That criterion, in English, says "all files with a name that
- /// does not end in the .doc extension."
- ///
- ///
- ///
- /// Supported nouns include "name" (or "filename") for the filename;
- /// "atime", "mtime", and "ctime" for last access time, last modfied time,
- /// and created time of the file, respectively; "attributes" (or "attrs")
- /// for the file attributes; "size" (or "length") for the file length
- /// (uncompressed); and "type" for the type of object, either a file or a
- /// directory. The "attributes", "type", and "name" nouns all support =
- /// and != as operators. The "size", "atime", "mtime", and "ctime" nouns
- /// support = and !=, and >, >=, <, <= as well. The times are
- /// taken to be expressed in local time.
- ///
- ///
- ///
- /// Specify values for the file attributes as a string with one or more of
- /// the characters H,R,S,A,I,L in any order, implying file attributes of
- /// Hidden, ReadOnly, System, Archive, NotContextIndexed, and ReparsePoint
- /// (symbolic link) respectively.
- ///
- ///
- ///
- /// To specify a time, use YYYY-MM-DD-HH:mm:ss or YYYY/MM/DD-HH:mm:ss as
- /// the format. If you omit the HH:mm:ss portion, it is assumed to be
- /// 00:00:00 (midnight).
- ///
- ///
- ///
- /// The value for a size criterion is expressed in integer quantities of
- /// bytes, kilobytes (use k or kb after the number), megabytes (m or mb),
- /// or gigabytes (g or gb).
- ///
- ///
- ///
- /// The value for a name is a pattern to match against the filename,
- /// potentially including wildcards. The pattern follows CMD.exe glob
- /// rules: * implies one or more of any character, while ? implies one
- /// character. If the name pattern contains any slashes, it is matched to
- /// the entire filename, including the path; otherwise, it is matched
- /// against only the filename without the path. This means a pattern of
- /// "*\*.*" matches all files one directory level deep, while a pattern of
- /// "*.*" matches all files in all directories.
- ///
- ///
- ///
- /// To specify a name pattern that includes spaces, use single quotes
- /// around the pattern. A pattern of "'* *.*'" will match all files that
- /// have spaces in the filename. The full criteria string for that would
- /// be "name = '* *.*'" .
- ///
- ///
- ///
- /// The value for a type criterion is either F (implying a file) or D
- /// (implying a directory).
- ///
- ///
- ///
- /// Some examples:
- ///
- ///
- ///
- ///
- /// criteria
- /// Files retrieved
- ///
- ///
- /// -
- /// name != *.xls
- /// any file with an extension that is not .xls
- ///
- ///
- ///
- /// -
- /// name = *.mp3
- /// any file with a .mp3 extension.
- ///
- ///
- ///
- /// -
- /// *.mp3
- /// (same as above) any file with a .mp3 extension.
- ///
- ///
- ///
- /// -
- /// attributes = A
- /// all files whose attributes include the Archive bit.
- ///
- ///
- ///
- /// -
- /// attributes != H
- /// all files whose attributes do not include the Hidden bit.
- ///
- ///
- ///
- /// -
- /// mtime > 2009-01-01
- /// all files with a last modified time after January 1st, 2009.
- ///
- ///
- ///
- /// -
- /// ctime > 2009/01/01-03:00:00
- /// all files with a created time after 3am (local time),
- /// on January 1st, 2009.
- ///
- ///
- ///
- /// -
- /// size > 2gb
- /// all files whose uncompressed size is greater than 2gb.
- ///
- ///
- ///
- /// -
- /// type = D
- /// all directories in the filesystem.
- ///
- ///
- ///
- ///
- ///
- /// You can combine criteria with the conjunctions AND, OR, and XOR. Using
- /// a string like "name = *.txt AND size >= 100k" for the
- /// selectionCriteria retrieves entries whose names end in .txt, and whose
- /// uncompressed size is greater than or equal to 100 kilobytes.
- ///
- ///
- ///
- /// For more complex combinations of criteria, you can use parenthesis to
- /// group clauses in the boolean logic. Absent parenthesis, the
- /// precedence of the criterion atoms is determined by order of
- /// appearance. Unlike the C# language, the AND conjunction does not take
- /// precendence over the logical OR. This is important only in strings
- /// that contain 3 or more criterion atoms. In other words, "name = *.txt
- /// and size > 1000 or attributes = H" implies "((name = *.txt AND size
- /// > 1000) OR attributes = H)" while "attributes = H OR name = *.txt
- /// and size > 1000" evaluates to "((attributes = H OR name = *.txt)
- /// AND size > 1000)". When in doubt, use parenthesis.
- ///
- ///
- ///
- /// Using time properties requires some extra care. If you want to
- /// retrieve all entries that were last updated on 2009 February 14,
- /// specify "mtime >= 2009-02-14 AND mtime < 2009-02-15". Read this
- /// to say: all files updated after 12:00am on February 14th, until
- /// 12:00am on February 15th. You can use the same bracketing approach to
- /// specify any time period - a year, a month, a week, and so on.
- ///
- ///
- ///
- /// The syntax allows one special case: if you provide a string with no
- /// spaces, it is treated as a pattern to match for the filename.
- /// Therefore a string like "*.xls" will be equivalent to specifying "name
- /// = *.xls". This "shorthand" notation does not work with compound
- /// criteria.
- ///
- ///
- ///
- /// There is no logic in this class that insures that the inclusion
- /// criteria are internally consistent. For example, it's possible to
- /// specify criteria that says the file must have a size of less than 100
- /// bytes, as well as a size that is greater than 1000 bytes. Obviously
- /// no file will ever satisfy such criteria, but this class does not check
- /// for or detect such inconsistencies.
- ///
- ///
- ///
- ///
- ///
- /// Thrown in the setter if the value has an invalid syntax.
- ///
- public String SelectionCriteria
- {
- get
- {
- if (_Criterion == null) return null;
- return _Criterion.ToString();
- }
- set
- {
- if (value == null) _Criterion = null;
- else if (value.Trim() == "") _Criterion = null;
- else
- _Criterion = _ParseCriterion(value);
- }
- }
-
- ///
- /// Indicates whether searches will traverse NTFS reparse points, like Junctions.
- ///
- public bool TraverseReparsePoints
- {
- get; set;
- }
-
-
- private enum ParseState
- {
- Start,
- OpenParen,
- CriterionDone,
- ConjunctionPending,
- Whitespace,
- }
-
-
- private static class RegexAssertions
- {
- public static readonly String PrecededByOddNumberOfSingleQuotes = "(?<=(?:[^']*'[^']*')*'[^']*)";
- public static readonly String FollowedByOddNumberOfSingleQuotesAndLineEnd = "(?=[^']*'(?:[^']*'[^']*')*[^']*$)";
-
- public static readonly String PrecededByEvenNumberOfSingleQuotes = "(?<=(?:[^']*'[^']*')*[^']*)";
- public static readonly String FollowedByEvenNumberOfSingleQuotesAndLineEnd = "(?=(?:[^']*'[^']*')*[^']*$)";
- }
-
-
- private static string NormalizeCriteriaExpression(string source)
- {
- // The goal here is to normalize the criterion expression. At output, in
- // the transformed criterion string, every significant syntactic element
- // - a property element, grouping paren for the boolean logic, operator
- // ( = < > != ), conjunction, or property value - will be separated from
- // its neighbors by at least one space. Thus,
- //
- // before after
- // -------------------------------------------------------------------
- // name=*.txt name = *.txt
- // (size>100)AND(name=*.txt) ( size > 100 ) AND ( name = *.txt )
- //
- // This is relatively straightforward using regular expression
- // replacement. This method applies a distinct regex pattern and
- // corresponding replacement string for each one of a number of cases:
- // an open paren followed by a word; a word followed by a close-paren; a
- // pair of open parens; a close paren followed by a word (which should
- // then be followed by an open paren). And so on. These patterns and
- // replacements are all stored in prPairs. By applying each of these
- // regex replacements in turn, we get the transformed string. Easy.
- //
- // The resulting "normalized" criterion string, is then used as the
- // subject that gets parsed, by splitting the string into tokens that
- // are separated by spaces. Here, there's a twist. The spaces within
- // single-quote delimiters do not delimit distinct tokens. So, this
- // normalization method temporarily replaces those spaces with
- // ASCII 6 (0x06), a control character which is not a legal
- // character in a filename. The parsing logic that happens later will
- // revert that change, restoring the original value of the filename
- // specification.
- //
- // To illustrate, for a "before" string of [(size>100)AND(name='Name
- // (with Parens).txt')] , the "after" string is [( size > 100 ) AND
- // ( name = 'Name\u0006(with\u0006Parens).txt' )].
- //
-
- string[][] prPairs =
- {
- // A. opening double parens - insert a space between them
- new string[] { @"([^']*)\(\(([^']+)", "$1( ($2" },
-
- // B. closing double parens - insert a space between
- new string[] { @"(.)\)\)", "$1) )" },
-
- // C. single open paren with a following word - insert a space between
- new string[] { @"\((\S)", "( $1" },
-
- // D. single close paren with a preceding word - insert a space between the two
- new string[] { @"(\S)\)", "$1 )" },
-
- // E. close paren at line start?, insert a space before the close paren
- // this seems like a degenerate case. I don't recall why it's here.
- new string[] { @"^\)", " )" },
-
- // F. a word (likely a conjunction) followed by an open paren - insert a space between
- new string[] { @"(\S)\(", "$1 (" },
-
- // G. single close paren followed by word - insert a paren after close paren
- new string[] { @"\)(\S)", ") $1" },
-
- // H. insert space between = and a following single quote
- //new string[] { @"(=|!=)('[^']*')", "$1 $2" },
- new string[] { @"(=)('[^']*')", "$1 $2" },
-
- // I. insert space between property names and the following operator
- //new string[] { @"([^ ])([><(?:!=)=])", "$1 $2" },
- new string[] { @"([^ !><])(>|<|!=|=)", "$1 $2" },
-
- // J. insert spaces between operators and the following values
- //new string[] { @"([><(?:!=)=])([^ ])", "$1 $2" },
- new string[] { @"(>|<|!=|=)([^ =])", "$1 $2" },
-
- // K. replace fwd slash with backslash
- new string[] { @"/", "\\" },
- };
-
- string interim = source;
-
- for (int i=0; i < prPairs.Length; i++)
- {
- //char caseIdx = (char)('A' + i);
- string pattern = RegexAssertions.PrecededByEvenNumberOfSingleQuotes +
- prPairs[i][0] +
- RegexAssertions.FollowedByEvenNumberOfSingleQuotesAndLineEnd;
-
- interim = Regex.Replace(interim, pattern, prPairs[i][1]);
- }
-
- // match a fwd slash, followed by an odd number of single quotes.
- // This matches fwd slashes only inside a pair of single quote delimiters,
- // eg, a filename. This must be done as well as the case above, to handle
- // filenames specified inside quotes as well as filenames without quotes.
- var regexPattern = @"/" +
- RegexAssertions.FollowedByOddNumberOfSingleQuotesAndLineEnd;
- // replace with backslash
- interim = Regex.Replace(interim, regexPattern, "\\");
-
- // match a space, followed by an odd number of single quotes.
- // This matches spaces only inside a pair of single quote delimiters.
- regexPattern = " " +
- RegexAssertions.FollowedByOddNumberOfSingleQuotesAndLineEnd;
-
- // Replace all spaces that appear inside single quotes, with
- // ascii 6. This allows a split on spaces to get tokens in
- // the expression. The split will not split any filename or
- // wildcard that appears within single quotes. After tokenizing, we
- // need to replace ascii 6 with ascii 32 to revert the
- // spaces within quotes.
- return Regex.Replace(interim, regexPattern, "\u0006");
- }
-
-
- private static SelectionCriterion _ParseCriterion(String s)
- {
- if (s == null) return null;
-
- // inject spaces after open paren and before close paren, etc
- s = NormalizeCriteriaExpression(s);
-
- // no spaces in the criteria is shorthand for filename glob
- if (s.IndexOf(" ") == -1)
- s = "name = " + s;
-
- // split the expression into tokens
- string[] tokens = s.Trim().Split(' ', '\t');
-
- if (tokens.Length < 3) throw new ArgumentException(s);
-
- SelectionCriterion current = null;
-
- LogicalConjunction pendingConjunction = LogicalConjunction.NONE;
-
- ParseState state;
- var stateStack = new System.Collections.Generic.Stack();
- var critStack = new System.Collections.Generic.Stack();
- stateStack.Push(ParseState.Start);
-
- for (int i = 0; i < tokens.Length; i++)
- {
- string tok1 = tokens[i].ToLower();
- switch (tok1)
- {
- case "and":
- case "xor":
- case "or":
- state = stateStack.Peek();
- if (state != ParseState.CriterionDone)
- throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
- if (tokens.Length <= i + 3)
- throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
- pendingConjunction = (LogicalConjunction)Enum.Parse(typeof(LogicalConjunction), tokens[i].ToUpper(), true);
- current = new CompoundCriterion { Left = current, Right = null, Conjunction = pendingConjunction };
- stateStack.Push(state);
- stateStack.Push(ParseState.ConjunctionPending);
- critStack.Push(current);
- break;
-
- case "(":
- state = stateStack.Peek();
- if (state != ParseState.Start && state != ParseState.ConjunctionPending && state != ParseState.OpenParen)
- throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
- if (tokens.Length <= i + 4)
- throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
- stateStack.Push(ParseState.OpenParen);
- break;
-
- case ")":
- state = stateStack.Pop();
- if (stateStack.Peek() != ParseState.OpenParen)
- throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
- stateStack.Pop();
- stateStack.Push(ParseState.CriterionDone);
- break;
-
- case "atime":
- case "ctime":
- case "mtime":
- if (tokens.Length <= i + 2)
- throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
- DateTime t;
- try
- {
- t = DateTime.ParseExact(tokens[i + 2], "yyyy-MM-dd-HH:mm:ss", null);
- }
- catch (FormatException)
- {
- try
- {
- t = DateTime.ParseExact(tokens[i + 2], "yyyy/MM/dd-HH:mm:ss", null);
- }
- catch (FormatException)
- {
- try
- {
- t = DateTime.ParseExact(tokens[i + 2], "yyyy/MM/dd", null);
- }
- catch (FormatException)
- {
- try
- {
- t = DateTime.ParseExact(tokens[i + 2], "MM/dd/yyyy", null);
- }
- catch (FormatException)
- {
- t = DateTime.ParseExact(tokens[i + 2], "yyyy-MM-dd", null);
- }
- }
- }
- }
- t= DateTime.SpecifyKind(t, DateTimeKind.Local).ToUniversalTime();
- current = new TimeCriterion
- {
- Which = (WhichTime)Enum.Parse(typeof(WhichTime), tokens[i], true),
- Operator = (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1]),
- Time = t
- };
- i += 2;
- stateStack.Push(ParseState.CriterionDone);
- break;
-
-
- case "length":
- case "size":
- if (tokens.Length <= i + 2)
- throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
- Int64 sz = 0;
- string v = tokens[i + 2];
- if (v.ToUpper().EndsWith("K"))
- sz = Int64.Parse(v.Substring(0, v.Length - 1)) * 1024;
- else if (v.ToUpper().EndsWith("KB"))
- sz = Int64.Parse(v.Substring(0, v.Length - 2)) * 1024;
- else if (v.ToUpper().EndsWith("M"))
- sz = Int64.Parse(v.Substring(0, v.Length - 1)) * 1024 * 1024;
- else if (v.ToUpper().EndsWith("MB"))
- sz = Int64.Parse(v.Substring(0, v.Length - 2)) * 1024 * 1024;
- else if (v.ToUpper().EndsWith("G"))
- sz = Int64.Parse(v.Substring(0, v.Length - 1)) * 1024 * 1024 * 1024;
- else if (v.ToUpper().EndsWith("GB"))
- sz = Int64.Parse(v.Substring(0, v.Length - 2)) * 1024 * 1024 * 1024;
- else sz = Int64.Parse(tokens[i + 2]);
-
- current = new SizeCriterion
- {
- Size = sz,
- Operator = (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1])
- };
- i += 2;
- stateStack.Push(ParseState.CriterionDone);
- break;
-
- case "filename":
- case "name":
- {
- if (tokens.Length <= i + 2)
- throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
- ComparisonOperator c =
- (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1]);
-
- if (c != ComparisonOperator.NotEqualTo && c != ComparisonOperator.EqualTo)
- throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
- string m = tokens[i + 2];
-
- // handle single-quoted filespecs (used to include
- // spaces in filename patterns)
- if (m.StartsWith("'") && m.EndsWith("'"))
- {
- // trim off leading and trailing single quotes and
- // revert the control characters to spaces.
- m = m.Substring(1, m.Length - 2)
- .Replace("\u0006", " ");
- }
-
- // if (m.StartsWith("'"))
- // m = m.Replace("\u0006", " ");
-
- current = new NameCriterion
- {
- MatchingFileSpec = m,
- Operator = c
- };
- i += 2;
- stateStack.Push(ParseState.CriterionDone);
- }
- break;
-
-#if !SILVERLIGHT
- case "attrs":
- case "attributes":
-#endif
- case "type":
- {
- if (tokens.Length <= i + 2)
- throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
- ComparisonOperator c =
- (ComparisonOperator)EnumUtil.Parse(typeof(ComparisonOperator), tokens[i + 1]);
-
- if (c != ComparisonOperator.NotEqualTo && c != ComparisonOperator.EqualTo)
- throw new ArgumentException(String.Join(" ", tokens, i, tokens.Length - i));
-
-#if SILVERLIGHT
- current = (SelectionCriterion) new TypeCriterion
- {
- AttributeString = tokens[i + 2],
- Operator = c
- };
-#else
- current = (tok1 == "type")
- ? (SelectionCriterion) new TypeCriterion
- {
- AttributeString = tokens[i + 2],
- Operator = c
- }
- : (SelectionCriterion) new AttributesCriterion
- {
- AttributeString = tokens[i + 2],
- Operator = c
- };
-#endif
- i += 2;
- stateStack.Push(ParseState.CriterionDone);
- }
- break;
-
- case "":
- // NOP
- stateStack.Push(ParseState.Whitespace);
- break;
-
- default:
- throw new ArgumentException("'" + tokens[i] + "'");
- }
-
- state = stateStack.Peek();
- if (state == ParseState.CriterionDone)
- {
- stateStack.Pop();
- if (stateStack.Peek() == ParseState.ConjunctionPending)
- {
- while (stateStack.Peek() == ParseState.ConjunctionPending)
- {
- var cc = critStack.Pop() as CompoundCriterion;
- cc.Right = current;
- current = cc; // mark the parent as current (walk up the tree)
- stateStack.Pop(); // the conjunction is no longer pending
-
- state = stateStack.Pop();
- if (state != ParseState.CriterionDone)
- throw new ArgumentException("??");
- }
- }
- else stateStack.Push(ParseState.CriterionDone); // not sure?
- }
-
- if (state == ParseState.Whitespace)
- stateStack.Pop();
- }
-
- return current;
- }
-
-
- ///
- /// Returns a string representation of the FileSelector object.
- ///
- /// The string representation of the boolean logic statement of the file
- /// selection criteria for this instance.
- public override String ToString()
- {
- return "FileSelector("+_Criterion.ToString()+")";
- }
-
-
- private bool Evaluate(string filename)
- {
- // dinoch - Thu, 11 Feb 2010 18:34
- SelectorTrace("Evaluate({0})", filename);
- bool result = _Criterion.Evaluate(filename);
- return result;
- }
-
- [System.Diagnostics.Conditional("SelectorTrace")]
- private void SelectorTrace(string format, params object[] args)
- {
- if (_Criterion != null && _Criterion.Verbose)
- System.Console.WriteLine(format, args);
- }
-
- ///
- /// Returns the names of the files in the specified directory
- /// that fit the selection criteria specified in the FileSelector.
- ///
- ///
- ///
- /// This is equivalent to calling
- /// with recurseDirectories = false.
- ///
- ///
- ///
- /// The name of the directory over which to apply the FileSelector
- /// criteria.
- ///
- ///
- ///
- /// A collection of strings containing fully-qualified pathnames of files
- /// that match the criteria specified in the FileSelector instance.
- ///
- public System.Collections.Generic.ICollection SelectFiles(String directory)
- {
- return SelectFiles(directory, false);
- }
-
-
- ///
- /// Returns the names of the files in the specified directory that fit the
- /// selection criteria specified in the FileSelector, optionally recursing
- /// through subdirectories.
- ///
- ///
- ///
- /// This method applies the file selection criteria contained in the
- /// FileSelector to the files contained in the given directory, and
- /// returns the names of files that conform to the criteria.
- ///
- ///
- ///
- /// The name of the directory over which to apply the FileSelector
- /// criteria.
- ///
- ///
- ///
- /// Whether to recurse through subdirectories when applying the file
- /// selection criteria.
- ///
- ///
- ///
- /// A collection of strings containing fully-qualified pathnames of files
- /// that match the criteria specified in the FileSelector instance.
- ///
- public System.Collections.ObjectModel.ReadOnlyCollection
- SelectFiles(String directory,
- bool recurseDirectories)
- {
- if (_Criterion == null)
- throw new ArgumentException("SelectionCriteria has not been set");
-
- var list = new List();
- try
- {
- if (Directory.Exists(directory))
- {
- String[] filenames = Directory.GetFiles(directory);
-
- // add the files:
- foreach (String filename in filenames)
- {
- if (Evaluate(filename))
- list.Add(filename);
- }
-
- if (recurseDirectories)
- {
- // add the subdirectories:
- String[] dirnames = Directory.GetDirectories(directory);
- foreach (String dir in dirnames)
- {
- if (this.TraverseReparsePoints
-#if !SILVERLIGHT
- || ((File.GetAttributes(dir) & FileAttributes.ReparsePoint) == 0)
-#endif
- )
- {
- // workitem 10191
- if (Evaluate(dir)) list.Add(dir);
- list.AddRange(this.SelectFiles(dir, recurseDirectories));
- }
- }
- }
- }
- }
- // can get System.UnauthorizedAccessException here
- catch (System.UnauthorizedAccessException)
- {
- }
- catch (System.IO.IOException)
- {
- }
-
- return list.AsReadOnly();
- }
- }
-
-
-
- ///
- /// Summary description for EnumUtil.
- ///
- internal sealed class EnumUtil
- {
- private EnumUtil() { }
- ///
- /// Returns the value of the DescriptionAttribute if the specified Enum
- /// value has one. If not, returns the ToString() representation of the
- /// Enum value.
- ///
- /// The Enum to get the description for
- ///
- internal static string GetDescription(System.Enum value)
- {
- FieldInfo fi = value.GetType().GetField(value.ToString());
- var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
- if (attributes.Length > 0)
- return attributes[0].Description;
- else
- return value.ToString();
- }
-
- ///
- /// Converts the string representation of the name or numeric value of one
- /// or more enumerated constants to an equivalent enumerated object.
- /// Note: use the DescriptionAttribute on enum values to enable this.
- ///
- /// The System.Type of the enumeration.
- ///
- /// A string containing the name or value to convert.
- ///
- ///
- internal static object Parse(Type enumType, string stringRepresentation)
- {
- return Parse(enumType, stringRepresentation, false);
- }
-
-
-#if SILVERLIGHT
- public static System.Enum[] GetEnumValues(Type type)
- {
- if (!type.IsEnum)
- throw new ArgumentException("not an enum");
-
- return (
- from field in type.GetFields(BindingFlags.Public | BindingFlags.Static)
- where field.IsLiteral
- select (System.Enum)field.GetValue(null)
- ).ToArray();
- }
-
- public static string[] GetEnumStrings()
- {
- var type = typeof(T);
- if (!type.IsEnum)
- throw new ArgumentException("not an enum");
-
- return (
- from field in type.GetFields(BindingFlags.Public | BindingFlags.Static)
- where field.IsLiteral
- select field.Name
- ).ToArray();
- }
-#endif
-
- ///
- /// Converts the string representation of the name or numeric value of one
- /// or more enumerated constants to an equivalent enumerated object. A
- /// parameter specified whether the operation is case-sensitive. Note:
- /// use the DescriptionAttribute on enum values to enable this.
- ///
- /// The System.Type of the enumeration.
- ///
- /// A string containing the name or value to convert.
- ///
- ///
- /// Whether the operation is case-sensitive or not.
- ///
- internal static object Parse(Type enumType, string stringRepresentation, bool ignoreCase)
- {
- if (ignoreCase)
- stringRepresentation = stringRepresentation.ToLower();
-
-#if SILVERLIGHT
- foreach (System.Enum enumVal in GetEnumValues(enumType))
-#else
- foreach (System.Enum enumVal in System.Enum.GetValues(enumType))
-#endif
- {
- string description = GetDescription(enumVal);
- if (ignoreCase)
- description = description.ToLower();
- if (description == stringRepresentation)
- return enumVal;
- }
-
- return System.Enum.Parse(enumType, stringRepresentation, ignoreCase);
- }
- }
-
-
-#if DEMO
- public class DemonstrateFileSelector
- {
- private string _directory;
- private bool _recurse;
- private bool _traverse;
- private bool _verbose;
- private string _selectionCriteria;
- private FileSelector f;
-
- public DemonstrateFileSelector()
- {
- this._directory = ".";
- this._recurse = true;
- }
-
- public DemonstrateFileSelector(string[] args) : this()
- {
- for (int i = 0; i < args.Length; i++)
- {
- switch(args[i])
- {
- case"-?":
- Usage();
- Environment.Exit(0);
- break;
- case "-d":
- i++;
- if (args.Length <= i)
- throw new ArgumentException("-directory");
- this._directory = args[i];
- break;
- case "-norecurse":
- this._recurse = false;
- break;
-
- case "-j-":
- this._traverse = false;
- break;
-
- case "-j+":
- this._traverse = true;
- break;
-
- case "-v":
- this._verbose = true;
- break;
-
- default:
- if (this._selectionCriteria != null)
- throw new ArgumentException(args[i]);
- this._selectionCriteria = args[i];
- break;
- }
-
- if (this._selectionCriteria != null)
- this.f = new FileSelector(this._selectionCriteria);
- }
- }
-
-
- public static void Main(string[] args)
- {
- try
- {
- Console.WriteLine();
- new DemonstrateFileSelector(args).Run();
- }
- catch (Exception exc1)
- {
- Console.WriteLine("Exception: {0}", exc1.ToString());
- Usage();
- }
- }
-
-
- public void Run()
- {
- if (this.f == null)
- this.f = new FileSelector("name = *.jpg AND (size > 1000 OR atime < 2009-02-14-01:00:00)");
-
- this.f.TraverseReparsePoints = _traverse;
- this.f.Verbose = this._verbose;
- Console.WriteLine();
- Console.WriteLine(new String(':', 88));
- Console.WriteLine("Selecting files:\n" + this.f.ToString());
- var files = this.f.SelectFiles(this._directory, this._recurse);
- if (files.Count == 0)
- {
- Console.WriteLine("no files.");
- }
- else
- {
- Console.WriteLine("files: {0}", files.Count);
- foreach (string file in files)
- {
- Console.WriteLine(" " + file);
- }
- }
- }
-
- public static void Usage()
- {
- Console.WriteLine("FileSelector: select files based on selection criteria.\n");
- Console.WriteLine("Usage:\n FileSelector [options]\n" +
- "\n" +
- " -d directory to select from (Default .)\n" +
- " -norecurse don't recurse into subdirs\n" +
- " -j- don't traverse junctions\n" +
- " -v verbose output\n");
- }
- }
-
-#endif
-
-
-
-}
-
-
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/OffsetStream.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/OffsetStream.cs
deleted file mode 100644
index 525019ae..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/OffsetStream.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-// OffsetStream.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa
-// 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-August-27 12:50:35>
-//
-// ------------------------------------------------------------------
-//
-// This module defines logic for handling reading of zip archives embedded
-// into larger streams. The initial position of the stream serves as
-// the base offset for all future Seek() operations.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-
-namespace Ionic.Zip
-{
- internal class OffsetStream : System.IO.Stream, System.IDisposable
- {
- private Int64 _originalPosition;
- private Stream _innerStream;
-
- public OffsetStream(Stream s)
- : base()
- {
- _originalPosition = s.Position;
- _innerStream = s;
- }
-
- public override int Read(byte[] buffer, int offset, int count)
- {
- return _innerStream.Read(buffer, offset, count);
- }
-
- public override void Write(byte[] buffer, int offset, int count)
- {
- throw new NotImplementedException();
- }
-
- public override bool CanRead
- {
- get { return _innerStream.CanRead; }
- }
-
- public override bool CanSeek
- {
- get { return _innerStream.CanSeek; }
- }
-
- public override bool CanWrite
- {
- get { return false; }
- }
-
- public override void Flush()
- {
- _innerStream.Flush();
- }
-
- public override long Length
- {
- get
- {
- return _innerStream.Length;
- }
- }
-
- public override long Position
- {
- get { return _innerStream.Position - _originalPosition; }
- set { _innerStream.Position = _originalPosition + value; }
- }
-
-
- public override long Seek(long offset, System.IO.SeekOrigin origin)
- {
- return _innerStream.Seek(_originalPosition + offset, origin) - _originalPosition;
- }
-
-
- public override void SetLength(long value)
- {
- throw new NotImplementedException();
- }
-
- void IDisposable.Dispose()
- {
- Close();
- }
-
- public override void Close()
- {
- base.Close();
- }
-
- }
-
-}
\ No newline at end of file
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/Shared.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/Shared.cs
deleted file mode 100644
index cdc71618..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/Shared.cs
+++ /dev/null
@@ -1,901 +0,0 @@
-// Shared.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2006-2011 Dino Chiesa.
-// 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: <2011-August-02 19:41:01>
-//
-// ------------------------------------------------------------------
-//
-// This module defines some shared utility classes and methods.
-//
-// Created: Tue, 27 Mar 2007 15:30
-//
-
-using System;
-using System.IO;
-using System.Security.Permissions;
-
-namespace Ionic.Zip
-{
- ///
- /// Collects general purpose utility methods.
- ///
- internal static class SharedUtilities
- {
- /// private null constructor
- //private SharedUtilities() { }
-
- // workitem 8423
- public static Int64 GetFileLength(string fileName)
- {
- if (!File.Exists(fileName))
- throw new System.IO.FileNotFoundException(fileName);
-
- long fileLength = 0L;
- FileShare fs = FileShare.ReadWrite;
-#if !NETCF
- // FileShare.Delete is not defined for the Compact Framework
- fs |= FileShare.Delete;
-#endif
- using (var s = File.Open(fileName, FileMode.Open, FileAccess.Read, fs))
- {
- fileLength = s.Length;
- }
- return fileLength;
- }
-
-
- [System.Diagnostics.Conditional("NETCF")]
- public static void Workaround_Ladybug318918(Stream s)
- {
- // This is a workaround for this issue:
- // https://connect.microsoft.com/VisualStudio/feedback/details/318918
- // It's required only on NETCF.
- s.Flush();
- }
-
-
-#if LEGACY
- ///
- /// Round the given DateTime value to an even second value.
- ///
- ///
- ///
- ///
- /// Round up in the case of an odd second value. The rounding does not consider
- /// fractional seconds.
- ///
- ///
- /// This is useful because the Zip spec allows storage of time only to the nearest
- /// even second. So if you want to compare the time of an entry in the archive with
- /// it's actual time in the filesystem, you need to round the actual filesystem
- /// time, or use a 2-second threshold for the comparison.
- ///
- ///
- /// This is most nautrally an extension method for the DateTime class but this
- /// library is built for .NET 2.0, not for .NET 3.5; This means extension methods
- /// are a no-no.
- ///
- ///
- /// The DateTime value to round
- /// The ruonded DateTime value
- public static DateTime RoundToEvenSecond(DateTime source)
- {
- // round to nearest second:
- if ((source.Second % 2) == 1)
- source += new TimeSpan(0, 0, 1);
-
- DateTime dtRounded = new DateTime(source.Year, source.Month, source.Day, source.Hour, source.Minute, source.Second);
- //if (source.Millisecond >= 500) dtRounded = dtRounded.AddSeconds(1);
- return dtRounded;
- }
-#endif
-
-#if YOU_LIKE_REDUNDANT_CODE
- internal static string NormalizePath(string path)
- {
- // remove leading single dot slash
- if (path.StartsWith(".\\")) path = path.Substring(2);
-
- // remove intervening dot-slash
- path = path.Replace("\\.\\", "\\");
-
- // remove double dot when preceded by a directory name
- var re = new System.Text.RegularExpressions.Regex(@"^(.*\\)?([^\\\.]+\\\.\.\\)(.+)$");
- path = re.Replace(path, "$1$3");
- return path;
- }
-#endif
-
- private static System.Text.RegularExpressions.Regex doubleDotRegex1 =
- new System.Text.RegularExpressions.Regex(@"^(.*/)?([^/\\.]+/\\.\\./)(.+)$");
-
- private static string SimplifyFwdSlashPath(string path)
- {
- if (path.StartsWith("./")) path = path.Substring(2);
- path = path.Replace("/./", "/");
-
- // Replace foo/anything/../bar with foo/bar
- path = doubleDotRegex1.Replace(path, "$1$3");
- return path;
- }
-
-
- ///
- /// Utility routine for transforming path names from filesystem format (on Windows that means backslashes) to
- /// a format suitable for use within zipfiles. This means trimming the volume letter and colon (if any) And
- /// swapping backslashes for forward slashes.
- ///
- /// source path.
- /// transformed path
- public static string NormalizePathForUseInZipFile(string pathName)
- {
- // boundary case
- if (String.IsNullOrEmpty(pathName)) return pathName;
-
- // trim volume if necessary
- if ((pathName.Length >= 2) && ((pathName[1] == ':') && (pathName[2] == '\\')))
- pathName = pathName.Substring(3);
-
- // swap slashes
- pathName = pathName.Replace('\\', '/');
-
- // trim all leading slashes
- while (pathName.StartsWith("/")) pathName = pathName.Substring(1);
-
- return SimplifyFwdSlashPath(pathName);
- }
-
-
- static System.Text.Encoding ibm437 = System.Text.Encoding.GetEncoding("IBM437");
- static System.Text.Encoding utf8 = System.Text.Encoding.GetEncoding("UTF-8");
-
- internal static byte[] StringToByteArray(string value, System.Text.Encoding encoding)
- {
- byte[] a = encoding.GetBytes(value);
- return a;
- }
- internal static byte[] StringToByteArray(string value)
- {
- return StringToByteArray(value, ibm437);
- }
-
- //internal static byte[] Utf8StringToByteArray(string value)
- //{
- // return StringToByteArray(value, utf8);
- //}
-
- //internal static string StringFromBuffer(byte[] buf, int maxlength)
- //{
- // return StringFromBuffer(buf, maxlength, ibm437);
- //}
-
- internal static string Utf8StringFromBuffer(byte[] buf)
- {
- return StringFromBuffer(buf, utf8);
- }
-
- internal static string StringFromBuffer(byte[] buf, System.Text.Encoding encoding)
- {
- // this form of the GetString() method is required for .NET CF compatibility
- string s = encoding.GetString(buf, 0, buf.Length);
- return s;
- }
-
-
- internal static int ReadSignature(System.IO.Stream s)
- {
- int x = 0;
- try { x = _ReadFourBytes(s, "n/a"); }
- catch (BadReadException) { }
- return x;
- }
-
-
- internal static int ReadEntrySignature(System.IO.Stream s)
- {
- // handle the case of ill-formatted zip archives - includes a data descriptor
- // when none is expected.
- int x = 0;
- try
- {
- x = _ReadFourBytes(s, "n/a");
- if (x == ZipConstants.ZipEntryDataDescriptorSignature)
- {
- // advance past data descriptor - 12 bytes if not zip64
- s.Seek(12, SeekOrigin.Current);
- // workitem 10178
- Workaround_Ladybug318918(s);
- x = _ReadFourBytes(s, "n/a");
- if (x != ZipConstants.ZipEntrySignature)
- {
- // Maybe zip64 was in use for the prior entry.
- // Therefore, skip another 8 bytes.
- s.Seek(8, SeekOrigin.Current);
- // workitem 10178
- Workaround_Ladybug318918(s);
- x = _ReadFourBytes(s, "n/a");
- if (x != ZipConstants.ZipEntrySignature)
- {
- // seek back to the first spot
- s.Seek(-24, SeekOrigin.Current);
- // workitem 10178
- Workaround_Ladybug318918(s);
- x = _ReadFourBytes(s, "n/a");
- }
- }
- }
- }
- catch (BadReadException) { }
- return x;
- }
-
-
- internal static int ReadInt(System.IO.Stream s)
- {
- return _ReadFourBytes(s, "Could not read block - no data! (position 0x{0:X8})");
- }
-
- private static int _ReadFourBytes(System.IO.Stream s, string message)
- {
- int n = 0;
- byte[] block = new byte[4];
-#if NETCF
- // workitem 9181
- // Reading here in NETCF sometimes reads "backwards". Seems to happen for
- // larger files. Not sure why. Maybe an error in caching. If the data is:
- //
- // 00100210: 9efa 0f00 7072 6f6a 6563 742e 6963 7750 ....project.icwP
- // 00100220: 4b05 0600 0000 0006 0006 0091 0100 008e K...............
- // 00100230: 0010 0000 00 .....
- //
- // ...and the stream Position is 10021F, then a Read of 4 bytes is returning
- // 50776369, instead of 06054b50. This seems to happen the 2nd time Read()
- // is called from that Position..
- //
- // submitted to connect.microsoft.com
- // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=318918#tabs
- //
- for (int i = 0; i < block.Length; i++)
- {
- n+= s.Read(block, i, 1);
- }
-#else
- n = s.Read(block, 0, block.Length);
-#endif
- if (n != block.Length) throw new BadReadException(String.Format(message, s.Position));
- int data = unchecked((((block[3] * 256 + block[2]) * 256) + block[1]) * 256 + block[0]);
- return data;
- }
-
-
-
- ///
- /// Finds a signature in the zip stream. This is useful for finding
- /// the end of a zip entry, for example, or the beginning of the next ZipEntry.
- ///
- ///
- ///
- ///
- /// Scans through 64k at a time.
- ///
- ///
- ///
- /// If the method fails to find the requested signature, the stream Position
- /// after completion of this method is unchanged. If the method succeeds in
- /// finding the requested signature, the stream position after completion is
- /// direct AFTER the signature found in the stream.
- ///
- ///
- ///
- /// The stream to search
- /// The 4-byte signature to find
- /// The number of bytes read
- internal static long FindSignature(System.IO.Stream stream, int SignatureToFind)
- {
- long startingPosition = stream.Position;
-
- int BATCH_SIZE = 65536; // 8192;
- byte[] targetBytes = new byte[4];
- targetBytes[0] = (byte)(SignatureToFind >> 24);
- targetBytes[1] = (byte)((SignatureToFind & 0x00FF0000) >> 16);
- targetBytes[2] = (byte)((SignatureToFind & 0x0000FF00) >> 8);
- targetBytes[3] = (byte)(SignatureToFind & 0x000000FF);
- byte[] batch = new byte[BATCH_SIZE];
- int n = 0;
- bool success = false;
- do
- {
- n = stream.Read(batch, 0, batch.Length);
- if (n != 0)
- {
- for (int i = 0; i < n; i++)
- {
- if (batch[i] == targetBytes[3])
- {
- long curPosition = stream.Position;
- stream.Seek(i - n, System.IO.SeekOrigin.Current);
- // workitem 10178
- Workaround_Ladybug318918(stream);
-
- // workitem 7711
- int sig = ReadSignature(stream);
-
- success = (sig == SignatureToFind);
- if (!success)
- {
- stream.Seek(curPosition, System.IO.SeekOrigin.Begin);
- // workitem 10178
- Workaround_Ladybug318918(stream);
- }
- else
- break; // out of for loop
- }
- }
- }
- else break;
- if (success) break;
-
- } while (true);
-
- if (!success)
- {
- stream.Seek(startingPosition, System.IO.SeekOrigin.Begin);
- // workitem 10178
- Workaround_Ladybug318918(stream);
- return -1; // or throw?
- }
-
- // subtract 4 for the signature.
- long bytesRead = (stream.Position - startingPosition) - 4;
-
- return bytesRead;
- }
-
-
- // If I have a time in the .NET environment, and I want to use it for
- // SetWastWriteTime() etc, then I need to adjust it for Win32.
- internal static DateTime AdjustTime_Reverse(DateTime time)
- {
- if (time.Kind == DateTimeKind.Utc) return time;
- DateTime adjusted = time;
- if (DateTime.Now.IsDaylightSavingTime() && !time.IsDaylightSavingTime())
- adjusted = time - new System.TimeSpan(1, 0, 0);
-
- else if (!DateTime.Now.IsDaylightSavingTime() && time.IsDaylightSavingTime())
- adjusted = time + new System.TimeSpan(1, 0, 0);
-
- return adjusted;
- }
-
-#if NECESSARY
- // If I read a time from a file with GetLastWriteTime() (etc), I need
- // to adjust it for display in the .NET environment.
- internal static DateTime AdjustTime_Forward(DateTime time)
- {
- if (time.Kind == DateTimeKind.Utc) return time;
- DateTime adjusted = time;
- if (DateTime.Now.IsDaylightSavingTime() && !time.IsDaylightSavingTime())
- adjusted = time + new System.TimeSpan(1, 0, 0);
-
- else if (!DateTime.Now.IsDaylightSavingTime() && time.IsDaylightSavingTime())
- adjusted = time - new System.TimeSpan(1, 0, 0);
-
- return adjusted;
- }
-#endif
-
-
- internal static DateTime PackedToDateTime(Int32 packedDateTime)
- {
- // workitem 7074 & workitem 7170
- if (packedDateTime == 0xFFFF || packedDateTime == 0)
- return new System.DateTime(1995, 1, 1, 0, 0, 0, 0); // return a fixed date when none is supplied.
-
- Int16 packedTime = unchecked((Int16)(packedDateTime & 0x0000ffff));
- Int16 packedDate = unchecked((Int16)((packedDateTime & 0xffff0000) >> 16));
-
- int year = 1980 + ((packedDate & 0xFE00) >> 9);
- int month = (packedDate & 0x01E0) >> 5;
- int day = packedDate & 0x001F;
-
- int hour = (packedTime & 0xF800) >> 11;
- int minute = (packedTime & 0x07E0) >> 5;
- //int second = packedTime & 0x001F;
- int second = (packedTime & 0x001F) * 2;
-
- // validation and error checking.
- // this is not foolproof but will catch most errors.
- if (second >= 60) { minute++; second = 0; }
- if (minute >= 60) { hour++; minute = 0; }
- if (hour >= 24) { day++; hour = 0; }
-
- DateTime d = System.DateTime.Now;
- bool success= false;
- try
- {
- d = new System.DateTime(year, month, day, hour, minute, second, 0);
- success= true;
- }
- catch (System.ArgumentOutOfRangeException)
- {
- if (year == 1980 && (month == 0 || day == 0))
- {
- try
- {
- d = new System.DateTime(1980, 1, 1, hour, minute, second, 0);
- success= true;
- }
- catch (System.ArgumentOutOfRangeException)
- {
- try
- {
- d = new System.DateTime(1980, 1, 1, 0, 0, 0, 0);
- success= true;
- }
- catch (System.ArgumentOutOfRangeException) { }
-
- }
- }
- // workitem 8814
- // my god, I can't believe how many different ways applications
- // can mess up a simple date format.
- else
- {
- try
- {
- while (year < 1980) year++;
- while (year > 2030) year--;
- while (month < 1) month++;
- while (month > 12) month--;
- while (day < 1) day++;
- while (day > 28) day--;
- while (minute < 0) minute++;
- while (minute > 59) minute--;
- while (second < 0) second++;
- while (second > 59) second--;
- d = new System.DateTime(year, month, day, hour, minute, second, 0);
- success= true;
- }
- catch (System.ArgumentOutOfRangeException) { }
- }
- }
- if (!success)
- {
- string msg = String.Format("y({0}) m({1}) d({2}) h({3}) m({4}) s({5})", year, month, day, hour, minute, second);
- throw new ZipException(String.Format("Bad date/time format in the zip file. ({0})", msg));
-
- }
- // workitem 6191
- //d = AdjustTime_Reverse(d);
- d = DateTime.SpecifyKind(d, DateTimeKind.Local);
- return d;
- }
-
-
- internal
- static Int32 DateTimeToPacked(DateTime time)
- {
- // The time is passed in here only for purposes of writing LastModified to the
- // zip archive. It should always be LocalTime, but we convert anyway. And,
- // since the time is being written out, it needs to be adjusted.
-
- time = time.ToLocalTime();
- // workitem 7966
- //time = AdjustTime_Forward(time);
-
- // see http://www.vsft.com/hal/dostime.htm for the format
- UInt16 packedDate = (UInt16)((time.Day & 0x0000001F) | ((time.Month << 5) & 0x000001E0) | (((time.Year - 1980) << 9) & 0x0000FE00));
- UInt16 packedTime = (UInt16)((time.Second / 2 & 0x0000001F) | ((time.Minute << 5) & 0x000007E0) | ((time.Hour << 11) & 0x0000F800));
-
- Int32 result = (Int32)(((UInt32)(packedDate << 16)) | packedTime);
- return result;
- }
-
-
- ///
- /// Create a pseudo-random filename, suitable for use as a temporary
- /// file, and open it.
- ///
- ///
- ///
- /// The System.IO.Path.GetRandomFileName() method is not available on
- /// the Compact Framework, so this library provides its own substitute
- /// on NETCF.
- ///
- ///
- /// This method produces a filename of the form
- /// DotNetZip-xxxxxxxx.tmp, where xxxxxxxx is replaced by randomly
- /// chosen characters, and creates that file.
- ///
- ///
- public static void CreateAndOpenUniqueTempFile(string dir,
- out Stream fs,
- out string filename)
- {
- // workitem 9763
- // http://dotnet.org.za/markn/archive/2006/04/15/51594.aspx
- // try 3 times:
- for (int i = 0; i < 3; i++)
- {
- try
- {
- filename = Path.Combine(dir, InternalGetTempFileName());
- fs = new FileStream(filename, FileMode.CreateNew);
- return;
- }
- catch (IOException)
- {
- if (i == 2) throw;
- }
- }
- throw new IOException();
- }
-
-#if NETCF || SILVERLIGHT
- public static string InternalGetTempFileName()
- {
- return "DotNetZip-" + GenerateRandomStringImpl(8,0) + ".tmp";
- }
-
- internal static string GenerateRandomStringImpl(int length, int delta)
- {
- bool WantMixedCase = (delta == 0);
- System.Random rnd = new System.Random();
-
- string result = "";
- char[] a = new char[length];
-
- for (int i = 0; i < length; i++)
- {
- // delta == 65 means uppercase
- // delta == 97 means lowercase
- if (WantMixedCase)
- delta = (rnd.Next(2) == 0) ? 65 : 97;
- a[i] = (char)(rnd.Next(26) + delta);
- }
-
- result = new System.String(a);
- return result;
- }
-#else
- public static string InternalGetTempFileName()
- {
- return "DotNetZip-" + Path.GetRandomFileName().Substring(0, 8) + ".tmp";
- }
-
-#endif
-
-
- ///
- /// Workitem 7889: handle ERROR_LOCK_VIOLATION during read
- ///
- ///
- /// This could be gracefully handled with an extension attribute, but
- /// This assembly is built for .NET 2.0, so I cannot use them.
- ///
- internal static int ReadWithRetry(System.IO.Stream s, byte[] buffer, int offset, int count, string FileName)
- {
- int n = 0;
- bool done = false;
-#if !NETCF && !SILVERLIGHT
- int retries = 0;
-#endif
- do
- {
- try
- {
- n = s.Read(buffer, offset, count);
- done = true;
- }
-#if NETCF || SILVERLIGHT
- catch (System.IO.IOException)
- {
- throw;
- }
-#else
- catch (System.IO.IOException ioexc1)
- {
- // Check if we can call GetHRForException,
- // which makes unmanaged code calls.
- var p = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
- if (p.IsUnrestricted())
- {
- uint hresult = _HRForException(ioexc1);
- if (hresult != 0x80070021) // ERROR_LOCK_VIOLATION
- throw new System.IO.IOException(String.Format("Cannot read file {0}", FileName), ioexc1);
- retries++;
- if (retries > 10)
- throw new System.IO.IOException(String.Format("Cannot read file {0}, at offset 0x{1:X8} after 10 retries", FileName, offset), ioexc1);
-
- // max time waited on last retry = 250 + 10*550 = 5.75s
- // aggregate time waited after 10 retries: 250 + 55*550 = 30.5s
- System.Threading.Thread.Sleep(250 + retries * 550);
- }
- else
- {
- // The permission.Demand() failed. Therefore, we cannot call
- // GetHRForException, and cannot do the subtle handling of
- // ERROR_LOCK_VIOLATION. Just bail.
- throw;
- }
- }
-#endif
- }
- while (!done);
-
- return n;
- }
-
-
-#if !NETCF
- // workitem 8009
- //
- // This method must remain separate.
- //
- // Marshal.GetHRForException() is needed to do special exception handling for
- // the read. But, that method requires UnmanagedCode permissions, and is marked
- // with LinkDemand for UnmanagedCode. In an ASP.NET medium trust environment,
- // where UnmanagedCode is restricted, will generate a SecurityException at the
- // time of JIT of the method that calls a method that is marked with LinkDemand
- // for UnmanagedCode. The SecurityException, if it is restricted, will occur
- // when this method is JITed.
- //
- // The Marshal.GetHRForException() is factored out of ReadWithRetry in order to
- // avoid the SecurityException at JIT compile time. Because _HRForException is
- // called only when the UnmanagedCode is allowed. This means .NET never
- // JIT-compiles this method when UnmanagedCode is disallowed, and thus never
- // generates the JIT-compile time exception.
- //
-#endif
- private static uint _HRForException(System.Exception ex1)
- {
- return unchecked((uint)System.Runtime.InteropServices.Marshal.GetHRForException(ex1));
- }
-
- }
-
-
-
- ///
- /// A decorator stream. It wraps another stream, and performs bookkeeping
- /// to keep track of the stream Position.
- ///
- ///
- ///
- /// In some cases, it is not possible to get the Position of a stream, let's
- /// say, on a write-only output stream like ASP.NET's
- /// Response.OutputStream, or on a different write-only stream
- /// provided as the destination for the zip by the application. In this
- /// case, programmers can use this counting stream to count the bytes read
- /// or written.
- ///
- ///
- /// Consider the scenario of an application that saves a self-extracting
- /// archive (SFX), that uses a custom SFX stub.
- ///
- ///
- /// Saving to a filesystem file, the application would open the
- /// filesystem file (getting a FileStream), save the custom sfx stub
- /// into it, and then call ZipFile.Save(), specifying the same
- /// FileStream. ZipFile.Save() does the right thing for the zipentry
- /// offsets, by inquiring the Position of the FileStream before writing
- /// any data, and then adding that initial offset into any ZipEntry
- /// offsets in the zip directory. Everything works fine.
- ///
- ///
- /// Now suppose the application is an ASPNET application and it saves
- /// directly to Response.OutputStream. It's not possible for DotNetZip to
- /// inquire the Position, so the offsets for the SFX will be wrong.
- ///
- ///
- /// The workaround is for the application to use this class to wrap
- /// HttpResponse.OutputStream, then write the SFX stub and the ZipFile
- /// into that wrapper stream. Because ZipFile.Save() can inquire the
- /// Position, it will then do the right thing with the offsets.
- ///
- ///
- public class CountingStream : System.IO.Stream
- {
- // workitem 12374: this class is now public
- private System.IO.Stream _s;
- private Int64 _bytesWritten;
- private Int64 _bytesRead;
- private Int64 _initialOffset;
-
- ///
- /// The constructor.
- ///
- /// The underlying stream
- public CountingStream(System.IO.Stream stream)
- : base()
- {
- _s = stream;
- try
- {
- _initialOffset = _s.Position;
- }
- catch
- {
- _initialOffset = 0L;
- }
- }
-
- ///
- /// Gets the wrapped stream.
- ///
- public Stream WrappedStream
- {
- get
- {
- return _s;
- }
- }
-
- ///
- /// The count of bytes written out to the stream.
- ///
- public Int64 BytesWritten
- {
- get { return _bytesWritten; }
- }
-
- ///
- /// the count of bytes that have been read from the stream.
- ///
- public Int64 BytesRead
- {
- get { return _bytesRead; }
- }
-
- ///
- /// Adjust the byte count on the stream.
- ///
- ///
- ///
- /// the number of bytes to subtract from the count.
- ///
- ///
- ///
- ///
- /// Subtract delta from the count of bytes written to the stream.
- /// This is necessary when seeking back, and writing additional data,
- /// as happens in some cases when saving Zip files.
- ///
- ///
- public void Adjust(Int64 delta)
- {
- _bytesWritten -= delta;
- if (_bytesWritten < 0)
- throw new InvalidOperationException();
- if (_s as CountingStream != null)
- ((CountingStream)_s).Adjust(delta);
- }
-
- ///
- /// The read method.
- ///
- /// The buffer to hold the data read from the stream.
- /// the offset within the buffer to copy the first byte read.
- /// the number of bytes to read.
- /// the number of bytes read, after decryption and decompression.
- public override int Read(byte[] buffer, int offset, int count)
- {
- int n = _s.Read(buffer, offset, count);
- _bytesRead += n;
- return n;
- }
-
- ///
- /// Write data into the stream.
- ///
- /// 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 (count == 0) return;
- _s.Write(buffer, offset, count);
- _bytesWritten += count;
- }
-
- ///
- /// Whether the stream can be read.
- ///
- public override bool CanRead
- {
- get { return _s.CanRead; }
- }
-
- ///
- /// Whether it is possible to call Seek() on the stream.
- ///
- public override bool CanSeek
- {
- get { return _s.CanSeek; }
- }
-
- ///
- /// Whether it is possible to call Write() on the stream.
- ///
- public override bool CanWrite
- {
- get { return _s.CanWrite; }
- }
-
- ///
- /// Flushes the underlying stream.
- ///
- public override void Flush()
- {
- _s.Flush();
- }
-
- ///
- /// The length of the underlying stream.
- ///
- public override long Length
- {
- get { return _s.Length; } // bytesWritten??
- }
-
- ///
- /// Returns the sum of number of bytes written, plus the initial
- /// offset before writing.
- ///
- public long ComputedPosition
- {
- get { return _initialOffset + _bytesWritten; }
- }
-
-
- ///
- /// The Position of the stream.
- ///
- public override long Position
- {
- get { return _s.Position; }
- set
- {
- _s.Seek(value, System.IO.SeekOrigin.Begin);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(_s);
- }
- }
-
- ///
- /// Seek in the stream.
- ///
- /// the offset point to seek to
- /// the reference point from which to seek
- /// The new position
- public override long Seek(long offset, System.IO.SeekOrigin origin)
- {
- return _s.Seek(offset, origin);
- }
-
- ///
- /// Set the length of the underlying stream. Be careful with this!
- ///
- ///
- /// the length to set on the underlying stream.
- public override void SetLength(long value)
- {
- _s.SetLength(value);
- }
- }
-
-
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/WinZipAes.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/WinZipAes.cs
deleted file mode 100644
index a316b91b..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/WinZipAes.cs
+++ /dev/null
@@ -1,941 +0,0 @@
-//#define Trace
-
-// WinZipAes.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 Dino Chiesa.
-// 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: <2011-July-12 13:42:06>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the classes for dealing with WinZip's AES encryption,
-// according to the specifications for the format available on WinZip's website.
-//
-// Created: January 2009
-//
-// ------------------------------------------------------------------
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-using System.Security.Cryptography;
-
-#if AESCRYPTO
-namespace Ionic.Zip
-{
- ///
- /// This is a helper class supporting WinZip AES encryption.
- /// This class is intended for use only by the DotNetZip library.
- ///
- ///
- ///
- /// Most uses of the DotNetZip library will not involve direct calls into
- /// the WinZipAesCrypto class. Instead, the WinZipAesCrypto class is
- /// instantiated and used by the ZipEntry() class when WinZip AES
- /// encryption or decryption on an entry is employed.
- ///
- internal class WinZipAesCrypto
- {
- internal byte[] _Salt;
- internal byte[] _providedPv;
- internal byte[] _generatedPv;
- internal int _KeyStrengthInBits;
- private byte[] _MacInitializationVector;
- private byte[] _StoredMac;
- private byte[] _keyBytes;
- private Int16 PasswordVerificationStored;
- private Int16 PasswordVerificationGenerated;
- private int Rfc2898KeygenIterations = 1000;
- private string _Password;
- private bool _cryptoGenerated ;
-
- private WinZipAesCrypto(string password, int KeyStrengthInBits)
- {
- _Password = password;
- _KeyStrengthInBits = KeyStrengthInBits;
- }
-
- public static WinZipAesCrypto Generate(string password, int KeyStrengthInBits)
- {
- WinZipAesCrypto c = new WinZipAesCrypto(password, KeyStrengthInBits);
-
- int saltSizeInBytes = c._KeyStrengthInBytes / 2;
- c._Salt = new byte[saltSizeInBytes];
- Random rnd = new Random();
- rnd.NextBytes(c._Salt);
- return c;
- }
-
-
-
- public static WinZipAesCrypto ReadFromStream(string password, int KeyStrengthInBits, Stream s)
- {
- // from http://www.winzip.com/aes_info.htm
- //
- // Size(bytes) Content
- // -----------------------------------
- // Variable Salt value
- // 2 Password verification value
- // Variable Encrypted file data
- // 10 Authentication code
- //
- // ZipEntry.CompressedSize represents the size of all of those elements.
-
- // salt size varies with key length:
- // 128 bit key => 8 bytes salt
- // 192 bits => 12 bytes salt
- // 256 bits => 16 bytes salt
-
- WinZipAesCrypto c = new WinZipAesCrypto(password, KeyStrengthInBits);
-
- int saltSizeInBytes = c._KeyStrengthInBytes / 2;
- c._Salt = new byte[saltSizeInBytes];
- c._providedPv = new byte[2];
-
- s.Read(c._Salt, 0, c._Salt.Length);
- s.Read(c._providedPv, 0, c._providedPv.Length);
-
- c.PasswordVerificationStored = (Int16)(c._providedPv[0] + c._providedPv[1] * 256);
- if (password != null)
- {
- c.PasswordVerificationGenerated = (Int16)(c.GeneratedPV[0] + c.GeneratedPV[1] * 256);
- if (c.PasswordVerificationGenerated != c.PasswordVerificationStored)
- throw new BadPasswordException("bad password");
- }
-
- return c;
- }
-
- public byte[] GeneratedPV
- {
- get
- {
- if (!_cryptoGenerated) _GenerateCryptoBytes();
- return _generatedPv;
- }
- }
-
-
- public byte[] Salt
- {
- get
- {
- return _Salt;
- }
- }
-
-
- private int _KeyStrengthInBytes
- {
- get
- {
- return _KeyStrengthInBits / 8;
-
- }
- }
-
- public int SizeOfEncryptionMetadata
- {
- get
- {
- // 10 bytes after, (n-10) before the compressed data
- return _KeyStrengthInBytes / 2 + 10 + 2;
- }
- }
-
- public string Password
- {
- set
- {
- _Password = value;
- if (_Password != null)
- {
- PasswordVerificationGenerated = (Int16)(GeneratedPV[0] + GeneratedPV[1] * 256);
- if (PasswordVerificationGenerated != PasswordVerificationStored)
- throw new Ionic.Zip.BadPasswordException();
- }
- }
- private get
- {
- return _Password;
- }
- }
-
-
- private void _GenerateCryptoBytes()
- {
- //Console.WriteLine(" provided password: '{0}'", _Password);
-
- System.Security.Cryptography.Rfc2898DeriveBytes rfc2898 =
- new System.Security.Cryptography.Rfc2898DeriveBytes(_Password, Salt, Rfc2898KeygenIterations);
-
- _keyBytes = rfc2898.GetBytes(_KeyStrengthInBytes); // 16 or 24 or 32 ???
- _MacInitializationVector = rfc2898.GetBytes(_KeyStrengthInBytes);
- _generatedPv = rfc2898.GetBytes(2);
-
- _cryptoGenerated = true;
- }
-
-
- public byte[] KeyBytes
- {
- get
- {
- if (!_cryptoGenerated) _GenerateCryptoBytes();
- return _keyBytes;
- }
- }
-
-
- public byte[] MacIv
- {
- get
- {
- if (!_cryptoGenerated) _GenerateCryptoBytes();
- return _MacInitializationVector;
- }
- }
-
- public byte[] CalculatedMac;
-
-
- public void ReadAndVerifyMac(System.IO.Stream s)
- {
- bool invalid = false;
-
- // read integrityCheckVector.
- // caller must ensure that the file pointer is in the right spot!
- _StoredMac = new byte[10]; // aka "authentication code"
- s.Read(_StoredMac, 0, _StoredMac.Length);
-
- if (_StoredMac.Length != CalculatedMac.Length)
- invalid = true;
-
- if (!invalid)
- {
- for (int i = 0; i < _StoredMac.Length; i++)
- {
- if (_StoredMac[i] != CalculatedMac[i])
- invalid = true;
- }
- }
-
- if (invalid)
- throw new Ionic.Zip.BadStateException("The MAC does not match.");
- }
-
- }
-
-
- #region DONT_COMPILE_BUT_KEEP_FOR_POTENTIAL_FUTURE_USE
-#if NO
- internal class Util
- {
- private static void _Format(System.Text.StringBuilder sb1,
- byte[] b,
- int offset,
- int length)
- {
-
- System.Text.StringBuilder sb2 = new System.Text.StringBuilder();
- sb1.Append("0000 ");
- int i;
- for (i = 0; i < length; i++)
- {
- int x = offset+i;
- if (i != 0 && i % 16 == 0)
- {
- sb1.Append(" ")
- .Append(sb2)
- .Append("\n")
- .Append(String.Format("{0:X4} ", i));
- sb2.Remove(0,sb2.Length);
- }
- sb1.Append(System.String.Format("{0:X2} ", b[x]));
- if (b[x] >=32 && b[x] <= 126)
- sb2.Append((char)b[x]);
- else
- sb2.Append(".");
- }
- if (sb2.Length > 0)
- {
- sb1.Append(new String(' ', ((16 - i%16) * 3) + 4))
- .Append(sb2);
- }
- }
-
-
-
- internal static string FormatByteArray(byte[] b, int limit)
- {
- System.Text.StringBuilder sb1 = new System.Text.StringBuilder();
-
- if ((limit * 2 > b.Length) || limit == 0)
- {
- _Format(sb1, b, 0, b.Length);
- }
- else
- {
- // first N bytes of the buffer
- _Format(sb1, b, 0, limit);
-
- if (b.Length > limit * 2)
- sb1.Append(String.Format("\n ...({0} other bytes here)....\n", b.Length - limit * 2));
-
- // last N bytes of the buffer
- _Format(sb1, b, b.Length - limit, limit);
- }
-
- return sb1.ToString();
- }
-
-
- internal static string FormatByteArray(byte[] b)
- {
- return FormatByteArray(b, 0);
- }
- }
-
-#endif
- #endregion
-
-
-
-
- ///
- /// A stream that encrypts as it writes, or decrypts as it reads. The
- /// Crypto is AES in CTR (counter) mode, which is compatible with the AES
- /// encryption employed by WinZip 12.0.
- ///
- ///
- ///
- /// The AES/CTR encryption protocol used by WinZip works like this:
- ///
- /// - start with a counter, initialized to zero.
- ///
- /// - to encrypt, take the data by 16-byte blocks. For each block:
- /// - apply the transform to the counter
- /// - increement the counter
- /// - XOR the result of the transform with the plaintext to
- /// get the ciphertext.
- /// - compute the mac on the encrypted bytes
- /// - when finished with all blocks, store the computed MAC.
- ///
- /// - to decrypt, take the data by 16-byte blocks. For each block:
- /// - compute the mac on the encrypted bytes,
- /// - apply the transform to the counter
- /// - increement the counter
- /// - XOR the result of the transform with the ciphertext to
- /// get the plaintext.
- /// - when finished with all blocks, compare the computed MAC against
- /// the stored MAC
- ///
- ///
- ///
- //
- internal class WinZipAesCipherStream : Stream
- {
- private WinZipAesCrypto _params;
- private System.IO.Stream _s;
- private CryptoMode _mode;
- private int _nonce;
- private bool _finalBlock;
-
- internal HMACSHA1 _mac;
-
- // Use RijndaelManaged from .NET 2.0.
- // AesManaged came in .NET 3.5, but we want to limit
- // dependency to .NET 2.0. AES is just a restricted form
- // of Rijndael (fixed block size of 128, some crypto modes not supported).
-
- internal RijndaelManaged _aesCipher;
- internal ICryptoTransform _xform;
-
- private const int BLOCK_SIZE_IN_BYTES = 16;
-
- private byte[] counter = new byte[BLOCK_SIZE_IN_BYTES];
- private byte[] counterOut = new byte[BLOCK_SIZE_IN_BYTES];
-
- // I've had a problem when wrapping a WinZipAesCipherStream inside
- // a DeflateStream. Calling Read() on the DeflateStream results in
- // a Read() on the WinZipAesCipherStream, but the buffer is larger
- // than the total size of the encrypted data, and larger than the
- // initial Read() on the DeflateStream! When the encrypted
- // bytestream is embedded within a larger stream (As in a zip
- // archive), the Read() doesn't fail with EOF. This causes bad
- // data to be returned, and it messes up the MAC.
-
- // This field is used to provide a hard-stop to the size of
- // data that can be read from the stream. In Read(), if the buffer or
- // read request goes beyond the stop, we truncate it.
-
- private long _length;
- private long _totalBytesXferred;
- private byte[] _PendingWriteBlock;
- private int _pendingCount;
- private byte[] _iobuf;
-
- ///
- /// The constructor.
- ///
- /// The underlying stream
- /// To either encrypt or decrypt.
- /// The pre-initialized WinZipAesCrypto object.
- /// The maximum number of bytes to read from the stream.
- internal WinZipAesCipherStream(System.IO.Stream s, WinZipAesCrypto cryptoParams, long length, CryptoMode mode)
- : this(s, cryptoParams, mode)
- {
- // don't read beyond this limit!
- _length = length;
- //Console.WriteLine("max length of AES stream: {0}", _length);
- }
-
-
-#if WANT_TRACE
- Stream untransformed;
- String traceFileUntransformed;
- Stream transformed;
- String traceFileTransformed;
-#endif
-
-
- internal WinZipAesCipherStream(System.IO.Stream s, WinZipAesCrypto cryptoParams, CryptoMode mode)
- : base()
- {
- TraceOutput("-------------------------------------------------------");
- TraceOutput("Create {0:X8}", this.GetHashCode());
-
- _params = cryptoParams;
- _s = s;
- _mode = mode;
- _nonce = 1;
-
- if (_params == null)
- throw new BadPasswordException("Supply a password to use AES encryption.");
-
- int keySizeInBits = _params.KeyBytes.Length * 8;
- if (keySizeInBits != 256 && keySizeInBits != 128 && keySizeInBits != 192)
- throw new ArgumentOutOfRangeException("keysize",
- "size of key must be 128, 192, or 256");
-
- _mac = new HMACSHA1(_params.MacIv);
-
- _aesCipher = new System.Security.Cryptography.RijndaelManaged();
- _aesCipher.BlockSize = 128;
- _aesCipher.KeySize = keySizeInBits; // 128, 192, 256
- _aesCipher.Mode = CipherMode.ECB;
- _aesCipher.Padding = PaddingMode.None;
-
- byte[] iv = new byte[BLOCK_SIZE_IN_BYTES]; // all zeroes
-
- // Create an ENCRYPTOR, regardless whether doing decryption or encryption.
- // It is reflexive.
- _xform = _aesCipher.CreateEncryptor(_params.KeyBytes, iv);
-
- if (_mode == CryptoMode.Encrypt)
- {
- _iobuf = new byte[2048];
- _PendingWriteBlock = new byte[BLOCK_SIZE_IN_BYTES];
- }
-
-
-#if WANT_TRACE
- traceFileUntransformed = "unpack\\WinZipAesCipherStream.trace.untransformed.out";
- traceFileTransformed = "unpack\\WinZipAesCipherStream.trace.transformed.out";
-
- untransformed = System.IO.File.Create(traceFileUntransformed);
- transformed = System.IO.File.Create(traceFileTransformed);
-#endif
- }
-
- private void XorInPlace(byte[] buffer, int offset, int count)
- {
- for (int i = 0; i < count; i++)
- {
- buffer[offset + i] = (byte)(counterOut[i] ^ buffer[offset + i]);
- }
- }
-
- private void WriteTransformOneBlock(byte[] buffer, int offset)
- {
- System.Array.Copy(BitConverter.GetBytes(_nonce++), 0, counter, 0, 4);
- _xform.TransformBlock(counter,
- 0,
- BLOCK_SIZE_IN_BYTES,
- counterOut,
- 0);
- XorInPlace(buffer, offset, BLOCK_SIZE_IN_BYTES);
- _mac.TransformBlock(buffer, offset, BLOCK_SIZE_IN_BYTES, null, 0);
- }
-
-
- private void WriteTransformBlocks(byte[] buffer, int offset, int count)
- {
- int posn = offset;
- int last = count + offset;
-
- while (posn < buffer.Length && posn < last)
- {
- WriteTransformOneBlock (buffer, posn);
- posn += BLOCK_SIZE_IN_BYTES;
- }
- }
-
-
- private void WriteTransformFinalBlock()
- {
- if (_pendingCount == 0)
- throw new InvalidOperationException("No bytes available.");
-
- if (_finalBlock)
- throw new InvalidOperationException("The final block has already been transformed.");
-
- System.Array.Copy(BitConverter.GetBytes(_nonce++), 0, counter, 0, 4);
- counterOut = _xform.TransformFinalBlock(counter,
- 0,
- BLOCK_SIZE_IN_BYTES);
- XorInPlace(_PendingWriteBlock, 0, _pendingCount);
- _mac.TransformFinalBlock(_PendingWriteBlock, 0, _pendingCount);
- _finalBlock = true;
- }
-
-
-
-
-
- private int ReadTransformOneBlock(byte[] buffer, int offset, int last)
- {
- if (_finalBlock)
- throw new NotSupportedException();
-
- int bytesRemaining = last - offset;
- int bytesToRead = (bytesRemaining > BLOCK_SIZE_IN_BYTES)
- ? BLOCK_SIZE_IN_BYTES
- : bytesRemaining;
-
- // update the counter
- System.Array.Copy(BitConverter.GetBytes(_nonce++), 0, counter, 0, 4);
-
- // Determine if this is the final block
- if ((bytesToRead == bytesRemaining) &&
- (_length > 0) &&
- (_totalBytesXferred + last == _length))
- {
- _mac.TransformFinalBlock(buffer, offset, bytesToRead);
- counterOut = _xform.TransformFinalBlock(counter,
- 0,
- BLOCK_SIZE_IN_BYTES);
- _finalBlock = true;
- }
- else
- {
- _mac.TransformBlock(buffer, offset, bytesToRead, null, 0);
- _xform.TransformBlock(counter,
- 0, // offset
- BLOCK_SIZE_IN_BYTES,
- counterOut,
- 0); // offset
- }
-
- XorInPlace(buffer, offset, bytesToRead);
- return bytesToRead;
- }
-
-
-
- private void ReadTransformBlocks(byte[] buffer, int offset, int count)
- {
- int posn = offset;
- int last = count + offset;
-
- while (posn < buffer.Length && posn < last )
- {
- int n = ReadTransformOneBlock (buffer, posn, last);
- posn += n;
- }
- }
-
-
-
- public override int Read(byte[] buffer, int offset, int count)
- {
- if (_mode == CryptoMode.Encrypt)
- throw new NotSupportedException();
-
- if (buffer == null)
- throw new ArgumentNullException("buffer");
-
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset",
- "Must not be less than zero.");
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- "Must not be less than zero.");
-
- if (buffer.Length < offset + count)
- throw new ArgumentException("The buffer is too small");
-
- // When I wrap a WinZipAesStream in a DeflateStream, the
- // DeflateStream asks its captive to read 4k blocks, even if the
- // encrypted bytestream is smaller than that. This is a way to
- // limit the number of bytes read.
-
- int bytesToRead = count;
-
- if (_totalBytesXferred >= _length)
- {
- return 0; // EOF
- }
-
- long bytesRemaining = _length - _totalBytesXferred;
- if (bytesRemaining < count) bytesToRead = (int)bytesRemaining;
-
- int n = _s.Read(buffer, offset, bytesToRead);
-
-
-#if WANT_TRACE
- untransformed.Write(buffer, offset, bytesToRead);
-#endif
-
- ReadTransformBlocks(buffer, offset, bytesToRead);
-
-#if WANT_TRACE
- transformed.Write(buffer, offset, bytesToRead);
-#endif
- _totalBytesXferred += n;
- return n;
- }
-
-
-
- ///
- /// Returns the final HMAC-SHA1-80 for the data that was encrypted.
- ///
- public byte[] FinalAuthentication
- {
- get
- {
- if (!_finalBlock)
- {
- // special-case zero-byte files
- if ( _totalBytesXferred != 0)
- throw new BadStateException("The final hash has not been computed.");
-
- // Must call ComputeHash on an empty byte array when no data
- // has run through the MAC.
-
- byte[] b = { };
- _mac.ComputeHash(b);
- // fall through
- }
- byte[] macBytes10 = new byte[10];
- System.Array.Copy(_mac.Hash, 0, macBytes10, 0, 10);
- return macBytes10;
- }
- }
-
-
- public override void Write(byte[] buffer, int offset, int count)
- {
- if (_finalBlock)
- throw new InvalidOperationException("The final block has already been transformed.");
-
- if (_mode == CryptoMode.Decrypt)
- throw new NotSupportedException();
-
- if (buffer == null)
- throw new ArgumentNullException("buffer");
-
- if (offset < 0)
- throw new ArgumentOutOfRangeException("offset",
- "Must not be less than zero.");
- if (count < 0)
- throw new ArgumentOutOfRangeException("count",
- "Must not be less than zero.");
- if (buffer.Length < offset + count)
- throw new ArgumentException("The offset and count are too large");
-
- if (count == 0)
- return;
-
- TraceOutput("Write off({0}) count({1})", offset, count);
-
-#if WANT_TRACE
- untransformed.Write(buffer, offset, count);
-#endif
-
- // For proper AES encryption, an AES encryptor application calls
- // TransformBlock repeatedly for all 16-byte blocks except the
- // last. For the last block, it then calls TransformFinalBlock().
- //
- // This class is a stream that encrypts via Write(). But, it's not
- // possible to recognize which are the "last" bytes from within the call
- // to Write(). The caller can call Write() several times in succession,
- // with varying buffers. This class only "knows" that the last bytes
- // have been written when the app calls Close().
- //
- // Therefore, this class buffers writes: After completion every Write(),
- // a 16-byte "pending" block (_PendingWriteBlock) must hold between 1
- // and 16 bytes, which will be used in TransformFinalBlock if the app
- // calls Close() immediately thereafter. Also, every write must
- // transform any pending bytes, before transforming the data passed in
- // to the current call.
- //
- // In operation, after the first call to Write() and before the call to
- // Close(), one full or partial block of bytes is always available,
- // pending. At time of Close(), this class calls
- // WriteTransformFinalBlock() to flush the pending bytes.
- //
- // This approach works whether the caller writes in odd-sized batches,
- // for example 5000 bytes, or in batches that are neat multiples of the
- // blocksize (16).
- //
- // Logicaly, what we do is this:
- //
- // 1. if there are fewer than 16 bytes (pending + current), then
- // just copy them into th pending buffer and return.
- //
- // 2. there are more than 16 bytes to write. So, take the leading slice
- // of bytes from the current buffer, enough to fill the pending
- // buffer. Transform the pending block, and write it out.
- //
- // 3. Take the trailing slice of bytes (a full block or a partial block),
- // and copy it to the pending block for next time.
- //
- // 4. transform and write all the other blocks, the middle slice.
- //
-
- // There are 16 or fewer bytes, so just buffer the bytes.
- if (count + _pendingCount <= BLOCK_SIZE_IN_BYTES)
- {
- Buffer.BlockCopy(buffer,
- offset,
- _PendingWriteBlock,
- _pendingCount,
- count);
- _pendingCount += count;
-
- // At this point, _PendingWriteBlock contains up to
- // BLOCK_SIZE_IN_BYTES bytes, and _pendingCount ranges from 0 to
- // BLOCK_SIZE_IN_BYTES. We don't want to xform+write them yet,
- // because this may have been the last block. The last block gets
- // written at Close().
- return;
- }
-
- // We know there are at least 17 bytes, counting those in the current
- // buffer, along with the (possibly empty) pending block.
-
- int bytesRemaining = count;
- int curOffset = offset;
-
- // workitem 12815
- //
- // xform chunkwise ... Cannot transform in place using the original
- // buffer because that is user-maintained.
-
- if (_pendingCount != 0)
- {
- // We have more than one block of data to write, therefore it is safe
- // to xform+write.
- int fillCount = BLOCK_SIZE_IN_BYTES - _pendingCount;
-
- // fillCount is possibly zero here. That happens when the pending
- // buffer held 16 bytes (one complete block) before this call to
- // Write.
- if (fillCount > 0)
- {
- Buffer.BlockCopy(buffer,
- offset,
- _PendingWriteBlock,
- _pendingCount,
- fillCount);
-
- // adjust counts:
- bytesRemaining -= fillCount;
- curOffset += fillCount;
- }
-
- // xform and write:
- WriteTransformOneBlock(_PendingWriteBlock, 0);
- _s.Write(_PendingWriteBlock, 0, BLOCK_SIZE_IN_BYTES);
- _totalBytesXferred += BLOCK_SIZE_IN_BYTES;
- _pendingCount = 0;
- }
-
- // At this point _PendingWriteBlock is empty, and bytesRemaining is
- // always greater than 0.
-
- // Now, xform N blocks, where N = floor((bytesRemaining-1)/16). If
- // writing 32 bytes, then xform 1 block, and stage the remaining 16. If
- // writing 10037 bytes, xform 627 blocks of 16 bytes, then stage the
- // remaining 5 bytes.
-
- int blocksToXform = (bytesRemaining-1)/BLOCK_SIZE_IN_BYTES;
- _pendingCount = bytesRemaining - (blocksToXform * BLOCK_SIZE_IN_BYTES);
-
- // _pendingCount is ALWAYS between 1 and 16.
- // Put the last _pendingCount bytes into the pending block.
- Buffer.BlockCopy(buffer,
- curOffset + bytesRemaining - _pendingCount,
- _PendingWriteBlock,
- 0,
- _pendingCount);
- bytesRemaining -= _pendingCount;
- _totalBytesXferred += bytesRemaining; // will be true after the loop
-
- // now, transform all the full blocks preceding that.
- // bytesRemaining is always a multiple of 16 .
- if (blocksToXform > 0)
- {
- do
- {
- int c = _iobuf.Length;
- if (c > bytesRemaining) c = bytesRemaining;
- Buffer.BlockCopy(buffer,
- curOffset,
- _iobuf,
- 0,
- c);
-
- WriteTransformBlocks(_iobuf, 0, c);
- _s.Write(_iobuf, 0, c);
- bytesRemaining -= c;
- curOffset += c;
- } while(bytesRemaining > 0);
- }
- }
-
-
-
- ///
- /// Close the stream.
- ///
- public override void Close()
- {
- TraceOutput("Close {0:X8}", this.GetHashCode());
-
- // In the degenerate case, no bytes have been written to the
- // stream at all. Need to check here, and NOT emit the
- // final block if Write has not been called.
- if (_pendingCount > 0)
- {
- WriteTransformFinalBlock();
- _s.Write(_PendingWriteBlock, 0, _pendingCount);
- _totalBytesXferred += _pendingCount;
- _pendingCount = 0;
- }
- _s.Close();
-
-#if WANT_TRACE
- untransformed.Close();
- transformed.Close();
- Console.WriteLine("\nuntransformed bytestream is in {0}", traceFileUntransformed);
- Console.WriteLine("\ntransformed bytestream is in {0}", traceFileTransformed);
-#endif
- TraceOutput("-------------------------------------------------------");
- }
-
-
- ///
- /// Returns true if the stream can be read.
- ///
- public override bool CanRead
- {
- get
- {
- if (_mode != CryptoMode.Decrypt) return false;
- return true;
- }
- }
-
-
- ///
- /// Always returns false.
- ///
- public override bool CanSeek
- {
- get { return false; }
- }
-
- ///
- /// Returns true if the CryptoMode is Encrypt.
- ///
- public override bool CanWrite
- {
- get { return (_mode == CryptoMode.Encrypt); }
- }
-
- ///
- /// Flush the content in the stream.
- ///
- public override void Flush()
- {
- _s.Flush();
- }
-
- ///
- /// Getting this property throws a NotImplementedException.
- ///
- public override long Length
- {
- get { throw new NotImplementedException(); }
- }
-
- ///
- /// Getting or Setting this property throws a NotImplementedException.
- ///
- public override long Position
- {
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
- }
-
- ///
- /// This method throws a NotImplementedException.
- ///
- public override long Seek(long offset, System.IO.SeekOrigin origin)
- {
- throw new NotImplementedException();
- }
-
- ///
- /// This method throws a NotImplementedException.
- ///
- public override void SetLength(long value)
- {
- throw new NotImplementedException();
- }
-
-
-
- [System.Diagnostics.ConditionalAttribute("Trace")]
- private void TraceOutput(string format, params object[] varParams)
- {
- lock(_outputLock)
- {
- int tid = System.Threading.Thread.CurrentThread.GetHashCode();
- Console.ForegroundColor = (ConsoleColor) (tid % 8 + 8);
- Console.Write("{0:000} WZACS ", tid);
- Console.WriteLine(format, varParams);
- Console.ResetColor();
- }
- }
-
- private object _outputLock = new Object();
- }
-}
-#endif
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipConstants.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipConstants.cs
deleted file mode 100644
index cc5eec1a..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipConstants.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// ZipConstants.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2006, 2007, 2008, 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-August-27 23:22:32>
-//
-// ------------------------------------------------------------------
-//
-// This module defines a few constants that are used in the project.
-//
-// ------------------------------------------------------------------
-
-using System;
-
-namespace Ionic.Zip
-{
- static class ZipConstants
- {
- public const UInt32 PackedToRemovableMedia = 0x30304b50;
- public const UInt32 Zip64EndOfCentralDirectoryRecordSignature = 0x06064b50;
- public const UInt32 Zip64EndOfCentralDirectoryLocatorSignature = 0x07064b50;
- public const UInt32 EndOfCentralDirectorySignature = 0x06054b50;
- public const int ZipEntrySignature = 0x04034b50;
- public const int ZipEntryDataDescriptorSignature = 0x08074b50;
- public const int SplitArchiveSignature = 0x08074b50;
- public const int ZipDirEntrySignature = 0x02014b50;
-
-
- // These are dictated by the Zip Spec.See APPNOTE.txt
- public const int AesKeySize = 192; // 128, 192, 256
- public const int AesBlockSize = 128; // ???
-
- public const UInt16 AesAlgId128 = 0x660E;
- public const UInt16 AesAlgId192 = 0x660F;
- public const UInt16 AesAlgId256 = 0x6610;
-
- }
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipCrypto.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipCrypto.cs
deleted file mode 100644
index a8c0b5fc..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipCrypto.cs
+++ /dev/null
@@ -1,455 +0,0 @@
-// ZipCrypto.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2008, 2009, 2011 Dino Chiesa
-// 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: <2011-July-28 06:30:59>
-//
-// ------------------------------------------------------------------
-//
-// This module provides the implementation for "traditional" Zip encryption.
-//
-// Created Tue Apr 15 17:39:56 2008
-//
-// ------------------------------------------------------------------
-
-using System;
-
-namespace Ionic.Zip
-{
- ///
- /// This class implements the "traditional" or "classic" PKZip encryption,
- /// which today is considered to be weak. On the other hand it is
- /// ubiquitous. This class is intended for use only by the DotNetZip
- /// library.
- ///
- ///
- ///
- /// Most uses of the DotNetZip library will not involve direct calls into
- /// the ZipCrypto class. Instead, the ZipCrypto class is instantiated and
- /// used by the ZipEntry() class when encryption or decryption on an entry
- /// is employed. If for some reason you really wanted to use a weak
- /// encryption algorithm in some other application, you might use this
- /// library. But you would be much better off using one of the built-in
- /// strong encryption libraries in the .NET Framework, like the AES
- /// algorithm or SHA.
- ///
- internal class ZipCrypto
- {
- ///
- /// The default constructor for ZipCrypto.
- ///
- ///
- ///
- /// This class is intended for internal use by the library only. It's
- /// probably not useful to you. Seriously. Stop reading this
- /// documentation. It's a waste of your time. Go do something else.
- /// Check the football scores. Go get an ice cream with a friend.
- /// Seriously.
- ///
- ///
- private ZipCrypto() { }
-
- public static ZipCrypto ForWrite(string password)
- {
- ZipCrypto z = new ZipCrypto();
- if (password == null)
- throw new BadPasswordException("This entry requires a password.");
- z.InitCipher(password);
- return z;
- }
-
-
- public static ZipCrypto ForRead(string password, ZipEntry e)
- {
- System.IO.Stream s = e._archiveStream;
- e._WeakEncryptionHeader = new byte[12];
- byte[] eh = e._WeakEncryptionHeader;
- ZipCrypto z = new ZipCrypto();
-
- if (password == null)
- throw new BadPasswordException("This entry requires a password.");
-
- z.InitCipher(password);
-
- ZipEntry.ReadWeakEncryptionHeader(s, eh);
-
- // Decrypt the header. This has a side effect of "further initializing the
- // encryption keys" in the traditional zip encryption.
- byte[] DecryptedHeader = z.DecryptMessage(eh, eh.Length);
-
- // CRC check
- // According to the pkzip spec, the final byte in the decrypted header
- // is the highest-order byte in the CRC. We check it here.
- if (DecryptedHeader[11] != (byte)((e._Crc32 >> 24) & 0xff))
- {
- // In the case that bit 3 of the general purpose bit flag is set to
- // indicate the presence of an 'Extended File Header' or a 'data
- // descriptor' (signature 0x08074b50), the last byte of the decrypted
- // header is sometimes compared with the high-order byte of the
- // lastmodified time, rather than the high-order byte of the CRC, to
- // verify the password.
- //
- // This is not documented in the PKWare Appnote.txt. It was
- // discovered this by analysis of the Crypt.c source file in the
- // InfoZip library http://www.info-zip.org/pub/infozip/
- //
- // The reason for this is that the CRC for a file cannot be known
- // until the entire contents of the file have been streamed. This
- // means a tool would have to read the file content TWICE in its
- // entirety in order to perform PKZIP encryption - once to compute
- // the CRC, and again to actually encrypt.
- //
- // This is so important for performance that using the timeblob as
- // the verification should be the standard practice for DotNetZip
- // when using PKZIP encryption. This implies that bit 3 must be
- // set. The downside is that some tools still cannot cope with ZIP
- // files that use bit 3. Therefore, DotNetZip DOES NOT force bit 3
- // when PKZIP encryption is in use, and instead, reads the stream
- // twice.
- //
-
- if ((e._BitField & 0x0008) != 0x0008)
- {
- throw new BadPasswordException("The password did not match.");
- }
- else if (DecryptedHeader[11] != (byte)((e._TimeBlob >> 8) & 0xff))
- {
- throw new BadPasswordException("The password did not match.");
- }
-
- // We have a good password.
- }
- else
- {
- // A-OK
- }
- return z;
- }
-
-
-
-
- ///
- /// From AppNote.txt:
- /// unsigned char decrypt_byte()
- /// local unsigned short temp
- /// temp :=- Key(2) | 2
- /// decrypt_byte := (temp * (temp ^ 1)) bitshift-right 8
- /// end decrypt_byte
- ///
- private byte MagicByte
- {
- get
- {
- UInt16 t = (UInt16)((UInt16)(_Keys[2] & 0xFFFF) | 2);
- return (byte)((t * (t ^ 1)) >> 8);
- }
- }
-
- // Decrypting:
- // From AppNote.txt:
- // loop for i from 0 to 11
- // C := buffer(i) ^ decrypt_byte()
- // update_keys(C)
- // buffer(i) := C
- // end loop
-
-
- ///
- /// Call this method on a cipher text to render the plaintext. You must
- /// first initialize the cipher with a call to InitCipher.
- ///
- ///
- ///
- ///
- /// var cipher = new ZipCrypto();
- /// cipher.InitCipher(Password);
- /// // Decrypt the header. This has a side effect of "further initializing the
- /// // encryption keys" in the traditional zip encryption.
- /// byte[] DecryptedMessage = cipher.DecryptMessage(EncryptedMessage);
- ///
- ///
- ///
- /// The encrypted buffer.
- ///
- /// The number of bytes to encrypt.
- /// Should be less than or equal to CipherText.Length.
- ///
- ///
- /// The plaintext.
- public byte[] DecryptMessage(byte[] cipherText, int length)
- {
- if (cipherText == null)
- throw new ArgumentNullException("cipherText");
-
- if (length > cipherText.Length)
- throw new ArgumentOutOfRangeException("length",
- "Bad length during Decryption: the length parameter must be smaller than or equal to the size of the destination array.");
-
- byte[] plainText = new byte[length];
- for (int i = 0; i < length; i++)
- {
- byte C = (byte)(cipherText[i] ^ MagicByte);
- UpdateKeys(C);
- plainText[i] = C;
- }
- return plainText;
- }
-
- ///
- /// This is the converse of DecryptMessage. It encrypts the plaintext
- /// and produces a ciphertext.
- ///
- ///
- /// The plain text buffer.
- ///
- ///
- /// The number of bytes to encrypt.
- /// Should be less than or equal to plainText.Length.
- ///
- ///
- /// The ciphertext.
- public byte[] EncryptMessage(byte[] plainText, int length)
- {
- if (plainText == null)
- throw new ArgumentNullException("plaintext");
-
- if (length > plainText.Length)
- throw new ArgumentOutOfRangeException("length",
- "Bad length during Encryption: The length parameter must be smaller than or equal to the size of the destination array.");
-
- byte[] cipherText = new byte[length];
- for (int i = 0; i < length; i++)
- {
- byte C = plainText[i];
- cipherText[i] = (byte)(plainText[i] ^ MagicByte);
- UpdateKeys(C);
- }
- return cipherText;
- }
-
-
- ///
- /// This initializes the cipher with the given password.
- /// See AppNote.txt for details.
- ///
- ///
- ///
- /// The passphrase for encrypting or decrypting with this cipher.
- ///
- ///
- ///
- ///
- /// Step 1 - Initializing the encryption keys
- /// -----------------------------------------
- /// Start with these keys:
- /// Key(0) := 305419896 (0x12345678)
- /// Key(1) := 591751049 (0x23456789)
- /// Key(2) := 878082192 (0x34567890)
- ///
- /// Then, initialize the keys with a password:
- ///
- /// loop for i from 0 to length(password)-1
- /// update_keys(password(i))
- /// end loop
- ///
- /// Where update_keys() is defined as:
- ///
- /// update_keys(char):
- /// Key(0) := crc32(key(0),char)
- /// Key(1) := Key(1) + (Key(0) bitwiseAND 000000ffH)
- /// Key(1) := Key(1) * 134775813 + 1
- /// Key(2) := crc32(key(2),key(1) rightshift 24)
- /// end update_keys
- ///
- /// Where crc32(old_crc,char) is a routine that given a CRC value and a
- /// character, returns an updated CRC value after applying the CRC-32
- /// algorithm described elsewhere in this document.
- ///
- ///
- ///
- ///
- /// After the keys are initialized, then you can use the cipher to
- /// encrypt the plaintext.
- ///
- ///
- ///
- /// Essentially we encrypt the password with the keys, then discard the
- /// ciphertext for the password. This initializes the keys for later use.
- ///
- ///
- ///
- public void InitCipher(string passphrase)
- {
- byte[] p = SharedUtilities.StringToByteArray(passphrase);
- for (int i = 0; i < passphrase.Length; i++)
- UpdateKeys(p[i]);
- }
-
-
- private void UpdateKeys(byte byteValue)
- {
- _Keys[0] = (UInt32)crc32.ComputeCrc32((int)_Keys[0], byteValue);
- _Keys[1] = _Keys[1] + (byte)_Keys[0];
- _Keys[1] = _Keys[1] * 0x08088405 + 1;
- _Keys[2] = (UInt32)crc32.ComputeCrc32((int)_Keys[2], (byte)(_Keys[1] >> 24));
- }
-
- /////
- ///// The byte array representing the seed keys used.
- ///// Get this after calling InitCipher. The 12 bytes represents
- ///// what the zip spec calls the "EncryptionHeader".
- /////
- //public byte[] KeyHeader
- //{
- // get
- // {
- // byte[] result = new byte[12];
- // result[0] = (byte)(_Keys[0] & 0xff);
- // result[1] = (byte)((_Keys[0] >> 8) & 0xff);
- // result[2] = (byte)((_Keys[0] >> 16) & 0xff);
- // result[3] = (byte)((_Keys[0] >> 24) & 0xff);
- // result[4] = (byte)(_Keys[1] & 0xff);
- // result[5] = (byte)((_Keys[1] >> 8) & 0xff);
- // result[6] = (byte)((_Keys[1] >> 16) & 0xff);
- // result[7] = (byte)((_Keys[1] >> 24) & 0xff);
- // result[8] = (byte)(_Keys[2] & 0xff);
- // result[9] = (byte)((_Keys[2] >> 8) & 0xff);
- // result[10] = (byte)((_Keys[2] >> 16) & 0xff);
- // result[11] = (byte)((_Keys[2] >> 24) & 0xff);
- // return result;
- // }
- //}
-
- // private fields for the crypto stuff:
- private UInt32[] _Keys = { 0x12345678, 0x23456789, 0x34567890 };
- private Ionic.Crc.CRC32 crc32 = new Ionic.Crc.CRC32();
-
- }
-
- internal enum CryptoMode
- {
- Encrypt,
- Decrypt
- }
-
- ///
- /// A Stream for reading and concurrently decrypting data from a zip file,
- /// or for writing and concurrently encrypting data to a zip file.
- ///
- internal class ZipCipherStream : System.IO.Stream
- {
- private ZipCrypto _cipher;
- private System.IO.Stream _s;
- private CryptoMode _mode;
-
- /// The constructor.
- /// The underlying stream
- /// To either encrypt or decrypt.
- /// The pre-initialized ZipCrypto object.
- public ZipCipherStream(System.IO.Stream s, ZipCrypto cipher, CryptoMode mode)
- : base()
- {
- _cipher = cipher;
- _s = s;
- _mode = mode;
- }
-
- public override int Read(byte[] buffer, int offset, int count)
- {
- if (_mode == CryptoMode.Encrypt)
- throw new NotSupportedException("This stream does not encrypt via Read()");
-
- if (buffer == null)
- throw new ArgumentNullException("buffer");
-
- byte[] db = new byte[count];
- int n = _s.Read(db, 0, count);
- byte[] decrypted = _cipher.DecryptMessage(db, n);
- for (int i = 0; i < n; i++)
- {
- buffer[offset + i] = decrypted[i];
- }
- return n;
- }
-
- public override void Write(byte[] buffer, int offset, int count)
- {
- if (_mode == CryptoMode.Decrypt)
- throw new NotSupportedException("This stream does not Decrypt via Write()");
-
- if (buffer == null)
- throw new ArgumentNullException("buffer");
-
- // workitem 7696
- if (count == 0) return;
-
- byte[] plaintext = null;
- if (offset != 0)
- {
- plaintext = new byte[count];
- for (int i = 0; i < count; i++)
- {
- plaintext[i] = buffer[offset + i];
- }
- }
- else plaintext = buffer;
-
- byte[] encrypted = _cipher.EncryptMessage(plaintext, count);
- _s.Write(encrypted, 0, encrypted.Length);
- }
-
-
- public override bool CanRead
- {
- get { return (_mode == CryptoMode.Decrypt); }
- }
- public override bool CanSeek
- {
- get { return false; }
- }
-
- public override bool CanWrite
- {
- get { return (_mode == CryptoMode.Encrypt); }
- }
-
- public override void Flush()
- {
- //throw new NotSupportedException();
- }
-
- public override long Length
- {
- get { throw new NotSupportedException(); }
- }
-
- public override long Position
- {
- get { throw new NotSupportedException(); }
- set { throw new NotSupportedException(); }
- }
- public override long Seek(long offset, System.IO.SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
-
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
- }
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipDirEntry.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipDirEntry.cs
deleted file mode 100644
index 882c6941..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipDirEntry.cs
+++ /dev/null
@@ -1,381 +0,0 @@
-// ZipDirEntry.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2006-2011 Dino Chiesa .
-// 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: <2011-July-11 12:03:03>
-//
-// ------------------------------------------------------------------
-//
-// This module defines members of the ZipEntry class for reading the
-// Zip file central directory.
-//
-// Created: Tue, 27 Mar 2007 15:30
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.Collections.Generic;
-
-namespace Ionic.Zip
-{
-
- partial class ZipEntry
- {
- ///
- /// True if the referenced entry is a directory.
- ///
- internal bool AttributesIndicateDirectory
- {
- get { return ((_InternalFileAttrs == 0) && ((_ExternalFileAttrs & 0x0010) == 0x0010)); }
- }
-
-
- internal void ResetDirEntry()
- {
- // __FileDataPosition is the position of the file data for an entry.
- // It is _RelativeOffsetOfLocalHeader + size of local header.
-
- // We cannot know the __FileDataPosition until we read the local
- // header.
-
- // The local header is not necessarily the same length as the record
- // in the central directory.
-
- // Set to -1, to indicate we need to read this later.
- this.__FileDataPosition = -1;
-
- // set _LengthOfHeader to 0, to indicate we need to read later.
- this._LengthOfHeader = 0;
- }
-
- ///
- /// Provides a human-readable string with information about the ZipEntry.
- ///
- public string Info
- {
- get
- {
- var builder = new System.Text.StringBuilder();
- builder
- .Append(string.Format(" ZipEntry: {0}\n", this.FileName))
- .Append(string.Format(" Version Made By: {0}\n", this._VersionMadeBy))
- .Append(string.Format(" Needed to extract: {0}\n", this.VersionNeeded));
-
- if (this._IsDirectory)
- builder.Append(" Entry type: directory\n");
- else
- {
- builder.Append(string.Format(" File type: {0}\n", this._IsText? "text":"binary"))
- .Append(string.Format(" Compression: {0}\n", this.CompressionMethod))
- .Append(string.Format(" Compressed: 0x{0:X}\n", this.CompressedSize))
- .Append(string.Format(" Uncompressed: 0x{0:X}\n", this.UncompressedSize))
- .Append(string.Format(" CRC32: 0x{0:X8}\n", this._Crc32));
- }
- builder.Append(string.Format(" Disk Number: {0}\n", this._diskNumber));
- if (this._RelativeOffsetOfLocalHeader > 0xFFFFFFFF)
- builder
- .Append(string.Format(" Relative Offset: 0x{0:X16}\n", this._RelativeOffsetOfLocalHeader));
- else
- builder
- .Append(string.Format(" Relative Offset: 0x{0:X8}\n", this._RelativeOffsetOfLocalHeader));
-
- builder
- .Append(string.Format(" Bit Field: 0x{0:X4}\n", this._BitField))
- .Append(string.Format(" Encrypted?: {0}\n", this._sourceIsEncrypted))
- .Append(string.Format(" Timeblob: 0x{0:X8}\n", this._TimeBlob))
- .Append(string.Format(" Time: {0}\n", Ionic.Zip.SharedUtilities.PackedToDateTime(this._TimeBlob)));
-
- builder.Append(string.Format(" Is Zip64?: {0}\n", this._InputUsesZip64));
- if (!string.IsNullOrEmpty(this._Comment))
- {
- builder.Append(string.Format(" Comment: {0}\n", this._Comment));
- }
- builder.Append("\n");
- return builder.ToString();
- }
- }
-
-
- // workitem 10330
- private class CopyHelper
- {
- private static System.Text.RegularExpressions.Regex re =
- new System.Text.RegularExpressions.Regex(" \\(copy (\\d+)\\)$");
-
- private static int callCount = 0;
-
- internal static string AppendCopyToFileName(string f)
- {
- callCount++;
- if (callCount > 25)
- throw new OverflowException("overflow while creating filename");
-
- int n = 1;
- int r = f.LastIndexOf(".");
-
- if (r == -1)
- {
- // there is no extension
- System.Text.RegularExpressions.Match m = re.Match(f);
- if (m.Success)
- {
- n = Int32.Parse(m.Groups[1].Value) + 1;
- string copy = String.Format(" (copy {0})", n);
- f = f.Substring(0, m.Index) + copy;
- }
- else
- {
- string copy = String.Format(" (copy {0})", n);
- f = f + copy;
- }
- }
- else
- {
- //System.Console.WriteLine("HasExtension");
- System.Text.RegularExpressions.Match m = re.Match(f.Substring(0, r));
- if (m.Success)
- {
- n = Int32.Parse(m.Groups[1].Value) + 1;
- string copy = String.Format(" (copy {0})", n);
- f = f.Substring(0, m.Index) + copy + f.Substring(r);
- }
- else
- {
- string copy = String.Format(" (copy {0})", n);
- f = f.Substring(0, r) + copy + f.Substring(r);
- }
-
- //System.Console.WriteLine("returning f({0})", f);
- }
- return f;
- }
- }
-
-
-
- ///
- /// Reads one entry from the zip directory structure in the zip file.
- ///
- ///
- ///
- /// The zipfile for which a directory entry will be read. From this param, the
- /// method gets the ReadStream and the expected text encoding
- /// (ProvisionalAlternateEncoding) which is used if the entry is not marked
- /// UTF-8.
- ///
- ///
- ///
- /// a list of previously seen entry names; used to prevent duplicates.
- ///
- ///
- /// the entry read from the archive.
- internal static ZipEntry ReadDirEntry(ZipFile zf,
- Dictionary previouslySeen)
- {
- System.IO.Stream s = zf.ReadStream;
- System.Text.Encoding expectedEncoding = (zf.AlternateEncodingUsage == ZipOption.Always)
- ? zf.AlternateEncoding
- : ZipFile.DefaultEncoding;
-
- int signature = Ionic.Zip.SharedUtilities.ReadSignature(s);
- // return null if this is not a local file header signature
- if (IsNotValidZipDirEntrySig(signature))
- {
- s.Seek(-4, System.IO.SeekOrigin.Current);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
-
- // Getting "not a ZipDirEntry signature" here is not always wrong or an
- // error. This can happen when walking through a zipfile. After the
- // last ZipDirEntry, we expect to read an
- // EndOfCentralDirectorySignature. When we get this is how we know
- // we've reached the end of the central directory.
- if (signature != ZipConstants.EndOfCentralDirectorySignature &&
- signature != ZipConstants.Zip64EndOfCentralDirectoryRecordSignature &&
- signature != ZipConstants.ZipEntrySignature // workitem 8299
- )
- {
- throw new BadReadException(String.Format(" Bad signature (0x{0:X8}) at position 0x{1:X8}", signature, s.Position));
- }
- return null;
- }
-
- int bytesRead = 42 + 4;
- byte[] block = new byte[42];
- int n = s.Read(block, 0, block.Length);
- if (n != block.Length) return null;
-
- int i = 0;
- ZipEntry zde = new ZipEntry();
- zde.AlternateEncoding = expectedEncoding;
- zde._Source = ZipEntrySource.ZipFile;
- zde._container = new ZipContainer(zf);
-
- unchecked
- {
- zde._VersionMadeBy = (short)(block[i++] + block[i++] * 256);
- zde._VersionNeeded = (short)(block[i++] + block[i++] * 256);
- zde._BitField = (short)(block[i++] + block[i++] * 256);
- zde._CompressionMethod = (Int16)(block[i++] + block[i++] * 256);
- zde._TimeBlob = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256;
- zde._LastModified = Ionic.Zip.SharedUtilities.PackedToDateTime(zde._TimeBlob);
- zde._timestamp |= ZipEntryTimestamp.DOS;
-
- zde._Crc32 = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256;
- zde._CompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
- zde._UncompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
- }
-
- // preserve
- zde._CompressionMethod_FromZipFile = zde._CompressionMethod;
-
- zde._filenameLength = (short)(block[i++] + block[i++] * 256);
- zde._extraFieldLength = (short)(block[i++] + block[i++] * 256);
- zde._commentLength = (short)(block[i++] + block[i++] * 256);
- zde._diskNumber = (UInt32)(block[i++] + block[i++] * 256);
-
- zde._InternalFileAttrs = (short)(block[i++] + block[i++] * 256);
- zde._ExternalFileAttrs = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256;
-
- zde._RelativeOffsetOfLocalHeader = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-
- // workitem 7801
- zde.IsText = ((zde._InternalFileAttrs & 0x01) == 0x01);
-
- block = new byte[zde._filenameLength];
- n = s.Read(block, 0, block.Length);
- bytesRead += n;
- if ((zde._BitField & 0x0800) == 0x0800)
- {
- // UTF-8 is in use
- zde._FileNameInArchive = Ionic.Zip.SharedUtilities.Utf8StringFromBuffer(block);
- }
- else
- {
- zde._FileNameInArchive = Ionic.Zip.SharedUtilities.StringFromBuffer(block, expectedEncoding);
- }
-
- // workitem 10330
- // insure unique entry names
- while (previouslySeen.ContainsKey(zde._FileNameInArchive))
- {
- zde._FileNameInArchive = CopyHelper.AppendCopyToFileName(zde._FileNameInArchive);
- zde._metadataChanged = true;
- }
-
- if (zde.AttributesIndicateDirectory)
- zde.MarkAsDirectory(); // may append a slash to filename if nec.
- // workitem 6898
- else if (zde._FileNameInArchive.EndsWith("/")) zde.MarkAsDirectory();
-
- zde._CompressedFileDataSize = zde._CompressedSize;
- if ((zde._BitField & 0x01) == 0x01)
- {
- // this may change after processing the Extra field
- zde._Encryption_FromZipFile = zde._Encryption =
- EncryptionAlgorithm.PkzipWeak;
- zde._sourceIsEncrypted = true;
- }
-
- if (zde._extraFieldLength > 0)
- {
- zde._InputUsesZip64 = (zde._CompressedSize == 0xFFFFFFFF ||
- zde._UncompressedSize == 0xFFFFFFFF ||
- zde._RelativeOffsetOfLocalHeader == 0xFFFFFFFF);
-
- // Console.WriteLine(" Input uses Z64?: {0}", zde._InputUsesZip64);
-
- bytesRead += zde.ProcessExtraField(s, zde._extraFieldLength);
- zde._CompressedFileDataSize = zde._CompressedSize;
- }
-
- // we've processed the extra field, so we know the encryption method is set now.
- if (zde._Encryption == EncryptionAlgorithm.PkzipWeak)
- {
- // the "encryption header" of 12 bytes precedes the file data
- zde._CompressedFileDataSize -= 12;
- }
-#if AESCRYPTO
- else if (zde.Encryption == EncryptionAlgorithm.WinZipAes128 ||
- zde.Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- zde._CompressedFileDataSize = zde.CompressedSize -
- (ZipEntry.GetLengthOfCryptoHeaderBytes(zde.Encryption) + 10);
- zde._LengthOfTrailer = 10;
- }
-#endif
-
- // tally the trailing descriptor
- if ((zde._BitField & 0x0008) == 0x0008)
- {
- // sig, CRC, Comp and Uncomp sizes
- if (zde._InputUsesZip64)
- zde._LengthOfTrailer += 24;
- else
- zde._LengthOfTrailer += 16;
- }
-
- // workitem 12744
- zde.AlternateEncoding = ((zde._BitField & 0x0800) == 0x0800)
- ? System.Text.Encoding.UTF8
- :expectedEncoding;
-
- zde.AlternateEncodingUsage = ZipOption.Always;
-
- if (zde._commentLength > 0)
- {
- block = new byte[zde._commentLength];
- n = s.Read(block, 0, block.Length);
- bytesRead += n;
- if ((zde._BitField & 0x0800) == 0x0800)
- {
- // UTF-8 is in use
- zde._Comment = Ionic.Zip.SharedUtilities.Utf8StringFromBuffer(block);
- }
- else
- {
- zde._Comment = Ionic.Zip.SharedUtilities.StringFromBuffer(block, expectedEncoding);
- }
- }
- //zde._LengthOfDirEntry = bytesRead;
- return zde;
- }
-
-
- ///
- /// Returns true if the passed-in value is a valid signature for a ZipDirEntry.
- ///
- /// the candidate 4-byte signature value.
- /// true, if the signature is valid according to the PKWare spec.
- internal static bool IsNotValidZipDirEntrySig(int signature)
- {
- return (signature != ZipConstants.ZipDirEntrySignature);
- }
-
-
- private Int16 _VersionMadeBy;
- private Int16 _InternalFileAttrs;
- private Int32 _ExternalFileAttrs;
-
- //private Int32 _LengthOfDirEntry;
- private Int16 _filenameLength;
- private Int16 _extraFieldLength;
- private Int16 _commentLength;
- }
-
-
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.Extract.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.Extract.cs
deleted file mode 100644
index 17117db1..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.Extract.cs
+++ /dev/null
@@ -1,1456 +0,0 @@
-// ZipEntry.Extract.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 Dino Chiesa
-// 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: <2011-August-06 18:08:21>
-//
-// ------------------------------------------------------------------
-//
-// This module defines logic for Extract methods on the ZipEntry class.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-
-namespace Ionic.Zip
-{
-
- public partial class ZipEntry
- {
- ///
- /// Extract the entry to the filesystem, starting at the current
- /// working directory.
- ///
- ///
- ///
- /// This method has a bunch of overloads! One of them is sure to
- /// be the right one for you... If you don't like these, check
- /// out the ExtractWithPassword() methods.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// This method extracts an entry from a zip file into the current
- /// working directory. The path of the entry as extracted is the full
- /// path as specified in the zip archive, relative to the current
- /// working directory. After the file is extracted successfully, the
- /// file attributes and timestamps are set.
- ///
- ///
- ///
- /// The action taken when extraction an entry would overwrite an
- /// existing file is determined by the property.
- ///
- ///
- ///
- /// Within the call to Extract(), the content for the entry is
- /// written into a filesystem file, and then the last modified time of the
- /// file is set according to the property on
- /// the entry. See the remarks the property for
- /// some details about the last modified time.
- ///
- ///
- ///
- public void Extract()
- {
- InternalExtract(".", null, null);
- }
-
-
- ///
- /// Extract the entry to a file in the filesystem, using the specified
- /// behavior when extraction would overwrite an existing file.
- ///
- ///
- ///
- ///
- /// See the remarks on the property, for some
- /// details about how the last modified time of the file is set after
- /// extraction.
- ///
- ///
- ///
- ///
- /// The action to take if extraction would overwrite an existing file.
- ///
- public void Extract(ExtractExistingFileAction extractExistingFile)
- {
- ExtractExistingFile = extractExistingFile;
- InternalExtract(".", null, null);
- }
-
- ///
- /// Extracts the entry to the specified stream.
- ///
- ///
- ///
- ///
- /// The caller can specify any write-able stream, for example a , a , or ASP.NET's
- /// Response.OutputStream. The content will be decrypted and
- /// decompressed as necessary. If the entry is encrypted and no password
- /// is provided, this method will throw.
- ///
- ///
- /// The position on the stream is not reset by this method before it extracts.
- /// You may want to call stream.Seek() before calling ZipEntry.Extract().
- ///
- ///
- ///
- ///
- /// the stream to which the entry should be extracted.
- ///
- ///
- public void Extract(Stream stream)
- {
- InternalExtract(null, stream, null);
- }
-
- ///
- /// Extract the entry to the filesystem, starting at the specified base
- /// directory.
- ///
- ///
- /// the pathname of the base directory
- ///
- ///
- ///
- ///
- ///
- /// This example extracts only the entries in a zip file that are .txt files,
- /// into a directory called "textfiles".
- ///
- /// using (ZipFile zip = ZipFile.Read("PackedDocuments.zip"))
- /// {
- /// foreach (string s1 in zip.EntryFilenames)
- /// {
- /// if (s1.EndsWith(".txt"))
- /// {
- /// zip[s1].Extract("textfiles");
- /// }
- /// }
- /// }
- ///
- ///
- /// Using zip As ZipFile = ZipFile.Read("PackedDocuments.zip")
- /// Dim s1 As String
- /// For Each s1 In zip.EntryFilenames
- /// If s1.EndsWith(".txt") Then
- /// zip(s1).Extract("textfiles")
- /// End If
- /// Next
- /// End Using
- ///
- ///
- ///
- ///
- ///
- ///
- /// Using this method, existing entries in the filesystem will not be
- /// overwritten. If you would like to force the overwrite of existing
- /// files, see the property, or call
- /// .
- ///
- ///
- ///
- /// See the remarks on the property, for some
- /// details about how the last modified time of the created file is set.
- ///
- ///
- public void Extract(string baseDirectory)
- {
- InternalExtract(baseDirectory, null, null);
- }
-
-
-
-
-
- ///
- /// Extract the entry to the filesystem, starting at the specified base
- /// directory, and using the specified behavior when extraction would
- /// overwrite an existing file.
- ///
- ///
- ///
- ///
- /// See the remarks on the property, for some
- /// details about how the last modified time of the created file is set.
- ///
- ///
- ///
- ///
- ///
- /// String sZipPath = "Airborne.zip";
- /// String sFilePath = "Readme.txt";
- /// String sRootFolder = "Digado";
- /// using (ZipFile zip = ZipFile.Read(sZipPath))
- /// {
- /// if (zip.EntryFileNames.Contains(sFilePath))
- /// {
- /// // use the string indexer on the zip file
- /// zip[sFileName].Extract(sRootFolder,
- /// ExtractExistingFileAction.OverwriteSilently);
- /// }
- /// }
- ///
- ///
- ///
- /// Dim sZipPath as String = "Airborne.zip"
- /// Dim sFilePath As String = "Readme.txt"
- /// Dim sRootFolder As String = "Digado"
- /// Using zip As ZipFile = ZipFile.Read(sZipPath)
- /// If zip.EntryFileNames.Contains(sFilePath)
- /// ' use the string indexer on the zip file
- /// zip(sFilePath).Extract(sRootFolder, _
- /// ExtractExistingFileAction.OverwriteSilently)
- /// End If
- /// End Using
- ///
- ///
- ///
- /// the pathname of the base directory
- ///
- /// The action to take if extraction would overwrite an existing file.
- ///
- public void Extract(string baseDirectory, ExtractExistingFileAction extractExistingFile)
- {
- ExtractExistingFile = extractExistingFile;
- InternalExtract(baseDirectory, null, null);
- }
-
-
- ///
- /// Extract the entry to the filesystem, using the current working directory
- /// and the specified password.
- ///
- ///
- ///
- /// This method has a bunch of overloads! One of them is sure to be
- /// the right one for you...
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// Existing entries in the filesystem will not be overwritten. If you
- /// would like to force the overwrite of existing files, see the property, or call
- /// .
- ///
- ///
- ///
- /// See the remarks on the property for some
- /// details about how the "last modified" time of the created file is
- /// set.
- ///
- ///
- ///
- ///
- /// In this example, entries that use encryption are extracted using a
- /// particular password.
- ///
- /// using (var zip = ZipFile.Read(FilePath))
- /// {
- /// foreach (ZipEntry e in zip)
- /// {
- /// if (e.UsesEncryption)
- /// e.ExtractWithPassword("Secret!");
- /// else
- /// e.Extract();
- /// }
- /// }
- ///
- ///
- /// Using zip As ZipFile = ZipFile.Read(FilePath)
- /// Dim e As ZipEntry
- /// For Each e In zip
- /// If (e.UsesEncryption)
- /// e.ExtractWithPassword("Secret!")
- /// Else
- /// e.Extract
- /// End If
- /// Next
- /// End Using
- ///
- ///
- /// The Password to use for decrypting the entry.
- public void ExtractWithPassword(string password)
- {
- InternalExtract(".", null, password);
- }
-
- ///
- /// Extract the entry to the filesystem, starting at the specified base
- /// directory, and using the specified password.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// Existing entries in the filesystem will not be overwritten. If you
- /// would like to force the overwrite of existing files, see the property, or call
- /// .
- ///
- ///
- ///
- /// See the remarks on the property, for some
- /// details about how the last modified time of the created file is set.
- ///
- ///
- ///
- /// The pathname of the base directory.
- /// The Password to use for decrypting the entry.
- public void ExtractWithPassword(string baseDirectory, string password)
- {
- InternalExtract(baseDirectory, null, password);
- }
-
-
-
-
- ///
- /// Extract the entry to a file in the filesystem, relative to the
- /// current directory, using the specified behavior when extraction
- /// would overwrite an existing file.
- ///
- ///
- ///
- ///
- /// See the remarks on the property, for some
- /// details about how the last modified time of the created file is set.
- ///
- ///
- ///
- /// The Password to use for decrypting the entry.
- ///
- ///
- /// The action to take if extraction would overwrite an existing file.
- ///
- public void ExtractWithPassword(ExtractExistingFileAction extractExistingFile, string password)
- {
- ExtractExistingFile = extractExistingFile;
- InternalExtract(".", null, password);
- }
-
-
-
- ///
- /// Extract the entry to the filesystem, starting at the specified base
- /// directory, and using the specified behavior when extraction would
- /// overwrite an existing file.
- ///
- ///
- ///
- /// See the remarks on the property, for some
- /// details about how the last modified time of the created file is set.
- ///
- ///
- /// the pathname of the base directory
- ///
- /// The action to take if extraction would
- /// overwrite an existing file.
- ///
- /// The Password to use for decrypting the entry.
- public void ExtractWithPassword(string baseDirectory, ExtractExistingFileAction extractExistingFile, string password)
- {
- ExtractExistingFile = extractExistingFile;
- InternalExtract(baseDirectory, null, password);
- }
-
- ///
- /// Extracts the entry to the specified stream, using the specified
- /// Password. For example, the caller could extract to Console.Out, or
- /// to a MemoryStream.
- ///
- ///
- ///
- ///
- /// The caller can specify any write-able stream, for example a , a , or ASP.NET's
- /// Response.OutputStream. The content will be decrypted and
- /// decompressed as necessary. If the entry is encrypted and no password
- /// is provided, this method will throw.
- ///
- ///
- /// The position on the stream is not reset by this method before it extracts.
- /// You may want to call stream.Seek() before calling ZipEntry.Extract().
- ///
- ///
- ///
- ///
- ///
- /// the stream to which the entry should be extracted.
- ///
- ///
- /// The password to use for decrypting the entry.
- ///
- public void ExtractWithPassword(Stream stream, string password)
- {
- InternalExtract(null, stream, password);
- }
-
-
- ///
- /// Opens a readable stream corresponding to the zip entry in the
- /// archive. The stream decompresses and decrypts as necessary, as it
- /// is read.
- ///
- ///
- ///
- ///
- ///
- /// DotNetZip offers a variety of ways to extract entries from a zip
- /// file. This method allows an application to extract an entry by
- /// reading a .
- ///
- ///
- ///
- /// The return value is of type . Use it as you would any
- /// stream for reading. When an application calls on that stream, it will
- /// receive data from the zip entry that is decrypted and decompressed
- /// as necessary.
- ///
- ///
- ///
- /// CrcCalculatorStream adds one additional feature: it keeps a
- /// CRC32 checksum on the bytes of the stream as it is read. The CRC
- /// value is available in the property on the
- /// CrcCalculatorStream. When the read is complete, your
- /// application
- /// should check this CRC against the
- /// property on the ZipEntry to validate the content of the
- /// ZipEntry. You don't have to validate the entry using the CRC, but
- /// you should, to verify integrity. Check the example for how to do
- /// this.
- ///
- ///
- ///
- /// If the entry is protected with a password, then you need to provide
- /// a password prior to calling , either by
- /// setting the property on the entry, or the
- /// property on the ZipFile
- /// itself. Or, you can use , the
- /// overload of OpenReader that accepts a password parameter.
- ///
- ///
- ///
- /// If you want to extract entry data into a write-able stream that is
- /// already opened, like a , do not
- /// use this method. Instead, use .
- ///
- ///
- ///
- /// Your application may use only one stream created by OpenReader() at
- /// a time, and you should not call other Extract methods before
- /// completing your reads on a stream obtained from OpenReader(). This
- /// is because there is really only one source stream for the compressed
- /// content. A call to OpenReader() seeks in the source stream, to the
- /// beginning of the compressed content. A subsequent call to
- /// OpenReader() on a different entry will seek to a different position
- /// in the source stream, as will a call to Extract() or one of its
- /// overloads. This will corrupt the state for the decompressing stream
- /// from the original call to OpenReader().
- ///
- ///
- ///
- /// The OpenReader() method works only when the ZipEntry is
- /// obtained from an instance of ZipFile. This method will throw
- /// an exception if the ZipEntry is obtained from a .
- ///
- ///
- ///
- ///
- /// This example shows how to open a zip archive, then read in a named
- /// entry via a stream. After the read loop is complete, the code
- /// compares the calculated during the read loop with the expected CRC
- /// on the ZipEntry, to verify the extraction.
- ///
- /// using (ZipFile zip = new ZipFile(ZipFileToRead))
- /// {
- /// ZipEntry e1= zip["Elevation.mp3"];
- /// using (Ionic.Zlib.CrcCalculatorStream s = e1.OpenReader())
- /// {
- /// byte[] buffer = new byte[4096];
- /// int n, totalBytesRead= 0;
- /// do {
- /// n = s.Read(buffer,0, buffer.Length);
- /// totalBytesRead+=n;
- /// } while (n>0);
- /// if (s.Crc32 != e1.Crc32)
- /// throw new Exception(string.Format("The Zip Entry failed the CRC Check. (0x{0:X8}!=0x{1:X8})", s.Crc32, e1.Crc32));
- /// if (totalBytesRead != e1.UncompressedSize)
- /// throw new Exception(string.Format("We read an unexpected number of bytes. ({0}!={1})", totalBytesRead, e1.UncompressedSize));
- /// }
- /// }
- ///
- ///
- /// Using zip As New ZipFile(ZipFileToRead)
- /// Dim e1 As ZipEntry = zip.Item("Elevation.mp3")
- /// Using s As Ionic.Zlib.CrcCalculatorStream = e1.OpenReader
- /// Dim n As Integer
- /// Dim buffer As Byte() = New Byte(4096) {}
- /// Dim totalBytesRead As Integer = 0
- /// Do
- /// n = s.Read(buffer, 0, buffer.Length)
- /// totalBytesRead = (totalBytesRead + n)
- /// Loop While (n > 0)
- /// If (s.Crc32 <> e1.Crc32) Then
- /// Throw New Exception(String.Format("The Zip Entry failed the CRC Check. (0x{0:X8}!=0x{1:X8})", s.Crc32, e1.Crc32))
- /// End If
- /// If (totalBytesRead <> e1.UncompressedSize) Then
- /// Throw New Exception(String.Format("We read an unexpected number of bytes. ({0}!={1})", totalBytesRead, e1.UncompressedSize))
- /// End If
- /// End Using
- /// End Using
- ///
- ///
- ///
- /// The Stream for reading.
- public Ionic.Crc.CrcCalculatorStream OpenReader()
- {
- // workitem 10923
- if (_container.ZipFile == null)
- throw new InvalidOperationException("Use OpenReader() only with ZipFile.");
-
- // use the entry password if it is non-null,
- // else use the zipfile password, which is possibly null
- return InternalOpenReader(this._Password ?? this._container.Password);
- }
-
- ///
- /// Opens a readable stream for an encrypted zip entry in the archive.
- /// The stream decompresses and decrypts as necessary, as it is read.
- ///
- ///
- ///
- ///
- /// See the documentation on the method for
- /// full details. This overload allows the application to specify a
- /// password for the ZipEntry to be read.
- ///
- ///
- ///
- /// The password to use for decrypting the entry.
- /// The Stream for reading.
- public Ionic.Crc.CrcCalculatorStream OpenReader(string password)
- {
- // workitem 10923
- if (_container.ZipFile == null)
- throw new InvalidOperationException("Use OpenReader() only with ZipFile.");
-
- return InternalOpenReader(password);
- }
-
-
-
- internal Ionic.Crc.CrcCalculatorStream InternalOpenReader(string password)
- {
- ValidateCompression();
- ValidateEncryption();
- SetupCryptoForExtract(password);
-
- // workitem 7958
- if (this._Source != ZipEntrySource.ZipFile)
- throw new BadStateException("You must call ZipFile.Save before calling OpenReader");
-
- // LeftToRead is a count of bytes remaining to be read (out)
- // from the stream AFTER decompression and decryption.
- // It is the uncompressed size, unless ... there is no compression in which
- // case ...? :< I'm not sure why it's not always UncompressedSize
- Int64 LeftToRead = (_CompressionMethod_FromZipFile == (short)CompressionMethod.None)
- ? this._CompressedFileDataSize
- : this.UncompressedSize;
-
- Stream input = this.ArchiveStream;
-
- this.ArchiveStream.Seek(this.FileDataPosition, SeekOrigin.Begin);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-
- _inputDecryptorStream = GetExtractDecryptor(input);
- Stream input3 = GetExtractDecompressor(_inputDecryptorStream);
-
- return new Ionic.Crc.CrcCalculatorStream(input3, LeftToRead);
- }
-
-
-
- private void OnExtractProgress(Int64 bytesWritten, Int64 totalBytesToWrite)
- {
- if (_container.ZipFile != null)
- _ioOperationCanceled = _container.ZipFile.OnExtractBlock(this, bytesWritten, totalBytesToWrite);
- }
-
-
- private void OnBeforeExtract(string path)
- {
- // When in the context of a ZipFile.ExtractAll, the events are generated from
- // the ZipFile method, not from within the ZipEntry instance. (why?)
- // Therefore we suppress the events originating from the ZipEntry method.
- if (_container.ZipFile != null)
- {
- if (!_container.ZipFile._inExtractAll)
- {
- _ioOperationCanceled = _container.ZipFile.OnSingleEntryExtract(this, path, true);
- }
- }
- }
-
- private void OnAfterExtract(string path)
- {
- // When in the context of a ZipFile.ExtractAll, the events are generated from
- // the ZipFile method, not from within the ZipEntry instance. (why?)
- // Therefore we suppress the events originating from the ZipEntry method.
- if (_container.ZipFile != null)
- {
- if (!_container.ZipFile._inExtractAll)
- {
- _container.ZipFile.OnSingleEntryExtract(this, path, false);
- }
- }
- }
-
- private void OnExtractExisting(string path)
- {
- if (_container.ZipFile != null)
- _ioOperationCanceled = _container.ZipFile.OnExtractExisting(this, path);
- }
-
- private static void ReallyDelete(string fileName)
- {
- // workitem 7881
- // reset ReadOnly bit if necessary
-#if NETCF
- if ( (NetCfFile.GetAttributes(fileName) & (uint)FileAttributes.ReadOnly) == (uint)FileAttributes.ReadOnly)
- NetCfFile.SetAttributes(fileName, (uint)FileAttributes.Normal);
-#elif SILVERLIGHT
-#else
- if ((File.GetAttributes(fileName) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
- File.SetAttributes(fileName, FileAttributes.Normal);
-#endif
- File.Delete(fileName);
- }
-
-
- private void WriteStatus(string format, params Object[] args)
- {
- if (_container.ZipFile != null && _container.ZipFile.Verbose) _container.ZipFile.StatusMessageTextWriter.WriteLine(format, args);
- }
-
-
- // Pass in either basedir or s, but not both.
- // In other words, you can extract to a stream or to a directory (filesystem), but not both!
- // The Password param is required for encrypted entries.
- private void InternalExtract(string baseDir, Stream outstream, string password)
- {
- // workitem 7958
- if (_container == null)
- throw new BadStateException("This entry is an orphan");
-
- // workitem 10355
- if (_container.ZipFile == null)
- throw new InvalidOperationException("Use Extract() only with ZipFile.");
-
- _container.ZipFile.Reset(false);
-
- if (this._Source != ZipEntrySource.ZipFile)
- throw new BadStateException("You must call ZipFile.Save before calling any Extract method");
-
- OnBeforeExtract(baseDir);
- _ioOperationCanceled = false;
- string targetFileName = null;
- Stream output = null;
- bool fileExistsBeforeExtraction = false;
- bool checkLaterForResetDirTimes = false;
- try
- {
- ValidateCompression();
- ValidateEncryption();
-
- if (ValidateOutput(baseDir, outstream, out targetFileName))
- {
- WriteStatus("extract dir {0}...", targetFileName);
- // if true, then the entry was a directory and has been created.
- // We need to fire the Extract Event.
- OnAfterExtract(baseDir);
- return;
- }
-
- // workitem 10639
- // do we want to extract to a regular filesystem file?
- if (targetFileName != null)
- {
- // Check for extracting to a previously extant file. The user
- // can specify bejavior for that case: overwrite, don't
- // overwrite, and throw. Also, if the file exists prior to
- // extraction, it affects exception handling: whether to delete
- // the target of extraction or not. This check needs to be done
- // before the password check is done, because password check may
- // throw a BadPasswordException, which triggers the catch,
- // wherein the extant file may be deleted if not flagged as
- // pre-existing.
- if (File.Exists(targetFileName))
- {
- fileExistsBeforeExtraction = true;
- int rc = CheckExtractExistingFile(baseDir, targetFileName);
- if (rc == 2) goto ExitTry; // cancel
- if (rc == 1) return; // do not overwrite
- }
- }
-
- // If no password explicitly specified, use the password on the entry itself,
- // or on the zipfile itself.
- string p = password ?? this._Password ?? this._container.Password;
- if (_Encryption_FromZipFile != EncryptionAlgorithm.None)
- {
- if (p == null)
- throw new BadPasswordException();
- SetupCryptoForExtract(p);
- }
-
-
- // set up the output stream
- if (targetFileName != null)
- {
- WriteStatus("extract file {0}...", targetFileName);
- targetFileName += ".tmp";
- var dirName = Path.GetDirectoryName(targetFileName);
- // ensure the target path exists
- if (!Directory.Exists(dirName))
- {
- // we create the directory here, but we do not set the
- // create/modified/accessed times on it because it is being
- // created implicitly, not explcitly. There's no entry in the
- // zip archive for the directory.
- Directory.CreateDirectory(dirName);
- }
- else
- {
- // workitem 8264
- if (_container.ZipFile != null)
- checkLaterForResetDirTimes = _container.ZipFile._inExtractAll;
- }
-
- // File.Create(CreateNew) will overwrite any existing file.
- output = new FileStream(targetFileName, FileMode.CreateNew);
- }
- else
- {
- WriteStatus("extract entry {0} to stream...", FileName);
- output = outstream;
- }
-
-
- if (_ioOperationCanceled)
- goto ExitTry;
-
- Int32 ActualCrc32 = ExtractOne(output);
-
- if (_ioOperationCanceled)
- goto ExitTry;
-
- VerifyCrcAfterExtract(ActualCrc32);
-
- if (targetFileName != null)
- {
- output.Close();
- output = null;
-
- // workitem 10639
- // move file to permanent home
- string tmpName = targetFileName;
- string zombie = null;
- targetFileName = tmpName.Substring(0,tmpName.Length-4);
-
- if (fileExistsBeforeExtraction)
- {
- // An AV program may hold the target file open, which means
- // File.Delete() will succeed, though the actual deletion
- // remains pending. This will prevent a subsequent
- // File.Move() from succeeding. To avoid this, when the file
- // already exists, we need to replace it in 3 steps:
- //
- // 1. rename the existing file to a zombie name;
- // 2. rename the extracted file from the temp name to
- // the target file name;
- // 3. delete the zombie.
- //
- zombie = targetFileName + ".PendingOverwrite";
- File.Move(targetFileName, zombie);
- }
-
- File.Move(tmpName, targetFileName);
- _SetTimes(targetFileName, true);
-
- if (zombie != null && File.Exists(zombie))
- ReallyDelete(zombie);
-
- // workitem 8264
- if (checkLaterForResetDirTimes)
- {
- // This is sort of a hack. What I do here is set the time on
- // the parent directory, every time a file is extracted into
- // it. If there is a directory with 1000 files, then I set
- // the time on the dir, 1000 times. This allows the directory
- // to have times that reflect the actual time on the entry in
- // the zip archive.
-
- // String.Contains is not available on .NET CF 2.0
- if (this.FileName.IndexOf('/') != -1)
- {
- string dirname = Path.GetDirectoryName(this.FileName);
- if (this._container.ZipFile[dirname] == null)
- {
- _SetTimes(Path.GetDirectoryName(targetFileName), false);
- }
- }
- }
-
-#if NETCF
- // workitem 7926 - version made by OS can be zero or 10
- if ((_VersionMadeBy & 0xFF00) == 0x0a00 || (_VersionMadeBy & 0xFF00) == 0x0000)
- NetCfFile.SetAttributes(targetFileName, (uint)_ExternalFileAttrs);
-
-#else
- // workitem 7071
- //
- // We can only apply attributes if they are relevant to the NTFS
- // OS. Must do this LAST because it may involve a ReadOnly bit,
- // which would prevent us from setting the time, etc.
- //
- // workitem 7926 - version made by OS can be zero (FAT) or 10
- // (NTFS)
- if ((_VersionMadeBy & 0xFF00) == 0x0a00 || (_VersionMadeBy & 0xFF00) == 0x0000)
- File.SetAttributes(targetFileName, (FileAttributes)_ExternalFileAttrs);
-#endif
- }
-
- OnAfterExtract(baseDir);
-
- ExitTry: ;
- }
- catch (Exception)
- {
- _ioOperationCanceled = true;
- throw;
- }
- finally
- {
- if (_ioOperationCanceled)
- {
- if (targetFileName != null)
- {
- try
- {
- if (output != null) output.Close();
- // An exception has occurred. If the file exists, check
- // to see if it existed before we tried extracting. If
- // it did not, attempt to remove the target file. There
- // is a small possibility that the existing file has
- // been extracted successfully, overwriting a previously
- // existing file, and an exception was thrown after that
- // but before final completion (setting times, etc). In
- // that case the file will remain, even though some
- // error occurred. Nothing to be done about it.
- if (File.Exists(targetFileName) && !fileExistsBeforeExtraction)
- File.Delete(targetFileName);
-
- }
- finally { }
- }
- }
- }
- }
-
-
-#if NOT
- internal void CalcWinZipAesMac(Stream input)
- {
- if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
- Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- if (input is WinZipAesCipherStream)
- wzs = input as WinZipAesCipherStream;
-
- else if (input is Ionic.Zlib.CrcCalculatorStream)
- {
- xxx;
- }
-
- }
- }
-#endif
-
-
- internal void VerifyCrcAfterExtract(Int32 actualCrc32)
- {
-
-#if AESCRYPTO
- // After extracting, Validate the CRC32
- if (actualCrc32 != _Crc32)
- {
- // CRC is not meaningful with WinZipAES and AES method 2 (AE-2)
- if ((Encryption != EncryptionAlgorithm.WinZipAes128 &&
- Encryption != EncryptionAlgorithm.WinZipAes256)
- || _WinZipAesMethod != 0x02)
- throw new BadCrcException("CRC error: the file being extracted appears to be corrupted. " +
- String.Format("Expected 0x{0:X8}, Actual 0x{1:X8}", _Crc32, actualCrc32));
- }
-
- // ignore MAC if the size of the file is zero
- if (this.UncompressedSize == 0)
- return;
-
- // calculate the MAC
- if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
- Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- WinZipAesCipherStream wzs = _inputDecryptorStream as WinZipAesCipherStream;
- _aesCrypto_forExtract.CalculatedMac = wzs.FinalAuthentication;
-
- _aesCrypto_forExtract.ReadAndVerifyMac(this.ArchiveStream); // throws if MAC is bad
- // side effect: advances file position.
- }
-
-
-
-
-#else
- if (actualCrc32 != _Crc32)
- throw new BadCrcException("CRC error: the file being extracted appears to be corrupted. " +
- String.Format("Expected 0x{0:X8}, Actual 0x{1:X8}", _Crc32, actualCrc32));
-#endif
- }
-
-
-
-
- private int CheckExtractExistingFile(string baseDir, string targetFileName)
- {
- int loop = 0;
- // returns: 0 == extract, 1 = don't, 2 = cancel
- do
- {
- switch (ExtractExistingFile)
- {
- case ExtractExistingFileAction.OverwriteSilently:
- WriteStatus("the file {0} exists; will overwrite it...", targetFileName);
- return 0;
-
- case ExtractExistingFileAction.DoNotOverwrite:
- WriteStatus("the file {0} exists; not extracting entry...", FileName);
- OnAfterExtract(baseDir);
- return 1;
-
- case ExtractExistingFileAction.InvokeExtractProgressEvent:
- if (loop>0)
- throw new ZipException(String.Format("The file {0} already exists.", targetFileName));
- OnExtractExisting(baseDir);
- if (_ioOperationCanceled)
- return 2;
-
- // loop around
- break;
-
- case ExtractExistingFileAction.Throw:
- default:
- throw new ZipException(String.Format("The file {0} already exists.", targetFileName));
- }
- loop++;
- }
- while (true);
- }
-
-
-
-
- private void _CheckRead(int nbytes)
- {
- if (nbytes == 0)
- throw new BadReadException(String.Format("bad read of entry {0} from compressed archive.",
- this.FileName));
- }
-
-
- private Stream _inputDecryptorStream;
-
- private Int32 ExtractOne(Stream output)
- {
- Int32 CrcResult = 0;
- Stream input = this.ArchiveStream;
-
- try
- {
- // change for workitem 8098
- input.Seek(this.FileDataPosition, SeekOrigin.Begin);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(input);
-
- byte[] bytes = new byte[BufferSize];
-
- // The extraction process varies depending on how the entry was
- // stored. It could have been encrypted, and it coould have
- // been compressed, or both, or neither. So we need to check
- // both the encryption flag and the compression flag, and take
- // the proper action in all cases.
-
- Int64 LeftToRead = (_CompressionMethod_FromZipFile != (short)CompressionMethod.None)
- ? this.UncompressedSize
- : this._CompressedFileDataSize;
-
- // Get a stream that either decrypts or not.
- _inputDecryptorStream = GetExtractDecryptor(input);
-
- Stream input3 = GetExtractDecompressor( _inputDecryptorStream );
-
- Int64 bytesWritten = 0;
- // As we read, we maybe decrypt, and then we maybe decompress. Then we write.
- using (var s1 = new Ionic.Crc.CrcCalculatorStream(input3))
- {
- while (LeftToRead > 0)
- {
- //Console.WriteLine("ExtractOne: LeftToRead {0}", LeftToRead);
-
- // Casting LeftToRead down to an int is ok here in the else clause,
- // because that only happens when it is less than bytes.Length,
- // which is much less than MAX_INT.
- int len = (LeftToRead > bytes.Length) ? bytes.Length : (int)LeftToRead;
- int n = s1.Read(bytes, 0, len);
-
- // must check data read - essential for detecting corrupt zip files
- _CheckRead(n);
-
- output.Write(bytes, 0, n);
- LeftToRead -= n;
- bytesWritten += n;
-
- // fire the progress event, check for cancels
- OnExtractProgress(bytesWritten, UncompressedSize);
- if (_ioOperationCanceled)
- {
- break;
- }
- }
-
- CrcResult = s1.Crc;
- }
- }
- finally
- {
- var zss = input as ZipSegmentedStream;
- if (zss != null)
- {
-#if NETCF
- zss.Close();
-#else
- // need to dispose it
- zss.Dispose();
-#endif
- _archiveStream = null;
- }
- }
-
- return CrcResult;
- }
-
-
-
- internal Stream GetExtractDecompressor(Stream input2)
- {
- // get a stream that either decompresses or not.
- switch (_CompressionMethod_FromZipFile)
- {
- case (short)CompressionMethod.None:
- return input2;
- case (short)CompressionMethod.Deflate:
- return new Ionic.Zlib.DeflateStream(input2, Ionic.Zlib.CompressionMode.Decompress, true);
-#if BZIP
- case (short)CompressionMethod.BZip2:
- return new Ionic.BZip2.BZip2InputStream(input2, true);
-#endif
- }
-
- return null;
- }
-
-
-
- internal Stream GetExtractDecryptor(Stream input)
- {
- Stream input2 = null;
- if (_Encryption_FromZipFile == EncryptionAlgorithm.PkzipWeak)
- input2 = new ZipCipherStream(input, _zipCrypto_forExtract, CryptoMode.Decrypt);
-
-#if AESCRYPTO
- else if (_Encryption_FromZipFile == EncryptionAlgorithm.WinZipAes128 ||
- _Encryption_FromZipFile == EncryptionAlgorithm.WinZipAes256)
- input2 = new WinZipAesCipherStream(input, _aesCrypto_forExtract, _CompressedFileDataSize, CryptoMode.Decrypt);
-#endif
-
- else
- input2 = input;
-
- return input2;
- }
-
-
-
-
- internal void _SetTimes(string fileOrDirectory, bool isFile)
- {
-#if SILVERLIGHT
- // punt on setting file times
-#else
- // workitem 8807:
- // Because setting the time is not considered to be a fatal error,
- // and because other applications can interfere with the setting
- // of a time on a directory, we're going to swallow IO exceptions
- // in this method.
-
- try
- {
- if (_ntfsTimesAreSet)
- {
-#if NETCF
- // workitem 7944: set time should not be a fatal error on CF
- int rc = NetCfFile.SetTimes(fileOrDirectory, _Ctime, _Atime, _Mtime);
- if ( rc != 0)
- {
- WriteStatus("Warning: SetTimes failed. entry({0}) file({1}) rc({2})",
- FileName, fileOrDirectory, rc);
- }
-#else
- if (isFile)
- {
- // It's possible that the extract was cancelled, in which case,
- // the file does not exist.
- if (File.Exists(fileOrDirectory))
- {
- File.SetCreationTimeUtc(fileOrDirectory, _Ctime);
- File.SetLastAccessTimeUtc(fileOrDirectory, _Atime);
- File.SetLastWriteTimeUtc(fileOrDirectory, _Mtime);
- }
- }
- else
- {
- // It's possible that the extract was cancelled, in which case,
- // the directory does not exist.
- if (Directory.Exists(fileOrDirectory))
- {
- Directory.SetCreationTimeUtc(fileOrDirectory, _Ctime);
- Directory.SetLastAccessTimeUtc(fileOrDirectory, _Atime);
- Directory.SetLastWriteTimeUtc(fileOrDirectory, _Mtime);
- }
- }
-#endif
- }
- else
- {
- // workitem 6191
- DateTime AdjustedLastModified = Ionic.Zip.SharedUtilities.AdjustTime_Reverse(LastModified);
-
-#if NETCF
- int rc = NetCfFile.SetLastWriteTime(fileOrDirectory, AdjustedLastModified);
-
- if ( rc != 0)
- {
- WriteStatus("Warning: SetLastWriteTime failed. entry({0}) file({1}) rc({2})",
- FileName, fileOrDirectory, rc);
- }
-#else
- if (isFile)
- File.SetLastWriteTime(fileOrDirectory, AdjustedLastModified);
- else
- Directory.SetLastWriteTime(fileOrDirectory, AdjustedLastModified);
-#endif
- }
- }
- catch (System.IO.IOException ioexc1)
- {
- WriteStatus("failed to set time on {0}: {1}", fileOrDirectory, ioexc1.Message);
- }
-#endif
- }
-
-
- #region Support methods
-
-
- // workitem 7968
- private string UnsupportedAlgorithm
- {
- get
- {
- string alg = String.Empty;
- switch (_UnsupportedAlgorithmId)
- {
- case 0:
- alg = "--";
- break;
- case 0x6601:
- alg = "DES";
- break;
- case 0x6602: // - RC2 (version needed to extract < 5.2)
- alg = "RC2";
- break;
- case 0x6603: // - 3DES 168
- alg = "3DES-168";
- break;
- case 0x6609: // - 3DES 112
- alg = "3DES-112";
- break;
- case 0x660E: // - AES 128
- alg = "PKWare AES128";
- break;
- case 0x660F: // - AES 192
- alg = "PKWare AES192";
- break;
- case 0x6610: // - AES 256
- alg = "PKWare AES256";
- break;
- case 0x6702: // - RC2 (version needed to extract >= 5.2)
- alg = "RC2";
- break;
- case 0x6720: // - Blowfish
- alg = "Blowfish";
- break;
- case 0x6721: // - Twofish
- alg = "Twofish";
- break;
- case 0x6801: // - RC4
- alg = "RC4";
- break;
- case 0xFFFF: // - Unknown algorithm
- default:
- alg = String.Format("Unknown (0x{0:X4})", _UnsupportedAlgorithmId);
- break;
- }
- return alg;
- }
- }
-
- // workitem 7968
- private string UnsupportedCompressionMethod
- {
- get
- {
- string meth = String.Empty;
- switch ((int)_CompressionMethod)
- {
- case 0:
- meth = "Store";
- break;
- case 1:
- meth = "Shrink";
- break;
- case 8:
- meth = "DEFLATE";
- break;
- case 9:
- meth = "Deflate64";
- break;
- case 12:
- meth = "BZIP2"; // only if BZIP not compiled in
- break;
- case 14:
- meth = "LZMA";
- break;
- case 19:
- meth = "LZ77";
- break;
- case 98:
- meth = "PPMd";
- break;
- default:
- meth = String.Format("Unknown (0x{0:X4})", _CompressionMethod);
- break;
- }
- return meth;
- }
- }
-
-
- internal void ValidateEncryption()
- {
- if (Encryption != EncryptionAlgorithm.PkzipWeak &&
-#if AESCRYPTO
- Encryption != EncryptionAlgorithm.WinZipAes128 &&
- Encryption != EncryptionAlgorithm.WinZipAes256 &&
-#endif
- Encryption != EncryptionAlgorithm.None)
- {
- // workitem 7968
- if (_UnsupportedAlgorithmId != 0)
- throw new ZipException(String.Format("Cannot extract: Entry {0} is encrypted with an algorithm not supported by DotNetZip: {1}",
- FileName, UnsupportedAlgorithm));
- else
- throw new ZipException(String.Format("Cannot extract: Entry {0} uses an unsupported encryption algorithm ({1:X2})",
- FileName, (int)Encryption));
- }
- }
-
-
- private void ValidateCompression()
- {
- if ((_CompressionMethod_FromZipFile != (short)CompressionMethod.None) &&
- (_CompressionMethod_FromZipFile != (short)CompressionMethod.Deflate)
-#if BZIP
- && (_CompressionMethod_FromZipFile != (short)CompressionMethod.BZip2)
-#endif
- )
- throw new ZipException(String.Format("Entry {0} uses an unsupported compression method (0x{1:X2}, {2})",
- FileName, _CompressionMethod_FromZipFile, UnsupportedCompressionMethod));
- }
-
-
- private void SetupCryptoForExtract(string password)
- {
- //if (password == null) return;
- if (_Encryption_FromZipFile == EncryptionAlgorithm.None) return;
-
- if (_Encryption_FromZipFile == EncryptionAlgorithm.PkzipWeak)
- {
- if (password == null)
- throw new ZipException("Missing password.");
-
- this.ArchiveStream.Seek(this.FileDataPosition - 12, SeekOrigin.Begin);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
- _zipCrypto_forExtract = ZipCrypto.ForRead(password, this);
- }
-
-#if AESCRYPTO
- else if (_Encryption_FromZipFile == EncryptionAlgorithm.WinZipAes128 ||
- _Encryption_FromZipFile == EncryptionAlgorithm.WinZipAes256)
- {
- if (password == null)
- throw new ZipException("Missing password.");
-
- // If we already have a WinZipAesCrypto object in place, use it.
- // It can be set up in the ReadDirEntry(), or during a previous Extract.
- if (_aesCrypto_forExtract != null)
- {
- _aesCrypto_forExtract.Password = password;
- }
- else
- {
- int sizeOfSaltAndPv = GetLengthOfCryptoHeaderBytes(_Encryption_FromZipFile);
- this.ArchiveStream.Seek(this.FileDataPosition - sizeOfSaltAndPv, SeekOrigin.Begin);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
- int keystrength = GetKeyStrengthInBits(_Encryption_FromZipFile);
- _aesCrypto_forExtract = WinZipAesCrypto.ReadFromStream(password, keystrength, this.ArchiveStream);
- }
- }
-#endif
- }
-
-
-
- ///
- /// Validates that the args are consistent.
- ///
- ///
- /// Only one of {baseDir, outStream} can be non-null.
- /// If baseDir is non-null, then the outputFile is created.
- ///
- private bool ValidateOutput(string basedir, Stream outstream, out string outFileName)
- {
- if (basedir != null)
- {
- // Sometimes the name on the entry starts with a slash.
- // Rather than unpack to the root of the volume, we're going to
- // drop the slash and unpack to the specified base directory.
- string f = this.FileName.Replace("\\","/");
-
- // workitem 11772: remove drive letter with separator
- if (f.IndexOf(':') == 1)
- f= f.Substring(2);
-
- if (f.StartsWith("/"))
- f= f.Substring(1);
-
- // String.Contains is not available on .NET CF 2.0
-
- if (_container.ZipFile.FlattenFoldersOnExtract)
- outFileName = Path.Combine(basedir,
- (f.IndexOf('/') != -1) ? Path.GetFileName(f) : f);
- else
- outFileName = Path.Combine(basedir, f);
-
- // workitem 10639
- outFileName = outFileName.Replace("/","\\");
-
- // check if it is a directory
- if ((IsDirectory) || (FileName.EndsWith("/")))
- {
- if (!Directory.Exists(outFileName))
- {
- Directory.CreateDirectory(outFileName);
- _SetTimes(outFileName, false);
- }
- else
- {
- // the dir exists, maybe we want to overwrite times.
- if (ExtractExistingFile == ExtractExistingFileAction.OverwriteSilently)
- _SetTimes(outFileName, false);
- }
- return true; // true == all done, caller will return
- }
- return false; // false == work to do by caller.
- }
-
- if (outstream != null)
- {
- outFileName = null;
- if ((IsDirectory) || (FileName.EndsWith("/")))
- {
- // extract a directory to streamwriter? nothing to do!
- return true; // true == all done! caller can return
- }
- return false;
- }
-
- throw new ArgumentNullException("outstream");
- }
-
-
- #endregion
-
- }
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.Read.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.Read.cs
deleted file mode 100644
index 7a53356d..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.Read.cs
+++ /dev/null
@@ -1,798 +0,0 @@
-// ZipEntry.Read.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 Dino Chiesa
-// 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: <2011-July-09 21:31:28>
-//
-// ------------------------------------------------------------------
-//
-// This module defines logic for Reading the ZipEntry from a
-// zip file.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-
-namespace Ionic.Zip
-{
- public partial class ZipEntry
- {
- private int _readExtraDepth;
- private void ReadExtraField()
- {
- _readExtraDepth++;
- // workitem 8098: ok (restore)
- long posn = this.ArchiveStream.Position;
- this.ArchiveStream.Seek(this._RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-
- byte[] block = new byte[30];
- this.ArchiveStream.Read(block, 0, block.Length);
- int i = 26;
- Int16 filenameLength = (short)(block[i++] + block[i++] * 256);
- Int16 extraFieldLength = (short)(block[i++] + block[i++] * 256);
-
- // workitem 8098: ok (relative)
- this.ArchiveStream.Seek(filenameLength, SeekOrigin.Current);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-
- ProcessExtraField(this.ArchiveStream, extraFieldLength);
-
- // workitem 8098: ok (restore)
- this.ArchiveStream.Seek(posn, SeekOrigin.Begin);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
- _readExtraDepth--;
- }
-
-
- private static bool ReadHeader(ZipEntry ze, System.Text.Encoding defaultEncoding)
- {
- int bytesRead = 0;
-
- // change for workitem 8098
- ze._RelativeOffsetOfLocalHeader = ze.ArchiveStream.Position;
-
- int signature = Ionic.Zip.SharedUtilities.ReadEntrySignature(ze.ArchiveStream);
- bytesRead += 4;
-
- // Return false if this is not a local file header signature.
- if (ZipEntry.IsNotValidSig(signature))
- {
- // Getting "not a ZipEntry signature" is not always wrong or an error.
- // This will happen after the last entry in a zipfile. In that case, we
- // expect to read :
- // a ZipDirEntry signature (if a non-empty zip file) or
- // a ZipConstants.EndOfCentralDirectorySignature.
- //
- // Anything else is a surprise.
-
- ze.ArchiveStream.Seek(-4, SeekOrigin.Current); // unread the signature
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(ze.ArchiveStream);
- if (ZipEntry.IsNotValidZipDirEntrySig(signature) && (signature != ZipConstants.EndOfCentralDirectorySignature))
- {
- throw new BadReadException(String.Format(" Bad signature (0x{0:X8}) at position 0x{1:X8}", signature, ze.ArchiveStream.Position));
- }
- return false;
- }
-
- byte[] block = new byte[26];
- int n = ze.ArchiveStream.Read(block, 0, block.Length);
- if (n != block.Length) return false;
- bytesRead += n;
-
- int i = 0;
- ze._VersionNeeded = (Int16)(block[i++] + block[i++] * 256);
- ze._BitField = (Int16)(block[i++] + block[i++] * 256);
- ze._CompressionMethod_FromZipFile = ze._CompressionMethod = (Int16)(block[i++] + block[i++] * 256);
- ze._TimeBlob = block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256;
- // transform the time data into something usable (a DateTime)
- ze._LastModified = Ionic.Zip.SharedUtilities.PackedToDateTime(ze._TimeBlob);
- ze._timestamp |= ZipEntryTimestamp.DOS;
-
- if ((ze._BitField & 0x01) == 0x01)
- {
- ze._Encryption_FromZipFile = ze._Encryption = EncryptionAlgorithm.PkzipWeak; // this *may* change after processing the Extra field
- ze._sourceIsEncrypted = true;
- }
-
- // NB: if ((ze._BitField & 0x0008) != 0x0008), then the Compressed, uncompressed and
- // CRC values are not true values; the true values will follow the entry data.
- // But, regardless of the status of bit 3 in the bitfield, the slots for
- // the three amigos may contain marker values for ZIP64. So we must read them.
- {
- ze._Crc32 = (Int32)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
- ze._CompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
- ze._UncompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-
- if ((uint)ze._CompressedSize == 0xFFFFFFFF ||
- (uint)ze._UncompressedSize == 0xFFFFFFFF)
-
- ze._InputUsesZip64 = true;
- }
-
- Int16 filenameLength = (short)(block[i++] + block[i++] * 256);
- Int16 extraFieldLength = (short)(block[i++] + block[i++] * 256);
-
- block = new byte[filenameLength];
- n = ze.ArchiveStream.Read(block, 0, block.Length);
- bytesRead += n;
-
- // if the UTF8 bit is set for this entry, override the
- // encoding the application requested.
-
- if ((ze._BitField & 0x0800) == 0x0800)
- {
- // workitem 12744
- ze.AlternateEncoding = System.Text.Encoding.UTF8;
- ze.AlternateEncodingUsage = ZipOption.Always;
- }
-
- // need to use this form of GetString() for .NET CF
- ze._FileNameInArchive = ze.AlternateEncoding.GetString(block, 0, block.Length);
-
- // workitem 6898
- if (ze._FileNameInArchive.EndsWith("/")) ze.MarkAsDirectory();
-
- bytesRead += ze.ProcessExtraField(ze.ArchiveStream, extraFieldLength);
-
- ze._LengthOfTrailer = 0;
-
- // workitem 6607 - don't read for directories
- // actually get the compressed size and CRC if necessary
- if (!ze._FileNameInArchive.EndsWith("/") && (ze._BitField & 0x0008) == 0x0008)
- {
- // This descriptor exists only if bit 3 of the general
- // purpose bit flag is set (see below). It is byte aligned
- // and immediately follows the last byte of compressed data,
- // as well as any encryption trailer, as with AES.
- // This descriptor is used only when it was not possible to
- // seek in the output .ZIP file, e.g., when the output .ZIP file
- // was standard output or a non-seekable device. For ZIP64(tm) format
- // archives, the compressed and uncompressed sizes are 8 bytes each.
-
- // workitem 8098: ok (restore)
- long posn = ze.ArchiveStream.Position;
-
- // Here, we're going to loop until we find a ZipEntryDataDescriptorSignature and
- // a consistent data record after that. To be consistent, the data record must
- // indicate the length of the entry data.
- bool wantMore = true;
- long SizeOfDataRead = 0;
- int tries = 0;
- while (wantMore)
- {
- tries++;
- // We call the FindSignature shared routine to find the specified signature
- // in the already-opened zip archive, starting from the current cursor
- // position in that filestream. If we cannot find the signature, then the
- // routine returns -1, and the ReadHeader() method returns false,
- // indicating we cannot read a legal entry header. If we have found it,
- // then the FindSignature() method returns the number of bytes in the
- // stream we had to seek forward, to find the sig. We need this to
- // determine if the zip entry is valid, later.
-
- if (ze._container.ZipFile != null)
- ze._container.ZipFile.OnReadBytes(ze);
-
- long d = Ionic.Zip.SharedUtilities.FindSignature(ze.ArchiveStream, ZipConstants.ZipEntryDataDescriptorSignature);
- if (d == -1) return false;
-
- // total size of data read (through all loops of this).
- SizeOfDataRead += d;
-
- if (ze._InputUsesZip64)
- {
- // read 1x 4-byte (CRC) and 2x 8-bytes (Compressed Size, Uncompressed Size)
- block = new byte[20];
- n = ze.ArchiveStream.Read(block, 0, block.Length);
- if (n != 20) return false;
-
- // do not increment bytesRead - it is for entry header only.
- // the data we have just read is a footer (falls after the file data)
- //bytesRead += n;
-
- i = 0;
- ze._Crc32 = (Int32)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
- ze._CompressedSize = BitConverter.ToInt64(block, i);
- i += 8;
- ze._UncompressedSize = BitConverter.ToInt64(block, i);
- i += 8;
-
- ze._LengthOfTrailer += 24; // bytes including sig, CRC, Comp and Uncomp sizes
- }
- else
- {
- // read 3x 4-byte fields (CRC, Compressed Size, Uncompressed Size)
- block = new byte[12];
- n = ze.ArchiveStream.Read(block, 0, block.Length);
- if (n != 12) return false;
-
- // do not increment bytesRead - it is for entry header only.
- // the data we have just read is a footer (falls after the file data)
- //bytesRead += n;
-
- i = 0;
- ze._Crc32 = (Int32)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
- ze._CompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
- ze._UncompressedSize = (uint)(block[i++] + block[i++] * 256 + block[i++] * 256 * 256 + block[i++] * 256 * 256 * 256);
-
- ze._LengthOfTrailer += 16; // bytes including sig, CRC, Comp and Uncomp sizes
-
- }
-
- wantMore = (SizeOfDataRead != ze._CompressedSize);
-
- if (wantMore)
- {
- // Seek back to un-read the last 12 bytes - maybe THEY contain
- // the ZipEntryDataDescriptorSignature.
- // (12 bytes for the CRC, Comp and Uncomp size.)
- ze.ArchiveStream.Seek(-12, SeekOrigin.Current);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(ze.ArchiveStream);
-
- // Adjust the size to account for the false signature read in
- // FindSignature().
- SizeOfDataRead += 4;
- }
- }
-
- // seek back to previous position, to prepare to read file data
- // workitem 8098: ok (restore)
- ze.ArchiveStream.Seek(posn, SeekOrigin.Begin);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(ze.ArchiveStream);
- }
-
- ze._CompressedFileDataSize = ze._CompressedSize;
-
-
- // bit 0 set indicates that some kind of encryption is in use
- if ((ze._BitField & 0x01) == 0x01)
- {
-#if AESCRYPTO
- if (ze.Encryption == EncryptionAlgorithm.WinZipAes128 ||
- ze.Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- int bits = ZipEntry.GetKeyStrengthInBits(ze._Encryption_FromZipFile);
- // read in the WinZip AES metadata: salt + PV. 18 bytes for AES256. 10 bytes for AES128.
- ze._aesCrypto_forExtract = WinZipAesCrypto.ReadFromStream(null, bits, ze.ArchiveStream);
- bytesRead += ze._aesCrypto_forExtract.SizeOfEncryptionMetadata - 10; // MAC (follows crypto bytes)
- // according to WinZip, the CompressedSize includes the AES Crypto framing data.
- ze._CompressedFileDataSize -= ze._aesCrypto_forExtract.SizeOfEncryptionMetadata;
- ze._LengthOfTrailer += 10; // MAC
- }
- else
-#endif
- {
- // read in the header data for "weak" encryption
- ze._WeakEncryptionHeader = new byte[12];
- bytesRead += ZipEntry.ReadWeakEncryptionHeader(ze._archiveStream, ze._WeakEncryptionHeader);
- // decrease the filedata size by 12 bytes
- ze._CompressedFileDataSize -= 12;
- }
- }
-
- // Remember the size of the blob for this entry.
- // We also have the starting position in the stream for this entry.
- ze._LengthOfHeader = bytesRead;
- ze._TotalEntrySize = ze._LengthOfHeader + ze._CompressedFileDataSize + ze._LengthOfTrailer;
-
-
- // We've read in the regular entry header, the extra field, and any
- // encryption header. The pointer in the file is now at the start of the
- // filedata, which is potentially compressed and encrypted. Just ahead in
- // the file, there are _CompressedFileDataSize bytes of data, followed by
- // potentially a non-zero length trailer, consisting of optionally, some
- // encryption stuff (10 byte MAC for AES), and the bit-3 trailer (16 or 24
- // bytes).
-
- return true;
- }
-
-
-
- internal static int ReadWeakEncryptionHeader(Stream s, byte[] buffer)
- {
- // PKZIP encrypts the compressed data stream. Encrypted files must
- // be decrypted before they can be extracted.
-
- // Each PKZIP-encrypted file has an extra 12 bytes stored at the start of the data
- // area defining the encryption header for that file. The encryption header is
- // originally set to random values, and then itself encrypted, using three, 32-bit
- // keys. The key values are initialized using the supplied encryption password.
- // After each byte is encrypted, the keys are then updated using pseudo-random
- // number generation techniques in combination with the same CRC-32 algorithm used
- // in PKZIP and implemented in the CRC32.cs module in this project.
-
- // read the 12-byte encryption header
- int additionalBytesRead = s.Read(buffer, 0, 12);
- if (additionalBytesRead != 12)
- throw new ZipException(String.Format("Unexpected end of data at position 0x{0:X8}", s.Position));
-
- return additionalBytesRead;
- }
-
-
-
- private static bool IsNotValidSig(int signature)
- {
- return (signature != ZipConstants.ZipEntrySignature);
- }
-
-
- ///
- /// Reads one ZipEntry from the given stream. The content for
- /// the entry does not get decompressed or decrypted. This method
- /// basically reads metadata, and seeks.
- ///
- /// the ZipContainer this entry belongs to.
- ///
- /// true of this is the first entry being read from the stream.
- ///
- /// the ZipEntry read from the stream.
- internal static ZipEntry ReadEntry(ZipContainer zc, bool first)
- {
- ZipFile zf = zc.ZipFile;
- Stream s = zc.ReadStream;
- System.Text.Encoding defaultEncoding = zc.AlternateEncoding;
- ZipEntry entry = new ZipEntry();
- entry._Source = ZipEntrySource.ZipFile;
- entry._container = zc;
- entry._archiveStream = s;
- if (zf != null)
- zf.OnReadEntry(true, null);
-
- if (first) HandlePK00Prefix(s);
-
- // Read entry header, including any encryption header
- if (!ReadHeader(entry, defaultEncoding)) return null;
-
- // Store the position in the stream for this entry
- // change for workitem 8098
- entry.__FileDataPosition = entry.ArchiveStream.Position;
-
- // seek past the data without reading it. We will read on Extract()
- s.Seek(entry._CompressedFileDataSize + entry._LengthOfTrailer, SeekOrigin.Current);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
-
- // ReadHeader moves the file pointer to the end of the entry header,
- // as well as any encryption header.
-
- // CompressedFileDataSize includes:
- // the maybe compressed, maybe encrypted file data
- // the encryption trailer, if any
- // the bit 3 descriptor, if any
-
- // workitem 5306
- // http://www.codeplex.com/DotNetZip/WorkItem/View.aspx?WorkItemId=5306
- HandleUnexpectedDataDescriptor(entry);
-
- if (zf != null)
- {
- zf.OnReadBytes(entry);
- zf.OnReadEntry(false, entry);
- }
-
- return entry;
- }
-
-
- internal static void HandlePK00Prefix(Stream s)
- {
- // in some cases, the zip file begins with "PK00". This is a throwback and is rare,
- // but we handle it anyway. We do not change behavior based on it.
- uint datum = (uint)Ionic.Zip.SharedUtilities.ReadInt(s);
- if (datum != ZipConstants.PackedToRemovableMedia)
- {
- s.Seek(-4, SeekOrigin.Current); // unread the block
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
- }
- }
-
-
-
- private static void HandleUnexpectedDataDescriptor(ZipEntry entry)
- {
- Stream s = entry.ArchiveStream;
-
- // In some cases, the "data descriptor" is present, without a signature, even when
- // bit 3 of the BitField is NOT SET. This is the CRC, followed
- // by the compressed length and the uncompressed length (4 bytes for each
- // of those three elements). Need to check that here.
- //
- uint datum = (uint)Ionic.Zip.SharedUtilities.ReadInt(s);
- if (datum == entry._Crc32)
- {
- int sz = Ionic.Zip.SharedUtilities.ReadInt(s);
- if (sz == entry._CompressedSize)
- {
- sz = Ionic.Zip.SharedUtilities.ReadInt(s);
- if (sz == entry._UncompressedSize)
- {
- // ignore everything and discard it.
- }
- else
- {
- s.Seek(-12, SeekOrigin.Current); // unread the three blocks
-
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
- }
- }
- else
- {
- s.Seek(-8, SeekOrigin.Current); // unread the two blocks
-
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
- }
- }
- else
- {
- s.Seek(-4, SeekOrigin.Current); // unread the block
-
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
- }
- }
-
-
- ///
- /// Finds a particular segment in the given extra field.
- /// This is used when modifying a previously-generated
- /// extra field, in particular when removing the AES crypto
- /// segment in the extra field.
- ///
- static internal int FindExtraFieldSegment(byte[] extra, int offx, UInt16 targetHeaderId)
- {
- int j = offx;
- while (j + 3 < extra.Length)
- {
- UInt16 headerId = (UInt16)(extra[j++] + extra[j++] * 256);
- if (headerId == targetHeaderId) return j-2;
-
- // else advance to next segment
- Int16 dataSize = (short)(extra[j++] + extra[j++] * 256);
- j+= dataSize;
- }
-
- return -1;
- }
-
-
- ///
- /// At current cursor position in the stream, read the extra
- /// field, and set the properties on the ZipEntry instance
- /// appropriately. This can be called when processing the
- /// Extra field in the Central Directory, or in the local
- /// header.
- ///
- internal int ProcessExtraField(Stream s, Int16 extraFieldLength)
- {
- int additionalBytesRead = 0;
- if (extraFieldLength > 0)
- {
- byte[] buffer = this._Extra = new byte[extraFieldLength];
- additionalBytesRead = s.Read(buffer, 0, buffer.Length);
- long posn = s.Position - additionalBytesRead;
- int j = 0;
- while (j + 3 < buffer.Length)
- {
- int start = j;
- UInt16 headerId = (UInt16)(buffer[j++] + buffer[j++] * 256);
- Int16 dataSize = (short)(buffer[j++] + buffer[j++] * 256);
-
- switch (headerId)
- {
- case 0x000a: // NTFS ctime, atime, mtime
- j = ProcessExtraFieldWindowsTimes(buffer, j, dataSize, posn);
- break;
-
- case 0x5455: // Unix ctime, atime, mtime
- j = ProcessExtraFieldUnixTimes(buffer, j, dataSize, posn);
- break;
-
- case 0x5855: // Info-zip Extra field (outdated)
- // This is outdated, so the field is supported on
- // read only.
- j = ProcessExtraFieldInfoZipTimes(buffer, j, dataSize, posn);
- break;
-
- case 0x7855: // Unix uid/gid
- // ignored. DotNetZip does not handle this field.
- break;
-
- case 0x7875: // ??
- // ignored. I could not find documentation on this field,
- // though it appears in some zip files.
- break;
-
- case 0x0001: // ZIP64
- j = ProcessExtraFieldZip64(buffer, j, dataSize, posn);
- break;
-
-#if AESCRYPTO
- case 0x9901: // WinZip AES encryption is in use. (workitem 6834)
- // we will handle this extra field only if compressionmethod is 0x63
- j = ProcessExtraFieldWinZipAes(buffer, j, dataSize, posn);
- break;
-#endif
- case 0x0017: // workitem 7968: handle PKWare Strong encryption header
- j = ProcessExtraFieldPkwareStrongEncryption(buffer, j);
- break;
- }
-
- // move to the next Header in the extra field
- j = start + dataSize + 4;
- }
- }
- return additionalBytesRead;
- }
-
- private int ProcessExtraFieldPkwareStrongEncryption(byte[] Buffer, int j)
- {
- // Value Size Description
- // ----- ---- -----------
- // 0x0017 2 bytes Tag for this "extra" block type
- // TSize 2 bytes Size of data that follows
- // Format 2 bytes Format definition for this record
- // AlgID 2 bytes Encryption algorithm identifier
- // Bitlen 2 bytes Bit length of encryption key
- // Flags 2 bytes Processing flags
- // CertData TSize-8 Certificate decryption extra field data
- // (refer to the explanation for CertData
- // in the section describing the
- // Certificate Processing Method under
- // the Strong Encryption Specification)
-
- j += 2;
- _UnsupportedAlgorithmId = (UInt16)(Buffer[j++] + Buffer[j++] * 256);
- _Encryption_FromZipFile = _Encryption = EncryptionAlgorithm.Unsupported;
-
- // DotNetZip doesn't support this algorithm, but we don't need to throw
- // here. we might just be reading the archive, which is fine. We'll
- // need to throw if Extract() is called.
-
- return j;
- }
-
-
-#if AESCRYPTO
- private int ProcessExtraFieldWinZipAes(byte[] buffer, int j, Int16 dataSize, long posn)
- {
- if (this._CompressionMethod == 0x0063)
- {
- if ((this._BitField & 0x01) != 0x01)
- throw new BadReadException(String.Format(" Inconsistent metadata at position 0x{0:X16}", posn));
-
- this._sourceIsEncrypted = true;
-
- //this._aesCrypto = new WinZipAesCrypto(this);
- // see spec at http://www.winzip.com/aes_info.htm
- if (dataSize != 7)
- throw new BadReadException(String.Format(" Inconsistent size (0x{0:X4}) in WinZip AES field at position 0x{1:X16}", dataSize, posn));
-
- this._WinZipAesMethod = BitConverter.ToInt16(buffer, j);
- j += 2;
- if (this._WinZipAesMethod != 0x01 && this._WinZipAesMethod != 0x02)
- throw new BadReadException(String.Format(" Unexpected vendor version number (0x{0:X4}) for WinZip AES metadata at position 0x{1:X16}",
- this._WinZipAesMethod, posn));
-
- Int16 vendorId = BitConverter.ToInt16(buffer, j);
- j += 2;
- if (vendorId != 0x4541)
- throw new BadReadException(String.Format(" Unexpected vendor ID (0x{0:X4}) for WinZip AES metadata at position 0x{1:X16}", vendorId, posn));
-
- int keystrength = (buffer[j] == 1) ? 128 : (buffer[j] == 3) ? 256 : -1;
- if (keystrength < 0)
- throw new BadReadException(String.Format("Invalid key strength ({0})", keystrength));
-
- _Encryption_FromZipFile = this._Encryption = (keystrength == 128)
- ? EncryptionAlgorithm.WinZipAes128
- : EncryptionAlgorithm.WinZipAes256;
-
- j++;
-
- // set the actual compression method
- this._CompressionMethod_FromZipFile =
- this._CompressionMethod = BitConverter.ToInt16(buffer, j);
- j += 2; // for the next segment of the extra field
- }
- return j;
- }
-
-#endif
-
- private delegate T Func();
-
- private int ProcessExtraFieldZip64(byte[] buffer, int j, Int16 dataSize, long posn)
- {
- // The PKWare spec says that any of {UncompressedSize, CompressedSize,
- // RelativeOffset} exceeding 0xFFFFFFFF can lead to the ZIP64 header,
- // and the ZIP64 header may contain one or more of those. If the
- // values are present, they will be found in the prescribed order.
- // There may also be a 4-byte "disk start number."
- // This means that the DataSize must be 28 bytes or less.
-
- this._InputUsesZip64 = true;
-
- // workitem 7941: check datasize before reading.
- if (dataSize > 28)
- throw new BadReadException(String.Format(" Inconsistent size (0x{0:X4}) for ZIP64 extra field at position 0x{1:X16}",
- dataSize, posn));
- int remainingData = dataSize;
-
- var slurp = new Func( () => {
- if (remainingData < 8)
- throw new BadReadException(String.Format(" Missing data for ZIP64 extra field, position 0x{0:X16}", posn));
- var x = BitConverter.ToInt64(buffer, j);
- j+= 8;
- remainingData -= 8;
- return x;
- });
-
- if (this._UncompressedSize == 0xFFFFFFFF)
- this._UncompressedSize = slurp();
-
- if (this._CompressedSize == 0xFFFFFFFF)
- this._CompressedSize = slurp();
-
- if (this._RelativeOffsetOfLocalHeader == 0xFFFFFFFF)
- this._RelativeOffsetOfLocalHeader = slurp();
-
- // Ignore anything else. Potentially there are 4 more bytes for the
- // disk start number. DotNetZip currently doesn't handle multi-disk
- // archives.
- return j;
- }
-
-
- private int ProcessExtraFieldInfoZipTimes(byte[] buffer, int j, Int16 dataSize, long posn)
- {
- if (dataSize != 12 && dataSize != 8)
- throw new BadReadException(String.Format(" Unexpected size (0x{0:X4}) for InfoZip v1 extra field at position 0x{1:X16}", dataSize, posn));
-
- Int32 timet = BitConverter.ToInt32(buffer, j);
- this._Mtime = _unixEpoch.AddSeconds(timet);
- j += 4;
-
- timet = BitConverter.ToInt32(buffer, j);
- this._Atime = _unixEpoch.AddSeconds(timet);
- j += 4;
-
- this._Ctime = DateTime.UtcNow;
-
- _ntfsTimesAreSet = true;
- _timestamp |= ZipEntryTimestamp.InfoZip1; return j;
- }
-
-
-
- private int ProcessExtraFieldUnixTimes(byte[] buffer, int j, Int16 dataSize, long posn)
- {
- // The Unix filetimes are 32-bit unsigned integers,
- // storing seconds since Unix epoch.
-
- if (dataSize != 13 && dataSize != 9 && dataSize != 5)
- throw new BadReadException(String.Format(" Unexpected size (0x{0:X4}) for Extended Timestamp extra field at position 0x{1:X16}", dataSize, posn));
-
- int remainingData = dataSize;
-
- var slurp = new Func( () => {
- Int32 timet = BitConverter.ToInt32(buffer, j);
- j += 4;
- remainingData -= 4;
- return _unixEpoch.AddSeconds(timet);
- });
-
- if (dataSize == 13 || _readExtraDepth > 0)
- {
- byte flag = buffer[j++];
- remainingData--;
-
- if ((flag & 0x0001) != 0 && remainingData >= 4)
- this._Mtime = slurp();
-
- this._Atime = ((flag & 0x0002) != 0 && remainingData >= 4)
- ? slurp()
- : DateTime.UtcNow;
-
- this._Ctime = ((flag & 0x0004) != 0 && remainingData >= 4)
- ? slurp()
- :DateTime.UtcNow;
-
- _timestamp |= ZipEntryTimestamp.Unix;
- _ntfsTimesAreSet = true;
- _emitUnixTimes = true;
- }
- else
- ReadExtraField(); // will recurse
-
- return j;
- }
-
-
- private int ProcessExtraFieldWindowsTimes(byte[] buffer, int j, Int16 dataSize, long posn)
- {
- // The NTFS filetimes are 64-bit unsigned integers, stored in Intel
- // (least significant byte first) byte order. They are expressed as the
- // number of 1.0E-07 seconds (1/10th microseconds!) past WinNT "epoch",
- // which is "01-Jan-1601 00:00:00 UTC".
- //
- // HeaderId 2 bytes 0x000a == NTFS stuff
- // Datasize 2 bytes ?? (usually 32)
- // reserved 4 bytes ??
- // timetag 2 bytes 0x0001 == time
- // size 2 bytes 24 == 8 bytes each for ctime, mtime, atime
- // mtime 8 bytes win32 ticks since win32epoch
- // atime 8 bytes win32 ticks since win32epoch
- // ctime 8 bytes win32 ticks since win32epoch
-
- if (dataSize != 32)
- throw new BadReadException(String.Format(" Unexpected size (0x{0:X4}) for NTFS times extra field at position 0x{1:X16}", dataSize, posn));
-
- j += 4; // reserved
- Int16 timetag = (Int16)(buffer[j] + buffer[j + 1] * 256);
- Int16 addlsize = (Int16)(buffer[j + 2] + buffer[j + 3] * 256);
- j += 4; // tag and size
-
- if (timetag == 0x0001 && addlsize == 24)
- {
- Int64 z = BitConverter.ToInt64(buffer, j);
- this._Mtime = DateTime.FromFileTimeUtc(z);
- j += 8;
-
- // At this point the library *could* set the LastModified value
- // to coincide with the Mtime value. In theory, they refer to
- // the same property of the file, and should be the same anyway,
- // allowing for differences in precision. But they are
- // independent quantities in the zip archive, and this library
- // will keep them separate in the object model. There is no ill
- // effect from this, because as files are extracted, the
- // higher-precision value (Mtime) is used if it is present.
- // Apps may wish to compare the Mtime versus LastModified
- // values, but any difference when both are present is not
- // germaine to the correctness of the library. but note: when
- // explicitly setting either value, both are set. See the setter
- // for LastModified or the SetNtfsTimes() method.
-
- z = BitConverter.ToInt64(buffer, j);
- this._Atime = DateTime.FromFileTimeUtc(z);
- j += 8;
-
- z = BitConverter.ToInt64(buffer, j);
- this._Ctime = DateTime.FromFileTimeUtc(z);
- j += 8;
-
- _ntfsTimesAreSet = true;
- _timestamp |= ZipEntryTimestamp.Windows;
- _emitNtfsTimes = true;
- }
- return j;
- }
-
-
- }
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.Write.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.Write.cs
deleted file mode 100644
index b4e87f6e..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.Write.cs
+++ /dev/null
@@ -1,2582 +0,0 @@
-//#define Trace
-
-// ZipEntry.Write.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 Dino Chiesa
-// 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: <2011-July-30 14:55:47>
-//
-// ------------------------------------------------------------------
-//
-// This module defines logic for writing (saving) the ZipEntry into a
-// zip file.
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-using RE = System.Text.RegularExpressions;
-
-namespace Ionic.Zip
-{
- public partial class ZipEntry
- {
- internal void WriteCentralDirectoryEntry(Stream s)
- {
- byte[] bytes = new byte[4096];
- int i = 0;
- // signature
- bytes[i++] = (byte)(ZipConstants.ZipDirEntrySignature & 0x000000FF);
- bytes[i++] = (byte)((ZipConstants.ZipDirEntrySignature & 0x0000FF00) >> 8);
- bytes[i++] = (byte)((ZipConstants.ZipDirEntrySignature & 0x00FF0000) >> 16);
- bytes[i++] = (byte)((ZipConstants.ZipDirEntrySignature & 0xFF000000) >> 24);
-
- // Version Made By
- // workitem 7071
- // We must not overwrite the VersionMadeBy field when writing out a zip
- // archive. The VersionMadeBy tells the zip reader the meaning of the
- // File attributes. Overwriting the VersionMadeBy will result in
- // inconsistent metadata. Consider the scenario where the application
- // opens and reads a zip file that had been created on Linux. Then the
- // app adds one file to the Zip archive, and saves it. The file
- // attributes for all the entries added on Linux will be significant for
- // Linux. Therefore the VersionMadeBy for those entries must not be
- // changed. Only the entries that are actually created on Windows NTFS
- // should get the VersionMadeBy indicating Windows/NTFS.
- bytes[i++] = (byte)(_VersionMadeBy & 0x00FF);
- bytes[i++] = (byte)((_VersionMadeBy & 0xFF00) >> 8);
-
- // Apparently we want to duplicate the extra field here; we cannot
- // simply zero it out and assume tools and apps will use the right one.
-
- ////Int16 extraFieldLengthSave = (short)(_EntryHeader[28] + _EntryHeader[29] * 256);
- ////_EntryHeader[28] = 0;
- ////_EntryHeader[29] = 0;
-
- // Version Needed, Bitfield, compression method, lastmod,
- // crc, compressed and uncompressed sizes, filename length and extra field length.
- // These are all present in the local file header, but they may be zero values there.
- // So we cannot just copy them.
-
- // workitem 11969: Version Needed To Extract in central directory must be
- // the same as the local entry or MS .NET System.IO.Zip fails read.
- Int16 vNeeded = (Int16)(VersionNeeded != 0 ? VersionNeeded : 20);
- // workitem 12964
- if (_OutputUsesZip64==null)
- {
- // a zipentry in a zipoutputstream, with zero bytes written
- _OutputUsesZip64 = new Nullable(_container.Zip64 == Zip64Option.Always);
- }
-
- Int16 versionNeededToExtract = (Int16)(_OutputUsesZip64.Value ? 45 : vNeeded);
-#if BZIP
- if (this.CompressionMethod == Ionic.Zip.CompressionMethod.BZip2)
- versionNeededToExtract = 46;
-#endif
-
- bytes[i++] = (byte)(versionNeededToExtract & 0x00FF);
- bytes[i++] = (byte)((versionNeededToExtract & 0xFF00) >> 8);
-
- bytes[i++] = (byte)(_BitField & 0x00FF);
- bytes[i++] = (byte)((_BitField & 0xFF00) >> 8);
-
- bytes[i++] = (byte)(_CompressionMethod & 0x00FF);
- bytes[i++] = (byte)((_CompressionMethod & 0xFF00) >> 8);
-
-#if AESCRYPTO
- if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
- Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- i -= 2;
- bytes[i++] = 0x63;
- bytes[i++] = 0;
- }
-#endif
-
- bytes[i++] = (byte)(_TimeBlob & 0x000000FF);
- bytes[i++] = (byte)((_TimeBlob & 0x0000FF00) >> 8);
- bytes[i++] = (byte)((_TimeBlob & 0x00FF0000) >> 16);
- bytes[i++] = (byte)((_TimeBlob & 0xFF000000) >> 24);
- bytes[i++] = (byte)(_Crc32 & 0x000000FF);
- bytes[i++] = (byte)((_Crc32 & 0x0000FF00) >> 8);
- bytes[i++] = (byte)((_Crc32 & 0x00FF0000) >> 16);
- bytes[i++] = (byte)((_Crc32 & 0xFF000000) >> 24);
-
- int j = 0;
- if (_OutputUsesZip64.Value)
- {
- // CompressedSize (Int32) and UncompressedSize - all 0xFF
- for (j = 0; j < 8; j++)
- bytes[i++] = 0xFF;
- }
- else
- {
- bytes[i++] = (byte)(_CompressedSize & 0x000000FF);
- bytes[i++] = (byte)((_CompressedSize & 0x0000FF00) >> 8);
- bytes[i++] = (byte)((_CompressedSize & 0x00FF0000) >> 16);
- bytes[i++] = (byte)((_CompressedSize & 0xFF000000) >> 24);
-
- bytes[i++] = (byte)(_UncompressedSize & 0x000000FF);
- bytes[i++] = (byte)((_UncompressedSize & 0x0000FF00) >> 8);
- bytes[i++] = (byte)((_UncompressedSize & 0x00FF0000) >> 16);
- bytes[i++] = (byte)((_UncompressedSize & 0xFF000000) >> 24);
- }
-
- byte[] fileNameBytes = GetEncodedFileNameBytes();
- Int16 filenameLength = (Int16)fileNameBytes.Length;
- bytes[i++] = (byte)(filenameLength & 0x00FF);
- bytes[i++] = (byte)((filenameLength & 0xFF00) >> 8);
-
- // do this again because now we have real data
- _presumeZip64 = _OutputUsesZip64.Value;
-
- // workitem 11131
- //
- // cannot generate the extra field again, here's why: In the case of a
- // zero-byte entry, which uses encryption, DotNetZip will "remove" the
- // encryption from the entry. It does this in PostProcessOutput; it
- // modifies the entry header, and rewrites it, resetting the Bitfield
- // (one bit indicates encryption), and potentially resetting the
- // compression method - for AES the Compression method is 0x63, and it
- // would get reset to zero (no compression). It then calls SetLength()
- // to truncate the stream to remove the encryption header (12 bytes for
- // AES256). But, it leaves the previously-generated "Extra Field"
- // metadata (11 bytes) for AES in the entry header. This extra field
- // data is now "orphaned" - it refers to AES encryption when in fact no
- // AES encryption is used. But no problem, the PKWARE spec says that
- // unrecognized extra fields can just be ignored. ok. After "removal"
- // of AES encryption, the length of the Extra Field can remains the
- // same; it's just that there will be 11 bytes in there that previously
- // pertained to AES which are now unused. Even the field code is still
- // there, but it will be unused by readers, as the encryption bit is not
- // set.
- //
- // Re-calculating the Extra field now would produce a block that is 11
- // bytes shorter, and that mismatch - between the extra field in the
- // local header and the extra field in the Central Directory - would
- // cause problems. (where? why? what problems?) So we can't do
- // that. It's all good though, because though the content may have
- // changed, the length definitely has not. Also, the _EntryHeader
- // contains the "updated" extra field (after PostProcessOutput) at
- // offset (30 + filenameLength).
-
- _Extra = ConstructExtraField(true);
-
- Int16 extraFieldLength = (Int16)((_Extra == null) ? 0 : _Extra.Length);
- bytes[i++] = (byte)(extraFieldLength & 0x00FF);
- bytes[i++] = (byte)((extraFieldLength & 0xFF00) >> 8);
-
- // File (entry) Comment Length
- // the _CommentBytes private field was set during WriteHeader()
- int commentLength = (_CommentBytes == null) ? 0 : _CommentBytes.Length;
-
- // the size of our buffer defines the max length of the comment we can write
- if (commentLength + i > bytes.Length) commentLength = bytes.Length - i;
- bytes[i++] = (byte)(commentLength & 0x00FF);
- bytes[i++] = (byte)((commentLength & 0xFF00) >> 8);
-
- // Disk number start
- bool segmented = (this._container.ZipFile != null) &&
- (this._container.ZipFile.MaxOutputSegmentSize != 0);
- if (segmented) // workitem 13915
- {
- // Emit nonzero disknumber only if saving segmented archive.
- bytes[i++] = (byte)(_diskNumber & 0x00FF);
- bytes[i++] = (byte)((_diskNumber & 0xFF00) >> 8);
- }
- else
- {
- // If reading a segmneted archive and saving to a regular archive,
- // ZipEntry._diskNumber will be non-zero but it should be saved as
- // zero.
- bytes[i++] = 0;
- bytes[i++] = 0;
- }
-
- // internal file attrs
- // workitem 7801
- bytes[i++] = (byte)((_IsText) ? 1 : 0); // lo bit: filetype hint. 0=bin, 1=txt.
- bytes[i++] = 0;
-
- // external file attrs
- // workitem 7071
- bytes[i++] = (byte)(_ExternalFileAttrs & 0x000000FF);
- bytes[i++] = (byte)((_ExternalFileAttrs & 0x0000FF00) >> 8);
- bytes[i++] = (byte)((_ExternalFileAttrs & 0x00FF0000) >> 16);
- bytes[i++] = (byte)((_ExternalFileAttrs & 0xFF000000) >> 24);
-
- // workitem 11131
- // relative offset of local header.
- //
- // If necessary to go to 64-bit value, then emit 0xFFFFFFFF,
- // else write out the value.
- //
- // Even if zip64 is required for other reasons - number of the entry
- // > 65534, or uncompressed size of the entry > MAX_INT32, the ROLH
- // need not be stored in a 64-bit field .
- if (_RelativeOffsetOfLocalHeader > 0xFFFFFFFFL) // _OutputUsesZip64.Value
- {
- bytes[i++] = 0xFF;
- bytes[i++] = 0xFF;
- bytes[i++] = 0xFF;
- bytes[i++] = 0xFF;
- }
- else
- {
- bytes[i++] = (byte)(_RelativeOffsetOfLocalHeader & 0x000000FF);
- bytes[i++] = (byte)((_RelativeOffsetOfLocalHeader & 0x0000FF00) >> 8);
- bytes[i++] = (byte)((_RelativeOffsetOfLocalHeader & 0x00FF0000) >> 16);
- bytes[i++] = (byte)((_RelativeOffsetOfLocalHeader & 0xFF000000) >> 24);
- }
-
- // actual filename
- Buffer.BlockCopy(fileNameBytes, 0, bytes, i, filenameLength);
- i += filenameLength;
-
- // "Extra field"
- if (_Extra != null)
- {
- // workitem 11131
- //
- // copy from EntryHeader if available - it may have been updated.
- // if not, copy from Extra. This would be unnecessary if I just
- // updated the Extra field when updating EntryHeader, in
- // PostProcessOutput.
-
- //?? I don't understand why I wouldn't want to just use
- // the recalculated Extra field. ??
-
- // byte[] h = _EntryHeader ?? _Extra;
- // int offx = (h == _EntryHeader) ? 30 + filenameLength : 0;
- // Buffer.BlockCopy(h, offx, bytes, i, extraFieldLength);
- // i += extraFieldLength;
-
- byte[] h = _Extra;
- int offx = 0;
- Buffer.BlockCopy(h, offx, bytes, i, extraFieldLength);
- i += extraFieldLength;
- }
-
- // file (entry) comment
- if (commentLength != 0)
- {
- // now actually write the comment itself into the byte buffer
- Buffer.BlockCopy(_CommentBytes, 0, bytes, i, commentLength);
- // for (j = 0; (j < commentLength) && (i + j < bytes.Length); j++)
- // bytes[i + j] = _CommentBytes[j];
- i += commentLength;
- }
-
- s.Write(bytes, 0, i);
- }
-
-
-#if INFOZIP_UTF8
- static private bool FileNameIsUtf8(char[] FileNameChars)
- {
- bool isUTF8 = false;
- bool isUnicode = false;
- for (int j = 0; j < FileNameChars.Length; j++)
- {
- byte[] b = System.BitConverter.GetBytes(FileNameChars[j]);
- isUnicode |= (b.Length != 2);
- isUnicode |= (b[1] != 0);
- isUTF8 |= ((b[0] & 0x80) != 0);
- }
-
- return isUTF8;
- }
-#endif
-
-
- private byte[] ConstructExtraField(bool forCentralDirectory)
- {
- var listOfBlocks = new System.Collections.Generic.List();
- byte[] block;
-
- // Conditionally emit an extra field with Zip64 information. If the
- // Zip64 option is Always, we emit the field, before knowing that it's
- // necessary. Later, if it turns out this entry does not need zip64,
- // we'll set the header ID to rubbish and the data will be ignored.
- // This results in additional overhead metadata in the zip file, but
- // it will be small in comparison to the entry data.
- //
- // On the other hand if the Zip64 option is AsNecessary and it's NOT
- // for the central directory, then we do the same thing. Or, if the
- // Zip64 option is AsNecessary and it IS for the central directory,
- // and the entry requires zip64, then emit the header.
- if (_container.Zip64 == Zip64Option.Always ||
- (_container.Zip64 == Zip64Option.AsNecessary &&
- (!forCentralDirectory || _entryRequiresZip64.Value)))
- {
- // add extra field for zip64 here
- // workitem 7924
- int sz = 4 + (forCentralDirectory ? 28 : 16);
- block = new byte[sz];
- int i = 0;
-
- if (_presumeZip64 || forCentralDirectory)
- {
- // HeaderId = always use zip64 extensions.
- block[i++] = 0x01;
- block[i++] = 0x00;
- }
- else
- {
- // HeaderId = dummy data now, maybe set to 0x0001 (ZIP64) later.
- block[i++] = 0x99;
- block[i++] = 0x99;
- }
-
- // DataSize
- block[i++] = (byte)(sz - 4); // decimal 28 or 16 (workitem 7924)
- block[i++] = 0x00;
-
- // The actual metadata - we may or may not have real values yet...
-
- // uncompressed size
- Array.Copy(BitConverter.GetBytes(_UncompressedSize), 0, block, i, 8);
- i += 8;
- // compressed size
- Array.Copy(BitConverter.GetBytes(_CompressedSize), 0, block, i, 8);
- i += 8;
-
- // workitem 7924 - only include this if the "extra" field is for
- // use in the central directory. It is unnecessary and not useful
- // for local header; makes WinZip choke.
- if (forCentralDirectory)
- {
- // relative offset
- Array.Copy(BitConverter.GetBytes(_RelativeOffsetOfLocalHeader), 0, block, i, 8);
- i += 8;
-
- // starting disk number
- Array.Copy(BitConverter.GetBytes(0), 0, block, i, 4);
- }
- listOfBlocks.Add(block);
- }
-
-
-#if AESCRYPTO
- if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
- Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- block = new byte[4 + 7];
- int i = 0;
- // extra field for WinZip AES
- // header id
- block[i++] = 0x01;
- block[i++] = 0x99;
-
- // data size
- block[i++] = 0x07;
- block[i++] = 0x00;
-
- // vendor number
- block[i++] = 0x01; // AE-1 - means "Verify CRC"
- block[i++] = 0x00;
-
- // vendor id "AE"
- block[i++] = 0x41;
- block[i++] = 0x45;
-
- // key strength
- int keystrength = GetKeyStrengthInBits(Encryption);
- if (keystrength == 128)
- block[i] = 1;
- else if (keystrength == 256)
- block[i] = 3;
- else
- block[i] = 0xFF;
- i++;
-
- // actual compression method
- block[i++] = (byte)(_CompressionMethod & 0x00FF);
- block[i++] = (byte)(_CompressionMethod & 0xFF00);
-
- listOfBlocks.Add(block);
- }
-#endif
-
- if (_ntfsTimesAreSet && _emitNtfsTimes)
- {
- block = new byte[32 + 4];
- // HeaderId 2 bytes 0x000a == NTFS times
- // Datasize 2 bytes 32
- // reserved 4 bytes ?? don't care
- // timetag 2 bytes 0x0001 == NTFS time
- // size 2 bytes 24 == 8 bytes each for ctime, mtime, atime
- // mtime 8 bytes win32 ticks since win32epoch
- // atime 8 bytes win32 ticks since win32epoch
- // ctime 8 bytes win32 ticks since win32epoch
- int i = 0;
- // extra field for NTFS times
- // header id
- block[i++] = 0x0a;
- block[i++] = 0x00;
-
- // data size
- block[i++] = 32;
- block[i++] = 0;
-
- i += 4; // reserved
-
- // time tag
- block[i++] = 0x01;
- block[i++] = 0x00;
-
- // data size (again)
- block[i++] = 24;
- block[i++] = 0;
-
- Int64 z = _Mtime.ToFileTime();
- Array.Copy(BitConverter.GetBytes(z), 0, block, i, 8);
- i += 8;
- z = _Atime.ToFileTime();
- Array.Copy(BitConverter.GetBytes(z), 0, block, i, 8);
- i += 8;
- z = _Ctime.ToFileTime();
- Array.Copy(BitConverter.GetBytes(z), 0, block, i, 8);
- i += 8;
-
- listOfBlocks.Add(block);
- }
-
- if (_ntfsTimesAreSet && _emitUnixTimes)
- {
- int len = 5 + 4;
- if (!forCentralDirectory) len += 8;
-
- block = new byte[len];
- // local form:
- // --------------
- // HeaderId 2 bytes 0x5455 == unix timestamp
- // Datasize 2 bytes 13
- // flags 1 byte 7 (low three bits all set)
- // mtime 4 bytes seconds since unix epoch
- // atime 4 bytes seconds since unix epoch
- // ctime 4 bytes seconds since unix epoch
- //
- // central directory form:
- //---------------------------------
- // HeaderId 2 bytes 0x5455 == unix timestamp
- // Datasize 2 bytes 5
- // flags 1 byte 7 (low three bits all set)
- // mtime 4 bytes seconds since unix epoch
- //
- int i = 0;
- // extra field for "unix" times
- // header id
- block[i++] = 0x55;
- block[i++] = 0x54;
-
- // data size
- block[i++] = unchecked((byte)(len - 4));
- block[i++] = 0;
-
- // flags
- block[i++] = 0x07;
-
- Int32 z = unchecked((int)((_Mtime - _unixEpoch).TotalSeconds));
- Array.Copy(BitConverter.GetBytes(z), 0, block, i, 4);
- i += 4;
- if (!forCentralDirectory)
- {
- z = unchecked((int)((_Atime - _unixEpoch).TotalSeconds));
- Array.Copy(BitConverter.GetBytes(z), 0, block, i, 4);
- i += 4;
- z = unchecked((int)((_Ctime - _unixEpoch).TotalSeconds));
- Array.Copy(BitConverter.GetBytes(z), 0, block, i, 4);
- i += 4;
- }
- listOfBlocks.Add(block);
- }
-
-
- // inject other blocks here...
-
-
- // concatenate any blocks we've got:
- byte[] aggregateBlock = null;
- if (listOfBlocks.Count > 0)
- {
- int totalLength = 0;
- int i, current = 0;
- for (i = 0; i < listOfBlocks.Count; i++)
- totalLength += listOfBlocks[i].Length;
- aggregateBlock = new byte[totalLength];
- for (i = 0; i < listOfBlocks.Count; i++)
- {
- System.Array.Copy(listOfBlocks[i], 0, aggregateBlock, current, listOfBlocks[i].Length);
- current += listOfBlocks[i].Length;
- }
- }
-
- return aggregateBlock;
- }
-
-
-
- // private System.Text.Encoding GenerateCommentBytes()
- // {
- // var getEncoding = new Func({
- // switch (AlternateEncodingUsage)
- // {
- // case ZipOption.Always:
- // return AlternateEncoding;
- // case ZipOption.Never:
- // return ibm437;
- // }
- // var cb = ibm437.GetBytes(_Comment);
- // // need to use this form of GetString() for .NET CF
- // string s1 = ibm437.GetString(cb, 0, cb.Length);
- // if (s1 == _Comment)
- // return ibm437;
- // return AlternateEncoding;
- // });
- //
- // var encoding = getEncoding();
- // _CommentBytes = encoding.GetBytes(_Comment);
- // return encoding;
- // }
-
-
- private string NormalizeFileName()
- {
- // here, we need to flip the backslashes to forward-slashes,
- // also, we need to trim the \\server\share syntax from any UNC path.
- // and finally, we need to remove any leading .\
-
- string SlashFixed = FileName.Replace("\\", "/");
- string s1 = null;
- if ((_TrimVolumeFromFullyQualifiedPaths) && (FileName.Length >= 3)
- && (FileName[1] == ':') && (SlashFixed[2] == '/'))
- {
- // trim off volume letter, colon, and slash
- s1 = SlashFixed.Substring(3);
- }
- else if ((FileName.Length >= 4)
- && ((SlashFixed[0] == '/') && (SlashFixed[1] == '/')))
- {
- int n = SlashFixed.IndexOf('/', 2);
- if (n == -1)
- throw new ArgumentException("The path for that entry appears to be badly formatted");
- s1 = SlashFixed.Substring(n + 1);
- }
- else if ((FileName.Length >= 3)
- && ((SlashFixed[0] == '.') && (SlashFixed[1] == '/')))
- {
- // trim off dot and slash
- s1 = SlashFixed.Substring(2);
- }
- else
- {
- s1 = SlashFixed;
- }
- return s1;
- }
-
-
- ///
- /// generate and return a byte array that encodes the filename
- /// for the entry.
- ///
- ///
- ///
- /// side effects: generate and store into _CommentBytes the
- /// byte array for any comment attached to the entry. Also
- /// sets _actualEncoding to indicate the actual encoding
- /// used. The same encoding is used for both filename and
- /// comment.
- ///
- ///
- private byte[] GetEncodedFileNameBytes()
- {
- // workitem 6513
- var s1 = NormalizeFileName();
-
- switch(AlternateEncodingUsage)
- {
- case ZipOption.Always:
- if (!(_Comment == null || _Comment.Length == 0))
- _CommentBytes = AlternateEncoding.GetBytes(_Comment);
- _actualEncoding = AlternateEncoding;
- return AlternateEncoding.GetBytes(s1);
-
- case ZipOption.Never:
- if (!(_Comment == null || _Comment.Length == 0))
- _CommentBytes = ibm437.GetBytes(_Comment);
- _actualEncoding = ibm437;
- return ibm437.GetBytes(s1);
- }
-
- // arriving here means AlternateEncodingUsage is "AsNecessary"
-
- // case ZipOption.AsNecessary:
- // workitem 6513: when writing, use the alternative encoding
- // only when _actualEncoding is not yet set (it can be set
- // during Read), and when ibm437 will not do.
-
- byte[] result = ibm437.GetBytes(s1);
- // need to use this form of GetString() for .NET CF
- string s2 = ibm437.GetString(result, 0, result.Length);
- _CommentBytes = null;
- if (s2 != s1)
- {
- // Encoding the filename with ibm437 does not allow round-trips.
- // Therefore, use the alternate encoding. Assume it will work,
- // no checking of round trips here.
- result = AlternateEncoding.GetBytes(s1);
- if (_Comment != null && _Comment.Length != 0)
- _CommentBytes = AlternateEncoding.GetBytes(_Comment);
- _actualEncoding = AlternateEncoding;
- return result;
- }
-
- _actualEncoding = ibm437;
-
- // Using ibm437, FileName can be encoded without information
- // loss; now try the Comment.
-
- // if there is no comment, use ibm437.
- if (_Comment == null || _Comment.Length == 0)
- return result;
-
- // there is a comment. Get the encoded form.
- byte[] cbytes = ibm437.GetBytes(_Comment);
- string c2 = ibm437.GetString(cbytes,0,cbytes.Length);
-
- // Check for round-trip.
- if (c2 != Comment)
- {
- // Comment cannot correctly be encoded with ibm437. Use
- // the alternate encoding.
-
- result = AlternateEncoding.GetBytes(s1);
- _CommentBytes = AlternateEncoding.GetBytes(_Comment);
- _actualEncoding = AlternateEncoding;
- return result;
- }
-
- // use IBM437
- _CommentBytes = cbytes;
- return result;
- }
-
-
-
- private bool WantReadAgain()
- {
- if (_UncompressedSize < 0x10) return false;
- if (_CompressionMethod == 0x00) return false;
- if (CompressionLevel == Ionic.Zlib.CompressionLevel.None) return false;
- if (_CompressedSize < _UncompressedSize) return false;
-
- if (this._Source == ZipEntrySource.Stream && !this._sourceStream.CanSeek) return false;
-
-#if AESCRYPTO
- if (_aesCrypto_forWrite != null && (CompressedSize - _aesCrypto_forWrite.SizeOfEncryptionMetadata) <= UncompressedSize + 0x10) return false;
-#endif
-
- if (_zipCrypto_forWrite != null && (CompressedSize - 12) <= UncompressedSize) return false;
-
- return true;
- }
-
-
-
- private void MaybeUnsetCompressionMethodForWriting(int cycle)
- {
- // if we've already tried with compression... turn it off this time
- if (cycle > 1)
- {
- _CompressionMethod = 0x0;
- return;
- }
- // compression for directories = 0x00 (No Compression)
- if (IsDirectory)
- {
- _CompressionMethod = 0x0;
- return;
- }
-
- if (this._Source == ZipEntrySource.ZipFile)
- {
- return; // do nothing
- }
-
- // If __FileDataPosition is zero, then that means we will get the data
- // from a file or stream.
-
- // It is never possible to compress a zero-length file, so we check for
- // this condition.
-
- if (this._Source == ZipEntrySource.Stream)
- {
- // workitem 7742
- if (_sourceStream != null && _sourceStream.CanSeek)
- {
- // Length prop will throw if CanSeek is false
- long fileLength = _sourceStream.Length;
- if (fileLength == 0)
- {
- _CompressionMethod = 0x00;
- return;
- }
- }
- }
- else if ((this._Source == ZipEntrySource.FileSystem) && (SharedUtilities.GetFileLength(LocalFileName) == 0L))
- {
- _CompressionMethod = 0x00;
- return;
- }
-
- // Ok, we're getting the data to be compressed from a
- // non-zero-length file or stream, or a file or stream of
- // unknown length, and we presume that it is non-zero. In
- // that case we check the callback to see if the app wants
- // to tell us whether to compress or not.
- if (SetCompression != null)
- CompressionLevel = SetCompression(LocalFileName, _FileNameInArchive);
-
- // finally, set CompressionMethod to None if CompressionLevel is None
- if (CompressionLevel == (short)Ionic.Zlib.CompressionLevel.None &&
- CompressionMethod == Ionic.Zip.CompressionMethod.Deflate)
- _CompressionMethod = 0x00;
-
- return;
- }
-
-
-
- // write the header info for an entry
- internal void WriteHeader(Stream s, int cycle)
- {
- // Must remember the offset, within the output stream, of this particular
- // entry header.
- //
- // This is for 2 reasons:
- //
- // 1. so we can determine the RelativeOffsetOfLocalHeader (ROLH) for
- // use in the central directory.
- // 2. so we can seek backward in case there is an error opening or reading
- // the file, and the application decides to skip the file. In this case,
- // we need to seek backward in the output stream to allow the next entry
- // to be added to the zipfile output stream.
- //
- // Normally you would just store the offset before writing to the output
- // stream and be done with it. But the possibility to use split archives
- // makes this approach ineffective. In split archives, each file or segment
- // is bound to a max size limit, and each local file header must not span a
- // segment boundary; it must be written contiguously. If it will fit in the
- // current segment, then the ROLH is just the current Position in the output
- // stream. If it won't fit, then we need a new file (segment) and the ROLH
- // is zero.
- //
- // But we only can know if it is possible to write a header contiguously
- // after we know the size of the local header, a size that varies with
- // things like filename length, comments, and extra fields. We have to
- // compute the header fully before knowing whether it will fit.
- //
- // That takes care of item #1 above. Now, regarding #2. If an error occurs
- // while computing the local header, we want to just seek backward. The
- // exception handling logic (in the caller of WriteHeader) uses ROLH to
- // scroll back.
- //
- // All this means we have to preserve the starting offset before computing
- // the header, and also we have to compute the offset later, to handle the
- // case of split archives.
-
- var counter = s as CountingStream;
-
- // workitem 8098: ok (output)
- // This may change later, for split archives
-
- // Don't set _RelativeOffsetOfLocalHeader. Instead, set a temp variable.
- // This allows for re-streaming, where a zip entry might be read from a
- // zip archive (and maybe decrypted, and maybe decompressed) and then
- // written to another zip archive, with different settings for
- // compression method, compression level, or encryption algorithm.
- _future_ROLH = (counter != null)
- ? counter.ComputedPosition
- : s.Position;
-
- int j = 0, i = 0;
-
- byte[] block = new byte[30];
-
- // signature
- block[i++] = (byte)(ZipConstants.ZipEntrySignature & 0x000000FF);
- block[i++] = (byte)((ZipConstants.ZipEntrySignature & 0x0000FF00) >> 8);
- block[i++] = (byte)((ZipConstants.ZipEntrySignature & 0x00FF0000) >> 16);
- block[i++] = (byte)((ZipConstants.ZipEntrySignature & 0xFF000000) >> 24);
-
- // Design notes for ZIP64:
- //
- // The specification says that the header must include the Compressed
- // and Uncompressed sizes, as well as the CRC32 value. When creating
- // a zip via streamed processing, these quantities are not known until
- // after the compression is done. Thus, a typical way to do it is to
- // insert zeroes for these quantities, then do the compression, then
- // seek back to insert the appropriate values, then seek forward to
- // the end of the file data.
- //
- // There is also the option of using bit 3 in the GP bitfield - to
- // specify that there is a data descriptor after the file data
- // containing these three quantities.
- //
- // This works when the size of the quantities is known, either 32-bits
- // or 64 bits as with the ZIP64 extensions.
- //
- // With Zip64, the 4-byte fields are set to 0xffffffff, and there is a
- // corresponding data block in the "extra field" that contains the
- // actual Compressed, uncompressed sizes. (As well as an additional
- // field, the "Relative Offset of Local Header")
- //
- // The problem is when the app desires to use ZIP64 extensions
- // optionally, only when necessary. Suppose the library assumes no
- // zip64 extensions when writing the header, then after compression
- // finds that the size of the data requires zip64. At this point, the
- // header, already written to the file, won't have the necessary data
- // block in the "extra field". The size of the entry header is fixed,
- // so it is not possible to just "add on" the zip64 data block after
- // compressing the file. On the other hand, always using zip64 will
- // break interoperability with many other systems and apps.
- //
- // The approach we take is to insert a 32-byte dummy data block in the
- // extra field, whenever zip64 is to be used "as necessary". This data
- // block will get the actual zip64 HeaderId and zip64 metadata if
- // necessary. If not necessary, the data block will get a meaningless
- // HeaderId (0x1111), and will be filled with zeroes.
- //
- // When zip64 is actually in use, we also need to set the
- // VersionNeededToExtract field to 45.
- //
- // There is one additional wrinkle: using zip64 as necessary conflicts
- // with output to non-seekable devices. The header is emitted and
- // must indicate whether zip64 is in use, before we know if zip64 is
- // necessary. Because there is no seeking, the header can never be
- // changed. Therefore, on non-seekable devices,
- // Zip64Option.AsNecessary is the same as Zip64Option.Always.
- //
-
-
- // version needed- see AppNote.txt.
- //
- // need v5.1 for PKZIP strong encryption, or v2.0 for no encryption or
- // for PK encryption, 4.5 for zip64. We may reset this later, as
- // necessary or zip64.
-
- _presumeZip64 = (_container.Zip64 == Zip64Option.Always ||
- (_container.Zip64 == Zip64Option.AsNecessary && !s.CanSeek));
- Int16 VersionNeededToExtract = (Int16)(_presumeZip64 ? 45 : 20);
-#if BZIP
- if (this.CompressionMethod == Ionic.Zip.CompressionMethod.BZip2)
- VersionNeededToExtract = 46;
-#endif
-
- // (i==4)
- block[i++] = (byte)(VersionNeededToExtract & 0x00FF);
- block[i++] = (byte)((VersionNeededToExtract & 0xFF00) >> 8);
-
- // Get byte array. Side effect: sets ActualEncoding.
- // Must determine encoding before setting the bitfield.
- // workitem 6513
- byte[] fileNameBytes = GetEncodedFileNameBytes();
- Int16 filenameLength = (Int16)fileNameBytes.Length;
-
- // general purpose bitfield
- // In the current implementation, this library uses only these bits
- // in the GP bitfield:
- // bit 0 = if set, indicates the entry is encrypted
- // bit 3 = if set, indicates the CRC, C and UC sizes follow the file data.
- // bit 6 = strong encryption - for pkware's meaning of strong encryption
- // bit 11 = UTF-8 encoding is used in the comment and filename
-
-
- // Here we set or unset the encryption bit.
- // _BitField may already be set, as with a ZipEntry added into ZipOutputStream, which
- // has bit 3 always set. We only want to set one bit
- if (_Encryption == EncryptionAlgorithm.None)
- _BitField &= ~1; // encryption bit OFF
- else
- _BitField |= 1; // encryption bit ON
-
-
- // workitem 7941: WinZip does not the "strong encryption" bit when using AES.
- // This "Strong Encryption" is a PKWare Strong encryption thing.
- // _BitField |= 0x0020;
-
- // set the UTF8 bit if necessary
-#if SILVERLIGHT
- if (_actualEncoding.WebName == "utf-8")
-#else
- if (_actualEncoding.CodePage == System.Text.Encoding.UTF8.CodePage)
-#endif
- _BitField |= 0x0800;
-
- // The PKZIP spec says that if bit 3 is set (0x0008) in the General
- // Purpose BitField, then the CRC, Compressed size, and uncompressed
- // size are written directly after the file data.
- //
- // These 3 quantities are normally present in the regular zip entry
- // header. But, they are not knowable until after the compression is
- // done. So, in the normal case, we
- //
- // - write the header, using zeros for these quantities
- // - compress the data, and incidentally compute these quantities.
- // - seek back and write the correct values them into the header.
- //
- // This is nice because, while it is more complicated to write the zip
- // file, it is simpler and less error prone to read the zip file, and
- // as a result more applications can read zip files produced this way,
- // with those 3 quantities in the header.
- //
- // But if seeking in the output stream is not possible, then we need
- // to set the appropriate bitfield and emit these quantities after the
- // compressed file data in the output.
- //
- // workitem 7216 - having trouble formatting a zip64 file that is
- // readable by WinZip. not sure why! What I found is that setting
- // bit 3 and following all the implications, the zip64 file is
- // readable by WinZip 12. and Perl's IO::Compress::Zip . Perl takes
- // an interesting approach - it always sets bit 3 if ZIP64 in use.
- // DotNetZip now does the same; this gives better compatibility with
- // WinZip 12.
-
- if (IsDirectory || cycle == 99)
- {
- // (cycle == 99) indicates a zero-length entry written by ZipOutputStream
-
- _BitField &= ~0x0008; // unset bit 3 - no "data descriptor" - ever
- _BitField &= ~0x0001; // unset bit 1 - no encryption - ever
- Encryption = EncryptionAlgorithm.None;
- Password = null;
- }
- else if (!s.CanSeek)
- _BitField |= 0x0008;
-
-#if DONT_GO_THERE
- else if (this.Encryption == EncryptionAlgorithm.PkzipWeak &&
- this._Source != ZipEntrySource.ZipFile)
- {
- // Set bit 3 to avoid the double-read perf issue.
- //
- // When PKZIP encryption is used, byte 11 of the encryption header is
- // used as a consistency check. It is normally set to the MSByte of the
- // CRC. But this means the cRC must be known ebfore compression and
- // encryption, which means the entire stream has to be read twice. To
- // avoid that, the high-byte of the time blob (when in DOS format) can
- // be used for the consistency check (byte 11 in the encryption header).
- // But this means the entry must have bit 3 set.
- //
- // Previously I used a more complex arrangement - using the methods like
- // FigureCrc32(), PrepOutputStream() and others, in order to manage the
- // seek-back in the source stream. Why? Because bit 3 is not always
- // friendly with third-party zip tools, like those on the Mac.
- //
- // This is why this code is still ifdef'd out.
- //
- // Might consider making this yet another programmable option -
- // AlwaysUseBit3ForPkzip. But that's for another day.
- //
- _BitField |= 0x0008;
- }
-#endif
-
- // (i==6)
- block[i++] = (byte)(_BitField & 0x00FF);
- block[i++] = (byte)((_BitField & 0xFF00) >> 8);
-
- // Here, we want to set values for Compressed Size, Uncompressed Size,
- // and CRC. If we have __FileDataPosition as not -1 (zero is a valid
- // FDP), then that means we are reading this zip entry from a zip
- // file, and we have good values for those quantities.
- //
- // If _FileDataPosition is -1, then we are constructing this Entry
- // from nothing. We zero those quantities now, and we will compute
- // actual values for the three quantities later, when we do the
- // compression, and then seek back to write them into the appropriate
- // place in the header.
- if (this.__FileDataPosition == -1)
- {
- //_UncompressedSize = 0; // do not unset - may need this value for restream
- // _Crc32 = 0; // ditto
- _CompressedSize = 0;
- _crcCalculated = false;
- }
-
- // set compression method here
- MaybeUnsetCompressionMethodForWriting(cycle);
-
- // (i==8) compression method
- block[i++] = (byte)(_CompressionMethod & 0x00FF);
- block[i++] = (byte)((_CompressionMethod & 0xFF00) >> 8);
-
- if (cycle == 99)
- {
- // (cycle == 99) indicates a zero-length entry written by ZipOutputStream
- SetZip64Flags();
- }
-
-#if AESCRYPTO
- else if (Encryption == EncryptionAlgorithm.WinZipAes128 || Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- i -= 2;
- block[i++] = 0x63;
- block[i++] = 0;
- }
-#endif
-
- // LastMod
- _TimeBlob = Ionic.Zip.SharedUtilities.DateTimeToPacked(LastModified);
-
- // (i==10) time blob
- block[i++] = (byte)(_TimeBlob & 0x000000FF);
- block[i++] = (byte)((_TimeBlob & 0x0000FF00) >> 8);
- block[i++] = (byte)((_TimeBlob & 0x00FF0000) >> 16);
- block[i++] = (byte)((_TimeBlob & 0xFF000000) >> 24);
-
- // (i==14) CRC - if source==filesystem, this is zero now, actual value
- // will be calculated later. if source==archive, this is a bonafide
- // value.
- block[i++] = (byte)(_Crc32 & 0x000000FF);
- block[i++] = (byte)((_Crc32 & 0x0000FF00) >> 8);
- block[i++] = (byte)((_Crc32 & 0x00FF0000) >> 16);
- block[i++] = (byte)((_Crc32 & 0xFF000000) >> 24);
-
- if (_presumeZip64)
- {
- // (i==18) CompressedSize (Int32) and UncompressedSize - all 0xFF for now
- for (j = 0; j < 8; j++)
- block[i++] = 0xFF;
- }
- else
- {
- // (i==18) CompressedSize (Int32) - this value may or may not be
- // bonafide. if source == filesystem, then it is zero, and we'll
- // learn it after we compress. if source == archive, then it is
- // bonafide data.
- block[i++] = (byte)(_CompressedSize & 0x000000FF);
- block[i++] = (byte)((_CompressedSize & 0x0000FF00) >> 8);
- block[i++] = (byte)((_CompressedSize & 0x00FF0000) >> 16);
- block[i++] = (byte)((_CompressedSize & 0xFF000000) >> 24);
-
- // (i==22) UncompressedSize (Int32) - this value may or may not be
- // bonafide.
- block[i++] = (byte)(_UncompressedSize & 0x000000FF);
- block[i++] = (byte)((_UncompressedSize & 0x0000FF00) >> 8);
- block[i++] = (byte)((_UncompressedSize & 0x00FF0000) >> 16);
- block[i++] = (byte)((_UncompressedSize & 0xFF000000) >> 24);
- }
-
- // (i==26) filename length (Int16)
- block[i++] = (byte)(filenameLength & 0x00FF);
- block[i++] = (byte)((filenameLength & 0xFF00) >> 8);
-
- _Extra = ConstructExtraField(false);
-
- // (i==28) extra field length (short)
- Int16 extraFieldLength = (Int16)((_Extra == null) ? 0 : _Extra.Length);
- block[i++] = (byte)(extraFieldLength & 0x00FF);
- block[i++] = (byte)((extraFieldLength & 0xFF00) >> 8);
-
- // workitem 13542
- byte[] bytes = new byte[i + filenameLength + extraFieldLength];
-
- // get the fixed portion
- Buffer.BlockCopy(block, 0, bytes, 0, i);
- //for (j = 0; j < i; j++) bytes[j] = block[j];
-
- // The filename written to the archive.
- Buffer.BlockCopy(fileNameBytes, 0, bytes, i, fileNameBytes.Length);
- // for (j = 0; j < fileNameBytes.Length; j++)
- // bytes[i + j] = fileNameBytes[j];
-
- i += fileNameBytes.Length;
-
- // "Extra field"
- if (_Extra != null)
- {
- Buffer.BlockCopy(_Extra, 0, bytes, i, _Extra.Length);
- // for (j = 0; j < _Extra.Length; j++)
- // bytes[i + j] = _Extra[j];
- i += _Extra.Length;
- }
-
- _LengthOfHeader = i;
-
- // handle split archives
- var zss = s as ZipSegmentedStream;
- if (zss != null)
- {
- zss.ContiguousWrite = true;
- UInt32 requiredSegment = zss.ComputeSegment(i);
- if (requiredSegment != zss.CurrentSegment)
- _future_ROLH = 0; // rollover!
- else
- _future_ROLH = zss.Position;
-
- _diskNumber = requiredSegment;
- }
-
- // validate the ZIP64 usage
- if (_container.Zip64 == Zip64Option.Never && (uint)_RelativeOffsetOfLocalHeader >= 0xFFFFFFFF)
- throw new ZipException("Offset within the zip archive exceeds 0xFFFFFFFF. Consider setting the UseZip64WhenSaving property on the ZipFile instance.");
-
-
- // finally, write the header to the stream
- s.Write(bytes, 0, i);
-
- // now that the header is written, we can turn off the contiguous write restriction.
- if (zss != null)
- zss.ContiguousWrite = false;
-
- // Preserve this header data, we'll use it again later.
- // ..when seeking backward, to write again, after we have the Crc, compressed
- // and uncompressed sizes.
- // ..and when writing the central directory structure.
- _EntryHeader = bytes;
- }
-
-
-
-
- private Int32 FigureCrc32()
- {
- if (_crcCalculated == false)
- {
- Stream input = null;
- // get the original stream:
- if (this._Source == ZipEntrySource.WriteDelegate)
- {
- var output = new Ionic.Crc.CrcCalculatorStream(Stream.Null);
- // allow the application to write the data
- this._WriteDelegate(this.FileName, output);
- _Crc32 = output.Crc;
- }
- else if (this._Source == ZipEntrySource.ZipFile)
- {
- // nothing to do - the CRC is already set
- }
- else
- {
- if (this._Source == ZipEntrySource.Stream)
- {
- PrepSourceStream();
- input = this._sourceStream;
- }
- else if (this._Source == ZipEntrySource.JitStream)
- {
- // allow the application to open the stream
- if (this._sourceStream == null)
- _sourceStream = this._OpenDelegate(this.FileName);
- PrepSourceStream();
- input = this._sourceStream;
- }
- else if (this._Source == ZipEntrySource.ZipOutputStream)
- {
- }
- else
- {
- //input = File.OpenRead(LocalFileName);
- input = File.Open(LocalFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
- }
-
- var crc32 = new Ionic.Crc.CRC32();
- _Crc32 = crc32.GetCrc32(input);
-
- if (_sourceStream == null)
- {
-#if NETCF
- input.Close();
-#else
- input.Dispose();
-#endif
- }
- }
- _crcCalculated = true;
- }
- return _Crc32;
- }
-
-
- ///
- /// Stores the position of the entry source stream, or, if the position is
- /// already stored, seeks to that position.
- ///
- ///
- ///
- ///
- /// This method is called in prep for reading the source stream. If PKZIP
- /// encryption is used, then we need to calc the CRC32 before doing the
- /// encryption, because the CRC is used in the 12th byte of the PKZIP
- /// encryption header. So, we need to be able to seek backward in the source
- /// when saving the ZipEntry. This method is called from the place that
- /// calculates the CRC, and also from the method that does the encryption of
- /// the file data.
- ///
- ///
- ///
- /// The first time through, this method sets the _sourceStreamOriginalPosition
- /// field. Subsequent calls to this method seek to that position.
- ///
- ///
- private void PrepSourceStream()
- {
- if (_sourceStream == null)
- throw new ZipException(String.Format("The input stream is null for entry '{0}'.", FileName));
-
- if (this._sourceStreamOriginalPosition != null)
- {
- // this will happen the 2nd cycle through, if the stream is seekable
- this._sourceStream.Position = this._sourceStreamOriginalPosition.Value;
- }
- else if (this._sourceStream.CanSeek)
- {
- // this will happen the first cycle through, if seekable
- this._sourceStreamOriginalPosition = new Nullable(this._sourceStream.Position);
- }
- else if (this.Encryption == EncryptionAlgorithm.PkzipWeak)
- {
- // In general, using PKZIP encryption on a a zip entry whose input
- // comes from a non-seekable stream, is tricky. Here's why:
- //
- // Byte 11 of the PKZIP encryption header is used for password
- // validation and consistency checknig.
- //
- // Normally, the highest byte of the CRC is used as the 11th (last) byte
- // in the PKZIP encryption header. This means the CRC must be known
- // before encryption is performed. Normally that means we read the full
- // data stream, compute the CRC, then seek back and read it again for
- // the compression+encryption phase. Obviously this is bad for
- // performance with a large input file.
- //
- // There's a twist in the ZIP spec (actually documented only in infozip
- // code, not in the spec itself) that allows the high-order byte of the
- // last modified time for the entry, when the lastmod time is in packed
- // (DOS) format, to be used for Byte 11 in the encryption header. In
- // this case, the bit 3 "data descriptor" must be used.
- //
- // An intelligent implementation would therefore force the use of the
- // bit 3 data descriptor when PKZIP encryption is in use, regardless.
- // This avoids the double-read of the stream to be encrypted. So far,
- // DotNetZip doesn't do that; it just punts when the input stream is
- // non-seekable, and the output does not use Bit 3.
- //
- // The other option is to use the CRC when it is already available, eg,
- // when the source for the data is a ZipEntry (when the zip file is
- // being updated). In this case we already know the CRC and can just use
- // what we know.
-
- if (this._Source != ZipEntrySource.ZipFile && ((this._BitField & 0x0008) != 0x0008))
- throw new ZipException("It is not possible to use PKZIP encryption on a non-seekable input stream");
- }
- }
-
-
- ///
- /// Copy metadata that may have been changed by the app. We do this when
- /// resetting the zipFile instance. If the app calls Save() on a ZipFile, then
- /// tries to party on that file some more, we may need to Reset() it , which
- /// means re-reading the entries and then copying the metadata. I think.
- ///
- internal void CopyMetaData(ZipEntry source)
- {
- this.__FileDataPosition = source.__FileDataPosition;
- this.CompressionMethod = source.CompressionMethod;
- this._CompressionMethod_FromZipFile = source._CompressionMethod_FromZipFile;
- this._CompressedFileDataSize = source._CompressedFileDataSize;
- this._UncompressedSize = source._UncompressedSize;
- this._BitField = source._BitField;
- this._Source = source._Source;
- this._LastModified = source._LastModified;
- this._Mtime = source._Mtime;
- this._Atime = source._Atime;
- this._Ctime = source._Ctime;
- this._ntfsTimesAreSet = source._ntfsTimesAreSet;
- this._emitUnixTimes = source._emitUnixTimes;
- this._emitNtfsTimes = source._emitNtfsTimes;
- }
-
-
- private void OnWriteBlock(Int64 bytesXferred, Int64 totalBytesToXfer)
- {
- if (_container.ZipFile != null)
- _ioOperationCanceled = _container.ZipFile.OnSaveBlock(this, bytesXferred, totalBytesToXfer);
- }
-
-
-
- private void _WriteEntryData(Stream s)
- {
- // Read in the data from the input stream (often a file in the filesystem),
- // and write it to the output stream, calculating a CRC on it as we go.
- // We will also compress and encrypt as necessary.
-
- Stream input = null;
- long fdp = -1L;
- try
- {
- // Want to record the position in the zip file of the zip entry
- // data (as opposed to the metadata). s.Position may fail on some
- // write-only streams, eg stdout or System.Web.HttpResponseStream.
- // We swallow that exception, because we don't care, in that case.
- // But, don't set __FileDataPosition directly. It may be needed
- // to READ the zip entry from the zip file, if this is a
- // "re-stream" situation. In other words if the zip entry has
- // changed compression level, or compression method, or (maybe?)
- // encryption algorithm. In that case if the original entry is
- // encrypted, we need __FileDataPosition to be the value for the
- // input zip file. This s.Position is for the output zipfile. So
- // we copy fdp to __FileDataPosition after this entry has been
- // (maybe) restreamed.
- fdp = s.Position;
- }
- catch (Exception) { }
-
- try
- {
- // Use fileLength for progress updates, and to decide whether we can
- // skip encryption and compression altogether (in case of length==zero)
- long fileLength = SetInputAndFigureFileLength(ref input);
-
- // Wrap a counting stream around the raw output stream:
- // This is the last thing that happens before the bits go to the
- // application-provided stream.
- //
- // Sometimes s is a CountingStream. Doesn't matter. Wrap it with a
- // counter anyway. We need to count at both levels.
-
- CountingStream entryCounter = new CountingStream(s);
-
- Stream encryptor;
- Stream compressor;
-
- if (fileLength != 0L)
- {
- // Maybe wrap an encrypting stream around the counter: This will
- // happen BEFORE output counting, and AFTER compression, if encryption
- // is used.
- encryptor = MaybeApplyEncryption(entryCounter);
-
- // Maybe wrap a compressing Stream around that.
- // This will happen BEFORE encryption (if any) as we write data out.
- compressor = MaybeApplyCompression(encryptor, fileLength);
- }
- else
- {
- encryptor = compressor = entryCounter;
- }
-
- // Wrap a CrcCalculatorStream around that.
- // This will happen BEFORE compression (if any) as we write data out.
- var output = new Ionic.Crc.CrcCalculatorStream(compressor, true);
-
- // output.Write() causes this flow:
- // calc-crc -> compress -> encrypt -> count -> actually write
-
- if (this._Source == ZipEntrySource.WriteDelegate)
- {
- // allow the application to write the data
- this._WriteDelegate(this.FileName, output);
- }
- else
- {
- // synchronously copy the input stream to the output stream-chain
- byte[] buffer = new byte[BufferSize];
- int n;
- while ((n = SharedUtilities.ReadWithRetry(input, buffer, 0, buffer.Length, FileName)) != 0)
- {
- output.Write(buffer, 0, n);
- OnWriteBlock(output.TotalBytesSlurped, fileLength);
- if (_ioOperationCanceled)
- break;
- }
- }
-
- FinishOutputStream(s, entryCounter, encryptor, compressor, output);
- }
- finally
- {
- if (this._Source == ZipEntrySource.JitStream)
- {
- // allow the application to close the stream
- if (this._CloseDelegate != null)
- this._CloseDelegate(this.FileName, input);
- }
- else if ((input as FileStream) != null)
- {
-#if NETCF
- input.Close();
-#else
- input.Dispose();
-#endif
- }
- }
-
- if (_ioOperationCanceled)
- return;
-
- // set FDP now, to allow for re-streaming
- this.__FileDataPosition = fdp;
- PostProcessOutput(s);
- }
-
-
- ///
- /// Set the input stream and get its length, if possible. The length is
- /// used for progress updates, AND, to allow an optimization in case of
- /// a stream/file of zero length. In that case we skip the Encrypt and
- /// compression Stream. (like DeflateStream or BZip2OutputStream)
- ///
- private long SetInputAndFigureFileLength(ref Stream input)
- {
- long fileLength = -1L;
- // get the original stream:
- if (this._Source == ZipEntrySource.Stream)
- {
- PrepSourceStream();
- input = this._sourceStream;
-
- // Try to get the length, no big deal if not available.
- try { fileLength = this._sourceStream.Length; }
- catch (NotSupportedException) { }
- }
- else if (this._Source == ZipEntrySource.ZipFile)
- {
- // we are "re-streaming" the zip entry.
- string pwd = (_Encryption_FromZipFile == EncryptionAlgorithm.None) ? null : (this._Password ?? this._container.Password);
- this._sourceStream = InternalOpenReader(pwd);
- PrepSourceStream();
- input = this._sourceStream;
- fileLength = this._sourceStream.Length;
- }
- else if (this._Source == ZipEntrySource.JitStream)
- {
- // allow the application to open the stream
- if (this._sourceStream == null) _sourceStream = this._OpenDelegate(this.FileName);
- PrepSourceStream();
- input = this._sourceStream;
- try { fileLength = this._sourceStream.Length; }
- catch (NotSupportedException) { }
- }
- else if (this._Source == ZipEntrySource.FileSystem)
- {
- // workitem 7145
- FileShare fs = FileShare.ReadWrite;
-#if !NETCF
- // FileShare.Delete is not defined for the Compact Framework
- fs |= FileShare.Delete;
-#endif
- // workitem 8423
- input = File.Open(LocalFileName, FileMode.Open, FileAccess.Read, fs);
- fileLength = input.Length;
- }
-
- return fileLength;
- }
-
-
-
- internal void FinishOutputStream(Stream s,
- CountingStream entryCounter,
- Stream encryptor,
- Stream compressor,
- Ionic.Crc.CrcCalculatorStream output)
- {
- if (output == null) return;
-
- output.Close();
-
- // by calling Close() on the deflate stream, we write the footer bytes, as necessary.
- if ((compressor as Ionic.Zlib.DeflateStream) != null)
- compressor.Close();
-#if BZIP
- else if ((compressor as Ionic.BZip2.BZip2OutputStream) != null)
- compressor.Close();
-#if !NETCF
- else if ((compressor as Ionic.BZip2.ParallelBZip2OutputStream) != null)
- compressor.Close();
-#endif
-#endif
-
-#if !NETCF
- else if ((compressor as Ionic.Zlib.ParallelDeflateOutputStream) != null)
- compressor.Close();
-#endif
-
- encryptor.Flush();
- encryptor.Close();
-
- _LengthOfTrailer = 0;
-
- _UncompressedSize = output.TotalBytesSlurped;
-
-#if AESCRYPTO
- WinZipAesCipherStream wzacs = encryptor as WinZipAesCipherStream;
- if (wzacs != null && _UncompressedSize > 0)
- {
- s.Write(wzacs.FinalAuthentication, 0, 10);
- _LengthOfTrailer += 10;
- }
-#endif
- _CompressedFileDataSize = entryCounter.BytesWritten;
- _CompressedSize = _CompressedFileDataSize; // may be adjusted
- _Crc32 = output.Crc;
-
- // Set _RelativeOffsetOfLocalHeader now, to allow for re-streaming
- StoreRelativeOffset();
- }
-
-
-
-
- internal void PostProcessOutput(Stream s)
- {
- var s1 = s as CountingStream;
-
- // workitem 8931 - for WriteDelegate.
- // The WriteDelegate changes things because there can be a zero-byte stream
- // written. In all other cases DotNetZip knows the length of the stream
- // before compressing and encrypting. In this case we have to circle back,
- // and omit all the crypto stuff - the GP bitfield, and the crypto header.
- if (_UncompressedSize == 0 && _CompressedSize == 0)
- {
- if (this._Source == ZipEntrySource.ZipOutputStream) return; // nothing to do...
-
- if (_Password != null)
- {
- int headerBytesToRetract = 0;
- if (Encryption == EncryptionAlgorithm.PkzipWeak)
- headerBytesToRetract = 12;
-#if AESCRYPTO
- else if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
- Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- headerBytesToRetract = _aesCrypto_forWrite._Salt.Length + _aesCrypto_forWrite.GeneratedPV.Length;
- }
-#endif
- if (this._Source == ZipEntrySource.ZipOutputStream && !s.CanSeek)
- throw new ZipException("Zero bytes written, encryption in use, and non-seekable output.");
-
- if (Encryption != EncryptionAlgorithm.None)
- {
- // seek back in the stream to un-output the security metadata
- s.Seek(-1 * headerBytesToRetract, SeekOrigin.Current);
- s.SetLength(s.Position);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(s);
-
- // workitem 11131
- // adjust the count on the CountingStream as necessary
- if (s1 != null) s1.Adjust(headerBytesToRetract);
-
- // subtract the size of the security header from the _LengthOfHeader
- _LengthOfHeader -= headerBytesToRetract;
- __FileDataPosition -= headerBytesToRetract;
- }
- _Password = null;
-
- // turn off the encryption bit
- _BitField &= ~(0x0001);
-
- // copy the updated bitfield value into the header
- int j = 6;
- _EntryHeader[j++] = (byte)(_BitField & 0x00FF);
- _EntryHeader[j++] = (byte)((_BitField & 0xFF00) >> 8);
-
-#if AESCRYPTO
- if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
- Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- // Fix the extra field - overwrite the 0x9901 headerId
- // with dummy data. (arbitrarily, 0x9999)
- Int16 fnLength = (short)(_EntryHeader[26] + _EntryHeader[27] * 256);
- int offx = 30 + fnLength;
- int aesIndex = FindExtraFieldSegment(_EntryHeader, offx, 0x9901);
- if (aesIndex >= 0)
- {
- _EntryHeader[aesIndex++] = 0x99;
- _EntryHeader[aesIndex++] = 0x99;
- }
- }
-#endif
- }
-
- CompressionMethod = 0;
- Encryption = EncryptionAlgorithm.None;
- }
- else if (_zipCrypto_forWrite != null
-#if AESCRYPTO
- || _aesCrypto_forWrite != null
-#endif
- )
-
- {
- if (Encryption == EncryptionAlgorithm.PkzipWeak)
- {
- _CompressedSize += 12; // 12 extra bytes for the encryption header
- }
-#if AESCRYPTO
- else if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
- Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- // adjust the compressed size to include the variable (salt+pv)
- // security header and 10-byte trailer. According to the winzip AES
- // spec, that metadata is included in the "Compressed Size" figure
- // when encoding the zip archive.
- _CompressedSize += _aesCrypto_forWrite.SizeOfEncryptionMetadata;
- }
-#endif
- }
-
- int i = 8;
- _EntryHeader[i++] = (byte)(_CompressionMethod & 0x00FF);
- _EntryHeader[i++] = (byte)((_CompressionMethod & 0xFF00) >> 8);
-
- i = 14;
- // CRC - the correct value now
- _EntryHeader[i++] = (byte)(_Crc32 & 0x000000FF);
- _EntryHeader[i++] = (byte)((_Crc32 & 0x0000FF00) >> 8);
- _EntryHeader[i++] = (byte)((_Crc32 & 0x00FF0000) >> 16);
- _EntryHeader[i++] = (byte)((_Crc32 & 0xFF000000) >> 24);
-
- SetZip64Flags();
-
- // (i==26) filename length (Int16)
- Int16 filenameLength = (short)(_EntryHeader[26] + _EntryHeader[27] * 256);
- Int16 extraFieldLength = (short)(_EntryHeader[28] + _EntryHeader[29] * 256);
-
- if (_OutputUsesZip64.Value)
- {
- // VersionNeededToExtract - set to 45 to indicate zip64
- _EntryHeader[4] = (byte)(45 & 0x00FF);
- _EntryHeader[5] = 0x00;
-
- // workitem 7924 - don't need bit 3
- // // workitem 7917
- // // set bit 3 for ZIP64 compatibility with WinZip12
- // _BitField |= 0x0008;
- // _EntryHeader[6] = (byte)(_BitField & 0x00FF);
-
- // CompressedSize and UncompressedSize - 0xFF
- for (int j = 0; j < 8; j++)
- _EntryHeader[i++] = 0xff;
-
- // At this point we need to find the "Extra field" that follows the
- // filename. We had already emitted it, but the data (uncomp, comp,
- // ROLH) was not available at the time we did so. Here, we emit it
- // again, with final values.
-
- i = 30 + filenameLength;
- _EntryHeader[i++] = 0x01; // zip64
- _EntryHeader[i++] = 0x00;
-
- i += 2; // skip over data size, which is 16+4
-
- Array.Copy(BitConverter.GetBytes(_UncompressedSize), 0, _EntryHeader, i, 8);
- i += 8;
- Array.Copy(BitConverter.GetBytes(_CompressedSize), 0, _EntryHeader, i, 8);
- }
- else
- {
- // VersionNeededToExtract - reset to 20 since no zip64
- _EntryHeader[4] = (byte)(20 & 0x00FF);
- _EntryHeader[5] = 0x00;
-
- // CompressedSize - the correct value now
- i = 18;
- _EntryHeader[i++] = (byte)(_CompressedSize & 0x000000FF);
- _EntryHeader[i++] = (byte)((_CompressedSize & 0x0000FF00) >> 8);
- _EntryHeader[i++] = (byte)((_CompressedSize & 0x00FF0000) >> 16);
- _EntryHeader[i++] = (byte)((_CompressedSize & 0xFF000000) >> 24);
-
- // UncompressedSize - the correct value now
- _EntryHeader[i++] = (byte)(_UncompressedSize & 0x000000FF);
- _EntryHeader[i++] = (byte)((_UncompressedSize & 0x0000FF00) >> 8);
- _EntryHeader[i++] = (byte)((_UncompressedSize & 0x00FF0000) >> 16);
- _EntryHeader[i++] = (byte)((_UncompressedSize & 0xFF000000) >> 24);
-
- // The HeaderId in the extra field header, is already dummied out.
- if (extraFieldLength != 0)
- {
- i = 30 + filenameLength;
- // For zip archives written by this library, if the zip64
- // header exists, it is the first header. Because of the logic
- // used when first writing the _EntryHeader bytes, the
- // HeaderId is not guaranteed to be any particular value. So
- // we determine if the first header is a putative zip64 header
- // by examining the datasize. UInt16 HeaderId =
- // (UInt16)(_EntryHeader[i] + _EntryHeader[i + 1] * 256);
- Int16 DataSize = (short)(_EntryHeader[i + 2] + _EntryHeader[i + 3] * 256);
- if (DataSize == 16)
- {
- // reset to Header Id to dummy value, effectively dummy-ing out the zip64 metadata
- _EntryHeader[i++] = 0x99;
- _EntryHeader[i++] = 0x99;
- }
- }
- }
-
-
-#if AESCRYPTO
-
- if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
- Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- // Must set compressionmethod to 0x0063 (decimal 99)
- //
- // and then set the compression method bytes inside the extra
- // field to the actual compression method value.
-
- i = 8;
- _EntryHeader[i++] = 0x63;
- _EntryHeader[i++] = 0;
-
- i = 30 + filenameLength;
- do
- {
- UInt16 HeaderId = (UInt16)(_EntryHeader[i] + _EntryHeader[i + 1] * 256);
- Int16 DataSize = (short)(_EntryHeader[i + 2] + _EntryHeader[i + 3] * 256);
- if (HeaderId != 0x9901)
- {
- // skip this header
- i += DataSize + 4;
- }
- else
- {
- i += 9;
- // actual compression method
- _EntryHeader[i++] = (byte)(_CompressionMethod & 0x00FF);
- _EntryHeader[i++] = (byte)(_CompressionMethod & 0xFF00);
- }
- } while (i < (extraFieldLength - 30 - filenameLength));
- }
-#endif
-
- // finally, write the data.
-
- // workitem 7216 - sometimes we don't seek even if we CAN. ASP.NET
- // Response.OutputStream, or stdout are non-seekable. But we may also want
- // to NOT seek in other cases, eg zip64. For all cases, we just check bit 3
- // to see if we want to seek. There's one exception - if using a
- // ZipOutputStream, and PKZip encryption is in use, then we set bit 3 even
- // if the out is seekable. This is so the check on the last byte of the
- // PKZip Encryption Header can be done on the current time, as opposed to
- // the CRC, to prevent streaming the file twice. So, test for
- // ZipOutputStream and seekable, and if so, seek back, even if bit 3 is set.
-
- if ((_BitField & 0x0008) != 0x0008 ||
- (this._Source == ZipEntrySource.ZipOutputStream && s.CanSeek))
- {
- // seek back and rewrite the entry header
- var zss = s as ZipSegmentedStream;
- if (zss != null && _diskNumber != zss.CurrentSegment)
- {
- // In this case the entry header is in a different file,
- // which has already been closed. Need to re-open it.
- using (Stream hseg = ZipSegmentedStream.ForUpdate(this._container.ZipFile.Name, _diskNumber))
- {
- hseg.Seek(this._RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
- hseg.Write(_EntryHeader, 0, _EntryHeader.Length);
- }
- }
- else
- {
- // seek in the raw output stream, to the beginning of the header for
- // this entry.
- // workitem 8098: ok (output)
- s.Seek(this._RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
-
- // write the updated header to the output stream
- s.Write(_EntryHeader, 0, _EntryHeader.Length);
-
- // adjust the count on the CountingStream as necessary
- if (s1 != null) s1.Adjust(_EntryHeader.Length);
-
- // seek in the raw output stream, to the end of the file data
- // for this entry
- s.Seek(_CompressedSize, SeekOrigin.Current);
- }
- }
-
- // emit the descriptor - only if not a directory.
- if (((_BitField & 0x0008) == 0x0008) && !IsDirectory)
- {
- byte[] Descriptor = new byte[16 + (_OutputUsesZip64.Value ? 8 : 0)];
- i = 0;
-
- // signature
- Array.Copy(BitConverter.GetBytes(ZipConstants.ZipEntryDataDescriptorSignature), 0, Descriptor, i, 4);
- i += 4;
-
- // CRC - the correct value now
- Array.Copy(BitConverter.GetBytes(_Crc32), 0, Descriptor, i, 4);
- i += 4;
-
- // workitem 7917
- if (_OutputUsesZip64.Value)
- {
- // CompressedSize - the correct value now
- Array.Copy(BitConverter.GetBytes(_CompressedSize), 0, Descriptor, i, 8);
- i += 8;
-
- // UncompressedSize - the correct value now
- Array.Copy(BitConverter.GetBytes(_UncompressedSize), 0, Descriptor, i, 8);
- i += 8;
- }
- else
- {
- // CompressedSize - (lower 32 bits) the correct value now
- Descriptor[i++] = (byte)(_CompressedSize & 0x000000FF);
- Descriptor[i++] = (byte)((_CompressedSize & 0x0000FF00) >> 8);
- Descriptor[i++] = (byte)((_CompressedSize & 0x00FF0000) >> 16);
- Descriptor[i++] = (byte)((_CompressedSize & 0xFF000000) >> 24);
-
- // UncompressedSize - (lower 32 bits) the correct value now
- Descriptor[i++] = (byte)(_UncompressedSize & 0x000000FF);
- Descriptor[i++] = (byte)((_UncompressedSize & 0x0000FF00) >> 8);
- Descriptor[i++] = (byte)((_UncompressedSize & 0x00FF0000) >> 16);
- Descriptor[i++] = (byte)((_UncompressedSize & 0xFF000000) >> 24);
- }
-
- // finally, write the trailing descriptor to the output stream
- s.Write(Descriptor, 0, Descriptor.Length);
-
- _LengthOfTrailer += Descriptor.Length;
- }
- }
-
-
-
- private void SetZip64Flags()
- {
- // zip64 housekeeping
- _entryRequiresZip64 = new Nullable
- (_CompressedSize >= 0xFFFFFFFF || _UncompressedSize >= 0xFFFFFFFF || _RelativeOffsetOfLocalHeader >= 0xFFFFFFFF);
-
- // validate the ZIP64 usage
- if (_container.Zip64 == Zip64Option.Never && _entryRequiresZip64.Value)
- throw new ZipException("Compressed or Uncompressed size, or offset exceeds the maximum value. Consider setting the UseZip64WhenSaving property on the ZipFile instance.");
-
- _OutputUsesZip64 = new Nullable(_container.Zip64 == Zip64Option.Always || _entryRequiresZip64.Value);
- }
-
-
-
- ///
- /// Prepare the given stream for output - wrap it in a CountingStream, and
- /// then in a CRC stream, and an encryptor and deflator as appropriate.
- ///
- ///
- ///
- /// Previously this was used in ZipEntry.Write(), but in an effort to
- /// introduce some efficiencies in that method I've refactored to put the
- /// code inline. This method still gets called by ZipOutputStream.
- ///
- ///
- internal void PrepOutputStream(Stream s,
- long streamLength,
- out CountingStream outputCounter,
- out Stream encryptor,
- out Stream compressor,
- out Ionic.Crc.CrcCalculatorStream output)
- {
- TraceWriteLine("PrepOutputStream: e({0}) comp({1}) crypto({2}) zf({3})",
- FileName,
- CompressionLevel,
- Encryption,
- _container.Name);
-
- // Wrap a counting stream around the raw output stream:
- // This is the last thing that happens before the bits go to the
- // application-provided stream.
- outputCounter = new CountingStream(s);
-
- // Sometimes the incoming "raw" output stream is already a CountingStream.
- // Doesn't matter. Wrap it with a counter anyway. We need to count at both
- // levels.
-
- if (streamLength != 0L)
- {
- // Maybe wrap an encrypting stream around that:
- // This will happen BEFORE output counting, and AFTER deflation, if encryption
- // is used.
- encryptor = MaybeApplyEncryption(outputCounter);
-
- // Maybe wrap a compressing Stream around that.
- // This will happen BEFORE encryption (if any) as we write data out.
- compressor = MaybeApplyCompression(encryptor, streamLength);
- }
- else
- {
- encryptor = compressor = outputCounter;
- }
- // Wrap a CrcCalculatorStream around that.
- // This will happen BEFORE compression (if any) as we write data out.
- output = new Ionic.Crc.CrcCalculatorStream(compressor, true);
- }
-
-
-
- private Stream MaybeApplyCompression(Stream s, long streamLength)
- {
- if (_CompressionMethod == 0x08 && CompressionLevel != Ionic.Zlib.CompressionLevel.None)
- {
-#if !NETCF
- // ParallelDeflateThreshold == 0 means ALWAYS use parallel deflate
- // ParallelDeflateThreshold == -1L means NEVER use parallel deflate
- // Other values specify the actual threshold.
- if (_container.ParallelDeflateThreshold == 0L ||
- (streamLength > _container.ParallelDeflateThreshold &&
- _container.ParallelDeflateThreshold > 0L))
- {
- // This is sort of hacky.
- //
- // It's expensive to create a ParallelDeflateOutputStream, because
- // of the large memory buffers. But the class is unlike most Stream
- // classes in that it can be re-used, so the caller can compress
- // multiple files with it, one file at a time. The key is to call
- // Reset() on it, in between uses.
- //
- // The ParallelDeflateOutputStream is attached to the container
- // itself - there is just one for the entire ZipFile or
- // ZipOutputStream. So it gets created once, per save, and then
- // re-used many times.
- //
- // This approach will break when we go to a "parallel save"
- // approach, where multiple entries within the zip file are being
- // compressed and saved at the same time. But for now it's ok.
- //
-
- // instantiate the ParallelDeflateOutputStream
- if (_container.ParallelDeflater == null)
- {
- _container.ParallelDeflater =
- new Ionic.Zlib.ParallelDeflateOutputStream(s,
- CompressionLevel,
- _container.Strategy,
- true);
- // can set the codec buffer size only before the first call to Write().
- if (_container.CodecBufferSize > 0)
- _container.ParallelDeflater.BufferSize = _container.CodecBufferSize;
- if (_container.ParallelDeflateMaxBufferPairs > 0)
- _container.ParallelDeflater.MaxBufferPairs =
- _container.ParallelDeflateMaxBufferPairs;
- }
- // reset it with the new stream
- Ionic.Zlib.ParallelDeflateOutputStream o1 = _container.ParallelDeflater;
- o1.Reset(s);
- return o1;
- }
-#endif
- var o = new Ionic.Zlib.DeflateStream(s, Ionic.Zlib.CompressionMode.Compress,
- CompressionLevel,
- true);
- if (_container.CodecBufferSize > 0)
- o.BufferSize = _container.CodecBufferSize;
- o.Strategy = _container.Strategy;
- return o;
- }
-
-
-#if BZIP
- if (_CompressionMethod == 0x0c)
- {
-#if !NETCF
- if (_container.ParallelDeflateThreshold == 0L ||
- (streamLength > _container.ParallelDeflateThreshold &&
- _container.ParallelDeflateThreshold > 0L))
- {
-
- var o1 = new Ionic.BZip2.ParallelBZip2OutputStream(s, true);
- return o1;
- }
-#endif
- var o = new Ionic.BZip2.BZip2OutputStream(s, true);
- return o;
- }
-#endif
-
- return s;
- }
-
-
-
- private Stream MaybeApplyEncryption(Stream s)
- {
- if (Encryption == EncryptionAlgorithm.PkzipWeak)
- {
- TraceWriteLine("MaybeApplyEncryption: e({0}) PKZIP", FileName);
-
- return new ZipCipherStream(s, _zipCrypto_forWrite, CryptoMode.Encrypt);
- }
-#if AESCRYPTO
- if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
- Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- TraceWriteLine("MaybeApplyEncryption: e({0}) AES", FileName);
-
- return new WinZipAesCipherStream(s, _aesCrypto_forWrite, CryptoMode.Encrypt);
- }
-#endif
- TraceWriteLine("MaybeApplyEncryption: e({0}) None", FileName);
-
- return s;
- }
-
-
-
- private void OnZipErrorWhileSaving(Exception e)
- {
- if (_container.ZipFile != null)
- _ioOperationCanceled = _container.ZipFile.OnZipErrorSaving(this, e);
- }
-
-
-
- internal void Write(Stream s)
- {
- var cs1 = s as CountingStream;
- var zss1 = s as ZipSegmentedStream;
-
- bool done = false;
- do
- {
- try
- {
- // When the app is updating a zip file, it may be possible to
- // just copy data for a ZipEntry from the source zipfile to the
- // destination, as a block, without decompressing and
- // recompressing, etc. But, in some cases the app modifies the
- // properties on a ZipEntry prior to calling Save(). A change to
- // any of the metadata - the FileName, CompressioLeve and so on,
- // means DotNetZip cannot simply copy through the existing
- // ZipEntry data unchanged.
- //
- // There are two cases:
- //
- // 1. Changes to only metadata, which means the header and
- // central directory must be changed.
- //
- // 2. Changes to the properties that affect the compressed
- // stream, such as CompressionMethod, CompressionLevel, or
- // EncryptionAlgorithm. In this case, DotNetZip must
- // "re-stream" the data: the old entry data must be maybe
- // decrypted, maybe decompressed, then maybe re-compressed
- // and maybe re-encrypted.
- //
- // This test checks if the source for the entry data is a zip file, and
- // if a restream is necessary. If NOT, then it just copies through
- // one entry, potentially changing the metadata.
-
- if (_Source == ZipEntrySource.ZipFile && !_restreamRequiredOnSave)
- {
- CopyThroughOneEntry(s);
- return;
- }
-
- // Is the entry a directory? If so, the write is relatively simple.
- if (IsDirectory)
- {
- WriteHeader(s, 1);
- StoreRelativeOffset();
- _entryRequiresZip64 = new Nullable(_RelativeOffsetOfLocalHeader >= 0xFFFFFFFF);
- _OutputUsesZip64 = new Nullable(_container.Zip64 == Zip64Option.Always || _entryRequiresZip64.Value);
- // handle case for split archives
- if (zss1 != null)
- _diskNumber = zss1.CurrentSegment;
-
- return;
- }
-
- // At this point, the source for this entry is not a directory, and
- // not a previously created zip file, or the source for the entry IS
- // a previously created zip but the settings whave changed in
- // important ways and therefore we will need to process the
- // bytestream (compute crc, maybe compress, maybe encrypt) in order
- // to write the content into the new zip.
- //
- // We do this in potentially 2 passes: The first time we do it as
- // requested, maybe with compression and maybe encryption. If that
- // causes the bytestream to inflate in size, and if compression was
- // on, then we turn off compression and do it again.
-
-
- bool readAgain = true;
- int nCycles = 0;
- do
- {
- nCycles++;
-
- WriteHeader(s, nCycles);
-
- // write the encrypted header
- WriteSecurityMetadata(s);
-
- // write the (potentially compressed, potentially encrypted) file data
- _WriteEntryData(s);
-
- // track total entry size (including the trailing descriptor and MAC)
- _TotalEntrySize = _LengthOfHeader + _CompressedFileDataSize + _LengthOfTrailer;
-
- // The file data has now been written to the stream, and
- // the file pointer is positioned directly after file data.
-
- if (nCycles > 1) readAgain = false;
- else if (!s.CanSeek) readAgain = false;
- else readAgain = WantReadAgain();
-
- if (readAgain)
- {
- // Seek back in the raw output stream, to the beginning of the file
- // data for this entry.
-
- // handle case for split archives
- if (zss1 != null)
- {
- // Console.WriteLine("***_diskNumber/first: {0}", _diskNumber);
- // Console.WriteLine("***_diskNumber/current: {0}", zss.CurrentSegment);
- zss1.TruncateBackward(_diskNumber, _RelativeOffsetOfLocalHeader);
- }
- else
- // workitem 8098: ok (output).
- s.Seek(_RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
-
- // If the last entry expands, we read again; but here, we must
- // truncate the stream to prevent garbage data after the
- // end-of-central-directory.
-
- // workitem 8098: ok (output).
- s.SetLength(s.Position);
-
- // Adjust the count on the CountingStream as necessary.
- if (cs1 != null) cs1.Adjust(_TotalEntrySize);
- }
- }
- while (readAgain);
- _skippedDuringSave = false;
- done = true;
- }
- catch (System.Exception exc1)
- {
- ZipErrorAction orig = this.ZipErrorAction;
- int loop = 0;
- do
- {
- if (ZipErrorAction == ZipErrorAction.Throw)
- throw;
-
- if (ZipErrorAction == ZipErrorAction.Skip ||
- ZipErrorAction == ZipErrorAction.Retry)
- {
- // must reset file pointer here.
- // workitem 13903 - seek back only when necessary
- long p1 = (cs1 != null)
- ? cs1.ComputedPosition
- : s.Position;
- long delta = p1 - _future_ROLH;
- if (delta > 0)
- {
- s.Seek(delta, SeekOrigin.Current); // may throw
- long p2 = s.Position;
- s.SetLength(s.Position); // to prevent garbage if this is the last entry
- if (cs1 != null) cs1.Adjust(p1 - p2);
- }
- if (ZipErrorAction == ZipErrorAction.Skip)
- {
- WriteStatus("Skipping file {0} (exception: {1})", LocalFileName, exc1.ToString());
-
- _skippedDuringSave = true;
- done = true;
- }
- else
- this.ZipErrorAction = orig;
- break;
- }
-
- if (loop > 0) throw;
-
- if (ZipErrorAction == ZipErrorAction.InvokeErrorEvent)
- {
- OnZipErrorWhileSaving(exc1);
- if (_ioOperationCanceled)
- {
- done = true;
- break;
- }
- }
- loop++;
- }
- while (true);
- }
- }
- while (!done);
- }
-
-
- internal void StoreRelativeOffset()
- {
- _RelativeOffsetOfLocalHeader = _future_ROLH;
- }
-
-
-
- internal void NotifySaveComplete()
- {
- // When updating a zip file, there are two contexts for properties
- // like Encryption or CompressionMethod - the values read from the
- // original zip file, and the values used in the updated zip file.
- // The _FromZipFile versions are the originals. At the end of a save,
- // these values are the same. So we need to update them. This takes
- // care of the boundary case where a single zipfile instance can be
- // saved multiple times, with distinct changes to the properties on
- // the entries, in between each Save().
- _Encryption_FromZipFile = _Encryption;
- _CompressionMethod_FromZipFile = _CompressionMethod;
- _restreamRequiredOnSave = false;
- _metadataChanged = false;
- //_Source = ZipEntrySource.None;
- _Source = ZipEntrySource.ZipFile; // workitem 10694
- }
-
-
- internal void WriteSecurityMetadata(Stream outstream)
- {
- if (Encryption == EncryptionAlgorithm.None)
- return;
-
- string pwd = this._Password;
-
- // special handling for source == ZipFile.
- // Want to support the case where we re-stream an encrypted entry. This will involve,
- // at runtime, reading, decrypting, and decompressing from the original zip file, then
- // compressing, encrypting, and writing to the output zip file.
-
- // If that's what we're doing, and the password hasn't been set on the entry,
- // we use the container (ZipFile/ZipOutputStream) password to decrypt.
- // This test here says to use the container password to re-encrypt, as well,
- // with that password, if the entry password is null.
-
- if (this._Source == ZipEntrySource.ZipFile && pwd == null)
- pwd = this._container.Password;
-
- if (pwd == null)
- {
- _zipCrypto_forWrite = null;
-#if AESCRYPTO
- _aesCrypto_forWrite = null;
-#endif
- return;
- }
-
- TraceWriteLine("WriteSecurityMetadata: e({0}) crypto({1}) pw({2})",
- FileName, Encryption.ToString(), pwd);
-
- if (Encryption == EncryptionAlgorithm.PkzipWeak)
- {
- // If PKZip (weak) encryption is in use, then the encrypted entry data
- // is preceded by 12-byte "encryption header" for the entry.
-
- _zipCrypto_forWrite = ZipCrypto.ForWrite(pwd);
-
- // generate the random 12-byte header:
- var rnd = new System.Random();
- byte[] encryptionHeader = new byte[12];
- rnd.NextBytes(encryptionHeader);
-
- // workitem 8271
- if ((this._BitField & 0x0008) == 0x0008)
- {
- // In the case that bit 3 of the general purpose bit flag is set to
- // indicate the presence of a 'data descriptor' (signature
- // 0x08074b50), the last byte of the decrypted header is sometimes
- // compared with the high-order byte of the lastmodified time,
- // rather than the high-order byte of the CRC, to verify the
- // password.
- //
- // This is not documented in the PKWare Appnote.txt.
- // This was discovered this by analysis of the Crypt.c source file in the
- // InfoZip library
- // http://www.info-zip.org/pub/infozip/
-
- // Also, winzip insists on this!
- _TimeBlob = Ionic.Zip.SharedUtilities.DateTimeToPacked(LastModified);
- encryptionHeader[11] = (byte)((this._TimeBlob >> 8) & 0xff);
- }
- else
- {
- // When bit 3 is not set, the CRC value is required before
- // encryption of the file data begins. In this case there is no way
- // around it: must read the stream in its entirety to compute the
- // actual CRC before proceeding.
- FigureCrc32();
- encryptionHeader[11] = (byte)((this._Crc32 >> 24) & 0xff);
- }
-
- // Encrypt the random header, INCLUDING the final byte which is either
- // the high-order byte of the CRC32, or the high-order byte of the
- // _TimeBlob. Must do this BEFORE encrypting the file data. This
- // step changes the state of the cipher, or in the words of the PKZIP
- // spec, it "further initializes" the cipher keys.
-
- byte[] cipherText = _zipCrypto_forWrite.EncryptMessage(encryptionHeader, encryptionHeader.Length);
-
- // Write the ciphered bonafide encryption header.
- outstream.Write(cipherText, 0, cipherText.Length);
- _LengthOfHeader += cipherText.Length; // 12 bytes
- }
-
-#if AESCRYPTO
- else if (Encryption == EncryptionAlgorithm.WinZipAes128 ||
- Encryption == EncryptionAlgorithm.WinZipAes256)
- {
- // If WinZip AES encryption is in use, then the encrypted entry data is
- // preceded by a variable-sized Salt and a 2-byte "password
- // verification" value for the entry.
-
- int keystrength = GetKeyStrengthInBits(Encryption);
- _aesCrypto_forWrite = WinZipAesCrypto.Generate(pwd, keystrength);
- outstream.Write(_aesCrypto_forWrite.Salt, 0, _aesCrypto_forWrite._Salt.Length);
- outstream.Write(_aesCrypto_forWrite.GeneratedPV, 0, _aesCrypto_forWrite.GeneratedPV.Length);
- _LengthOfHeader += _aesCrypto_forWrite._Salt.Length + _aesCrypto_forWrite.GeneratedPV.Length;
-
- TraceWriteLine("WriteSecurityMetadata: AES e({0}) keybits({1}) _LOH({2})",
- FileName, keystrength, _LengthOfHeader);
-
- }
-#endif
-
- }
-
-
-
- private void CopyThroughOneEntry(Stream outStream)
- {
- // Just read the entry from the existing input zipfile and write to the output.
- // But, if metadata has changed (like file times or attributes), or if the ZIP64
- // option has changed, we can re-stream the entry data but must recompute the
- // metadata.
- if (this.LengthOfHeader == 0)
- throw new BadStateException("Bad header length.");
-
- // is it necessary to re-constitute new metadata for this entry?
- bool needRecompute = _metadataChanged ||
- (this.ArchiveStream is ZipSegmentedStream) ||
- (outStream is ZipSegmentedStream) ||
- (_InputUsesZip64 && _container.UseZip64WhenSaving == Zip64Option.Never) ||
- (!_InputUsesZip64 && _container.UseZip64WhenSaving == Zip64Option.Always);
-
- if (needRecompute)
- CopyThroughWithRecompute(outStream);
- else
- CopyThroughWithNoChange(outStream);
-
- // zip64 housekeeping
- _entryRequiresZip64 = new Nullable
- (_CompressedSize >= 0xFFFFFFFF || _UncompressedSize >= 0xFFFFFFFF ||
- _RelativeOffsetOfLocalHeader >= 0xFFFFFFFF
- );
-
- _OutputUsesZip64 = new Nullable(_container.Zip64 == Zip64Option.Always || _entryRequiresZip64.Value);
- }
-
-
-
- private void CopyThroughWithRecompute(Stream outstream)
- {
- int n;
- byte[] bytes = new byte[BufferSize];
- var input = new CountingStream(this.ArchiveStream);
-
- long origRelativeOffsetOfHeader = _RelativeOffsetOfLocalHeader;
-
- // The header length may change due to rename of file, add a comment, etc.
- // We need to retain the original.
- int origLengthOfHeader = LengthOfHeader; // including crypto bytes!
-
- // WriteHeader() has the side effect of changing _RelativeOffsetOfLocalHeader
- // and setting _LengthOfHeader. While ReadHeader() reads the crypto header if
- // present, WriteHeader() does not write the crypto header.
- WriteHeader(outstream, 0);
- StoreRelativeOffset();
-
- if (!this.FileName.EndsWith("/"))
- {
- // Not a directory; there is file data.
- // Seek to the beginning of the entry data in the input stream.
-
- long pos = origRelativeOffsetOfHeader + origLengthOfHeader;
- int len = GetLengthOfCryptoHeaderBytes(_Encryption_FromZipFile);
- pos -= len; // want to keep the crypto header
- _LengthOfHeader += len;
-
- input.Seek(pos, SeekOrigin.Begin);
-
- // copy through everything after the header to the output stream
- long remaining = this._CompressedSize;
-
- while (remaining > 0)
- {
- len = (remaining > bytes.Length) ? bytes.Length : (int)remaining;
-
- // read
- n = input.Read(bytes, 0, len);
- //_CheckRead(n);
-
- // write
- outstream.Write(bytes, 0, n);
- remaining -= n;
- OnWriteBlock(input.BytesRead, this._CompressedSize);
- if (_ioOperationCanceled)
- break;
- }
-
- // bit 3 descriptor
- if ((this._BitField & 0x0008) == 0x0008)
- {
- int size = 16;
- if (_InputUsesZip64) size += 8;
- byte[] Descriptor = new byte[size];
- input.Read(Descriptor, 0, size);
-
- if (_InputUsesZip64 && _container.UseZip64WhenSaving == Zip64Option.Never)
- {
- // original descriptor was 24 bytes, now we need 16.
- // Must check for underflow here.
- // signature + CRC.
- outstream.Write(Descriptor, 0, 8);
-
- // Compressed
- if (_CompressedSize > 0xFFFFFFFF)
- throw new InvalidOperationException("ZIP64 is required");
- outstream.Write(Descriptor, 8, 4);
-
- // UnCompressed
- if (_UncompressedSize > 0xFFFFFFFF)
- throw new InvalidOperationException("ZIP64 is required");
- outstream.Write(Descriptor, 16, 4);
- _LengthOfTrailer -= 8;
- }
- else if (!_InputUsesZip64 && _container.UseZip64WhenSaving == Zip64Option.Always)
- {
- // original descriptor was 16 bytes, now we need 24
- // signature + CRC
- byte[] pad = new byte[4];
- outstream.Write(Descriptor, 0, 8);
- // Compressed
- outstream.Write(Descriptor, 8, 4);
- outstream.Write(pad, 0, 4);
- // UnCompressed
- outstream.Write(Descriptor, 12, 4);
- outstream.Write(pad, 0, 4);
- _LengthOfTrailer += 8;
- }
- else
- {
- // same descriptor on input and output. Copy it through.
- outstream.Write(Descriptor, 0, size);
- //_LengthOfTrailer += size;
- }
- }
- }
-
- _TotalEntrySize = _LengthOfHeader + _CompressedFileDataSize + _LengthOfTrailer;
- }
-
-
- private void CopyThroughWithNoChange(Stream outstream)
- {
- int n;
- byte[] bytes = new byte[BufferSize];
- var input = new CountingStream(this.ArchiveStream);
-
- // seek to the beginning of the entry data in the input stream
- input.Seek(this._RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
-
- if (this._TotalEntrySize == 0)
- {
- // We've never set the length of the entry.
- // Set it here.
- this._TotalEntrySize = this._LengthOfHeader + this._CompressedFileDataSize + _LengthOfTrailer;
-
- // The CompressedSize includes all the leading metadata associated
- // to encryption, if any, as well as the compressed data, or
- // compressed-then-encrypted data, and the trailer in case of AES.
-
- // The CompressedFileData size is the same, less the encryption
- // framing data (12 bytes header for PKZip; 10/18 bytes header and
- // 10 byte trailer for AES).
-
- // The _LengthOfHeader includes all the zip entry header plus the
- // crypto header, if any. The _LengthOfTrailer includes the
- // 10-byte MAC for AES, where appropriate, and the bit-3
- // Descriptor, where applicable.
- }
-
-
- // workitem 5616
- // remember the offset, within the output stream, of this particular entry header.
- // This may have changed if any of the other entries changed (eg, if a different
- // entry was removed or added.)
- var counter = outstream as CountingStream;
- _RelativeOffsetOfLocalHeader = (counter != null)
- ? counter.ComputedPosition
- : outstream.Position; // BytesWritten
-
- // copy through the header, filedata, trailer, everything...
- long remaining = this._TotalEntrySize;
- while (remaining > 0)
- {
- int len = (remaining > bytes.Length) ? bytes.Length : (int)remaining;
-
- // read
- n = input.Read(bytes, 0, len);
- //_CheckRead(n);
-
- // write
- outstream.Write(bytes, 0, n);
- remaining -= n;
- OnWriteBlock(input.BytesRead, this._TotalEntrySize);
- if (_ioOperationCanceled)
- break;
- }
- }
-
-
-
-
- [System.Diagnostics.ConditionalAttribute("Trace")]
- private void TraceWriteLine(string format, params object[] varParams)
- {
- lock (_outputLock)
- {
- int tid = System.Threading.Thread.CurrentThread.GetHashCode();
-#if ! (NETCF || SILVERLIGHT)
- Console.ForegroundColor = (ConsoleColor)(tid % 8 + 8);
-#endif
- Console.Write("{0:000} ZipEntry.Write ", tid);
- Console.WriteLine(format, varParams);
-#if ! (NETCF || SILVERLIGHT)
- Console.ResetColor();
-#endif
- }
- }
-
- private object _outputLock = new Object();
- }
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.cs
deleted file mode 100644
index 02d3f5b7..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntry.cs
+++ /dev/null
@@ -1,2968 +0,0 @@
-// ZipEntry.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2006-2010 Dino Chiesa.
-// 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: <2011-August-06 17:25:53>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the ZipEntry class, which models the entries within a zip file.
-//
-// Created: Tue, 27 Mar 2007 15:30
-//
-// ------------------------------------------------------------------
-
-
-using System;
-using System.IO;
-using Interop = System.Runtime.InteropServices;
-
-namespace Ionic.Zip
-{
- ///
- /// Represents a single entry in a ZipFile. Typically, applications get a ZipEntry
- /// by enumerating the entries within a ZipFile, or by adding an entry to a ZipFile.
- ///
-
- [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d00004")]
- [Interop.ComVisible(true)]
-#if !NETCF
- [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)] // AutoDual
-#endif
- public partial class ZipEntry
- {
- ///
- /// Default constructor.
- ///
- ///
- /// Applications should never need to call this directly. It is exposed to
- /// support COM Automation environments.
- ///
- public ZipEntry()
- {
- _CompressionMethod = (Int16)CompressionMethod.Deflate;
- _CompressionLevel = Ionic.Zlib.CompressionLevel.Default;
- _Encryption = EncryptionAlgorithm.None;
- _Source = ZipEntrySource.None;
- AlternateEncoding = System.Text.Encoding.GetEncoding("IBM437");
- AlternateEncodingUsage = ZipOption.Never;
- }
-
- ///
- /// The time and date at which the file indicated by the ZipEntry was
- /// last modified.
- ///
- ///
- ///
- ///
- /// The DotNetZip library sets the LastModified value for an entry, equal to
- /// the Last Modified time of the file in the filesystem. If an entry is
- /// added from a stream, the library uses System.DateTime.Now for this
- /// value, for the given entry.
- ///
- ///
- ///
- /// This property allows the application to retrieve and possibly set the
- /// LastModified value on an entry, to an arbitrary value. values with a
- /// setting of DateTimeKind.Unspecified are taken to be expressed as
- /// DateTimeKind.Local.
- ///
- ///
- ///
- /// Be aware that because of the way PKWare's
- /// Zip specification describes how times are stored in the zip file,
- /// the full precision of the System.DateTime datatype is not stored
- /// for the last modified time when saving zip files. For more information on
- /// how times are formatted, see the PKZip specification.
- ///
- ///
- ///
- /// The actual last modified time of a file can be stored in multiple ways in
- /// the zip file, and they are not mutually exclusive:
- ///
- ///
- ///
- /// -
- /// In the so-called "DOS" format, which has a 2-second precision. Values
- /// are rounded to the nearest even second. For example, if the time on the
- /// file is 12:34:43, then it will be stored as 12:34:44. This first value
- /// is accessible via the LastModified property. This value is always
- /// present in the metadata for each zip entry. In some cases the value is
- /// invalid, or zero.
- ///
- ///
- /// -
- /// In the so-called "Windows" or "NTFS" format, as an 8-byte integer
- /// quantity expressed as the number of 1/10 milliseconds (in other words
- /// the number of 100 nanosecond units) since January 1, 1601 (UTC). This
- /// format is how Windows represents file times. This time is accessible
- /// via the ModifiedTime property.
- ///
- ///
- /// -
- /// In the "Unix" format, a 4-byte quantity specifying the number of seconds since
- /// January 1, 1970 UTC.
- ///
- ///
- /// -
- /// In an older format, now deprecated but still used by some current
- /// tools. This format is also a 4-byte quantity specifying the number of
- /// seconds since January 1, 1970 UTC.
- ///
- ///
- ///
- ///
- ///
- /// Zip tools and libraries will always at least handle (read or write) the
- /// DOS time, and may also handle the other time formats. Keep in mind that
- /// while the names refer to particular operating systems, there is nothing in
- /// the time formats themselves that prevents their use on other operating
- /// systems.
- ///
- ///
- ///
- /// When reading ZIP files, the DotNetZip library reads the Windows-formatted
- /// time, if it is stored in the entry, and sets both LastModified and
- /// ModifiedTime to that value. When writing ZIP files, the DotNetZip
- /// library by default will write both time quantities. It can also emit the
- /// Unix-formatted time if desired (See .)
- ///
- ///
- ///
- /// The last modified time of the file created upon a call to
- /// ZipEntry.Extract() may be adjusted during extraction to compensate
- /// for differences in how the .NET Base Class Library deals with daylight
- /// saving time (DST) versus how the Windows filesystem deals with daylight
- /// saving time. Raymond Chen provides
- /// some good context.
- ///
- ///
- ///
- /// In a nutshell: Daylight savings time rules change regularly. In 2007, for
- /// example, the inception week of DST changed. In 1977, DST was in place all
- /// year round. In 1945, likewise. And so on. Win32 does not attempt to
- /// guess which time zone rules were in effect at the time in question. It
- /// will render a time as "standard time" and allow the app to change to DST
- /// as necessary. .NET makes a different choice.
- ///
- ///
- ///
- /// Compare the output of FileInfo.LastWriteTime.ToString("f") with what you
- /// see in the Windows Explorer property sheet for a file that was last
- /// written to on the other side of the DST transition. For example, suppose
- /// the file was last modified on October 17, 2003, during DST but DST is not
- /// currently in effect. Explorer's file properties reports Thursday, October
- /// 17, 2003, 8:45:38 AM, but .NETs FileInfo reports Thursday, October 17,
- /// 2003, 9:45 AM.
- ///
- ///
- ///
- /// Win32 says, "Thursday, October 17, 2002 8:45:38 AM PST". Note: Pacific
- /// STANDARD Time. Even though October 17 of that year occurred during Pacific
- /// Daylight Time, Win32 displays the time as standard time because that's
- /// what time it is NOW.
- ///
- ///
- ///
- /// .NET BCL assumes that the current DST rules were in place at the time in
- /// question. So, .NET says, "Well, if the rules in effect now were also in
- /// effect on October 17, 2003, then that would be daylight time" so it
- /// displays "Thursday, October 17, 2003, 9:45 AM PDT" - daylight time.
- ///
- ///
- ///
- /// So .NET gives a value which is more intuitively correct, but is also
- /// potentially incorrect, and which is not invertible. Win32 gives a value
- /// which is intuitively incorrect, but is strictly correct.
- ///
- ///
- ///
- /// Because of this funkiness, this library adds one hour to the LastModified
- /// time on the extracted file, if necessary. That is to say, if the time in
- /// question had occurred in what the .NET Base Class Library assumed to be
- /// DST. This assumption may be wrong given the constantly changing DST rules,
- /// but it is the best we can do.
- ///
- ///
- ///
- ///
- public DateTime LastModified
- {
- get { return _LastModified.ToLocalTime(); }
- set
- {
- _LastModified = (value.Kind == DateTimeKind.Unspecified)
- ? DateTime.SpecifyKind(value, DateTimeKind.Local)
- : value.ToLocalTime();
- _Mtime = Ionic.Zip.SharedUtilities.AdjustTime_Reverse(_LastModified).ToUniversalTime();
- _metadataChanged = true;
- }
- }
-
-
- private int BufferSize
- {
- get
- {
- return this._container.BufferSize;
- }
- }
-
- ///
- /// Last Modified time for the file represented by the entry.
- ///
- ///
- ///
- ///
- ///
- /// This value corresponds to the "last modified" time in the NTFS file times
- /// as described in the Zip
- /// specification. When getting this property, the value may be
- /// different from . When setting the property,
- /// the property also gets set, but with a lower
- /// precision.
- ///
- ///
- ///
- /// Let me explain. It's going to take a while, so get
- /// comfortable. Originally, waaaaay back in 1989 when the ZIP specification
- /// was originally described by the esteemed Mr. Phil Katz, the dominant
- /// operating system of the time was MS-DOS. MSDOS stored file times with a
- /// 2-second precision, because, c'mon, who is ever going to need better
- /// resolution than THAT? And so ZIP files, regardless of the platform on
- /// which the zip file was created, store file times in exactly the same format that DOS used
- /// in 1989.
- ///
- ///
- ///
- /// Since then, the ZIP spec has evolved, but the internal format for file
- /// timestamps remains the same. Despite the fact that the way times are
- /// stored in a zip file is rooted in DOS heritage, any program on any
- /// operating system can format a time in this way, and most zip tools and
- /// libraries DO - they round file times to the nearest even second and store
- /// it just like DOS did 25+ years ago.
- ///
- ///
- ///
- /// PKWare extended the ZIP specification to allow a zip file to store what
- /// are called "NTFS Times" and "Unix(tm) times" for a file. These are the
- /// last write, last access, and file creation
- /// times of a particular file. These metadata are not actually specific
- /// to NTFS or Unix. They are tracked for each file by NTFS and by various
- /// Unix filesystems, but they are also tracked by other filesystems, too.
- /// The key point is that the times are formatted in the zip file
- /// in the same way that NTFS formats the time (ticks since win32 epoch),
- /// or in the same way that Unix formats the time (seconds since Unix
- /// epoch). As with the DOS time, any tool or library running on any
- /// operating system is capable of formatting a time in one of these ways
- /// and embedding it into the zip file.
- ///
- ///
- ///
- /// These extended times are higher precision quantities than the DOS time.
- /// As described above, the (DOS) LastModified has a precision of 2 seconds.
- /// The Unix time is stored with a precision of 1 second. The NTFS time is
- /// stored with a precision of 0.0000001 seconds. The quantities are easily
- /// convertible, except for the loss of precision you may incur.
- ///
- ///
- ///
- /// A zip archive can store the {C,A,M} times in NTFS format, in Unix format,
- /// or not at all. Often a tool running on Unix or Mac will embed the times
- /// in Unix format (1 second precision), while WinZip running on Windows might
- /// embed the times in NTFS format (precision of of 0.0000001 seconds). When
- /// reading a zip file with these "extended" times, in either format,
- /// DotNetZip represents the values with the
- /// ModifiedTime, AccessedTime and CreationTime
- /// properties on the ZipEntry.
- ///
- ///
- ///
- /// While any zip application or library, regardless of the platform it
- /// runs on, could use any of the time formats allowed by the ZIP
- /// specification, not all zip tools or libraries do support all these
- /// formats. Storing the higher-precision times for each entry is
- /// optional for zip files, and many tools and libraries don't use the
- /// higher precision quantities at all. The old DOS time, represented by
- /// , is guaranteed to be present, though it
- /// sometimes unset.
- ///
- ///
- ///
- /// Ok, getting back to the question about how the LastModified
- /// property relates to this ModifiedTime
- /// property... LastModified is always set, while
- /// ModifiedTime is not. (The other times stored in the NTFS
- /// times extension, CreationTime and AccessedTime also
- /// may not be set on an entry that is read from an existing zip file.)
- /// When reading a zip file, then LastModified takes the DOS time
- /// that is stored with the file. If the DOS time has been stored as zero
- /// in the zipfile, then this library will use DateTime.Now for the
- /// LastModified value. If the ZIP file was created by an evolved
- /// tool, then there will also be higher precision NTFS or Unix times in
- /// the zip file. In that case, this library will read those times, and
- /// set LastModified and ModifiedTime to the same value, the
- /// one corresponding to the last write time of the file. If there are no
- /// higher precision times stored for the entry, then ModifiedTime
- /// remains unset (likewise AccessedTime and CreationTime),
- /// and LastModified keeps its DOS time.
- ///
- ///
- ///
- /// When creating zip files with this library, by default the extended time
- /// properties (ModifiedTime, AccessedTime, and
- /// CreationTime) are set on the ZipEntry instance, and these data are
- /// stored in the zip archive for each entry, in NTFS format. If you add an
- /// entry from an actual filesystem file, then the entry gets the actual file
- /// times for that file, to NTFS-level precision. If you add an entry from a
- /// stream, or a string, then the times get the value DateTime.Now. In
- /// this case LastModified and ModifiedTime will be identical,
- /// to 2 seconds of precision. You can explicitly set the
- /// CreationTime, AccessedTime, and ModifiedTime of an
- /// entry using the property setters. If you want to set all of those
- /// quantities, it's more efficient to use the method. Those
- /// changes are not made permanent in the zip file until you call or one of its cousins.
- ///
- ///
- ///
- /// When creating a zip file, you can override the default behavior of
- /// this library for formatting times in the zip file, disabling the
- /// embedding of file times in NTFS format or enabling the storage of file
- /// times in Unix format, or both. You may want to do this, for example,
- /// when creating a zip file on Windows, that will be consumed on a Mac,
- /// by an application that is not hip to the "NTFS times" format. To do
- /// this, use the and
- /// properties. A valid zip
- /// file may store the file times in both formats. But, there are no
- /// guarantees that a program running on Mac or Linux will gracefully
- /// handle the NTFS-formatted times when Unix times are present, or that a
- /// non-DotNetZip-powered application running on Windows will be able to
- /// handle file times in Unix format. DotNetZip will always do something
- /// reasonable; other libraries or tools may not. When in doubt, test.
- ///
- ///
- ///
- /// I'll bet you didn't think one person could type so much about time, eh?
- /// And reading it was so enjoyable, too! Well, in appreciation, maybe you
- /// should donate?
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public DateTime ModifiedTime
- {
- get { return _Mtime; }
- set
- {
- SetEntryTimes(_Ctime, _Atime, value);
- }
- }
-
- ///
- /// Last Access time for the file represented by the entry.
- ///
- ///
- /// This value may or may not be meaningful. If the ZipEntry was read from an existing
- /// Zip archive, this information may not be available. For an explanation of why, see
- /// .
- ///
- ///
- ///
- ///
- public DateTime AccessedTime
- {
- get { return _Atime; }
- set
- {
- SetEntryTimes(_Ctime, value, _Mtime);
- }
- }
-
- ///
- /// The file creation time for the file represented by the entry.
- ///
- ///
- ///
- /// This value may or may not be meaningful. If the ZipEntry was read
- /// from an existing zip archive, and the creation time was not set on the entry
- /// when the zip file was created, then this property may be meaningless. For an
- /// explanation of why, see .
- ///
- ///
- ///
- ///
- public DateTime CreationTime
- {
- get { return _Ctime; }
- set
- {
- SetEntryTimes(value, _Atime, _Mtime);
- }
- }
-
- ///
- /// Sets the NTFS Creation, Access, and Modified times for the given entry.
- ///
- ///
- ///
- ///
- /// When adding an entry from a file or directory, the Creation, Access, and
- /// Modified times for the given entry are automatically set from the
- /// filesystem values. When adding an entry from a stream or string, the
- /// values are implicitly set to DateTime.Now. The application may wish to
- /// set these values to some arbitrary value, before saving the archive, and
- /// can do so using the various setters. If you want to set all of the times,
- /// this method is more efficient.
- ///
- ///
- ///
- /// The values you set here will be retrievable with the , and properties.
- ///
- ///
- ///
- /// When this method is called, if both and are false, then the
- /// EmitTimesInWindowsFormatWhenSaving flag is automatically set.
- ///
- ///
- ///
- /// DateTime values provided here without a DateTimeKind are assumed to be Local Time.
- ///
- ///
- ///
- /// the creation time of the entry.
- /// the last access time of the entry.
- /// the last modified time of the entry.
- ///
- ///
- ///
- ///
- ///
- ///
- public void SetEntryTimes(DateTime created, DateTime accessed, DateTime modified)
- {
- _ntfsTimesAreSet = true;
- if (created == _zeroHour && created.Kind == _zeroHour.Kind) created = _win32Epoch;
- if (accessed == _zeroHour && accessed.Kind == _zeroHour.Kind) accessed = _win32Epoch;
- if (modified == _zeroHour && modified.Kind == _zeroHour.Kind) modified = _win32Epoch;
- _Ctime = created.ToUniversalTime();
- _Atime = accessed.ToUniversalTime();
- _Mtime = modified.ToUniversalTime();
- _LastModified = _Mtime;
- if (!_emitUnixTimes && !_emitNtfsTimes)
- _emitNtfsTimes = true;
- _metadataChanged = true;
- }
-
-
-
- ///
- /// Specifies whether the Creation, Access, and Modified times for the given
- /// entry will be emitted in "Windows format" when the zip archive is saved.
- ///
- ///
- ///
- ///
- /// An application creating a zip archive can use this flag to explicitly
- /// specify that the file times for the entry should or should not be stored
- /// in the zip archive in the format used by Windows. The default value of
- /// this property is true.
- ///
- ///
- ///
- /// When adding an entry from a file or directory, the Creation (), Access (), and Modified
- /// () times for the given entry are automatically
- /// set from the filesystem values. When adding an entry from a stream or
- /// string, all three values are implicitly set to DateTime.Now. Applications
- /// can also explicitly set those times by calling .
- ///
- ///
- ///
- /// PKWARE's
- /// zip specification describes multiple ways to format these times in a
- /// zip file. One is the format Windows applications normally use: 100ns ticks
- /// since Jan 1, 1601 UTC. The other is a format Unix applications typically
- /// use: seconds since January 1, 1970 UTC. Each format can be stored in an
- /// "extra field" in the zip entry when saving the zip archive. The former
- /// uses an extra field with a Header Id of 0x000A, while the latter uses a
- /// header ID of 0x5455.
- ///
- ///
- ///
- /// Not all zip tools and libraries can interpret these fields. Windows
- /// compressed folders is one that can read the Windows Format timestamps,
- /// while I believe the Infozip
- /// tools can read the Unix format timestamps. Although the time values are
- /// easily convertible, subject to a loss of precision, some tools and
- /// libraries may be able to read only one or the other. DotNetZip can read or
- /// write times in either or both formats.
- ///
- ///
- ///
- /// The times stored are taken from , , and .
- ///
- ///
- ///
- /// This property is not mutually exclusive from the property. It is
- /// possible that a zip entry can embed the timestamps in both forms, one
- /// form, or neither. But, there are no guarantees that a program running on
- /// Mac or Linux will gracefully handle NTFS Formatted times, or that a
- /// non-DotNetZip-powered application running on Windows will be able to
- /// handle file times in Unix format. When in doubt, test.
- ///
- ///
- ///
- /// Normally you will use the ZipFile.EmitTimesInWindowsFormatWhenSaving
- /// property, to specify the behavior for all entries in a zip, rather than
- /// the property on each individual entry.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public bool EmitTimesInWindowsFormatWhenSaving
- {
- get
- {
- return _emitNtfsTimes;
- }
- set
- {
- _emitNtfsTimes = value;
- _metadataChanged = true;
- }
- }
-
- ///
- /// Specifies whether the Creation, Access, and Modified times for the given
- /// entry will be emitted in "Unix(tm) format" when the zip archive is saved.
- ///
- ///
- ///
- ///
- /// An application creating a zip archive can use this flag to explicitly
- /// specify that the file times for the entry should or should not be stored
- /// in the zip archive in the format used by Unix. By default this flag is
- /// false, meaning the Unix-format times are not stored in the zip
- /// archive.
- ///
- ///
- ///
- /// When adding an entry from a file or directory, the Creation (), Access (), and Modified
- /// () times for the given entry are automatically
- /// set from the filesystem values. When adding an entry from a stream or
- /// string, all three values are implicitly set to DateTime.Now. Applications
- /// can also explicitly set those times by calling .
- ///
- ///
- ///
- /// PKWARE's
- /// zip specification describes multiple ways to format these times in a
- /// zip file. One is the format Windows applications normally use: 100ns ticks
- /// since Jan 1, 1601 UTC. The other is a format Unix applications typically
- /// use: seconds since Jan 1, 1970 UTC. Each format can be stored in an
- /// "extra field" in the zip entry when saving the zip archive. The former
- /// uses an extra field with a Header Id of 0x000A, while the latter uses a
- /// header ID of 0x5455.
- ///
- ///
- ///
- /// Not all tools and libraries can interpret these fields. Windows
- /// compressed folders is one that can read the Windows Format timestamps,
- /// while I believe the Infozip
- /// tools can read the Unix format timestamps. Although the time values are
- /// easily convertible, subject to a loss of precision, some tools and
- /// libraries may be able to read only one or the other. DotNetZip can read or
- /// write times in either or both formats.
- ///
- ///
- ///
- /// The times stored are taken from , , and .
- ///
- ///
- ///
- /// This property is not mutually exclusive from the property. It is
- /// possible that a zip entry can embed the timestamps in both forms, one
- /// form, or neither. But, there are no guarantees that a program running on
- /// Mac or Linux will gracefully handle NTFS Formatted times, or that a
- /// non-DotNetZip-powered application running on Windows will be able to
- /// handle file times in Unix format. When in doubt, test.
- ///
- ///
- ///
- /// Normally you will use the ZipFile.EmitTimesInUnixFormatWhenSaving
- /// property, to specify the behavior for all entries, rather than the
- /// property on each individual entry.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public bool EmitTimesInUnixFormatWhenSaving
- {
- get
- {
- return _emitUnixTimes;
- }
- set
- {
- _emitUnixTimes = value;
- _metadataChanged = true;
- }
- }
-
-
- ///
- /// The type of timestamp attached to the ZipEntry.
- ///
- ///
- ///
- /// This property is valid only for a ZipEntry that was read from a zip archive.
- /// It indicates the type of timestamp attached to the entry.
- ///
- ///
- ///
- ///
- public ZipEntryTimestamp Timestamp
- {
- get
- {
- return _timestamp;
- }
- }
-
- ///
- /// The file attributes for the entry.
- ///
- ///
- ///
- ///
- ///
- /// The attributes in NTFS include
- /// ReadOnly, Archive, Hidden, System, and Indexed. When adding a
- /// ZipEntry to a ZipFile, these attributes are set implicitly when
- /// adding an entry from the filesystem. When adding an entry from a stream
- /// or string, the Attributes are not set implicitly. Regardless of the way
- /// an entry was added to a ZipFile, you can set the attributes
- /// explicitly if you like.
- ///
- ///
- ///
- /// When reading a ZipEntry from a ZipFile, the attributes are
- /// set according to the data stored in the ZipFile. If you extract the
- /// entry from the archive to a filesystem file, DotNetZip will set the
- /// attributes on the resulting file accordingly.
- ///
- ///
- ///
- /// The attributes can be set explicitly by the application. For example the
- /// application may wish to set the FileAttributes.ReadOnly bit for all
- /// entries added to an archive, so that on unpack, this attribute will be set
- /// on the extracted file. Any changes you make to this property are made
- /// permanent only when you call a Save() method on the ZipFile
- /// instance that contains the ZipEntry.
- ///
- ///
- ///
- /// For example, an application may wish to zip up a directory and set the
- /// ReadOnly bit on every file in the archive, so that upon later extraction,
- /// the resulting files will be marked as ReadOnly. Not every extraction tool
- /// respects these attributes, but if you unpack with DotNetZip, as for
- /// example in a self-extracting archive, then the attributes will be set as
- /// they are stored in the ZipFile.
- ///
- ///
- ///
- /// These attributes may not be interesting or useful if the resulting archive
- /// is extracted on a non-Windows platform. How these attributes get used
- /// upon extraction depends on the platform and tool used.
- ///
- ///
- ///
- /// This property is only partially supported in the Silverlight version
- /// of the library: applications can read attributes on entries within
- /// ZipFiles. But extracting entries within Silverlight will not set the
- /// attributes on the extracted files.
- ///
- ///
- ///
- public System.IO.FileAttributes Attributes
- {
- // workitem 7071
- get { return (System.IO.FileAttributes)_ExternalFileAttrs; }
- set
- {
- _ExternalFileAttrs = (int)value;
- // Since the application is explicitly setting the attributes, overwriting
- // whatever was there, we will explicitly set the Version made by field.
- // workitem 7926 - "version made by" OS should be zero for compat with WinZip
- _VersionMadeBy = (0 << 8) + 45; // v4.5 of the spec
- _metadataChanged = true;
- }
- }
-
-
- ///
- /// The name of the filesystem file, referred to by the ZipEntry.
- ///
- ///
- ///
- ///
- /// This property specifies the thing-to-be-zipped on disk, and is set only
- /// when the ZipEntry is being created from a filesystem file. If the
- /// ZipFile is instantiated by reading an existing .zip archive, then
- /// the LocalFileName will be null (Nothing in VB).
- ///
- ///
- ///
- /// When it is set, the value of this property may be different than , which is the path used in the archive itself. If you
- /// call Zip.AddFile("foop.txt", AlternativeDirectory), then the path
- /// used for the ZipEntry within the zip archive will be different
- /// than this path.
- ///
- ///
- ///
- /// If the entry is being added from a stream, then this is null (Nothing in VB).
- ///
- ///
- ///
- ///
- internal string LocalFileName
- {
- get { return _LocalFileName; }
- }
-
- ///
- /// The name of the file contained in the ZipEntry.
- ///
- ///
- ///
- ///
- ///
- /// This is the name of the entry in the ZipFile itself. When creating
- /// a zip archive, if the ZipEntry has been created from a filesystem
- /// file, via a call to or , or a related overload, the value
- /// of this property is derived from the name of that file. The
- /// FileName property does not include drive letters, and may include a
- /// different directory path, depending on the value of the
- /// directoryPathInArchive parameter used when adding the entry into
- /// the ZipFile.
- ///
- ///
- ///
- /// In some cases there is no related filesystem file - for example when a
- /// ZipEntry is created using or one of the similar overloads. In this case, the value of
- /// this property is derived from the fileName and the directory path passed
- /// to that method.
- ///
- ///
- ///
- /// When reading a zip file, this property takes the value of the entry name
- /// as stored in the zip file. If you extract such an entry, the extracted
- /// file will take the name given by this property.
- ///
- ///
- ///
- /// Applications can set this property when creating new zip archives or when
- /// reading existing archives. When setting this property, the actual value
- /// that is set will replace backslashes with forward slashes, in accordance
- /// with the Zip
- /// specification, for compatibility with Unix(tm) and ... get
- /// this.... Amiga!
- ///
- ///
- ///
- /// If an application reads a ZipFile via or a related overload, and then explicitly
- /// sets the FileName on an entry contained within the ZipFile, and
- /// then calls , the application will effectively
- /// rename the entry within the zip archive.
- ///
- ///
- ///
- /// If an application sets the value of FileName, then calls
- /// Extract() on the entry, the entry is extracted to a file using the
- /// newly set value as the filename. The FileName value is made
- /// permanent in the zip archive only after a call to one of the
- /// ZipFile.Save() methods on the ZipFile that contains the
- /// ZipEntry.
- ///
- ///
- ///
- /// If an application attempts to set the FileName to a value that
- /// would result in a duplicate entry in the ZipFile, an exception is
- /// thrown.
- ///
- ///
- ///
- /// When a ZipEntry is contained within a ZipFile, applications
- /// cannot rename the entry within the context of a foreach (For
- /// Each in VB) loop, because of the way the ZipFile stores
- /// entries. If you need to enumerate through all the entries and rename one
- /// or more of them, use ZipFile.EntriesSorted as the
- /// collection. See also, ZipFile.GetEnumerator().
- ///
- ///
- ///
- public string FileName
- {
- get { return _FileNameInArchive; }
- set
- {
- if (_container.ZipFile == null)
- throw new ZipException("Cannot rename; this is not supported in ZipOutputStream/ZipInputStream.");
-
- // rename the entry!
- if (String.IsNullOrEmpty(value)) throw new ZipException("The FileName must be non empty and non-null.");
-
- var filename = ZipEntry.NameInArchive(value, null);
- // workitem 8180
- if (_FileNameInArchive == filename) return; // nothing to do
-
- // workitem 8047 - when renaming, must remove old and then add a new entry
- this._container.ZipFile.RemoveEntry(this);
- this._container.ZipFile.InternalAddEntry(filename, this);
-
- _FileNameInArchive = filename;
- _container.ZipFile.NotifyEntryChanged();
- _metadataChanged = true;
- }
- }
-
-
- ///
- /// The stream that provides content for the ZipEntry.
- ///
- ///
- ///
- ///
- ///
- /// The application can use this property to set the input stream for an
- /// entry on a just-in-time basis. Imagine a scenario where the application
- /// creates a ZipFile comprised of content obtained from hundreds of
- /// files, via calls to AddFile(). The DotNetZip library opens streams
- /// on these files on a just-in-time basis, only when writing the entry out to
- /// an external store within the scope of a ZipFile.Save() call. Only
- /// one input stream is opened at a time, as each entry is being written out.
- ///
- ///
- ///
- /// Now imagine a different application that creates a ZipFile
- /// with content obtained from hundreds of streams, added through . Normally the
- /// application would supply an open stream to that call. But when large
- /// numbers of streams are being added, this can mean many open streams at one
- /// time, unnecessarily.
- ///
- ///
- ///
- /// To avoid this, call and specify delegates that open and close the stream at
- /// the time of Save.
- ///
- ///
- ///
- ///
- /// Setting the value of this property when the entry was not added from a
- /// stream (for example, when the ZipEntry was added with or , or when the entry was added by
- /// reading an existing zip archive) will throw an exception.
- ///
- ///
- ///
- ///
- public Stream InputStream
- {
- get { return _sourceStream; }
-
- set
- {
- if (this._Source != ZipEntrySource.Stream)
- throw new ZipException("You must not set the input stream for this entry.");
-
- _sourceWasJitProvided = true;
- _sourceStream = value;
- }
- }
-
-
- ///
- /// A flag indicating whether the InputStream was provided Just-in-time.
- ///
- ///
- ///
- ///
- ///
- /// When creating a zip archive, an application can obtain content for one or
- /// more of the ZipEntry instances from streams, using the method. At the time
- /// of calling that method, the application can supply null as the value of
- /// the stream parameter. By doing so, the application indicates to the
- /// library that it will provide a stream for the entry on a just-in-time
- /// basis, at the time one of the ZipFile.Save() methods is called and
- /// the data for the various entries are being compressed and written out.
- ///
- ///
- ///
- /// In this case, the application can set the
- /// property, typically within the SaveProgress event (event type: ) for that entry.
- ///
- ///
- ///
- /// The application will later want to call Close() and Dispose() on that
- /// stream. In the SaveProgress event, when the event type is , the application can
- /// do so. This flag indicates that the stream has been provided by the
- /// application on a just-in-time basis and that it is the application's
- /// responsibility to call Close/Dispose on that stream.
- ///
- ///
- ///
- ///
- public bool InputStreamWasJitProvided
- {
- get { return _sourceWasJitProvided; }
- }
-
-
-
- ///
- /// An enum indicating the source of the ZipEntry.
- ///
- public ZipEntrySource Source
- {
- get { return _Source; }
- }
-
-
- ///
- /// The version of the zip engine needed to read the ZipEntry.
- ///
- ///
- ///
- ///
- /// This is a readonly property, indicating the version of the Zip
- /// specification that the extracting tool or library must support to
- /// extract the given entry. Generally higher versions indicate newer
- /// features. Older zip engines obviously won't know about new features, and
- /// won't be able to extract entries that depend on those newer features.
- ///
- ///
- ///
- ///
- /// value
- /// Features
- ///
- ///
- /// -
- /// 20
- /// a basic Zip Entry, potentially using PKZIP encryption.
- ///
- ///
- ///
- /// -
- /// 45
- /// The ZIP64 extension is used on the entry.
- ///
- ///
- ///
- /// -
- /// 46
- /// File is compressed using BZIP2 compression*
- ///
- ///
- /// -
- /// 50
- /// File is encrypted using PkWare's DES, 3DES, (broken) RC2 or RC4
- ///
- ///
- /// -
- /// 51
- /// File is encrypted using PKWare's AES encryption or corrected RC2 encryption.
- ///
- ///
- /// -
- /// 52
- /// File is encrypted using corrected RC2-64 encryption**
- ///
- ///
- /// -
- /// 61
- /// File is encrypted using non-OAEP key wrapping***
- ///
- ///
- /// -
- /// 63
- /// File is compressed using LZMA, PPMd+, Blowfish, or Twofish
- ///
- ///
- ///
- ///
- ///
- /// There are other values possible, not listed here. DotNetZip supports
- /// regular PKZip encryption, and ZIP64 extensions. DotNetZip cannot extract
- /// entries that require a zip engine higher than 45.
- ///
- ///
- ///
- /// This value is set upon reading an existing zip file, or after saving a zip
- /// archive.
- ///
- ///
- public Int16 VersionNeeded
- {
- get { return _VersionNeeded; }
- }
-
- ///
- /// The comment attached to the ZipEntry.
- ///
- ///
- ///
- ///
- /// Each entry in a zip file can optionally have a comment associated to
- /// it. The comment might be displayed by a zip tool during extraction, for
- /// example.
- ///
- ///
- ///
- /// By default, the Comment is encoded in IBM437 code page. You can
- /// specify an alternative with and
- /// .
- ///
- ///
- ///
- ///
- public string Comment
- {
- get { return _Comment; }
- set
- {
- _Comment = value;
- _metadataChanged = true;
- }
- }
-
-
- ///
- /// Indicates whether the entry requires ZIP64 extensions.
- ///
- ///
- ///
- ///
- ///
- /// This property is null (Nothing in VB) until a Save() method on the
- /// containing instance has been called. The property is
- /// non-null (HasValue is true) only after a Save() method has
- /// been called.
- ///
- ///
- ///
- /// After the containing ZipFile has been saved, the Value of this
- /// property is true if any of the following three conditions holds: the
- /// uncompressed size of the entry is larger than 0xFFFFFFFF; the compressed
- /// size of the entry is larger than 0xFFFFFFFF; the relative offset of the
- /// entry within the zip archive is larger than 0xFFFFFFFF. These quantities
- /// are not known until a Save() is attempted on the zip archive and
- /// the compression is applied.
- ///
- ///
- ///
- /// If none of the three conditions holds, then the Value is false.
- ///
- ///
- ///
- /// A Value of false does not indicate that the entry, as saved in the
- /// zip archive, does not use ZIP64. It merely indicates that ZIP64 is
- /// not required. An entry may use ZIP64 even when not required if
- /// the property on the containing
- /// ZipFile instance is set to , or if
- /// the property on the containing
- /// ZipFile instance is set to
- /// and the output stream was not seekable.
- ///
- ///
- ///
- ///
- public Nullable RequiresZip64
- {
- get
- {
- return _entryRequiresZip64;
- }
- }
-
- ///
- /// Indicates whether the entry actually used ZIP64 extensions, as it was most
- /// recently written to the output file or stream.
- ///
- ///
- ///
- ///
- ///
- /// This Nullable property is null (Nothing in VB) until a Save()
- /// method on the containing instance has been
- /// called. HasValue is true only after a Save() method has been
- /// called.
- ///
- ///
- ///
- /// The value of this property for a particular ZipEntry may change
- /// over successive calls to Save() methods on the containing ZipFile,
- /// even if the file that corresponds to the ZipEntry does not. This
- /// may happen if other entries contained in the ZipFile expand,
- /// causing the offset for this particular entry to exceed 0xFFFFFFFF.
- ///
- ///
- ///
- public Nullable OutputUsedZip64
- {
- get { return _OutputUsesZip64; }
- }
-
-
- ///
- /// The bitfield for the entry as defined in the zip spec. You probably
- /// never need to look at this.
- ///
- ///
- ///
- ///
- /// You probably do not need to concern yourself with the contents of this
- /// property, but in case you do:
- ///
- ///
- ///
- ///
- /// bit
- /// meaning
- ///
- ///
- /// -
- /// 0
- /// set if encryption is used.
- ///
- ///
- /// -
- /// 1-2
- ///
- /// set to determine whether normal, max, fast deflation. DotNetZip library
- /// always leaves these bits unset when writing (indicating "normal"
- /// deflation"), but can read an entry with any value here.
- ///
- ///
- ///
- /// -
- /// 3
- ///
- /// Indicates that the Crc32, Compressed and Uncompressed sizes are zero in the
- /// local header. This bit gets set on an entry during writing a zip file, when
- /// it is saved to a non-seekable output stream.
- ///
- ///
- ///
- ///
- /// -
- /// 4
- /// reserved for "enhanced deflating". This library doesn't do enhanced deflating.
- ///
- ///
- /// -
- /// 5
- /// set to indicate the zip is compressed patched data. This library doesn't do that.
- ///
- ///
- /// -
- /// 6
- ///
- /// set if PKWare's strong encryption is used (must also set bit 1 if bit 6 is
- /// set). This bit is not set if WinZip's AES encryption is set.
- ///
- ///
- /// -
- /// 7
- /// not used
- ///
- ///
- /// -
- /// 8
- /// not used
- ///
- ///
- /// -
- /// 9
- /// not used
- ///
- ///
- /// -
- /// 10
- /// not used
- ///
- ///
- /// -
- /// 11
- ///
- /// Language encoding flag (EFS). If this bit is set, the filename and comment
- /// fields for this file must be encoded using UTF-8. This library currently
- /// does not support UTF-8.
- ///
- ///
- ///
- /// -
- /// 12
- /// Reserved by PKWARE for enhanced compression.
- ///
- ///
- /// -
- /// 13
- ///
- /// Used when encrypting the Central Directory to indicate selected data
- /// values in the Local Header are masked to hide their actual values. See
- /// the section in the Zip
- /// specification describing the Strong Encryption Specification for
- /// details.
- ///
- ///
- ///
- /// -
- /// 14
- /// Reserved by PKWARE.
- ///
- ///
- /// -
- /// 15
- /// Reserved by PKWARE.
- ///
- ///
- ///
- ///
- ///
- public Int16 BitField
- {
- get { return _BitField; }
- }
-
- ///
- /// The compression method employed for this ZipEntry.
- ///
- ///
- ///
- ///
- ///
- /// The
- /// Zip specification allows a variety of compression methods. This
- /// library supports just two: 0x08 = Deflate. 0x00 = Store (no compression),
- /// for reading or writing.
- ///
- ///
- ///
- /// When reading an entry from an existing zipfile, the value you retrieve
- /// here indicates the compression method used on the entry by the original
- /// creator of the zip. When writing a zipfile, you can specify either 0x08
- /// (Deflate) or 0x00 (None). If you try setting something else, you will get
- /// an exception.
- ///
- ///
- ///
- /// You may wish to set CompressionMethod to CompressionMethod.None (0)
- /// when zipping already-compressed data like a jpg, png, or mp3 file.
- /// This can save time and cpu cycles.
- ///
- ///
- ///
- /// When setting this property on a ZipEntry that is read from an
- /// existing zip file, calling ZipFile.Save() will cause the new
- /// CompressionMethod to be used on the entry in the newly saved zip file.
- ///
- ///
- ///
- /// Setting this property may have the side effect of modifying the
- /// CompressionLevel property. If you set the CompressionMethod to a
- /// value other than None, and CompressionLevel is previously
- /// set to None, then CompressionLevel will be set to
- /// Default.
- ///
- ///
- ///
- ///
- ///
- ///
- /// In this example, the first entry added to the zip archive uses the default
- /// behavior - compression is used where it makes sense. The second entry,
- /// the MP3 file, is added to the archive without being compressed.
- ///
- /// using (ZipFile zip = new ZipFile(ZipFileToCreate))
- /// {
- /// ZipEntry e1= zip.AddFile(@"notes\Readme.txt");
- /// ZipEntry e2= zip.AddFile(@"music\StopThisTrain.mp3");
- /// e2.CompressionMethod = CompressionMethod.None;
- /// zip.Save();
- /// }
- ///
- ///
- ///
- /// Using zip As New ZipFile(ZipFileToCreate)
- /// zip.AddFile("notes\Readme.txt")
- /// Dim e2 as ZipEntry = zip.AddFile("music\StopThisTrain.mp3")
- /// e2.CompressionMethod = CompressionMethod.None
- /// zip.Save
- /// End Using
- ///
- ///
- public CompressionMethod CompressionMethod
- {
- get { return (CompressionMethod)_CompressionMethod; }
- set
- {
- if (value == (CompressionMethod)_CompressionMethod) return; // nothing to do.
-
- if (value != CompressionMethod.None && value != CompressionMethod.Deflate
-#if BZIP
- && value != CompressionMethod.BZip2
-#endif
- )
- throw new InvalidOperationException("Unsupported compression method.");
-
- // If the source is a zip archive and there was encryption on the
- // entry, changing the compression method is not supported.
- // if (this._Source == ZipEntrySource.ZipFile && _sourceIsEncrypted)
- // throw new InvalidOperationException("Cannot change compression method on encrypted entries read from archives.");
-
- _CompressionMethod = (Int16)value;
-
- if (_CompressionMethod == (Int16)Ionic.Zip.CompressionMethod.None)
- _CompressionLevel = Ionic.Zlib.CompressionLevel.None;
- else if (CompressionLevel == Ionic.Zlib.CompressionLevel.None)
- _CompressionLevel = Ionic.Zlib.CompressionLevel.Default;
-
- if (_container.ZipFile != null) _container.ZipFile.NotifyEntryChanged();
- _restreamRequiredOnSave = true;
- }
- }
-
-
- ///
- /// Sets the compression level to be used for the entry when saving the zip
- /// archive. This applies only for CompressionMethod = DEFLATE.
- ///
- ///
- ///
- ///
- /// When using the DEFLATE compression method, Varying the compression
- /// level used on entries can affect the size-vs-speed tradeoff when
- /// compression and decompressing data streams or files.
- ///
- ///
- ///
- /// If you do not set this property, the default compression level is used,
- /// which normally gives a good balance of compression efficiency and
- /// compression speed. In some tests, using BestCompression can
- /// double the time it takes to compress, while delivering just a small
- /// increase in compression efficiency. This behavior will vary with the
- /// type of data you compress. If you are in doubt, just leave this setting
- /// alone, and accept the default.
- ///
- ///
- ///
- /// When setting this property on a ZipEntry that is read from an
- /// existing zip file, calling ZipFile.Save() will cause the new
- /// CompressionLevel to be used on the entry in the newly saved zip file.
- ///
- ///
- ///
- /// Setting this property may have the side effect of modifying the
- /// CompressionMethod property. If you set the CompressionLevel
- /// to a value other than None, CompressionMethod will be set
- /// to Deflate, if it was previously None.
- ///
- ///
- ///
- /// Setting this property has no effect if the CompressionMethod is something
- /// other than Deflate or None.
- ///
- ///
- ///
- ///
- public Ionic.Zlib.CompressionLevel CompressionLevel
- {
- get
- {
- return _CompressionLevel;
- }
- set
- {
- if (_CompressionMethod != (short)CompressionMethod.Deflate &&
- _CompressionMethod != (short)CompressionMethod.None)
- return ; // no effect
-
- if (value == Ionic.Zlib.CompressionLevel.Default &&
- _CompressionMethod == (short)CompressionMethod.Deflate) return; // nothing to do
- _CompressionLevel = value;
-
- if (value == Ionic.Zlib.CompressionLevel.None &&
- _CompressionMethod == (short)CompressionMethod.None)
- return; // nothing more to do
-
- if (_CompressionLevel == Ionic.Zlib.CompressionLevel.None)
- _CompressionMethod = (short) Ionic.Zip.CompressionMethod.None;
- else
- _CompressionMethod = (short) Ionic.Zip.CompressionMethod.Deflate;
-
- if (_container.ZipFile != null) _container.ZipFile.NotifyEntryChanged();
- _restreamRequiredOnSave = true;
- }
- }
-
-
-
- ///
- /// The compressed size of the file, in bytes, within the zip archive.
- ///
- ///
- ///
- /// When reading a ZipFile, this value is read in from the existing
- /// zip file. When creating or updating a ZipFile, the compressed
- /// size is computed during compression. Therefore the value on a
- /// ZipEntry is valid after a call to Save() (or one of its
- /// overloads) in that case.
- ///
- ///
- ///
- public Int64 CompressedSize
- {
- get { return _CompressedSize; }
- }
-
- ///
- /// The size of the file, in bytes, before compression, or after extraction.
- ///
- ///
- ///
- /// When reading a ZipFile, this value is read in from the existing
- /// zip file. When creating or updating a ZipFile, the uncompressed
- /// size is computed during compression. Therefore the value on a
- /// ZipEntry is valid after a call to Save() (or one of its
- /// overloads) in that case.
- ///
- ///
- ///
- public Int64 UncompressedSize
- {
- get { return _UncompressedSize; }
- }
-
- ///
- /// The ratio of compressed size to uncompressed size of the ZipEntry.
- ///
- ///
- ///
- ///
- /// This is a ratio of the compressed size to the uncompressed size of the
- /// entry, expressed as a double in the range of 0 to 100+. A value of 100
- /// indicates no compression at all. It could be higher than 100 when the
- /// compression algorithm actually inflates the data, as may occur for small
- /// files, or uncompressible data that is encrypted.
- ///
- ///
- ///
- /// You could format it for presentation to a user via a format string of
- /// "{3,5:F0}%" to see it as a percentage.
- ///
- ///
- ///
- /// If the size of the original uncompressed file is 0, implying a
- /// denominator of 0, the return value will be zero.
- ///
- ///
- ///
- /// This property is valid after reading in an existing zip file, or after
- /// saving the ZipFile that contains the ZipEntry. You cannot know the
- /// effect of a compression transform until you try it.
- ///
- ///
- ///
- public Double CompressionRatio
- {
- get
- {
- if (UncompressedSize == 0) return 0;
- return 100 * (1.0 - (1.0 * CompressedSize) / (1.0 * UncompressedSize));
- }
- }
-
- ///
- /// The 32-bit CRC (Cyclic Redundancy Check) on the contents of the ZipEntry.
- ///
- ///
- ///
- ///
- /// You probably don't need to concern yourself with this. It is used
- /// internally by DotNetZip to verify files or streams upon extraction.
- ///
- /// The value is a 32-bit
- /// CRC using 0xEDB88320 for the polynomial. This is the same CRC-32 used in
- /// PNG, MPEG-2, and other protocols and formats. It is a read-only property; when
- /// creating a Zip archive, the CRC for each entry is set only after a call to
- /// Save() on the containing ZipFile. When reading an existing zip file, the value
- /// of this property reflects the stored CRC for the entry.
- ///
- ///
- public Int32 Crc
- {
- get { return _Crc32; }
- }
-
- ///
- /// True if the entry is a directory (not a file).
- /// This is a readonly property on the entry.
- ///
- public bool IsDirectory
- {
- get { return _IsDirectory; }
- }
-
- ///
- /// A derived property that is true if the entry uses encryption.
- ///
- ///
- ///
- ///
- /// This is a readonly property on the entry. When reading a zip file,
- /// the value for the ZipEntry is determined by the data read
- /// from the zip file. After saving a ZipFile, the value of this
- /// property for each ZipEntry indicates whether encryption was
- /// actually used (which will have been true if the was set and the property
- /// was something other than .
- ///
- ///
- public bool UsesEncryption
- {
- get { return (_Encryption_FromZipFile != EncryptionAlgorithm.None); }
- }
-
-
- ///
- /// Set this to specify which encryption algorithm to use for the entry when
- /// saving it to a zip archive.
- ///
- ///
- ///
- ///
- ///
- /// Set this property in order to encrypt the entry when the ZipFile is
- /// saved. When setting this property, you must also set a on the entry. If you set a value other than on this property and do not set a
- /// Password then the entry will not be encrypted. The ZipEntry
- /// data is encrypted as the ZipFile is saved, when you call or one of its cousins on the containing
- /// ZipFile instance. You do not need to specify the Encryption
- /// when extracting entries from an archive.
- ///
- ///
- ///
- /// The Zip specification from PKWare defines a set of encryption algorithms,
- /// and the data formats for the zip archive that support them, and PKWare
- /// supports those algorithms in the tools it produces. Other vendors of tools
- /// and libraries, such as WinZip or Xceed, typically support a
- /// subset of the algorithms specified by PKWare. These tools can
- /// sometimes support additional different encryption algorithms and data
- /// formats, not specified by PKWare. The AES Encryption specified and
- /// supported by WinZip is the most popular example. This library supports a
- /// subset of the complete set of algorithms specified by PKWare and other
- /// vendors.
- ///
- ///
- ///
- /// There is no common, ubiquitous multi-vendor standard for strong encryption
- /// within zip files. There is broad support for so-called "traditional" Zip
- /// encryption, sometimes called Zip 2.0 encryption, as specified
- /// by PKWare, but this encryption is considered weak and
- /// breakable. This library currently supports the Zip 2.0 "weak" encryption,
- /// and also a stronger WinZip-compatible AES encryption, using either 128-bit
- /// or 256-bit key strength. If you want DotNetZip to support an algorithm
- /// that is not currently supported, call the author of this library and maybe
- /// we can talk business.
- ///
- ///
- ///
- /// The class also has a property. In most cases you will use
- /// that property when setting encryption. This property takes
- /// precedence over any Encryption set on the ZipFile itself.
- /// Typically, you would use the per-entry Encryption when most entries in the
- /// zip archive use one encryption algorithm, and a few entries use a
- /// different one. If all entries in the zip file use the same Encryption,
- /// then it is simpler to just set this property on the ZipFile itself, when
- /// creating a zip archive.
- ///
- ///
- ///
- /// Some comments on updating archives: If you read a ZipFile, you can
- /// modify the Encryption on an encrypted entry: you can remove encryption
- /// from an entry that was encrypted; you can encrypt an entry that was not
- /// encrypted previously; or, you can change the encryption algorithm. The
- /// changes in encryption are not made permanent until you call Save() on the
- /// ZipFile. To effect changes in encryption, the entry content is
- /// streamed through several transformations, depending on the modification
- /// the application has requested. For example if the entry is not encrypted
- /// and the application sets Encryption to PkzipWeak, then at
- /// the time of Save(), the original entry is read and decompressed,
- /// then re-compressed and encrypted. Conversely, if the original entry is
- /// encrypted with PkzipWeak encryption, and the application sets the
- /// Encryption property to WinZipAes128, then at the time of
- /// Save(), the original entry is decrypted via PKZIP encryption and
- /// decompressed, then re-compressed and re-encrypted with AES. This all
- /// happens automatically within the library, but it can be time-consuming for
- /// large entries.
- ///
- ///
- ///
- /// Additionally, when updating archives, it is not possible to change the
- /// password when changing the encryption algorithm. To change both the
- /// algorithm and the password, you need to Save() the zipfile twice. First
- /// set the Encryption to None, then call Save(). Then set the
- /// Encryption to the new value (not "None"), then call Save()
- /// once again.
- ///
- ///
- ///
- /// The WinZip AES encryption algorithms are not supported on the .NET Compact
- /// Framework.
- ///
- ///
- ///
- ///
- ///
- /// This example creates a zip archive that uses encryption, and then extracts
- /// entries from the archive. When creating the zip archive, the ReadMe.txt
- /// file is zipped without using a password or encryption. The other file
- /// uses encryption.
- ///
- ///
- /// // Create a zip archive with AES Encryption.
- /// using (ZipFile zip = new ZipFile())
- /// {
- /// zip.AddFile("ReadMe.txt")
- /// ZipEntry e1= zip.AddFile("2008-Regional-Sales-Report.pdf");
- /// e1.Encryption= EncryptionAlgorithm.WinZipAes256;
- /// e1.Password= "Top.Secret.No.Peeking!";
- /// zip.Save("EncryptedArchive.zip");
- /// }
- ///
- /// // Extract a zip archive that uses AES Encryption.
- /// // You do not need to specify the algorithm during extraction.
- /// using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
- /// {
- /// // Specify the password that is used during extraction, for
- /// // all entries that require a password:
- /// zip.Password= "Top.Secret.No.Peeking!";
- /// zip.ExtractAll("extractDirectory");
- /// }
- ///
- ///
- ///
- /// ' Create a zip that uses Encryption.
- /// Using zip As New ZipFile()
- /// zip.AddFile("ReadMe.txt")
- /// Dim e1 as ZipEntry
- /// e1= zip.AddFile("2008-Regional-Sales-Report.pdf")
- /// e1.Encryption= EncryptionAlgorithm.WinZipAes256
- /// e1.Password= "Top.Secret.No.Peeking!"
- /// zip.Save("EncryptedArchive.zip")
- /// End Using
- ///
- /// ' Extract a zip archive that uses AES Encryption.
- /// ' You do not need to specify the algorithm during extraction.
- /// Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
- /// ' Specify the password that is used during extraction, for
- /// ' all entries that require a password:
- /// zip.Password= "Top.Secret.No.Peeking!"
- /// zip.ExtractAll("extractDirectory")
- /// End Using
- ///
- ///
- ///
- ///
- ///
- /// Thrown in the setter if EncryptionAlgorithm.Unsupported is specified.
- ///
- ///
- /// ZipEntry.Password
- /// ZipFile.Encryption
- public EncryptionAlgorithm Encryption
- {
- get
- {
- return _Encryption;
- }
- set
- {
- if (value == _Encryption) return; // no change
-
- if (value == EncryptionAlgorithm.Unsupported)
- throw new InvalidOperationException("You may not set Encryption to that value.");
-
- // If the source is a zip archive and there was encryption
- // on the entry, this will not work.
- //if (this._Source == ZipEntrySource.ZipFile && _sourceIsEncrypted)
- // throw new InvalidOperationException("You cannot change the encryption method on encrypted entries read from archives.");
-
- _Encryption = value;
- _restreamRequiredOnSave = true;
- if (_container.ZipFile!=null)
- _container.ZipFile.NotifyEntryChanged();
- }
- }
-
-
- ///
- /// The Password to be used when encrypting a ZipEntry upon
- /// ZipFile.Save(), or when decrypting an entry upon Extract().
- ///
- ///
- ///
- ///
- /// This is a write-only property on the entry. Set this to request that the
- /// entry be encrypted when writing the zip archive, or set it to specify the
- /// password to be used when extracting an existing entry that is encrypted.
- ///
- ///
- ///
- /// The password set here is implicitly used to encrypt the entry during the
- /// operation, or to decrypt during the or operation. If you set
- /// the Password on a ZipEntry after calling Save(), there is no
- /// effect.
- ///
- ///
- ///
- /// Consider setting the property when using a
- /// password. Answering concerns that the standard password protection
- /// supported by all zip tools is weak, WinZip has extended the ZIP
- /// specification with a way to use AES Encryption to protect entries in the
- /// Zip file. Unlike the "PKZIP 2.0" encryption specified in the PKZIP
- /// specification, AES
- /// Encryption uses a standard, strong, tested, encryption
- /// algorithm. DotNetZip can create zip archives that use WinZip-compatible
- /// AES encryption, if you set the property. But,
- /// archives created that use AES encryption may not be readable by all other
- /// tools and libraries. For example, Windows Explorer cannot read a
- /// "compressed folder" (a zip file) that uses AES encryption, though it can
- /// read a zip file that uses "PKZIP encryption."
- ///
- ///
- ///
- /// The class also has a
- /// property. This property takes precedence over any password set on the
- /// ZipFile itself. Typically, you would use the per-entry Password when most
- /// entries in the zip archive use one password, and a few entries use a
- /// different password. If all entries in the zip file use the same password,
- /// then it is simpler to just set this property on the ZipFile itself,
- /// whether creating a zip archive or extracting a zip archive.
- ///
- ///
- ///
- /// Some comments on updating archives: If you read a ZipFile, you
- /// cannot modify the password on any encrypted entry, except by extracting
- /// the entry with the original password (if any), removing the original entry
- /// via , and then adding a new
- /// entry with a new Password.
- ///
- ///
- ///
- /// For example, suppose you read a ZipFile, and there is an encrypted
- /// entry. Setting the Password property on that ZipEntry and then
- /// calling Save() on the ZipFile does not update the password
- /// on that entry in the archive. Neither is an exception thrown. Instead,
- /// what happens during the Save() is the existing entry is copied
- /// through to the new zip archive, in its original encrypted form. Upon
- /// re-reading that archive, the entry can be decrypted with its original
- /// password.
- ///
- ///
- ///
- /// If you read a ZipFile, and there is an un-encrypted entry, you can set the
- /// Password on the entry and then call Save() on the ZipFile, and get
- /// encryption on that entry.
- ///
- ///
- ///
- ///
- ///
- ///
- /// This example creates a zip file with two entries, and then extracts the
- /// entries from the zip file. When creating the zip file, the two files are
- /// added to the zip file using password protection. Each entry uses a
- /// different password. During extraction, each file is extracted with the
- /// appropriate password.
- ///
- ///
- /// // create a file with encryption
- /// using (ZipFile zip = new ZipFile())
- /// {
- /// ZipEntry entry;
- /// entry= zip.AddFile("Declaration.txt");
- /// entry.Password= "123456!";
- /// entry = zip.AddFile("Report.xls");
- /// entry.Password= "1Secret!";
- /// zip.Save("EncryptedArchive.zip");
- /// }
- ///
- /// // extract entries that use encryption
- /// using (ZipFile zip = ZipFile.Read("EncryptedArchive.zip"))
- /// {
- /// ZipEntry entry;
- /// entry = zip["Declaration.txt"];
- /// entry.Password = "123456!";
- /// entry.Extract("extractDir");
- /// entry = zip["Report.xls"];
- /// entry.Password = "1Secret!";
- /// entry.Extract("extractDir");
- /// }
- ///
- ///
- ///
- ///
- /// Using zip As New ZipFile
- /// Dim entry as ZipEntry
- /// entry= zip.AddFile("Declaration.txt")
- /// entry.Password= "123456!"
- /// entry = zip.AddFile("Report.xls")
- /// entry.Password= "1Secret!"
- /// zip.Save("EncryptedArchive.zip")
- /// End Using
- ///
- ///
- /// ' extract entries that use encryption
- /// Using (zip as ZipFile = ZipFile.Read("EncryptedArchive.zip"))
- /// Dim entry as ZipEntry
- /// entry = zip("Declaration.txt")
- /// entry.Password = "123456!"
- /// entry.Extract("extractDir")
- /// entry = zip("Report.xls")
- /// entry.Password = "1Secret!"
- /// entry.Extract("extractDir")
- /// End Using
- ///
- ///
- ///
- ///
- ///
- ///
- /// ZipFile.Password
- public string Password
- {
- set
- {
- _Password = value;
- if (_Password == null)
- {
- _Encryption = EncryptionAlgorithm.None;
- }
- else
- {
- // We're setting a non-null password.
-
- // For entries obtained from a zip file that are encrypted, we cannot
- // simply restream (recompress, re-encrypt) the file data, because we
- // need the old password in order to decrypt the data, and then we
- // need the new password to encrypt. So, setting the password is
- // never going to work on an entry that is stored encrypted in a zipfile.
-
- // But it is not en error to set the password, obviously: callers will
- // set the password in order to Extract encrypted archives.
-
- // If the source is a zip archive and there was previously no encryption
- // on the entry, then we must re-stream the entry in order to encrypt it.
- if (this._Source == ZipEntrySource.ZipFile && !_sourceIsEncrypted)
- _restreamRequiredOnSave = true;
-
- if (Encryption == EncryptionAlgorithm.None)
- {
- _Encryption = EncryptionAlgorithm.PkzipWeak;
- }
- }
- }
- private get { return _Password; }
- }
-
-
-
- internal bool IsChanged
- {
- get
- {
- return _restreamRequiredOnSave | _metadataChanged;
- }
- }
-
-
- ///
- /// The action the library should take when extracting a file that already exists.
- ///
- ///
- ///
- ///
- /// This property affects the behavior of the Extract methods (one of the
- /// Extract() or ExtractWithPassword() overloads), when
- /// extraction would would overwrite an existing filesystem file. If you do
- /// not set this property, the library throws an exception when extracting
- /// an entry would overwrite an existing file.
- ///
- ///
- ///
- /// This property has no effect when extracting to a stream, or when the file to be
- /// extracted does not already exist.
- ///
- ///
- ///
- ///
- ///
- ///
- /// This example shows how to set the ExtractExistingFile property in
- /// an ExtractProgress event, in response to user input. The
- /// ExtractProgress event is invoked if and only if the
- /// ExtractExistingFile property was previously set to
- /// ExtractExistingFileAction.InvokeExtractProgressEvent.
- ///
- /// public static void ExtractProgress(object sender, ExtractProgressEventArgs e)
- /// {
- /// if (e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry)
- /// Console.WriteLine("extract {0} ", e.CurrentEntry.FileName);
- ///
- /// else if (e.EventType == ZipProgressEventType.Extracting_ExtractEntryWouldOverwrite)
- /// {
- /// ZipEntry entry = e.CurrentEntry;
- /// string response = null;
- /// // Ask the user if he wants overwrite the file
- /// do
- /// {
- /// Console.Write("Overwrite {0} in {1} ? (y/n/C) ", entry.FileName, e.ExtractLocation);
- /// response = Console.ReadLine();
- /// Console.WriteLine();
- ///
- /// } while (response != null && response[0]!='Y' &&
- /// response[0]!='N' && response[0]!='C');
- ///
- /// if (response[0]=='C')
- /// e.Cancel = true;
- /// else if (response[0]=='Y')
- /// entry.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
- /// else
- /// entry.ExtractExistingFile= ExtractExistingFileAction.DoNotOverwrite;
- /// }
- /// }
- ///
- ///
- public ExtractExistingFileAction ExtractExistingFile
- {
- get;
- set;
- }
-
-
- ///
- /// The action to take when an error is encountered while
- /// opening or reading files as they are saved into a zip archive.
- ///
- ///
- ///
- ///
- /// Errors can occur within a call to ZipFile.Save, as the various files contained
- /// in a ZipFile are being saved into the zip archive. During the
- /// Save, DotNetZip will perform a File.Open on the file
- /// associated to the ZipEntry, and then will read the entire contents of
- /// the file as it is zipped. Either the open or the Read may fail, because
- /// of lock conflicts or other reasons. Using this property, you can
- /// specify the action to take when such errors occur.
- ///
- ///
- ///
- /// Typically you will NOT set this property on individual ZipEntry
- /// instances. Instead, you will set the ZipFile.ZipErrorAction property on
- /// the ZipFile instance, before adding any entries to the
- /// ZipFile. If you do this, errors encountered on behalf of any of
- /// the entries in the ZipFile will be handled the same way.
- ///
- ///
- ///
- /// But, if you use a handler, you will want
- /// to set this property on the ZipEntry within the handler, to
- /// communicate back to DotNetZip what you would like to do with the
- /// particular error.
- ///
- ///
- ///
- ///
- ///
- public ZipErrorAction ZipErrorAction
- {
- get;
- set;
- }
-
-
- ///
- /// Indicates whether the entry was included in the most recent save.
- ///
- ///
- /// An entry can be excluded or skipped from a save if there is an error
- /// opening or reading the entry.
- ///
- ///
- public bool IncludedInMostRecentSave
- {
- get
- {
- return !_skippedDuringSave;
- }
- }
-
-
- ///
- /// A callback that allows the application to specify the compression to use
- /// for a given entry that is about to be added to the zip archive.
- ///
- ///
- ///
- ///
- /// See
- ///
- ///
- public SetCompressionCallback SetCompression
- {
- get;
- set;
- }
-
-
-
- ///
- /// Set to indicate whether to use UTF-8 encoding for filenames and comments.
- ///
- ///
- ///
- ///
- ///
- /// If this flag is set, the comment and filename for the entry will be
- /// encoded with UTF-8, as described in the Zip
- /// specification, if necessary. "Necessary" means, the filename or
- /// entry comment (if any) cannot be reflexively encoded and decoded using the
- /// default code page, IBM437.
- ///
- ///
- ///
- /// Setting this flag to true is equivalent to setting to System.Text.Encoding.UTF8.
- ///
- ///
- ///
- /// This flag has no effect or relation to the text encoding used within the
- /// file itself.
- ///
- ///
- ///
- [Obsolete("Beginning with v1.9.1.6 of DotNetZip, this property is obsolete. It will be removed in a future version of the library. Your applications should use AlternateEncoding and AlternateEncodingUsage instead.")]
- public bool UseUnicodeAsNecessary
- {
- get
- {
- return (AlternateEncoding == System.Text.Encoding.GetEncoding("UTF-8")) &&
- (AlternateEncodingUsage == ZipOption.AsNecessary);
- }
- set
- {
- if (value)
- {
- AlternateEncoding = System.Text.Encoding.GetEncoding("UTF-8");
- AlternateEncodingUsage = ZipOption.AsNecessary;
-
- }
- else
- {
- AlternateEncoding = Ionic.Zip.ZipFile.DefaultEncoding;
- AlternateEncodingUsage = ZipOption.Never;
- }
- }
- }
-
- ///
- /// The text encoding to use for the FileName and Comment on this ZipEntry,
- /// when the default encoding is insufficient.
- ///
- ///
- ///
- ///
- ///
- /// Don't use this property. See .
- ///
- ///
- ///
- [Obsolete("This property is obsolete since v1.9.1.6. Use AlternateEncoding and AlternateEncodingUsage instead.", true)]
- public System.Text.Encoding ProvisionalAlternateEncoding
- {
- get; set;
- }
-
- ///
- /// Specifies the alternate text encoding used by this ZipEntry
- ///
- ///
- ///
- /// The default text encoding used in Zip files for encoding filenames and
- /// comments is IBM437, which is something like a superset of ASCII. In
- /// cases where this is insufficient, applications can specify an
- /// alternate encoding.
- ///
- ///
- /// When creating a zip file, the usage of the alternate encoding is
- /// governed by the property.
- /// Typically you would set both properties to tell DotNetZip to employ an
- /// encoding that is not IBM437 in the zipfile you are creating.
- ///
- ///
- /// Keep in mind that because the ZIP specification states that the only
- /// valid encodings to use are IBM437 and UTF-8, if you use something
- /// other than that, then zip tools and libraries may not be able to
- /// successfully read the zip archive you generate.
- ///
- ///
- /// The zip specification states that applications should presume that
- /// IBM437 is in use, except when a special bit is set, which indicates
- /// UTF-8. There is no way to specify an arbitrary code page, within the
- /// zip file itself. When you create a zip file encoded with gb2312 or
- /// ibm861 or anything other than IBM437 or UTF-8, then the application
- /// that reads the zip file needs to "know" which code page to use. In
- /// some cases, the code page used when reading is chosen implicitly. For
- /// example, WinRar uses the ambient code page for the host desktop
- /// operating system. The pitfall here is that if you create a zip in
- /// Copenhagen and send it to Tokyo, the reader of the zipfile may not be
- /// able to decode successfully.
- ///
- ///
- ///
- /// This example shows how to create a zipfile encoded with a
- /// language-specific encoding:
- ///
- /// using (var zip = new ZipFile())
- /// {
- /// zip.AlternateEnoding = System.Text.Encoding.GetEncoding("ibm861");
- /// zip.AlternateEnodingUsage = ZipOption.Always;
- /// zip.AddFileS(arrayOfFiles);
- /// zip.Save("Myarchive-Encoded-in-IBM861.zip");
- /// }
- ///
- ///
- ///
- public System.Text.Encoding AlternateEncoding
- {
- get; set;
- }
-
-
- ///
- /// Describes if and when this instance should apply
- /// AlternateEncoding to encode the FileName and Comment, when
- /// saving.
- ///
- ///
- public ZipOption AlternateEncodingUsage
- {
- get; set;
- }
-
-
- // ///
- // /// The text encoding actually used for this ZipEntry.
- // ///
- // ///
- // ///
- // ///
- // ///
- // /// This read-only property describes the encoding used by the
- // /// ZipEntry. If the entry has been read in from an existing ZipFile,
- // /// then it may take the value UTF-8, if the entry is coded to specify UTF-8.
- // /// If the entry does not specify UTF-8, the typical case, then the encoding
- // /// used is whatever the application specified in the call to
- // /// ZipFile.Read(). If the application has used one of the overloads of
- // /// ZipFile.Read() that does not accept an encoding parameter, then the
- // /// encoding used is IBM437, which is the default encoding described in the
- // /// ZIP specification.
- // ///
- // ///
- // /// If the entry is being created, then the value of ActualEncoding is taken
- // /// according to the logic described in the documentation for .
- // ///
- // ///
- // /// An application might be interested in retrieving this property to see if
- // /// an entry read in from a file has used Unicode (UTF-8).
- // ///
- // ///
- // ///
- // ///
- // public System.Text.Encoding ActualEncoding
- // {
- // get
- // {
- // return _actualEncoding;
- // }
- // }
-
-
-
-
- internal static string NameInArchive(String filename, string directoryPathInArchive)
- {
- string result = null;
- if (directoryPathInArchive == null)
- result = filename;
-
- else
- {
- if (String.IsNullOrEmpty(directoryPathInArchive))
- {
- result = Path.GetFileName(filename);
- }
- else
- {
- // explicitly specify a pathname for this file
- result = Path.Combine(directoryPathInArchive, Path.GetFileName(filename));
- }
- }
-
- //result = Path.GetFullPath(result);
- result = SharedUtilities.NormalizePathForUseInZipFile(result);
-
- return result;
- }
-
- // workitem 9073
- internal static ZipEntry CreateFromNothing(String nameInArchive)
- {
- return Create(nameInArchive, ZipEntrySource.None, null, null);
- }
-
- internal static ZipEntry CreateFromFile(String filename, string nameInArchive)
- {
- return Create(nameInArchive, ZipEntrySource.FileSystem, filename, null);
- }
-
- internal static ZipEntry CreateForStream(String entryName, Stream s)
- {
- return Create(entryName, ZipEntrySource.Stream, s, null);
- }
-
- internal static ZipEntry CreateForWriter(String entryName, WriteDelegate d)
- {
- return Create(entryName, ZipEntrySource.WriteDelegate, d, null);
- }
-
- internal static ZipEntry CreateForJitStreamProvider(string nameInArchive, OpenDelegate opener, CloseDelegate closer)
- {
- return Create(nameInArchive, ZipEntrySource.JitStream, opener, closer);
- }
-
- internal static ZipEntry CreateForZipOutputStream(string nameInArchive)
- {
- return Create(nameInArchive, ZipEntrySource.ZipOutputStream, null, null);
- }
-
-
- private static ZipEntry Create(string nameInArchive, ZipEntrySource source, Object arg1, Object arg2)
- {
- if (String.IsNullOrEmpty(nameInArchive))
- throw new Ionic.Zip.ZipException("The entry name must be non-null and non-empty.");
-
- ZipEntry entry = new ZipEntry();
-
- // workitem 7071
- // workitem 7926 - "version made by" OS should be zero for compat with WinZip
- entry._VersionMadeBy = (0 << 8) + 45; // indicates the attributes are FAT Attributes, and v4.5 of the spec
- entry._Source = source;
- entry._Mtime = entry._Atime = entry._Ctime = DateTime.UtcNow;
-
- if (source == ZipEntrySource.Stream)
- {
- entry._sourceStream = (arg1 as Stream); // may or may not be null
- }
- else if (source == ZipEntrySource.WriteDelegate)
- {
- entry._WriteDelegate = (arg1 as WriteDelegate); // may or may not be null
- }
- else if (source == ZipEntrySource.JitStream)
- {
- entry._OpenDelegate = (arg1 as OpenDelegate); // may or may not be null
- entry._CloseDelegate = (arg2 as CloseDelegate); // may or may not be null
- }
- else if (source == ZipEntrySource.ZipOutputStream)
- {
- }
- // workitem 9073
- else if (source == ZipEntrySource.None)
- {
- // make this a valid value, for later.
- entry._Source = ZipEntrySource.FileSystem;
- }
- else
- {
- String filename = (arg1 as String); // must not be null
-
- if (String.IsNullOrEmpty(filename))
- throw new Ionic.Zip.ZipException("The filename must be non-null and non-empty.");
-
- try
- {
- // The named file may or may not exist at this time. For
- // example, when adding a directory by name. We test existence
- // when necessary: when saving the ZipFile, or when getting the
- // attributes, and so on.
-
-#if NETCF
- // workitem 6878
- // Ionic.Zip.SharedUtilities.AdjustTime_Win32ToDotNet
- entry._Mtime = File.GetLastWriteTime(filename).ToUniversalTime();
- entry._Ctime = File.GetCreationTime(filename).ToUniversalTime();
- entry._Atime = File.GetLastAccessTime(filename).ToUniversalTime();
-
- // workitem 7071
- // can only get attributes of files that exist.
- if (File.Exists(filename) || Directory.Exists(filename))
- entry._ExternalFileAttrs = (int)NetCfFile.GetAttributes(filename);
-
-#elif SILVERLIGHT
- entry._Mtime =
- entry._Ctime =
- entry._Atime = System.DateTime.UtcNow;
- entry._ExternalFileAttrs = (int)0;
-#else
- // workitem 6878??
- entry._Mtime = File.GetLastWriteTime(filename).ToUniversalTime();
- entry._Ctime = File.GetCreationTime(filename).ToUniversalTime();
- entry._Atime = File.GetLastAccessTime(filename).ToUniversalTime();
-
- // workitem 7071
- // can only get attributes on files that exist.
- if (File.Exists(filename) || Directory.Exists(filename))
- entry._ExternalFileAttrs = (int)File.GetAttributes(filename);
-
-#endif
- entry._ntfsTimesAreSet = true;
-
- entry._LocalFileName = Path.GetFullPath(filename); // workitem 8813
-
- }
- catch (System.IO.PathTooLongException ptle)
- {
- // workitem 14035
- var msg = String.Format("The path is too long, filename={0}",
- filename);
- throw new ZipException(msg, ptle);
- }
-
- }
-
- entry._LastModified = entry._Mtime;
- entry._FileNameInArchive = SharedUtilities.NormalizePathForUseInZipFile(nameInArchive);
- // We don't actually slurp in the file data until the caller invokes Write on this entry.
-
- return entry;
- }
-
-
-
-
- internal void MarkAsDirectory()
- {
- _IsDirectory = true;
- // workitem 6279
- if (!_FileNameInArchive.EndsWith("/"))
- _FileNameInArchive += "/";
- }
-
-
-
- ///
- /// Indicates whether an entry is marked as a text file. Be careful when
- /// using on this property. Unless you have a good reason, you should
- /// probably ignore this property.
- ///
- ///
- ///
- ///
- /// The ZIP format includes a provision for specifying whether an entry in
- /// the zip archive is a text or binary file. This property exposes that
- /// metadata item. Be careful when using this property: It's not clear
- /// that this property as a firm meaning, across tools and libraries.
- ///
- ///
- ///
- /// To be clear, when reading a zip file, the property value may or may
- /// not be set, and its value may or may not be valid. Not all entries
- /// that you may think of as "text" entries will be so marked, and entries
- /// marked as "text" are not guaranteed in any way to be text entries.
- /// Whether the value is set and set correctly depends entirely on the
- /// application that produced the zip file.
- ///
- ///
- ///
- /// There are many zip tools available, and when creating zip files, some
- /// of them "respect" the IsText metadata field, and some of them do not.
- /// Unfortunately, even when an application tries to do "the right thing",
- /// it's not always clear what "the right thing" is.
- ///
- ///
- ///
- /// There's no firm definition of just what it means to be "a text file",
- /// and the zip specification does not help in this regard. Twenty years
- /// ago, text was ASCII, each byte was less than 127. IsText meant, all
- /// bytes in the file were less than 127. These days, it is not the case
- /// that all text files have all bytes less than 127. Any unicode file
- /// may have bytes that are above 0x7f. The zip specification has nothing
- /// to say on this topic. Therefore, it's not clear what IsText really
- /// means.
- ///
- ///
- ///
- /// This property merely tells a reading application what is stored in the
- /// metadata for an entry, without guaranteeing its validity or its
- /// meaning.
- ///
- ///
- ///
- /// When DotNetZip is used to create a zipfile, it attempts to set this
- /// field "correctly." For example, if a file ends in ".txt", this field
- /// will be set. Your application may override that default setting. When
- /// writing a zip file, you must set the property before calling
- /// Save() on the ZipFile.
- ///
- ///
- ///
- /// When reading a zip file, a more general way to decide just what kind
- /// of file is contained in a particular entry is to use the file type
- /// database stored in the operating system. The operating system stores
- /// a table that says, a file with .jpg extension is a JPG image file, a
- /// file with a .xml extension is an XML document, a file with a .txt is a
- /// pure ASCII text document, and so on. To get this information on
- /// Windows, you
- /// need to read and parse the registry.
- ///
- ///
- ///
- ///
- /// using (var zip = new ZipFile())
- /// {
- /// var e = zip.UpdateFile("Descriptions.mme", "");
- /// e.IsText = true;
- /// zip.Save(zipPath);
- /// }
- ///
- ///
- ///
- /// Using zip As New ZipFile
- /// Dim e2 as ZipEntry = zip.AddFile("Descriptions.mme", "")
- /// e.IsText= True
- /// zip.Save(zipPath)
- /// End Using
- ///
- ///
- public bool IsText
- {
- // workitem 7801
- get { return _IsText; }
- set { _IsText = value; }
- }
-
-
-
- /// Provides a string representation of the instance.
- /// a string representation of the instance.
- public override String ToString()
- {
- return String.Format("ZipEntry::{0}", FileName);
- }
-
-
- internal Stream ArchiveStream
- {
- get
- {
- if (_archiveStream == null)
- {
- if (_container.ZipFile != null)
- {
- var zf = _container.ZipFile;
- zf.Reset(false);
- _archiveStream = zf.StreamForDiskNumber(_diskNumber);
- }
- else
- {
- _archiveStream = _container.ZipOutputStream.OutputStream;
- }
- }
- return _archiveStream;
- }
- }
-
-
- private void SetFdpLoh()
- {
- // The value for FileDataPosition has not yet been set.
- // Therefore, seek to the local header, and figure the start of file data.
- // workitem 8098: ok (restore)
- long origPosition = this.ArchiveStream.Position;
- try
- {
- this.ArchiveStream.Seek(this._RelativeOffsetOfLocalHeader, SeekOrigin.Begin);
-
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
- }
- catch (System.IO.IOException exc1)
- {
- string description = String.Format("Exception seeking entry({0}) offset(0x{1:X8}) len(0x{2:X8})",
- this.FileName, this._RelativeOffsetOfLocalHeader,
- this.ArchiveStream.Length);
- throw new BadStateException(description, exc1);
- }
-
- byte[] block = new byte[30];
- this.ArchiveStream.Read(block, 0, block.Length);
-
- // At this point we could verify the contents read from the local header
- // with the contents read from the central header. We could, but don't need to.
- // So we won't.
-
- Int16 filenameLength = (short)(block[26] + block[27] * 256);
- Int16 extraFieldLength = (short)(block[28] + block[29] * 256);
-
- // Console.WriteLine(" pos 0x{0:X8} ({0})", this.ArchiveStream.Position);
- // Console.WriteLine(" seek 0x{0:X8} ({0})", filenameLength + extraFieldLength);
-
- this.ArchiveStream.Seek(filenameLength + extraFieldLength, SeekOrigin.Current);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
-
- this._LengthOfHeader = 30 + extraFieldLength + filenameLength +
- GetLengthOfCryptoHeaderBytes(_Encryption_FromZipFile);
-
- // Console.WriteLine(" ROLH 0x{0:X8} ({0})", _RelativeOffsetOfLocalHeader);
- // Console.WriteLine(" LOH 0x{0:X8} ({0})", _LengthOfHeader);
- // workitem 8098: ok (arithmetic)
- this.__FileDataPosition = _RelativeOffsetOfLocalHeader + _LengthOfHeader;
- // Console.WriteLine(" FDP 0x{0:X8} ({0})", __FileDataPosition);
-
- // restore file position:
- // workitem 8098: ok (restore)
- this.ArchiveStream.Seek(origPosition, SeekOrigin.Begin);
- // workitem 10178
- Ionic.Zip.SharedUtilities.Workaround_Ladybug318918(this.ArchiveStream);
- }
-
-
-
-#if AESCRYPTO
- private static int GetKeyStrengthInBits(EncryptionAlgorithm a)
- {
- if (a == EncryptionAlgorithm.WinZipAes256) return 256;
- else if (a == EncryptionAlgorithm.WinZipAes128) return 128;
- return -1;
- }
-#endif
-
- internal static int GetLengthOfCryptoHeaderBytes(EncryptionAlgorithm a)
- {
- //if ((_BitField & 0x01) != 0x01) return 0;
- if (a == EncryptionAlgorithm.None) return 0;
-
-#if AESCRYPTO
- if (a == EncryptionAlgorithm.WinZipAes128 ||
- a == EncryptionAlgorithm.WinZipAes256)
- {
- int KeyStrengthInBits = GetKeyStrengthInBits(a);
- int sizeOfSaltAndPv = ((KeyStrengthInBits / 8 / 2) + 2);
- return sizeOfSaltAndPv;
- }
-#endif
- if (a == EncryptionAlgorithm.PkzipWeak)
- return 12;
- throw new ZipException("internal error");
- }
-
-
- internal long FileDataPosition
- {
- get
- {
- if (__FileDataPosition == -1)
- SetFdpLoh();
-
- return __FileDataPosition;
- }
- }
-
- private int LengthOfHeader
- {
- get
- {
- if (_LengthOfHeader == 0)
- SetFdpLoh();
-
- return _LengthOfHeader;
- }
- }
-
-
-
- private ZipCrypto _zipCrypto_forExtract;
- private ZipCrypto _zipCrypto_forWrite;
-#if AESCRYPTO
- private WinZipAesCrypto _aesCrypto_forExtract;
- private WinZipAesCrypto _aesCrypto_forWrite;
- private Int16 _WinZipAesMethod;
-#endif
-
- internal DateTime _LastModified;
- private DateTime _Mtime, _Atime, _Ctime; // workitem 6878: NTFS quantities
- private bool _ntfsTimesAreSet;
- private bool _emitNtfsTimes = true;
- private bool _emitUnixTimes; // by default, false
- private bool _TrimVolumeFromFullyQualifiedPaths = true; // by default, trim them.
- internal string _LocalFileName;
- private string _FileNameInArchive;
- internal Int16 _VersionNeeded;
- internal Int16 _BitField;
- internal Int16 _CompressionMethod;
- private Int16 _CompressionMethod_FromZipFile;
- private Ionic.Zlib.CompressionLevel _CompressionLevel;
- internal string _Comment;
- private bool _IsDirectory;
- private byte[] _CommentBytes;
- internal Int64 _CompressedSize;
- internal Int64 _CompressedFileDataSize; // CompressedSize less 12 bytes for the encryption header, if any
- internal Int64 _UncompressedSize;
- internal Int32 _TimeBlob;
- private bool _crcCalculated;
- internal Int32 _Crc32;
- internal byte[] _Extra;
- private bool _metadataChanged;
- private bool _restreamRequiredOnSave;
- private bool _sourceIsEncrypted;
- private bool _skippedDuringSave;
- private UInt32 _diskNumber;
-
- private static System.Text.Encoding ibm437 = System.Text.Encoding.GetEncoding("IBM437");
- //private System.Text.Encoding _provisionalAlternateEncoding = System.Text.Encoding.GetEncoding("IBM437");
- private System.Text.Encoding _actualEncoding;
-
- internal ZipContainer _container;
-
- private long __FileDataPosition = -1;
- private byte[] _EntryHeader;
- internal Int64 _RelativeOffsetOfLocalHeader;
- private Int64 _future_ROLH;
- private Int64 _TotalEntrySize;
- private int _LengthOfHeader;
- private int _LengthOfTrailer;
- internal bool _InputUsesZip64;
- private UInt32 _UnsupportedAlgorithmId;
-
- internal string _Password;
- internal ZipEntrySource _Source;
- internal EncryptionAlgorithm _Encryption;
- internal EncryptionAlgorithm _Encryption_FromZipFile;
- internal byte[] _WeakEncryptionHeader;
- internal Stream _archiveStream;
- private Stream _sourceStream;
- private Nullable _sourceStreamOriginalPosition;
- private bool _sourceWasJitProvided;
- private bool _ioOperationCanceled;
- private bool _presumeZip64;
- private Nullable _entryRequiresZip64;
- private Nullable _OutputUsesZip64;
- private bool _IsText; // workitem 7801
- private ZipEntryTimestamp _timestamp;
-
- private static System.DateTime _unixEpoch = new System.DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- private static System.DateTime _win32Epoch = System.DateTime.FromFileTimeUtc(0L);
- private static System.DateTime _zeroHour = new System.DateTime(1, 1, 1, 0, 0, 0, DateTimeKind.Utc);
-
- private WriteDelegate _WriteDelegate;
- private OpenDelegate _OpenDelegate;
- private CloseDelegate _CloseDelegate;
-
-
- // summary
- // The default size of the IO buffer for ZipEntry instances. Currently it is 8192 bytes.
- // summary
- //public const int IO_BUFFER_SIZE_DEFAULT = 8192; // 0x8000; // 0x4400
-
- }
-
-
-
- ///
- /// An enum that specifies the type of timestamp available on the ZipEntry.
- ///
- ///
- ///
- ///
- ///
- /// The last modified time of a file can be stored in multiple ways in
- /// a zip file, and they are not mutually exclusive:
- ///
- ///
- ///
- /// -
- /// In the so-called "DOS" format, which has a 2-second precision. Values
- /// are rounded to the nearest even second. For example, if the time on the
- /// file is 12:34:43, then it will be stored as 12:34:44. This first value
- /// is accessible via the LastModified property. This value is always
- /// present in the metadata for each zip entry. In some cases the value is
- /// invalid, or zero.
- ///
- ///
- /// -
- /// In the so-called "Windows" or "NTFS" format, as an 8-byte integer
- /// quantity expressed as the number of 1/10 milliseconds (in other words
- /// the number of 100 nanosecond units) since January 1, 1601 (UTC). This
- /// format is how Windows represents file times. This time is accessible
- /// via the ModifiedTime property.
- ///
- ///
- /// -
- /// In the "Unix" format, a 4-byte quantity specifying the number of seconds since
- /// January 1, 1970 UTC.
- ///
- ///
- /// -
- /// In an older format, now deprecated but still used by some current
- /// tools. This format is also a 4-byte quantity specifying the number of
- /// seconds since January 1, 1970 UTC.
- ///
- ///
- ///
- ///
- ///
- /// This bit field describes which of the formats were found in a ZipEntry that was read.
- ///
- ///
- ///
- [Flags]
- public enum ZipEntryTimestamp
- {
- ///
- /// Default value.
- ///
- None = 0,
-
- ///
- /// A DOS timestamp with 2-second precision.
- ///
- DOS = 1,
-
- ///
- /// A Windows timestamp with 100-ns precision.
- ///
- Windows = 2,
-
- ///
- /// A Unix timestamp with 1-second precision.
- ///
- Unix = 4,
-
- ///
- /// A Unix timestamp with 1-second precision, stored in InfoZip v1 format. This
- /// format is outdated and is supported for reading archives only.
- ///
- InfoZip1 = 8,
- }
-
-
-
- ///
- /// The method of compression to use for a particular ZipEntry.
- ///
- ///
- ///
- /// PKWare's
- /// ZIP Specification describes a number of distinct
- /// cmopression methods that can be used within a zip
- /// file. DotNetZip supports a subset of them.
- ///
- public enum CompressionMethod
- {
- ///
- /// No compression at all. For COM environments, the value is 0 (zero).
- ///
- None = 0,
-
- ///
- /// DEFLATE compression, as described in IETF RFC
- /// 1951. This is the "normal" compression used in zip
- /// files. For COM environments, the value is 8.
- ///
- Deflate = 8,
-
-#if BZIP
- ///
- /// BZip2 compression, a compression algorithm developed by Julian Seward.
- /// For COM environments, the value is 12.
- ///
- BZip2 = 12,
-#endif
- }
-
-
-#if NETCF
- internal class NetCfFile
- {
- public static int SetTimes(string filename, DateTime ctime, DateTime atime, DateTime mtime)
- {
- IntPtr hFile = (IntPtr) CreateFileCE(filename,
- (uint)0x40000000L, // (uint)FileAccess.Write,
- (uint)0x00000002L, // (uint)FileShare.Write,
- 0,
- (uint) 3, // == open existing
- (uint)0, // flagsAndAttributes
- 0);
-
- if((int)hFile == -1)
- {
- // workitem 7944: don't throw on failure to set file times
- // throw new ZipException("CreateFileCE Failed");
- return Interop.Marshal.GetLastWin32Error();
- }
-
- SetFileTime(hFile,
- BitConverter.GetBytes(ctime.ToFileTime()),
- BitConverter.GetBytes(atime.ToFileTime()),
- BitConverter.GetBytes(mtime.ToFileTime()));
-
- CloseHandle(hFile);
- return 0;
- }
-
-
- public static int SetLastWriteTime(string filename, DateTime mtime)
- {
- IntPtr hFile = (IntPtr) CreateFileCE(filename,
- (uint)0x40000000L, // (uint)FileAccess.Write,
- (uint)0x00000002L, // (uint)FileShare.Write,
- 0,
- (uint) 3, // == open existing
- (uint)0, // flagsAndAttributes
- 0);
-
- if((int)hFile == -1)
- {
- // workitem 7944: don't throw on failure to set file time
- // throw new ZipException(String.Format("CreateFileCE Failed ({0})",
- // Interop.Marshal.GetLastWin32Error()));
- return Interop.Marshal.GetLastWin32Error();
- }
-
- SetFileTime(hFile, null, null,
- BitConverter.GetBytes(mtime.ToFileTime()));
-
- CloseHandle(hFile);
- return 0;
- }
-
-
- [Interop.DllImport("coredll.dll", EntryPoint="CreateFile", SetLastError=true)]
- internal static extern int CreateFileCE(string lpFileName,
- uint dwDesiredAccess,
- uint dwShareMode,
- int lpSecurityAttributes,
- uint dwCreationDisposition,
- uint dwFlagsAndAttributes,
- int hTemplateFile);
-
-
- [Interop.DllImport("coredll", EntryPoint="GetFileAttributes", SetLastError=true)]
- internal static extern uint GetAttributes(string lpFileName);
-
- [Interop.DllImport("coredll", EntryPoint="SetFileAttributes", SetLastError=true)]
- internal static extern bool SetAttributes(string lpFileName, uint dwFileAttributes);
-
- [Interop.DllImport("coredll", EntryPoint="SetFileTime", SetLastError=true)]
- internal static extern bool SetFileTime(IntPtr hFile, byte[] lpCreationTime, byte[] lpLastAccessTime, byte[] lpLastWriteTime);
-
- [Interop.DllImport("coredll.dll", SetLastError=true)]
- internal static extern bool CloseHandle(IntPtr hObject);
-
- }
-#endif
-
-
-
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntrySource.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntrySource.cs
deleted file mode 100644
index b64380df..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipEntrySource.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// ZipEntrySource.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa
-// 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-19 11:18:42>
-//
-// ------------------------------------------------------------------
-//
-
-namespace Ionic.Zip
-{
- ///
- /// An enum that specifies the source of the ZipEntry.
- ///
- public enum ZipEntrySource
- {
- ///
- /// Default value. Invalid on a bonafide ZipEntry.
- ///
- None = 0,
-
- ///
- /// The entry was instantiated by calling AddFile() or another method that
- /// added an entry from the filesystem.
- ///
- FileSystem,
-
- ///
- /// The entry was instantiated via or
- /// .
- ///
- Stream,
-
- ///
- /// The ZipEntry was instantiated by reading a zipfile.
- ///
- ZipFile,
-
- ///
- /// The content for the ZipEntry will be or was provided by the WriteDelegate.
- ///
- WriteDelegate,
-
- ///
- /// The content for the ZipEntry will be obtained from the stream dispensed by the OpenDelegate.
- /// The entry was instantiated via .
- ///
- JitStream,
-
- ///
- /// The content for the ZipEntry will be or was obtained from a ZipOutputStream.
- ///
- ZipOutputStream,
- }
-
-}
\ No newline at end of file
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipErrorAction.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipErrorAction.cs
deleted file mode 100644
index 3a394cd2..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipErrorAction.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-// ZipErrorAction.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009 Dino Chiesa
-// 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-September-01 18:43:20>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the ZipErrorAction enum, which provides
-// an action to take when errors occur when opening or reading
-// files to be added to a zip file.
-//
-// ------------------------------------------------------------------
-
-
-namespace Ionic.Zip
-{
- ///
- /// An enum providing the options when an error occurs during opening or reading
- /// of a file or directory that is being saved to a zip file.
- ///
- ///
- ///
- ///
- /// This enum describes the actions that the library can take when an error occurs
- /// opening or reading a file, as it is being saved into a Zip archive.
- ///
- ///
- ///
- /// In some cases an error will occur when DotNetZip tries to open a file to be
- /// added to the zip archive. In other cases, an error might occur after the
- /// file has been successfully opened, while DotNetZip is reading the file.
- ///
- ///
- ///
- /// The first problem might occur when calling AddDirectory() on a directory
- /// that contains a Clipper .dbf file; the file is locked by Clipper and
- /// cannot be opened by another process. An example of the second problem is
- /// the ERROR_LOCK_VIOLATION that results when a file is opened by another
- /// process, but not locked, and a range lock has been taken on the file.
- /// Microsoft Outlook takes range locks on .PST files.
- ///
- ///
- public enum ZipErrorAction
- {
- ///
- /// Throw an exception when an error occurs while zipping. This is the default
- /// behavior. (For COM clients, this is a 0 (zero).)
- ///
- Throw,
-
- ///
- /// When an error occurs during zipping, for example a file cannot be opened,
- /// skip the file causing the error, and continue zipping. (For COM clients,
- /// this is a 1.)
- ///
- Skip,
-
- ///
- /// When an error occurs during zipping, for example a file cannot be opened,
- /// retry the operation that caused the error. Be careful with this option. If
- /// the error is not temporary, the library will retry forever. (For COM
- /// clients, this is a 2.)
- ///
- Retry,
-
- ///
- /// When an error occurs, invoke the zipError event. The event type used is
- /// . A typical use of this option:
- /// a GUI application may wish to pop up a dialog to allow the user to view the
- /// error that occurred, and choose an appropriate action. After your
- /// processing in the error event, if you want to skip the file, set on the
- /// ZipProgressEventArgs.CurrentEntry to Skip. If you want the
- /// exception to be thrown, set ZipErrorAction on the CurrentEntry
- /// to Throw. If you want to cancel the zip, set
- /// ZipProgressEventArgs.Cancel to true. Cancelling differs from using
- /// Skip in that a cancel will not save any further entries, if there are any.
- /// (For COM clients, the value of this enum is a 3.)
- ///
- InvokeErrorEvent,
- }
-
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipFile.AddUpdate.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipFile.AddUpdate.cs
deleted file mode 100644
index d5da4fc4..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipFile.AddUpdate.cs
+++ /dev/null
@@ -1,2182 +0,0 @@
-// ZipFile.AddUpdate.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 Dino Chiesa.
-// 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: <2011-November-01 13:56:58>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the methods for Adding and Updating entries in
-// the ZipFile.
-//
-// ------------------------------------------------------------------
-//
-
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-
-namespace Ionic.Zip
-{
- public partial class ZipFile
- {
- ///
- /// Adds an item, either a file or a directory, to a zip file archive.
- ///
- ///
- ///
- ///
- /// This method is handy if you are adding things to zip archive and don't
- /// want to bother distinguishing between directories or files. Any files are
- /// added as single entries. A directory added through this method is added
- /// recursively: all files and subdirectories contained within the directory
- /// are added to the ZipFile.
- ///
- ///
- ///
- /// The name of the item may be a relative path or a fully-qualified
- /// path. Remember, the items contained in ZipFile instance get written
- /// to the disk only when you call or a similar
- /// save method.
- ///
- ///
- ///
- /// The directory name used for the file within the archive is the same
- /// as the directory name (potentially a relative path) specified in the
- /// .
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// This method has two overloads.
- ///
- /// the name of the file or directory to add.
- ///
- /// The ZipEntry added.
- public ZipEntry AddItem(string fileOrDirectoryName)
- {
- return AddItem(fileOrDirectoryName, null);
- }
-
-
- ///
- /// Adds an item, either a file or a directory, to a zip file archive,
- /// explicitly specifying the directory path to be used in the archive.
- ///
- ///
- ///
- ///
- /// If adding a directory, the add is recursive on all files and
- /// subdirectories contained within it.
- ///
- ///
- /// The name of the item may be a relative path or a fully-qualified path.
- /// The item added by this call to the ZipFile is not read from the
- /// disk nor written to the zip file archive until the application calls
- /// Save() on the ZipFile.
- ///
- ///
- ///
- /// This version of the method allows the caller to explicitly specify the
- /// directory path to be used in the archive, which would override the
- /// "natural" path of the filesystem file.
- ///
- ///
- ///
- /// Encryption will be used on the file data if the Password has
- /// been set on the ZipFile object, prior to calling this method.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- /// Thrown if the file or directory passed in does not exist.
- ///
- ///
- /// the name of the file or directory to add.
- ///
- ///
- ///
- /// The name of the directory path to use within the zip archive. This path
- /// need not refer to an extant directory in the current filesystem. If the
- /// files within the zip are later extracted, this is the path used for the
- /// extracted file. Passing null (Nothing in VB) will use the
- /// path on the fileOrDirectoryName. Passing the empty string ("") will
- /// insert the item at the root path within the archive.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// This example shows how to zip up a set of files into a flat hierarchy,
- /// regardless of where in the filesystem the files originated. The resulting
- /// zip archive will contain a toplevel directory named "flat", which itself
- /// will contain files Readme.txt, MyProposal.docx, and Image1.jpg. A
- /// subdirectory under "flat" called SupportFiles will contain all the files
- /// in the "c:\SupportFiles" directory on disk.
- ///
- ///
- /// String[] itemnames= {
- /// "c:\\fixedContent\\Readme.txt",
- /// "MyProposal.docx",
- /// "c:\\SupportFiles", // a directory
- /// "images\\Image1.jpg"
- /// };
- ///
- /// try
- /// {
- /// using (ZipFile zip = new ZipFile())
- /// {
- /// for (int i = 1; i < itemnames.Length; i++)
- /// {
- /// // will add Files or Dirs, recurses and flattens subdirectories
- /// zip.AddItem(itemnames[i],"flat");
- /// }
- /// zip.Save(ZipToCreate);
- /// }
- /// }
- /// catch (System.Exception ex1)
- /// {
- /// System.Console.Error.WriteLine("exception: {0}", ex1);
- /// }
- ///
- ///
- ///
- /// Dim itemnames As String() = _
- /// New String() { "c:\fixedContent\Readme.txt", _
- /// "MyProposal.docx", _
- /// "SupportFiles", _
- /// "images\Image1.jpg" }
- /// Try
- /// Using zip As New ZipFile
- /// Dim i As Integer
- /// For i = 1 To itemnames.Length - 1
- /// ' will add Files or Dirs, recursing and flattening subdirectories.
- /// zip.AddItem(itemnames(i), "flat")
- /// Next i
- /// zip.Save(ZipToCreate)
- /// End Using
- /// Catch ex1 As Exception
- /// Console.Error.WriteLine("exception: {0}", ex1.ToString())
- /// End Try
- ///
- ///
- /// The ZipEntry added.
- public ZipEntry AddItem(String fileOrDirectoryName, String directoryPathInArchive)
- {
- if (File.Exists(fileOrDirectoryName))
- return AddFile(fileOrDirectoryName, directoryPathInArchive);
-
- if (Directory.Exists(fileOrDirectoryName))
- return AddDirectory(fileOrDirectoryName, directoryPathInArchive);
-
- throw new FileNotFoundException(String.Format("That file or directory ({0}) does not exist!",
- fileOrDirectoryName));
- }
-
- ///
- /// Adds a File to a Zip file archive.
- ///
- ///
- ///
- ///
- /// This call collects metadata for the named file in the filesystem,
- /// including the file attributes and the timestamp, and inserts that metadata
- /// into the resulting ZipEntry. Only when the application calls Save() on
- /// the ZipFile, does DotNetZip read the file from the filesystem and
- /// then write the content to the zip file archive.
- ///
- ///
- ///
- /// This method will throw an exception if an entry with the same name already
- /// exists in the ZipFile.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- ///
- /// In this example, three files are added to a Zip archive. The ReadMe.txt
- /// file will be placed in the root of the archive. The .png file will be
- /// placed in a folder within the zip called photos\personal. The pdf file
- /// will be included into a folder within the zip called Desktop.
- ///
- ///
- /// try
- /// {
- /// using (ZipFile zip = new ZipFile())
- /// {
- /// zip.AddFile("c:\\photos\\personal\\7440-N49th.png");
- /// zip.AddFile("c:\\Desktop\\2008-Regional-Sales-Report.pdf");
- /// zip.AddFile("ReadMe.txt");
- ///
- /// zip.Save("Package.zip");
- /// }
- /// }
- /// catch (System.Exception ex1)
- /// {
- /// System.Console.Error.WriteLine("exception: " + ex1);
- /// }
- ///
- ///
- ///
- /// Try
- /// Using zip As ZipFile = New ZipFile
- /// zip.AddFile("c:\photos\personal\7440-N49th.png")
- /// zip.AddFile("c:\Desktop\2008-Regional-Sales-Report.pdf")
- /// zip.AddFile("ReadMe.txt")
- /// zip.Save("Package.zip")
- /// End Using
- /// Catch ex1 As Exception
- /// Console.Error.WriteLine("exception: {0}", ex1.ToString)
- /// End Try
- ///
- ///
- ///
- /// This method has two overloads.
- ///
- ///
- ///
- ///
- ///
- ///
- /// The name of the file to add. It should refer to a file in the filesystem.
- /// The name of the file may be a relative path or a fully-qualified path.
- ///
- /// The ZipEntry corresponding to the File added.
- public ZipEntry AddFile(string fileName)
- {
- return AddFile(fileName, null);
- }
-
-
-
-
-
- ///
- /// Adds a File to a Zip file archive, potentially overriding the path to be
- /// used within the zip archive.
- ///
- ///
- ///
- ///
- /// The file added by this call to the ZipFile is not written to the
- /// zip file archive until the application calls Save() on the ZipFile.
- ///
- ///
- ///
- /// This method will throw an exception if an entry with the same name already
- /// exists in the ZipFile.
- ///
- ///
- ///
- /// This version of the method allows the caller to explicitly specify the
- /// directory path to be used in the archive.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- ///
- /// In this example, three files are added to a Zip archive. The ReadMe.txt
- /// file will be placed in the root of the archive. The .png file will be
- /// placed in a folder within the zip called images. The pdf file will be
- /// included into a folder within the zip called files\docs, and will be
- /// encrypted with the given password.
- ///
- ///
- /// try
- /// {
- /// using (ZipFile zip = new ZipFile())
- /// {
- /// // the following entry will be inserted at the root in the archive.
- /// zip.AddFile("c:\\datafiles\\ReadMe.txt", "");
- /// // this image file will be inserted into the "images" directory in the archive.
- /// zip.AddFile("c:\\photos\\personal\\7440-N49th.png", "images");
- /// // the following will result in a password-protected file called
- /// // files\\docs\\2008-Regional-Sales-Report.pdf in the archive.
- /// zip.Password = "EncryptMe!";
- /// zip.AddFile("c:\\Desktop\\2008-Regional-Sales-Report.pdf", "files\\docs");
- /// zip.Save("Archive.zip");
- /// }
- /// }
- /// catch (System.Exception ex1)
- /// {
- /// System.Console.Error.WriteLine("exception: {0}", ex1);
- /// }
- ///
- ///
- ///
- /// Try
- /// Using zip As ZipFile = New ZipFile
- /// ' the following entry will be inserted at the root in the archive.
- /// zip.AddFile("c:\datafiles\ReadMe.txt", "")
- /// ' this image file will be inserted into the "images" directory in the archive.
- /// zip.AddFile("c:\photos\personal\7440-N49th.png", "images")
- /// ' the following will result in a password-protected file called
- /// ' files\\docs\\2008-Regional-Sales-Report.pdf in the archive.
- /// zip.Password = "EncryptMe!"
- /// zip.AddFile("c:\Desktop\2008-Regional-Sales-Report.pdf", "files\documents")
- /// zip.Save("Archive.zip")
- /// End Using
- /// Catch ex1 As Exception
- /// Console.Error.WriteLine("exception: {0}", ex1)
- /// End Try
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// The name of the file to add. The name of the file may be a relative path
- /// or a fully-qualified path.
- ///
- ///
- ///
- /// Specifies a directory path to use to override any path in the fileName.
- /// This path may, or may not, correspond to a real directory in the current
- /// filesystem. If the files within the zip are later extracted, this is the
- /// path used for the extracted file. Passing null (Nothing in
- /// VB) will use the path on the fileName, if any. Passing the empty string
- /// ("") will insert the item at the root path within the archive.
- ///
- ///
- /// The ZipEntry corresponding to the file added.
- public ZipEntry AddFile(string fileName, String directoryPathInArchive)
- {
- string nameInArchive = ZipEntry.NameInArchive(fileName, directoryPathInArchive);
- ZipEntry ze = ZipEntry.CreateFromFile(fileName, nameInArchive);
- if (Verbose) StatusMessageTextWriter.WriteLine("adding {0}...", fileName);
- return _InternalAddEntry(ze);
- }
-
-
- ///
- /// This method removes a collection of entries from the ZipFile.
- ///
- ///
- ///
- /// A collection of ZipEntry instances from this zip file to be removed. For
- /// example, you can pass in an array of ZipEntry instances; or you can call
- /// SelectEntries(), and then add or remove entries from that
- /// ICollection<ZipEntry> (ICollection(Of ZipEntry) in VB), and pass
- /// that ICollection to this method.
- ///
- ///
- ///
- ///
- public void RemoveEntries(System.Collections.Generic.ICollection entriesToRemove)
- {
- if (entriesToRemove == null)
- throw new ArgumentNullException("entriesToRemove");
-
- foreach (ZipEntry e in entriesToRemove)
- {
- this.RemoveEntry(e);
- }
- }
-
-
- ///
- /// This method removes a collection of entries from the ZipFile, by name.
- ///
- ///
- ///
- /// A collection of strings that refer to names of entries to be removed
- /// from the ZipFile. For example, you can pass in an array or a
- /// List of Strings that provide the names of entries to be removed.
- ///
- ///
- ///
- ///
- public void RemoveEntries(System.Collections.Generic.ICollection entriesToRemove)
- {
- if (entriesToRemove == null)
- throw new ArgumentNullException("entriesToRemove");
-
- foreach (String e in entriesToRemove)
- {
- this.RemoveEntry(e);
- }
- }
-
-
- ///
- /// This method adds a set of files to the ZipFile.
- ///
- ///
- ///
- ///
- /// Use this method to add a set of files to the zip archive, in one call.
- /// For example, a list of files received from
- /// System.IO.Directory.GetFiles() can be added to a zip archive in one
- /// call.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to each
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- /// The collection of names of the files to add. Each string should refer to a
- /// file in the filesystem. The name of the file may be a relative path or a
- /// fully-qualified path.
- ///
- ///
- ///
- /// This example shows how to create a zip file, and add a few files into it.
- ///
- /// String ZipFileToCreate = "archive1.zip";
- /// String DirectoryToZip = "c:\\reports";
- /// using (ZipFile zip = new ZipFile())
- /// {
- /// // Store all files found in the top level directory, into the zip archive.
- /// String[] filenames = System.IO.Directory.GetFiles(DirectoryToZip);
- /// zip.AddFiles(filenames);
- /// zip.Save(ZipFileToCreate);
- /// }
- ///
- ///
- ///
- /// Dim ZipFileToCreate As String = "archive1.zip"
- /// Dim DirectoryToZip As String = "c:\reports"
- /// Using zip As ZipFile = New ZipFile
- /// ' Store all files found in the top level directory, into the zip archive.
- /// Dim filenames As String() = System.IO.Directory.GetFiles(DirectoryToZip)
- /// zip.AddFiles(filenames)
- /// zip.Save(ZipFileToCreate)
- /// End Using
- ///
- ///
- ///
- ///
- public void AddFiles(System.Collections.Generic.IEnumerable fileNames)
- {
- this.AddFiles(fileNames, null);
- }
-
-
- ///
- /// Adds or updates a set of files in the ZipFile.
- ///
- ///
- ///
- ///
- /// Any files that already exist in the archive are updated. Any files that
- /// don't yet exist in the archive are added.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to each
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- /// The collection of names of the files to update. Each string should refer to a file in
- /// the filesystem. The name of the file may be a relative path or a fully-qualified path.
- ///
- ///
- public void UpdateFiles(System.Collections.Generic.IEnumerable fileNames)
- {
- this.UpdateFiles(fileNames, null);
- }
-
-
- ///
- /// Adds a set of files to the ZipFile, using the
- /// specified directory path in the archive.
- ///
- ///
- ///
- ///
- /// Any directory structure that may be present in the
- /// filenames contained in the list is "flattened" in the
- /// archive. Each file in the list is added to the archive in
- /// the specified top-level directory.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , , , and , their respective values at the
- /// time of this call will be applied to each ZipEntry added.
- ///
- ///
- ///
- ///
- /// The names of the files to add. Each string should refer to
- /// a file in the filesystem. The name of the file may be a
- /// relative path or a fully-qualified path.
- ///
- ///
- ///
- /// Specifies a directory path to use to override any path in the file name.
- /// Th is path may, or may not, correspond to a real directory in the current
- /// filesystem. If the files within the zip are later extracted, this is the
- /// path used for the extracted file. Passing null (Nothing in
- /// VB) will use the path on each of the fileNames, if any. Passing
- /// the empty string ("") will insert the item at the root path within the
- /// archive.
- ///
- ///
- ///
- public void AddFiles(System.Collections.Generic.IEnumerable fileNames, String directoryPathInArchive)
- {
- AddFiles(fileNames, false, directoryPathInArchive);
- }
-
-
-
- ///
- /// Adds a set of files to the ZipFile, using the specified directory
- /// path in the archive, and preserving the full directory structure in the
- /// filenames.
- ///
- ///
- ///
- ///
- ///
- /// Think of the as a "root" or
- /// base directory used in the archive for the files that get added. when
- /// is true, the hierarchy of files
- /// found in the filesystem will be placed, with the hierarchy intact,
- /// starting at that root in the archive. When preserveDirHierarchy
- /// is false, the path hierarchy of files is flattned, and the flattened
- /// set of files gets placed in the root within the archive as specified in
- /// directoryPathInArchive.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to each
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- /// The names of the files to add. Each string should refer to a file in the
- /// filesystem. The name of the file may be a relative path or a
- /// fully-qualified path.
- ///
- ///
- ///
- /// Specifies a directory path to use as a prefix for each entry name.
- /// This path may, or may not, correspond to a real directory in the current
- /// filesystem. If the files within the zip are later extracted, this is the
- /// path used for the extracted file. Passing null (Nothing in
- /// VB) will use the path on each of the fileNames, if any. Passing
- /// the empty string ("") will insert the item at the root path within the
- /// archive.
- ///
- ///
- ///
- /// whether the entries in the zip archive will reflect the directory
- /// hierarchy that is present in the various filenames. For example, if
- /// includes two paths,
- /// \Animalia\Chordata\Mammalia\Info.txt and
- /// \Plantae\Magnoliophyta\Dicotyledon\Info.txt, then calling this method
- /// with = false will
- /// result in an exception because of a duplicate entry name, while
- /// calling this method with =
- /// true will result in the full direcory paths being included in
- /// the entries added to the ZipFile.
- ///
- ///
- public void AddFiles(System.Collections.Generic.IEnumerable fileNames,
- bool preserveDirHierarchy,
- String directoryPathInArchive)
- {
- if (fileNames == null)
- throw new ArgumentNullException("fileNames");
-
- _addOperationCanceled = false;
- OnAddStarted();
- if (preserveDirHierarchy)
- {
- foreach (var f in fileNames)
- {
- if (_addOperationCanceled) break;
- if (directoryPathInArchive != null)
- {
- //string s = SharedUtilities.NormalizePath(Path.Combine(directoryPathInArchive, Path.GetDirectoryName(f)));
- string s = Path.GetFullPath(Path.Combine(directoryPathInArchive, Path.GetDirectoryName(f)));
- this.AddFile(f, s);
- }
- else
- this.AddFile(f, null);
- }
- }
- else
- {
- foreach (var f in fileNames)
- {
- if (_addOperationCanceled) break;
- this.AddFile(f, directoryPathInArchive);
- }
- }
- if (!_addOperationCanceled)
- OnAddCompleted();
- }
-
-
- ///
- /// Adds or updates a set of files to the ZipFile, using the specified
- /// directory path in the archive.
- ///
- ///
- ///
- ///
- ///
- /// Any files that already exist in the archive are updated. Any files that
- /// don't yet exist in the archive are added.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to each
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- /// The names of the files to add or update. Each string should refer to a
- /// file in the filesystem. The name of the file may be a relative path or a
- /// fully-qualified path.
- ///
- ///
- ///
- /// Specifies a directory path to use to override any path in the file name.
- /// This path may, or may not, correspond to a real directory in the current
- /// filesystem. If the files within the zip are later extracted, this is the
- /// path used for the extracted file. Passing null (Nothing in
- /// VB) will use the path on each of the fileNames, if any. Passing
- /// the empty string ("") will insert the item at the root path within the
- /// archive.
- ///
- ///
- ///
- public void UpdateFiles(System.Collections.Generic.IEnumerable fileNames, String directoryPathInArchive)
- {
- if (fileNames == null)
- throw new ArgumentNullException("fileNames");
-
- OnAddStarted();
- foreach (var f in fileNames)
- this.UpdateFile(f, directoryPathInArchive);
- OnAddCompleted();
- }
-
-
-
-
- ///
- /// Adds or Updates a File in a Zip file archive.
- ///
- ///
- ///
- ///
- /// This method adds a file to a zip archive, or, if the file already exists
- /// in the zip archive, this method Updates the content of that given filename
- /// in the zip archive. The UpdateFile method might more accurately be
- /// called "AddOrUpdateFile".
- ///
- ///
- ///
- /// Upon success, there is no way for the application to learn whether the file
- /// was added versus updated.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- /// This example shows how to Update an existing entry in a zipfile. The first
- /// call to UpdateFile adds the file to the newly-created zip archive. The
- /// second call to UpdateFile updates the content for that file in the zip
- /// archive.
- ///
- ///
- /// using (ZipFile zip1 = new ZipFile())
- /// {
- /// // UpdateFile might more accurately be called "AddOrUpdateFile"
- /// zip1.UpdateFile("MyDocuments\\Readme.txt");
- /// zip1.UpdateFile("CustomerList.csv");
- /// zip1.Comment = "This zip archive has been created.";
- /// zip1.Save("Content.zip");
- /// }
- ///
- /// using (ZipFile zip2 = ZipFile.Read("Content.zip"))
- /// {
- /// zip2.UpdateFile("Updates\\Readme.txt");
- /// zip2.Comment = "This zip archive has been updated: The Readme.txt file has been changed.";
- /// zip2.Save();
- /// }
- ///
- ///
- ///
- /// Using zip1 As New ZipFile
- /// ' UpdateFile might more accurately be called "AddOrUpdateFile"
- /// zip1.UpdateFile("MyDocuments\Readme.txt")
- /// zip1.UpdateFile("CustomerList.csv")
- /// zip1.Comment = "This zip archive has been created."
- /// zip1.Save("Content.zip")
- /// End Using
- ///
- /// Using zip2 As ZipFile = ZipFile.Read("Content.zip")
- /// zip2.UpdateFile("Updates\Readme.txt")
- /// zip2.Comment = "This zip archive has been updated: The Readme.txt file has been changed."
- /// zip2.Save
- /// End Using
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// The name of the file to add or update. It should refer to a file in the
- /// filesystem. The name of the file may be a relative path or a
- /// fully-qualified path.
- ///
- ///
- ///
- /// The ZipEntry corresponding to the File that was added or updated.
- ///
- public ZipEntry UpdateFile(string fileName)
- {
- return UpdateFile(fileName, null);
- }
-
-
-
- ///
- /// Adds or Updates a File in a Zip file archive.
- ///
- ///
- ///
- ///
- /// This method adds a file to a zip archive, or, if the file already exists
- /// in the zip archive, this method Updates the content of that given filename
- /// in the zip archive.
- ///
- ///
- ///
- /// This version of the method allows the caller to explicitly specify the
- /// directory path to be used in the archive. The entry to be added or
- /// updated is found by using the specified directory path, combined with the
- /// basename of the specified filename.
- ///
- ///
- ///
- /// Upon success, there is no way for the application to learn if the file was
- /// added versus updated.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// The name of the file to add or update. It should refer to a file in the
- /// filesystem. The name of the file may be a relative path or a
- /// fully-qualified path.
- ///
- ///
- ///
- /// Specifies a directory path to use to override any path in the
- /// fileName. This path may, or may not, correspond to a real
- /// directory in the current filesystem. If the files within the zip are
- /// later extracted, this is the path used for the extracted file. Passing
- /// null (Nothing in VB) will use the path on the
- /// fileName, if any. Passing the empty string ("") will insert the
- /// item at the root path within the archive.
- ///
- ///
- ///
- /// The ZipEntry corresponding to the File that was added or updated.
- ///
- public ZipEntry UpdateFile(string fileName, String directoryPathInArchive)
- {
- // ideally this would all be transactional!
- var key = ZipEntry.NameInArchive(fileName, directoryPathInArchive);
- if (this[key] != null)
- this.RemoveEntry(key);
- return this.AddFile(fileName, directoryPathInArchive);
- }
-
-
-
-
-
- ///
- /// Add or update a directory in a zip archive.
- ///
- ///
- ///
- /// If the specified directory does not exist in the archive, then this method
- /// is equivalent to calling AddDirectory(). If the specified
- /// directory already exists in the archive, then this method updates any
- /// existing entries, and adds any new entries. Any entries that are in the
- /// zip archive but not in the specified directory, are left alone. In other
- /// words, the contents of the zip file will be a union of the previous
- /// contents and the new files.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// The path to the directory to be added to the zip archive, or updated in
- /// the zip archive.
- ///
- ///
- ///
- /// The ZipEntry corresponding to the Directory that was added or updated.
- ///
- public ZipEntry UpdateDirectory(string directoryName)
- {
- return UpdateDirectory(directoryName, null);
- }
-
-
- ///
- /// Add or update a directory in the zip archive at the specified root
- /// directory in the archive.
- ///
- ///
- ///
- /// If the specified directory does not exist in the archive, then this method
- /// is equivalent to calling AddDirectory(). If the specified
- /// directory already exists in the archive, then this method updates any
- /// existing entries, and adds any new entries. Any entries that are in the
- /// zip archive but not in the specified directory, are left alone. In other
- /// words, the contents of the zip file will be a union of the previous
- /// contents and the new files.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// The path to the directory to be added to the zip archive, or updated
- /// in the zip archive.
- ///
- ///
- ///
- /// Specifies a directory path to use to override any path in the
- /// directoryName. This path may, or may not, correspond to a real
- /// directory in the current filesystem. If the files within the zip are
- /// later extracted, this is the path used for the extracted file. Passing
- /// null (Nothing in VB) will use the path on the
- /// directoryName, if any. Passing the empty string ("") will insert
- /// the item at the root path within the archive.
- ///
- ///
- ///
- /// The ZipEntry corresponding to the Directory that was added or updated.
- ///
- public ZipEntry UpdateDirectory(string directoryName, String directoryPathInArchive)
- {
- return this.AddOrUpdateDirectoryImpl(directoryName, directoryPathInArchive, AddOrUpdateAction.AddOrUpdate);
- }
-
-
-
-
-
- ///
- /// Add or update a file or directory in the zip archive.
- ///
- ///
- ///
- ///
- /// This is useful when the application is not sure or does not care if the
- /// item to be added is a file or directory, and does not know or does not
- /// care if the item already exists in the ZipFile. Calling this method
- /// is equivalent to calling RemoveEntry() if an entry by the same name
- /// already exists, followed calling by AddItem().
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// the path to the file or directory to be added or updated.
- ///
- public void UpdateItem(string itemName)
- {
- UpdateItem(itemName, null);
- }
-
-
- ///
- /// Add or update a file or directory.
- ///
- ///
- ///
- ///
- /// This method is useful when the application is not sure or does not care if
- /// the item to be added is a file or directory, and does not know or does not
- /// care if the item already exists in the ZipFile. Calling this method
- /// is equivalent to calling RemoveEntry(), if an entry by that name
- /// exists, and then calling AddItem().
- ///
- ///
- ///
- /// This version of the method allows the caller to explicitly specify the
- /// directory path to be used for the item being added to the archive. The
- /// entry or entries that are added or updated will use the specified
- /// DirectoryPathInArchive. Extracting the entry from the archive will
- /// result in a file stored in that directory path.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// The path for the File or Directory to be added or updated.
- ///
- ///
- /// Specifies a directory path to use to override any path in the
- /// itemName. This path may, or may not, correspond to a real
- /// directory in the current filesystem. If the files within the zip are
- /// later extracted, this is the path used for the extracted file. Passing
- /// null (Nothing in VB) will use the path on the
- /// itemName, if any. Passing the empty string ("") will insert the
- /// item at the root path within the archive.
- ///
- public void UpdateItem(string itemName, string directoryPathInArchive)
- {
- if (File.Exists(itemName))
- UpdateFile(itemName, directoryPathInArchive);
-
- else if (Directory.Exists(itemName))
- UpdateDirectory(itemName, directoryPathInArchive);
-
- else
- throw new FileNotFoundException(String.Format("That file or directory ({0}) does not exist!", itemName));
- }
-
-
-
-
- ///
- /// Adds a named entry into the zip archive, taking content for the entry
- /// from a string.
- ///
- ///
- ///
- /// Calling this method creates an entry using the given fileName and
- /// directory path within the archive. There is no need for a file by the
- /// given name to exist in the filesystem; the name is used within the zip
- /// archive only. The content for the entry is encoded using the default text
- /// encoding for the machine, or on Silverlight, using UTF-8.
- ///
- ///
- ///
- /// The content of the file, should it be extracted from the zip.
- ///
- ///
- ///
- /// The name, including any path, to use for the entry within the archive.
- ///
- ///
- /// The ZipEntry added.
- ///
- ///
- ///
- /// This example shows how to add an entry to the zipfile, using a string as
- /// content for that entry.
- ///
- ///
- /// string Content = "This string will be the content of the Readme.txt file in the zip archive.";
- /// using (ZipFile zip1 = new ZipFile())
- /// {
- /// zip1.AddFile("MyDocuments\\Resume.doc", "files");
- /// zip1.AddEntry("Readme.txt", Content);
- /// zip1.Comment = "This zip file was created at " + System.DateTime.Now.ToString("G");
- /// zip1.Save("Content.zip");
- /// }
- ///
- ///
- ///
- /// Public Sub Run()
- /// Dim Content As String = "This string will be the content of the Readme.txt file in the zip archive."
- /// Using zip1 As ZipFile = New ZipFile
- /// zip1.AddEntry("Readme.txt", Content)
- /// zip1.AddFile("MyDocuments\Resume.doc", "files")
- /// zip1.Comment = ("This zip file was created at " & DateTime.Now.ToString("G"))
- /// zip1.Save("Content.zip")
- /// End Using
- /// End Sub
- ///
- ///
- public ZipEntry AddEntry(string entryName, string content)
- {
-#if SILVERLIGHT
- return AddEntry(entryName, content, System.Text.Encoding.UTF8);
-#else
- return AddEntry(entryName, content, System.Text.Encoding.Default);
-#endif
- }
-
-
-
- ///
- /// Adds a named entry into the zip archive, taking content for the entry
- /// from a string, and using the specified text encoding.
- ///
- ///
- ///
- ///
- ///
- /// Calling this method creates an entry using the given fileName and
- /// directory path within the archive. There is no need for a file by the
- /// given name to exist in the filesystem; the name is used within the zip
- /// archive only.
- ///
- ///
- ///
- /// The content for the entry, a string value, is encoded using the given
- /// text encoding. A BOM (byte-order-mark) is emitted into the file, if the
- /// Encoding parameter is set for that.
- ///
- ///
- ///
- /// Most Encoding classes support a constructor that accepts a boolean,
- /// indicating whether to emit a BOM or not. For example see .
- ///
- ///
- ///
- ///
- ///
- /// The name, including any path, to use within the archive for the entry.
- ///
- ///
- ///
- /// The content of the file, should it be extracted from the zip.
- ///
- ///
- ///
- /// The text encoding to use when encoding the string. Be aware: This is
- /// distinct from the text encoding used to encode the fileName, as specified
- /// in .
- ///
- ///
- /// The ZipEntry added.
- ///
- public ZipEntry AddEntry(string entryName, string content, System.Text.Encoding encoding)
- {
- // cannot employ a using clause here. We need the stream to
- // persist after exit from this method.
- var ms = new MemoryStream();
-
- // cannot use a using clause here; StreamWriter takes
- // ownership of the stream and Disposes it before we are ready.
- var sw = new StreamWriter(ms, encoding);
- sw.Write(content);
- sw.Flush();
-
- // reset to allow reading later
- ms.Seek(0, SeekOrigin.Begin);
-
- return AddEntry(entryName, ms);
-
- // must not dispose the MemoryStream - it will be used later.
- }
-
-
- ///
- /// Create an entry in the ZipFile using the given Stream
- /// as input. The entry will have the given filename.
- ///
- ///
- ///
- ///
- ///
- /// The application should provide an open, readable stream; in this case it
- /// will be read during the call to or one of
- /// its overloads.
- ///
- ///
- ///
- /// The passed stream will be read from its current position. If
- /// necessary, callers should set the position in the stream before
- /// calling AddEntry(). This might be appropriate when using this method
- /// with a MemoryStream, for example.
- ///
- ///
- ///
- /// In cases where a large number of streams will be added to the
- /// ZipFile, the application may wish to avoid maintaining all of the
- /// streams open simultaneously. To handle this situation, the application
- /// should use the
- /// overload.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- ///
- /// This example adds a single entry to a ZipFile via a Stream.
- ///
- ///
- ///
- /// String zipToCreate = "Content.zip";
- /// String fileNameInArchive = "Content-From-Stream.bin";
- /// using (System.IO.Stream streamToRead = MyStreamOpener())
- /// {
- /// using (ZipFile zip = new ZipFile())
- /// {
- /// ZipEntry entry= zip.AddEntry(fileNameInArchive, streamToRead);
- /// zip.AddFile("Readme.txt");
- /// zip.Save(zipToCreate); // the stream is read implicitly here
- /// }
- /// }
- ///
- ///
- ///
- /// Dim zipToCreate As String = "Content.zip"
- /// Dim fileNameInArchive As String = "Content-From-Stream.bin"
- /// Using streamToRead as System.IO.Stream = MyStreamOpener()
- /// Using zip As ZipFile = New ZipFile()
- /// Dim entry as ZipEntry = zip.AddEntry(fileNameInArchive, streamToRead)
- /// zip.AddFile("Readme.txt")
- /// zip.Save(zipToCreate) '' the stream is read implicitly, here
- /// End Using
- /// End Using
- ///
- ///
- ///
- ///
- ///
- ///
- /// The name, including any path, which is shown in the zip file for the added
- /// entry.
- ///
- ///
- /// The input stream from which to grab content for the file
- ///
- /// The ZipEntry added.
- public ZipEntry AddEntry(string entryName, Stream stream)
- {
- ZipEntry ze = ZipEntry.CreateForStream(entryName, stream);
- ze.SetEntryTimes(DateTime.Now,DateTime.Now,DateTime.Now);
- if (Verbose) StatusMessageTextWriter.WriteLine("adding {0}...", entryName);
- return _InternalAddEntry(ze);
- }
-
-
-
- ///
- /// Add a ZipEntry for which content is written directly by the application.
- ///
- ///
- ///
- ///
- /// When the application needs to write the zip entry data, use this
- /// method to add the ZipEntry. For example, in the case that the
- /// application wishes to write the XML representation of a DataSet into
- /// a ZipEntry, the application can use this method to do so.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- /// About progress events: When using the WriteDelegate, DotNetZip does
- /// not issue any SaveProgress events with EventType =
- /// Saving_EntryBytesRead. (This is because it is the
- /// application's code that runs in WriteDelegate - there's no way for
- /// DotNetZip to know when to issue a EntryBytesRead event.)
- /// Applications that want to update a progress bar or similar status
- /// indicator should do so from within the WriteDelegate
- /// itself. DotNetZip will issue the other SaveProgress events,
- /// including
- /// Saving_Started,
- ///
- /// Saving_BeforeWriteEntry, and
- /// Saving_AfterWriteEntry.
- ///
- ///
- ///
- /// Note: When you use PKZip encryption, it's normally necessary to
- /// compute the CRC of the content to be encrypted, before compressing or
- /// encrypting it. Therefore, when using PKZip encryption with a
- /// WriteDelegate, the WriteDelegate CAN BE called twice: once to compute
- /// the CRC, and the second time to potentially compress and
- /// encrypt. Surprising, but true. This is because PKWARE specified that
- /// the encryption initialization data depends on the CRC.
- /// If this happens, for each call of the delegate, your
- /// application must stream the same entry data in its entirety. If your
- /// application writes different data during the second call, it will
- /// result in a corrupt zip file.
- ///
- ///
- ///
- /// The double-read behavior happens with all types of entries, not only
- /// those that use WriteDelegate. It happens if you add an entry from a
- /// filesystem file, or using a string, or a stream, or an opener/closer
- /// pair. But in those cases, DotNetZip takes care of reading twice; in
- /// the case of the WriteDelegate, the application code gets invoked
- /// twice. Be aware.
- ///
- ///
- ///
- /// As you can imagine, this can cause performance problems for large
- /// streams, and it can lead to correctness problems when you use a
- /// WriteDelegate. This is a pretty big pitfall. There are two
- /// ways to avoid it. First, and most preferred: don't use PKZIP
- /// encryption. If you use the WinZip AES encryption, this problem
- /// doesn't occur, because the encryption protocol doesn't require the CRC
- /// up front. Second: if you do choose to use PKZIP encryption, write out
- /// to a non-seekable stream (like standard output, or the
- /// Response.OutputStream in an ASP.NET application). In this case,
- /// DotNetZip will use an alternative encryption protocol that does not
- /// rely on the CRC of the content. This also implies setting bit 3 in
- /// the zip entry, which still presents problems for some zip tools.
- ///
- ///
- ///
- /// In the future I may modify DotNetZip to *always* use bit 3 when PKZIP
- /// encryption is in use. This seems like a win overall, but there will
- /// be some work involved. If you feel strongly about it, visit the
- /// DotNetZip forums and vote up the Workitem
- /// tracking this issue.
- ///
- ///
- ///
- ///
- /// the name of the entry to add
- /// the delegate which will write the entry content
- /// the ZipEntry added
- ///
- ///
- ///
- /// This example shows an application filling a DataSet, then saving the
- /// contents of that DataSet as XML, into a ZipEntry in a ZipFile, using an
- /// anonymous delegate in C#. The DataSet XML is never saved to a disk file.
- ///
- ///
- /// var c1= new System.Data.SqlClient.SqlConnection(connstring1);
- /// var da = new System.Data.SqlClient.SqlDataAdapter()
- /// {
- /// SelectCommand= new System.Data.SqlClient.SqlCommand(strSelect, c1)
- /// };
- ///
- /// DataSet ds1 = new DataSet();
- /// da.Fill(ds1, "Invoices");
- ///
- /// using(Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
- /// {
- /// zip.AddEntry(zipEntryName, (name,stream) => ds1.WriteXml(stream) );
- /// zip.Save(zipFileName);
- /// }
- ///
- ///
- ///
- ///
- ///
- /// This example uses an anonymous method in C# as the WriteDelegate to provide
- /// the data for the ZipEntry. The example is a bit contrived - the
- /// AddFile() method is a simpler way to insert the contents of a file
- /// into an entry in a zip file. On the other hand, if there is some sort of
- /// processing or transformation of the file contents required before writing,
- /// the application could use the WriteDelegate to do it, in this way.
- ///
- ///
- /// using (var input = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ))
- /// {
- /// using(Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
- /// {
- /// zip.AddEntry(zipEntryName, (name,output) =>
- /// {
- /// byte[] buffer = new byte[BufferSize];
- /// int n;
- /// while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
- /// {
- /// // could transform the data here...
- /// output.Write(buffer, 0, n);
- /// // could update a progress bar here
- /// }
- /// });
- ///
- /// zip.Save(zipFileName);
- /// }
- /// }
- ///
- ///
- ///
- ///
- ///
- /// This example uses a named delegate in VB to write data for the given
- /// ZipEntry (VB9 does not have anonymous delegates). The example here is a bit
- /// contrived - a simpler way to add the contents of a file to a ZipEntry is to
- /// simply use the appropriate AddFile() method. The key scenario for
- /// which the WriteDelegate makes sense is saving a DataSet, in XML
- /// format, to the zip file. The DataSet can write XML to a stream, and the
- /// WriteDelegate is the perfect place to write into the zip file. There may be
- /// other data structures that can write to a stream, but cannot be read as a
- /// stream. The WriteDelegate would be appropriate for those cases as
- /// well.
- ///
- ///
- /// Private Sub WriteEntry (ByVal name As String, ByVal output As Stream)
- /// Using input As FileStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
- /// Dim n As Integer = -1
- /// Dim buffer As Byte() = New Byte(BufferSize){}
- /// Do While n <> 0
- /// n = input.Read(buffer, 0, buffer.Length)
- /// output.Write(buffer, 0, n)
- /// Loop
- /// End Using
- /// End Sub
- ///
- /// Public Sub Run()
- /// Using zip = New ZipFile
- /// zip.AddEntry(zipEntryName, New WriteDelegate(AddressOf WriteEntry))
- /// zip.Save(zipFileName)
- /// End Using
- /// End Sub
- ///
- ///
- public ZipEntry AddEntry(string entryName, WriteDelegate writer)
- {
- ZipEntry ze = ZipEntry.CreateForWriter(entryName, writer);
- if (Verbose) StatusMessageTextWriter.WriteLine("adding {0}...", entryName);
- return _InternalAddEntry(ze);
- }
-
-
- ///
- /// Add an entry, for which the application will provide a stream
- /// containing the entry data, on a just-in-time basis.
- ///
- ///
- ///
- ///
- /// In cases where the application wishes to open the stream that
- /// holds the content for the ZipEntry, on a just-in-time basis, the
- /// application can use this method. The application provides an
- /// opener delegate that will be called by the DotNetZip library to
- /// obtain a readable stream that can be read to get the bytes for
- /// the given entry. Typically, this delegate opens a stream.
- /// Optionally, the application can provide a closer delegate as
- /// well, which will be called by DotNetZip when all bytes have been
- /// read from the entry.
- ///
- ///
- ///
- /// These delegates are called from within the scope of the call to
- /// ZipFile.Save().
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- ///
- /// This example uses anonymous methods in C# to open and close the
- /// source stream for the content for a zip entry.
- ///
- ///
- /// using(Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile())
- /// {
- /// zip.AddEntry(zipEntryName,
- /// (name) => File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ),
- /// (name, stream) => stream.Close()
- /// );
- ///
- /// zip.Save(zipFileName);
- /// }
- ///
- ///
- ///
- ///
- ///
- ///
- /// This example uses delegates in VB.NET to open and close the
- /// the source stream for the content for a zip entry. VB 9.0 lacks
- /// support for "Sub" lambda expressions, and so the CloseDelegate must
- /// be an actual, named Sub.
- ///
- ///
- ///
- /// Function MyStreamOpener(ByVal entryName As String) As Stream
- /// '' This simply opens a file. You probably want to do somethinig
- /// '' more involved here: open a stream to read from a database,
- /// '' open a stream on an HTTP connection, and so on.
- /// Return File.OpenRead(entryName)
- /// End Function
- ///
- /// Sub MyStreamCloser(entryName As String, stream As Stream)
- /// stream.Close()
- /// End Sub
- ///
- /// Public Sub Run()
- /// Dim dirToZip As String = "fodder"
- /// Dim zipFileToCreate As String = "Archive.zip"
- /// Dim opener As OpenDelegate = AddressOf MyStreamOpener
- /// Dim closer As CloseDelegate = AddressOf MyStreamCloser
- /// Dim numFilestoAdd As Int32 = 4
- /// Using zip As ZipFile = New ZipFile
- /// Dim i As Integer
- /// For i = 0 To numFilesToAdd - 1
- /// zip.AddEntry(String.Format("content-{0:000}.txt"), opener, closer)
- /// Next i
- /// zip.Save(zipFileToCreate)
- /// End Using
- /// End Sub
- ///
- ///
- ///
- ///
- /// the name of the entry to add
- ///
- /// the delegate that will be invoked by ZipFile.Save() to get the
- /// readable stream for the given entry. ZipFile.Save() will call
- /// read on this stream to obtain the data for the entry. This data
- /// will then be compressed and written to the newly created zip
- /// file.
- ///
- ///
- /// the delegate that will be invoked to close the stream. This may
- /// be null (Nothing in VB), in which case no call is makde to close
- /// the stream.
- ///
- /// the ZipEntry added
- ///
- public ZipEntry AddEntry(string entryName, OpenDelegate opener, CloseDelegate closer)
- {
- ZipEntry ze = ZipEntry.CreateForJitStreamProvider(entryName, opener, closer);
- ze.SetEntryTimes(DateTime.Now,DateTime.Now,DateTime.Now);
- if (Verbose) StatusMessageTextWriter.WriteLine("adding {0}...", entryName);
- return _InternalAddEntry(ze);
- }
-
-
-
- private ZipEntry _InternalAddEntry(ZipEntry ze)
- {
- // stamp all the props onto the entry
- ze._container = new ZipContainer(this);
- ze.CompressionMethod = this.CompressionMethod;
- ze.CompressionLevel = this.CompressionLevel;
- ze.ExtractExistingFile = this.ExtractExistingFile;
- ze.ZipErrorAction = this.ZipErrorAction;
- ze.SetCompression = this.SetCompression;
- ze.AlternateEncoding = this.AlternateEncoding;
- ze.AlternateEncodingUsage = this.AlternateEncodingUsage;
- ze.Password = this._Password;
- ze.Encryption = this.Encryption;
- ze.EmitTimesInWindowsFormatWhenSaving = this._emitNtfsTimes;
- ze.EmitTimesInUnixFormatWhenSaving = this._emitUnixTimes;
- //string key = DictionaryKeyForEntry(ze);
- InternalAddEntry(ze.FileName,ze);
- AfterAddEntry(ze);
- return ze;
- }
-
-
-
-
- ///
- /// Updates the given entry in the ZipFile, using the given
- /// string as content for the ZipEntry.
- ///
- ///
- ///
- ///
- ///
- /// Calling this method is equivalent to removing the ZipEntry for
- /// the given file name and directory path, if it exists, and then calling
- /// . See the documentation for
- /// that method for further explanation. The string content is encoded
- /// using the default encoding for the machine, or on Silverlight, using
- /// UTF-8. This encoding is distinct from the encoding used for the
- /// filename itself. See .
- ///
- ///
- ///
- ///
- ///
- /// The name, including any path, to use within the archive for the entry.
- ///
- ///
- ///
- /// The content of the file, should it be extracted from the zip.
- ///
- ///
- /// The ZipEntry added.
- ///
- public ZipEntry UpdateEntry(string entryName, string content)
- {
-#if SILVERLIGHT
- return UpdateEntry(entryName, content, System.Text.Encoding.UTF8);
-#else
- return UpdateEntry(entryName, content, System.Text.Encoding.Default);
-#endif
- }
-
-
- ///
- /// Updates the given entry in the ZipFile, using the given string as
- /// content for the ZipEntry.
- ///
- ///
- ///
- /// Calling this method is equivalent to removing the ZipEntry for the
- /// given file name and directory path, if it exists, and then calling . See the
- /// documentation for that method for further explanation.
- ///
- ///
- ///
- /// The name, including any path, to use within the archive for the entry.
- ///
- ///
- ///
- /// The content of the file, should it be extracted from the zip.
- ///
- ///
- ///
- /// The text encoding to use when encoding the string. Be aware: This is
- /// distinct from the text encoding used to encode the filename. See .
- ///
- ///
- /// The ZipEntry added.
- ///
- public ZipEntry UpdateEntry(string entryName, string content, System.Text.Encoding encoding)
- {
- RemoveEntryForUpdate(entryName);
- return AddEntry(entryName, content, encoding);
- }
-
-
-
- ///
- /// Updates the given entry in the ZipFile, using the given delegate
- /// as the source for content for the ZipEntry.
- ///
- ///
- ///
- /// Calling this method is equivalent to removing the ZipEntry for the
- /// given file name and directory path, if it exists, and then calling . See the
- /// documentation for that method for further explanation.
- ///
- ///
- ///
- /// The name, including any path, to use within the archive for the entry.
- ///
- ///
- /// the delegate which will write the entry content.
- ///
- /// The ZipEntry added.
- ///
- public ZipEntry UpdateEntry(string entryName, WriteDelegate writer)
- {
- RemoveEntryForUpdate(entryName);
- return AddEntry(entryName, writer);
- }
-
-
-
- ///
- /// Updates the given entry in the ZipFile, using the given delegates
- /// to open and close the stream that provides the content for the ZipEntry.
- ///
- ///
- ///
- /// Calling this method is equivalent to removing the ZipEntry for the
- /// given file name and directory path, if it exists, and then calling . See the
- /// documentation for that method for further explanation.
- ///
- ///
- ///
- /// The name, including any path, to use within the archive for the entry.
- ///
- ///
- ///
- /// the delegate that will be invoked to open the stream
- ///
- ///
- /// the delegate that will be invoked to close the stream
- ///
- ///
- /// The ZipEntry added or updated.
- ///
- public ZipEntry UpdateEntry(string entryName, OpenDelegate opener, CloseDelegate closer)
- {
- RemoveEntryForUpdate(entryName);
- return AddEntry(entryName, opener, closer);
- }
-
-
- ///
- /// Updates the given entry in the ZipFile, using the given stream as
- /// input, and the given filename and given directory Path.
- ///
- ///
- ///
- ///
- /// Calling the method is equivalent to calling RemoveEntry() if an
- /// entry by the same name already exists, and then calling AddEntry()
- /// with the given fileName and stream.
- ///
- ///
- ///
- /// The stream must be open and readable during the call to
- /// ZipFile.Save. You can dispense the stream on a just-in-time basis
- /// using the property. Check the
- /// documentation of that property for more information.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to the
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// The name, including any path, to use within the archive for the entry.
- ///
- ///
- /// The input stream from which to read file data.
- /// The ZipEntry added.
- public ZipEntry UpdateEntry(string entryName, Stream stream)
- {
- RemoveEntryForUpdate(entryName);
- return AddEntry(entryName, stream);
- }
-
-
- private void RemoveEntryForUpdate(string entryName)
- {
- if (String.IsNullOrEmpty(entryName))
- throw new ArgumentNullException("entryName");
-
- string directoryPathInArchive = null;
- if (entryName.IndexOf('\\') != -1)
- {
- directoryPathInArchive = Path.GetDirectoryName(entryName);
- entryName = Path.GetFileName(entryName);
- }
- var key = ZipEntry.NameInArchive(entryName, directoryPathInArchive);
- if (this[key] != null)
- this.RemoveEntry(key);
- }
-
-
-
-
- ///
- /// Add an entry into the zip archive using the given filename and
- /// directory path within the archive, and the given content for the
- /// file. No file is created in the filesystem.
- ///
- ///
- /// The data to use for the entry.
- ///
- ///
- /// The name, including any path, to use within the archive for the entry.
- ///
- ///
- /// The ZipEntry added.
- public ZipEntry AddEntry(string entryName, byte[] byteContent)
- {
- if (byteContent == null) throw new ArgumentException("bad argument", "byteContent");
- var ms = new MemoryStream(byteContent);
- return AddEntry(entryName, ms);
- }
-
-
- ///
- /// Updates the given entry in the ZipFile, using the given byte
- /// array as content for the entry.
- ///
- ///
- ///
- /// Calling this method is equivalent to removing the ZipEntry
- /// for the given filename and directory path, if it exists, and then
- /// calling . See the
- /// documentation for that method for further explanation.
- ///
- ///
- ///
- /// The name, including any path, to use within the archive for the entry.
- ///
- ///
- /// The content to use for the ZipEntry.
- ///
- /// The ZipEntry added.
- ///
- public ZipEntry UpdateEntry(string entryName, byte[] byteContent)
- {
- RemoveEntryForUpdate(entryName);
- return AddEntry(entryName, byteContent);
- }
-
-
-// private string DictionaryKeyForEntry(ZipEntry ze1)
-// {
-// var filename = SharedUtilities.NormalizePathForUseInZipFile(ze1.FileName);
-// return filename;
-// }
-
-
- ///
- /// Adds the contents of a filesystem directory to a Zip file archive.
- ///
- ///
- ///
- ///
- ///
- /// The name of the directory may be a relative path or a fully-qualified
- /// path. Any files within the named directory are added to the archive. Any
- /// subdirectories within the named directory are also added to the archive,
- /// recursively.
- ///
- ///
- ///
- /// Top-level entries in the named directory will appear as top-level entries
- /// in the zip archive. Entries in subdirectories in the named directory will
- /// result in entries in subdirectories in the zip archive.
- ///
- ///
- ///
- /// If you want the entries to appear in a containing directory in the zip
- /// archive itself, then you should call the AddDirectory() overload that
- /// allows you to explicitly specify a directory path for use in the archive.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to each
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// This method has 2 overloads.
- ///
- /// The name of the directory to add.
- /// The ZipEntry added.
- public ZipEntry AddDirectory(string directoryName)
- {
- return AddDirectory(directoryName, null);
- }
-
-
- ///
- /// Adds the contents of a filesystem directory to a Zip file archive,
- /// overriding the path to be used for entries in the archive.
- ///
- ///
- ///
- ///
- /// The name of the directory may be a relative path or a fully-qualified
- /// path. The add operation is recursive, so that any files or subdirectories
- /// within the name directory are also added to the archive.
- ///
- ///
- ///
- /// Top-level entries in the named directory will appear as top-level entries
- /// in the zip archive. Entries in subdirectories in the named directory will
- /// result in entries in subdirectories in the zip archive.
- ///
- ///
- ///
- /// For ZipFile properties including , , , , ,
- /// , and , their
- /// respective values at the time of this call will be applied to each
- /// ZipEntry added.
- ///
- ///
- ///
- ///
- ///
- ///
- /// In this code, calling the ZipUp() method with a value of "c:\reports" for
- /// the directory parameter will result in a zip file structure in which all
- /// entries are contained in a toplevel "reports" directory.
- ///
- ///
- ///
- /// public void ZipUp(string targetZip, string directory)
- /// {
- /// using (var zip = new ZipFile())
- /// {
- /// zip.AddDirectory(directory, System.IO.Path.GetFileName(directory));
- /// zip.Save(targetZip);
- /// }
- /// }
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// The name of the directory to add.
- ///
- ///
- /// Specifies a directory path to use to override any path in the
- /// DirectoryName. This path may, or may not, correspond to a real directory
- /// in the current filesystem. If the zip is later extracted, this is the
- /// path used for the extracted file or directory. Passing null
- /// (Nothing in VB) or the empty string ("") will insert the items at
- /// the root path within the archive.
- ///
- ///
- /// The ZipEntry added.
- public ZipEntry AddDirectory(string directoryName, string directoryPathInArchive)
- {
- return AddOrUpdateDirectoryImpl(directoryName, directoryPathInArchive, AddOrUpdateAction.AddOnly);
- }
-
-
- ///
- /// Creates a directory in the zip archive.
- ///
- ///
- ///
- ///
- ///
- /// Use this when you want to create a directory in the archive but there is
- /// no corresponding filesystem representation for that directory.
- ///
- ///
- ///
- /// You will probably not need to do this in your code. One of the only times
- /// you will want to do this is if you want an empty directory in the zip
- /// archive. The reason: if you add a file to a zip archive that is stored
- /// within a multi-level directory, all of the directory tree is implicitly
- /// created in the zip archive.
- ///
- ///
- ///
- ///
- ///
- /// The name of the directory to create in the archive.
- ///
- /// The ZipEntry added.
- public ZipEntry AddDirectoryByName(string directoryNameInArchive)
- {
- // workitem 9073
- ZipEntry dir = ZipEntry.CreateFromNothing(directoryNameInArchive);
- dir._container = new ZipContainer(this);
- dir.MarkAsDirectory();
- dir.AlternateEncoding = this.AlternateEncoding; // workitem 8984
- dir.AlternateEncodingUsage = this.AlternateEncodingUsage;
- dir.SetEntryTimes(DateTime.Now,DateTime.Now,DateTime.Now);
- dir.EmitTimesInWindowsFormatWhenSaving = _emitNtfsTimes;
- dir.EmitTimesInUnixFormatWhenSaving = _emitUnixTimes;
- dir._Source = ZipEntrySource.Stream;
- //string key = DictionaryKeyForEntry(dir);
- InternalAddEntry(dir.FileName,dir);
- AfterAddEntry(dir);
- return dir;
- }
-
-
-
- private ZipEntry AddOrUpdateDirectoryImpl(string directoryName,
- string rootDirectoryPathInArchive,
- AddOrUpdateAction action)
- {
- if (rootDirectoryPathInArchive == null)
- {
- rootDirectoryPathInArchive = "";
- }
-
- return AddOrUpdateDirectoryImpl(directoryName, rootDirectoryPathInArchive, action, true, 0);
- }
-
-
- internal void InternalAddEntry(String name, ZipEntry entry)
- {
- _entries.Add(name, entry);
- _zipEntriesAsList = null;
- _contentsChanged = true;
- }
-
-
-
- private ZipEntry AddOrUpdateDirectoryImpl(string directoryName,
- string rootDirectoryPathInArchive,
- AddOrUpdateAction action,
- bool recurse,
- int level)
- {
- if (Verbose)
- StatusMessageTextWriter.WriteLine("{0} {1}...",
- (action == AddOrUpdateAction.AddOnly) ? "adding" : "Adding or updating",
- directoryName);
-
- if (level == 0)
- {
- _addOperationCanceled = false;
- OnAddStarted();
- }
-
- // workitem 13371
- if (_addOperationCanceled)
- return null;
-
- string dirForEntries = rootDirectoryPathInArchive;
- ZipEntry baseDir = null;
-
- if (level > 0)
- {
- int f = directoryName.Length;
- for (int i = level; i > 0; i--)
- f = directoryName.LastIndexOfAny("/\\".ToCharArray(), f - 1, f - 1);
-
- dirForEntries = directoryName.Substring(f + 1);
- dirForEntries = Path.Combine(rootDirectoryPathInArchive, dirForEntries);
- }
-
- // if not top level, or if the root is non-empty, then explicitly add the directory
- if (level > 0 || rootDirectoryPathInArchive != "")
- {
- baseDir = ZipEntry.CreateFromFile(directoryName, dirForEntries);
- baseDir._container = new ZipContainer(this);
- baseDir.AlternateEncoding = this.AlternateEncoding; // workitem 6410
- baseDir.AlternateEncodingUsage = this.AlternateEncodingUsage;
- baseDir.MarkAsDirectory();
- baseDir.EmitTimesInWindowsFormatWhenSaving = _emitNtfsTimes;
- baseDir.EmitTimesInUnixFormatWhenSaving = _emitUnixTimes;
-
- // add the directory only if it does not exist.
- // It's not an error if it already exists.
- if (!_entries.ContainsKey(baseDir.FileName))
- {
- InternalAddEntry(baseDir.FileName,baseDir);
- AfterAddEntry(baseDir);
- }
- dirForEntries = baseDir.FileName;
- }
-
- if (!_addOperationCanceled)
- {
-
- String[] filenames = Directory.GetFiles(directoryName);
-
- if (recurse)
- {
- // add the files:
- foreach (String filename in filenames)
- {
- if (_addOperationCanceled) break;
- if (action == AddOrUpdateAction.AddOnly)
- AddFile(filename, dirForEntries);
- else
- UpdateFile(filename, dirForEntries);
- }
-
- if (!_addOperationCanceled)
- {
- // add the subdirectories:
- String[] dirnames = Directory.GetDirectories(directoryName);
- foreach (String dir in dirnames)
- {
- // workitem 8617: Optionally traverse reparse points
-#if SILVERLIGHT
-#elif NETCF
- FileAttributes fileAttrs = (FileAttributes) NetCfFile.GetAttributes(dir);
-#else
- FileAttributes fileAttrs = System.IO.File.GetAttributes(dir);
-#endif
- if (this.AddDirectoryWillTraverseReparsePoints
-#if !SILVERLIGHT
- || ((fileAttrs & FileAttributes.ReparsePoint) == 0)
-#endif
- )
- AddOrUpdateDirectoryImpl(dir, rootDirectoryPathInArchive, action, recurse, level + 1);
-
- }
-
- }
- }
- }
-
- if (level == 0)
- OnAddCompleted();
-
- return baseDir;
- }
-
- }
-
-}
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipFile.Check.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipFile.Check.cs
deleted file mode 100644
index b8307d50..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipFile.Check.cs
+++ /dev/null
@@ -1,352 +0,0 @@
-// ZipFile.Check.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2009-2011 Dino Chiesa.
-// 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: <2011-July-31 14:40:50>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the methods for doing Checks on zip files.
-// These are not necessary to include in the Reduced or CF
-// version of the library.
-//
-// ------------------------------------------------------------------
-//
-
-
-using System;
-using System.IO;
-using System.Collections.Generic;
-
-namespace Ionic.Zip
-{
- public partial class ZipFile
- {
- ///
- /// Checks a zip file to see if its directory is consistent.
- ///
- ///
- ///
- ///
- ///
- /// In cases of data error, the directory within a zip file can get out
- /// of synch with the entries in the zip file. This method checks the
- /// given zip file and returns true if this has occurred.
- ///
- ///
- /// This method may take a long time to run for large zip files.
- ///
- ///
- /// This method is not supported in the Reduced or Compact Framework
- /// versions of DotNetZip.
- ///
- ///
- ///
- /// Developers using COM can use the ComHelper.CheckZip(String)
- /// method.
- ///
- ///
- ///
- ///
- /// The filename to of the zip file to check.
- ///
- /// true if the named zip file checks OK. Otherwise, false.
- ///
- ///
- ///
- public static bool CheckZip(string zipFileName)
- {
- return CheckZip(zipFileName, false, null);
- }
-
-
- ///
- /// Checks a zip file to see if its directory is consistent,
- /// and optionally fixes the directory if necessary.
- ///
- ///
- ///
- ///
- ///
- /// In cases of data error, the directory within a zip file can get out of
- /// synch with the entries in the zip file. This method checks the given
- /// zip file, and returns true if this has occurred. It also optionally
- /// fixes the zipfile, saving the fixed copy in Name_Fixed.zip.
- ///
- ///
- ///
- /// This method may take a long time to run for large zip files. It
- /// will take even longer if the file actually needs to be fixed, and if
- /// fixIfNecessary is true.
- ///
- ///
- ///
- /// This method is not supported in the Reduced or Compact
- /// Framework versions of DotNetZip.
- ///
- ///
- ///
- ///
- /// The filename to of the zip file to check.
- ///
- /// If true, the method will fix the zip file if
- /// necessary.
- ///
- ///
- /// a TextWriter in which messages generated while checking will be written.
- ///
- ///
- /// true if the named zip is OK; false if the file needs to be fixed.
- ///
- ///
- ///
- public static bool CheckZip(string zipFileName, bool fixIfNecessary,
- TextWriter writer)
-
- {
- ZipFile zip1 = null, zip2 = null;
- bool isOk = true;
- try
- {
- zip1 = new ZipFile();
- zip1.FullScan = true;
- zip1.Initialize(zipFileName);
-
- zip2 = ZipFile.Read(zipFileName);
-
- foreach (var e1 in zip1)
- {
- foreach (var e2 in zip2)
- {
- if (e1.FileName == e2.FileName)
- {
- if (e1._RelativeOffsetOfLocalHeader != e2._RelativeOffsetOfLocalHeader)
- {
- isOk = false;
- if (writer != null)
- writer.WriteLine("{0}: mismatch in RelativeOffsetOfLocalHeader (0x{1:X16} != 0x{2:X16})",
- e1.FileName, e1._RelativeOffsetOfLocalHeader,
- e2._RelativeOffsetOfLocalHeader);
- }
- if (e1._CompressedSize != e2._CompressedSize)
- {
- isOk = false;
- if (writer != null)
- writer.WriteLine("{0}: mismatch in CompressedSize (0x{1:X16} != 0x{2:X16})",
- e1.FileName, e1._CompressedSize,
- e2._CompressedSize);
- }
- if (e1._UncompressedSize != e2._UncompressedSize)
- {
- isOk = false;
- if (writer != null)
- writer.WriteLine("{0}: mismatch in UncompressedSize (0x{1:X16} != 0x{2:X16})",
- e1.FileName, e1._UncompressedSize,
- e2._UncompressedSize);
- }
- if (e1.CompressionMethod != e2.CompressionMethod)
- {
- isOk = false;
- if (writer != null)
- writer.WriteLine("{0}: mismatch in CompressionMethod (0x{1:X4} != 0x{2:X4})",
- e1.FileName, e1.CompressionMethod,
- e2.CompressionMethod);
- }
- if (e1.Crc != e2.Crc)
- {
- isOk = false;
- if (writer != null)
- writer.WriteLine("{0}: mismatch in Crc32 (0x{1:X4} != 0x{2:X4})",
- e1.FileName, e1.Crc,
- e2.Crc);
- }
-
- // found a match, so stop the inside loop
- break;
- }
- }
- }
-
- zip2.Dispose();
- zip2 = null;
-
- if (!isOk && fixIfNecessary)
- {
- string newFileName = Path.GetFileNameWithoutExtension(zipFileName);
- newFileName = System.String.Format("{0}_fixed.zip", newFileName);
- zip1.Save(newFileName);
- }
- }
- finally
- {
- if (zip1 != null) zip1.Dispose();
- if (zip2 != null) zip2.Dispose();
- }
- return isOk;
- }
-
-
-
- ///
- /// Rewrite the directory within a zipfile.
- ///
- ///
- ///
- ///
- ///
- /// In cases of data error, the directory in a zip file can get out of
- /// synch with the entries in the zip file. This method attempts to fix
- /// the zip file if this has occurred.
- ///
- ///
- /// This can take a long time for large zip files.
- ///
- /// This won't work if the zip file uses a non-standard
- /// code page - neither IBM437 nor UTF-8.
- ///
- ///
- /// This method is not supported in the Reduced or Compact Framework
- /// versions of DotNetZip.
- ///
- ///
- ///
- /// Developers using COM can use the ComHelper.FixZipDirectory(String)
- /// method.
- ///
- ///
- ///
- ///
- /// The filename to of the zip file to fix.
- ///
- ///
- ///
- public static void FixZipDirectory(string zipFileName)
- {
- using (var zip = new ZipFile())
- {
- zip.FullScan = true;
- zip.Initialize(zipFileName);
- zip.Save(zipFileName);
- }
- }
-
-
-
- ///
- /// Verify the password on a zip file.
- ///
- ///
- ///
- ///
- /// Keep in mind that passwords in zipfiles are applied to
- /// zip entries, not to the entire zip file. So testing a
- /// zipfile for a particular password doesn't work in the
- /// general case. On the other hand, it's often the case
- /// that a single password will be used on all entries in a
- /// zip file. This method works for that case.
- ///
- ///
- /// There is no way to check a password without doing the
- /// decryption. So this code decrypts and extracts the given
- /// zipfile into
- ///
- ///
- ///
- /// The filename to of the zip file to fix.
- ///
- /// The password to check.
- ///
- /// a bool indicating whether the password matches.
- public static bool CheckZipPassword(string zipFileName, string password)
- {
- // workitem 13664
- bool success = false;
- try
- {
- using (ZipFile zip1 = ZipFile.Read(zipFileName))
- {
- foreach (var e in zip1)
- {
- if (!e.IsDirectory && e.UsesEncryption)
- {
- e.ExtractWithPassword(System.IO.Stream.Null, password);
- }
- }
- }
- success = true;
- }
- catch(Ionic.Zip.BadPasswordException) { }
- return success;
- }
-
-
- ///
- /// Provides a human-readable string with information about the ZipFile.
- ///
- ///
- ///
- ///
- /// The information string contains 10 lines or so, about each ZipEntry,
- /// describing whether encryption is in use, the compressed and uncompressed
- /// length of the entry, the offset of the entry, and so on. As a result the
- /// information string can be very long for zip files that contain many
- /// entries.
- ///
- ///
- /// This information is mostly useful for diagnostic purposes.
- ///
- ///
- public string Info
- {
- get
- {
- var builder = new System.Text.StringBuilder();
- builder.Append(string.Format(" ZipFile: {0}\n", this.Name));
- if (!string.IsNullOrEmpty(this._Comment))
- {
- builder.Append(string.Format(" Comment: {0}\n", this._Comment));
- }
- if (this._versionMadeBy != 0)
- {
- builder.Append(string.Format(" version made by: 0x{0:X4}\n", this._versionMadeBy));
- }
- if (this._versionNeededToExtract != 0)
- {
- builder.Append(string.Format("needed to extract: 0x{0:X4}\n", this._versionNeededToExtract));
- }
-
- builder.Append(string.Format(" uses ZIP64: {0}\n", this.InputUsesZip64));
-
- builder.Append(string.Format(" disk with CD: {0}\n", this._diskNumberWithCd));
- if (this._OffsetOfCentralDirectory == 0xFFFFFFFF)
- builder.Append(string.Format(" CD64 offset: 0x{0:X16}\n", this._OffsetOfCentralDirectory64));
- else
- builder.Append(string.Format(" CD offset: 0x{0:X8}\n", this._OffsetOfCentralDirectory));
- builder.Append("\n");
- foreach (ZipEntry entry in this._entries.Values)
- {
- builder.Append(entry.Info);
- }
- return builder.ToString();
- }
- }
-
-
- }
-
-}
\ No newline at end of file
diff --git a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipFile.Events.cs b/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipFile.Events.cs
deleted file mode 100644
index 110ee6d1..00000000
--- a/MinecraftClient/Protocol/Handlers/Compression/Zip/ZipFile.Events.cs
+++ /dev/null
@@ -1,1219 +0,0 @@
-// ZipFile.Events.cs
-// ------------------------------------------------------------------
-//
-// Copyright (c) 2008, 2009, 2011 Dino Chiesa .
-// 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: <2011-July-09 08:42:35>
-//
-// ------------------------------------------------------------------
-//
-// This module defines the methods for issuing events from the ZipFile class.
-//
-// ------------------------------------------------------------------
-//
-
-using System;
-using System.IO;
-
-namespace Ionic.Zip
-{
- public partial class ZipFile
- {
- private string ArchiveNameForEvent
- {
- get
- {
- return (_name != null) ? _name : "(stream)";
- }
- }
-
- #region Save
-
- ///
- /// An event handler invoked when a Save() starts, before and after each
- /// entry has been written to the archive, when a Save() completes, and
- /// during other Save events.
- ///
- ///
- ///
- ///
- /// Depending on the particular event, different properties on the parameter are set. The following
- /// table summarizes the available EventTypes and the conditions under
- /// which this event handler is invoked with a
- /// SaveProgressEventArgs with the given EventType.
- ///
- ///
- ///
- ///
- /// value of EntryType
- /// Meaning and conditions
- ///
- ///
- /// -
- /// ZipProgressEventType.Saving_Started
- /// Fired when ZipFile.Save() begins.
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Saving_BeforeSaveEntry
- ///
- /// Fired within ZipFile.Save(), just before writing data for each
- /// particular entry.
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Saving_AfterSaveEntry
- ///
- /// Fired within ZipFile.Save(), just after having finished writing data
- /// for each particular entry.
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Saving_Completed
- /// Fired when ZipFile.Save() has completed.
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Saving_AfterSaveTempArchive
- ///
- /// Fired after the temporary file has been created. This happens only
- /// when saving to a disk file. This event will not be invoked when
- /// saving to a stream.
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Saving_BeforeRenameTempArchive
- ///
- /// Fired just before renaming the temporary file to the permanent
- /// location. This happens only when saving to a disk file. This event
- /// will not be invoked when saving to a stream.
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Saving_AfterRenameTempArchive
- ///
- /// Fired just after renaming the temporary file to the permanent
- /// location. This happens only when saving to a disk file. This event
- /// will not be invoked when saving to a stream.
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Saving_AfterCompileSelfExtractor
- ///
- /// Fired after a self-extracting archive has finished compiling. This
- /// EventType is used only within SaveSelfExtractor().
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Saving_BytesRead
- ///
- /// Set during the save of a particular entry, to update progress of the
- /// Save(). When this EventType is set, the BytesTransferred is the
- /// number of bytes that have been read from the source stream. The
- /// TotalBytesToTransfer is the number of bytes in the uncompressed
- /// file.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- /// This example uses an anonymous method to handle the
- /// SaveProgress event, by updating a progress bar.
- ///
- ///
- /// progressBar1.Value = 0;
- /// progressBar1.Max = listbox1.Items.Count;
- /// using (ZipFile zip = new ZipFile())
- /// {
- /// // listbox1 contains a list of filenames
- /// zip.AddFiles(listbox1.Items);
- ///
- /// // do the progress bar:
- /// zip.SaveProgress += (sender, e) => {
- /// if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry) {
- /// progressBar1.PerformStep();
- /// }
- /// };
- ///
- /// zip.Save(fs);
- /// }
- ///
- ///
- ///
- ///
- /// This example uses a named method as the
- /// SaveProgress event handler, to update the user, in a
- /// console-based application.
- ///
- ///
- /// static bool justHadByteUpdate= false;
- /// public static void SaveProgress(object sender, SaveProgressEventArgs e)
- /// {
- /// if (e.EventType == ZipProgressEventType.Saving_Started)
- /// Console.WriteLine("Saving: {0}", e.ArchiveName);
- ///
- /// else if (e.EventType == ZipProgressEventType.Saving_Completed)
- /// {
- /// justHadByteUpdate= false;
- /// Console.WriteLine();
- /// Console.WriteLine("Done: {0}", e.ArchiveName);
- /// }
- ///
- /// else if (e.EventType == ZipProgressEventType.Saving_BeforeWriteEntry)
- /// {
- /// if (justHadByteUpdate)
- /// Console.WriteLine();
- /// Console.WriteLine(" Writing: {0} ({1}/{2})",
- /// e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal);
- /// justHadByteUpdate= false;
- /// }
- ///
- /// else if (e.EventType == ZipProgressEventType.Saving_EntryBytesRead)
- /// {
- /// if (justHadByteUpdate)
- /// Console.SetCursorPosition(0, Console.CursorTop);
- /// Console.Write(" {0}/{1} ({2:N0}%)", e.BytesTransferred, e.TotalBytesToTransfer,
- /// e.BytesTransferred / (0.01 * e.TotalBytesToTransfer ));
- /// justHadByteUpdate= true;
- /// }
- /// }
- ///
- /// public static ZipUp(string targetZip, string directory)
- /// {
- /// using (var zip = new ZipFile()) {
- /// zip.SaveProgress += SaveProgress;
- /// zip.AddDirectory(directory);
- /// zip.Save(targetZip);
- /// }
- /// }
- ///
- ///
- ///
- ///
- /// Public Sub ZipUp(ByVal targetZip As String, ByVal directory As String)
- /// Using zip As ZipFile = New ZipFile
- /// AddHandler zip.SaveProgress, AddressOf MySaveProgress
- /// zip.AddDirectory(directory)
- /// zip.Save(targetZip)
- /// End Using
- /// End Sub
- ///
- /// Private Shared justHadByteUpdate As Boolean = False
- ///
- /// Public Shared Sub MySaveProgress(ByVal sender As Object, ByVal e As SaveProgressEventArgs)
- /// If (e.EventType Is ZipProgressEventType.Saving_Started) Then
- /// Console.WriteLine("Saving: {0}", e.ArchiveName)
- ///
- /// ElseIf (e.EventType Is ZipProgressEventType.Saving_Completed) Then
- /// justHadByteUpdate = False
- /// Console.WriteLine
- /// Console.WriteLine("Done: {0}", e.ArchiveName)
- ///
- /// ElseIf (e.EventType Is ZipProgressEventType.Saving_BeforeWriteEntry) Then
- /// If justHadByteUpdate Then
- /// Console.WriteLine
- /// End If
- /// Console.WriteLine(" Writing: {0} ({1}/{2})", e.CurrentEntry.FileName, e.EntriesSaved, e.EntriesTotal)
- /// justHadByteUpdate = False
- ///
- /// ElseIf (e.EventType Is ZipProgressEventType.Saving_EntryBytesRead) Then
- /// If justHadByteUpdate Then
- /// Console.SetCursorPosition(0, Console.CursorTop)
- /// End If
- /// Console.Write(" {0}/{1} ({2:N0}%)", e.BytesTransferred, _
- /// e.TotalBytesToTransfer, _
- /// (CDbl(e.BytesTransferred) / (0.01 * e.TotalBytesToTransfer)))
- /// justHadByteUpdate = True
- /// End If
- /// End Sub
- ///
- ///
- ///
- ///
- ///
- /// This is a more complete example of using the SaveProgress
- /// events in a Windows Forms application, with a
- /// Thread object.
- ///
- ///
- /// delegate void SaveEntryProgress(SaveProgressEventArgs e);
- /// delegate void ButtonClick(object sender, EventArgs e);
- ///
- /// public class WorkerOptions
- /// {
- /// public string ZipName;
- /// public string Folder;
- /// public string Encoding;
- /// public string Comment;
- /// public int ZipFlavor;
- /// public Zip64Option Zip64;
- /// }
- ///
- /// private int _progress2MaxFactor;
- /// private bool _saveCanceled;
- /// private long _totalBytesBeforeCompress;
- /// private long _totalBytesAfterCompress;
- /// private Thread _workerThread;
- ///
- ///
- /// private void btnZipup_Click(object sender, EventArgs e)
- /// {
- /// KickoffZipup();
- /// }
- ///
- /// private void btnCancel_Click(object sender, EventArgs e)
- /// {
- /// if (this.lblStatus.InvokeRequired)
- /// {
- /// this.lblStatus.Invoke(new ButtonClick(this.btnCancel_Click), new object[] { sender, e });
- /// }
- /// else
- /// {
- /// _saveCanceled = true;
- /// lblStatus.Text = "Canceled...";
- /// ResetState();
- /// }
- /// }
- ///
- /// private void KickoffZipup()
- /// {
- /// _folderName = tbDirName.Text;
- ///
- /// if (_folderName == null || _folderName == "") return;
- /// if (this.tbZipName.Text == null || this.tbZipName.Text == "") return;
- ///
- /// // check for existence of the zip file:
- /// if (System.IO.File.Exists(this.tbZipName.Text))
- /// {
- /// var dlgResult = MessageBox.Show(String.Format("The file you have specified ({0}) already exists." +
- /// " Do you want to overwrite this file?", this.tbZipName.Text),
- /// "Confirmation is Required", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
- /// if (dlgResult != DialogResult.Yes) return;
- /// System.IO.File.Delete(this.tbZipName.Text);
- /// }
- ///
- /// _saveCanceled = false;
- /// _nFilesCompleted = 0;
- /// _totalBytesAfterCompress = 0;
- /// _totalBytesBeforeCompress = 0;
- /// this.btnOk.Enabled = false;
- /// this.btnOk.Text = "Zipping...";
- /// this.btnCancel.Enabled = true;
- /// lblStatus.Text = "Zipping...";
- ///
- /// var options = new WorkerOptions
- /// {
- /// ZipName = this.tbZipName.Text,
- /// Folder = _folderName,
- /// Encoding = "ibm437"
- /// };
- ///
- /// if (this.comboBox1.SelectedIndex != 0)
- /// {
- /// options.Encoding = this.comboBox1.SelectedItem.ToString();
- /// }
- ///
- /// if (this.radioFlavorSfxCmd.Checked)
- /// options.ZipFlavor = 2;
- /// else if (this.radioFlavorSfxGui.Checked)
- /// options.ZipFlavor = 1;
- /// else options.ZipFlavor = 0;
- ///
- /// if (this.radioZip64AsNecessary.Checked)
- /// options.Zip64 = Zip64Option.AsNecessary;
- /// else if (this.radioZip64Always.Checked)
- /// options.Zip64 = Zip64Option.Always;
- /// else options.Zip64 = Zip64Option.Never;
- ///
- /// options.Comment = String.Format("Encoding:{0} || Flavor:{1} || ZIP64:{2}\r\nCreated at {3} || {4}\r\n",
- /// options.Encoding,
- /// FlavorToString(options.ZipFlavor),
- /// options.Zip64.ToString(),
- /// System.DateTime.Now.ToString("yyyy-MMM-dd HH:mm:ss"),
- /// this.Text);
- ///
- /// if (this.tbComment.Text != TB_COMMENT_NOTE)
- /// options.Comment += this.tbComment.Text;
- ///
- /// _workerThread = new Thread(this.DoSave);
- /// _workerThread.Name = "Zip Saver thread";
- /// _workerThread.Start(options);
- /// this.Cursor = Cursors.WaitCursor;
- /// }
- ///
- ///
- /// private void DoSave(Object p)
- /// {
- /// WorkerOptions options = p as WorkerOptions;
- /// try
- /// {
- /// using (var zip1 = new ZipFile())
- /// {
- /// zip1.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding(options.Encoding);
- /// zip1.Comment = options.Comment;
- /// zip1.AddDirectory(options.Folder);
- /// _entriesToZip = zip1.EntryFileNames.Count;
- /// SetProgressBars();
- /// zip1.SaveProgress += this.zip1_SaveProgress;
- ///
- /// zip1.UseZip64WhenSaving = options.Zip64;
- ///
- /// if (options.ZipFlavor == 1)
- /// zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.WinFormsApplication);
- /// else if (options.ZipFlavor == 2)
- /// zip1.SaveSelfExtractor(options.ZipName, SelfExtractorFlavor.ConsoleApplication);
- /// else
- /// zip1.Save(options.ZipName);
- /// }
- /// }
- /// catch (System.Exception exc1)
- /// {
- /// MessageBox.Show(String.Format("Exception while zipping: {0}", exc1.Message));
- /// btnCancel_Click(null, null);
- /// }
- /// }
- ///
- ///
- ///
- /// void zip1_SaveProgress(object sender, SaveProgressEventArgs e)
- /// {
- /// switch (e.EventType)
- /// {
- /// case ZipProgressEventType.Saving_AfterWriteEntry:
- /// StepArchiveProgress(e);
- /// break;
- /// case ZipProgressEventType.Saving_EntryBytesRead:
- /// StepEntryProgress(e);
- /// break;
- /// case ZipProgressEventType.Saving_Completed:
- /// SaveCompleted();
- /// break;
- /// case ZipProgressEventType.Saving_AfterSaveTempArchive:
- /// // this event only occurs when saving an SFX file
- /// TempArchiveSaved();
- /// break;
- /// }
- /// if (_saveCanceled)
- /// e.Cancel = true;
- /// }
- ///
- ///
- ///
- /// private void StepArchiveProgress(SaveProgressEventArgs e)
- /// {
- /// if (this.progressBar1.InvokeRequired)
- /// {
- /// this.progressBar1.Invoke(new SaveEntryProgress(this.StepArchiveProgress), new object[] { e });
- /// }
- /// else
- /// {
- /// if (!_saveCanceled)
- /// {
- /// _nFilesCompleted++;
- /// this.progressBar1.PerformStep();
- /// _totalBytesAfterCompress += e.CurrentEntry.CompressedSize;
- /// _totalBytesBeforeCompress += e.CurrentEntry.UncompressedSize;
- ///
- /// // reset the progress bar for the entry:
- /// this.progressBar2.Value = this.progressBar2.Maximum = 1;
- ///
- /// this.Update();
- /// }
- /// }
- /// }
- ///
- ///
- /// private void StepEntryProgress(SaveProgressEventArgs e)
- /// {
- /// if (this.progressBar2.InvokeRequired)
- /// {
- /// this.progressBar2.Invoke(new SaveEntryProgress(this.StepEntryProgress), new object[] { e });
- /// }
- /// else
- /// {
- /// if (!_saveCanceled)
- /// {
- /// if (this.progressBar2.Maximum == 1)
- /// {
- /// // reset
- /// Int64 max = e.TotalBytesToTransfer;
- /// _progress2MaxFactor = 0;
- /// while (max > System.Int32.MaxValue)
- /// {
- /// max /= 2;
- /// _progress2MaxFactor++;
- /// }
- /// this.progressBar2.Maximum = (int)max;
- /// lblStatus.Text = String.Format("{0} of {1} files...({2})",
- /// _nFilesCompleted + 1, _entriesToZip, e.CurrentEntry.FileName);
- /// }
- ///
- /// int xferred = e.BytesTransferred >> _progress2MaxFactor;
- ///
- /// this.progressBar2.Value = (xferred >= this.progressBar2.Maximum)
- /// ? this.progressBar2.Maximum
- /// : xferred;
- ///
- /// this.Update();
- /// }
- /// }
- /// }
- ///
- /// private void SaveCompleted()
- /// {
- /// if (this.lblStatus.InvokeRequired)
- /// {
- /// this.lblStatus.Invoke(new MethodInvoker(this.SaveCompleted));
- /// }
- /// else
- /// {
- /// lblStatus.Text = String.Format("Done, Compressed {0} files, {1:N0}% of original.",
- /// _nFilesCompleted, (100.00 * _totalBytesAfterCompress) / _totalBytesBeforeCompress);
- /// ResetState();
- /// }
- /// }
- ///
- /// private void ResetState()
- /// {
- /// this.btnCancel.Enabled = false;
- /// this.btnOk.Enabled = true;
- /// this.btnOk.Text = "Zip it!";
- /// this.progressBar1.Value = 0;
- /// this.progressBar2.Value = 0;
- /// this.Cursor = Cursors.Default;
- /// if (!_workerThread.IsAlive)
- /// _workerThread.Join();
- /// }
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public event EventHandler SaveProgress;
-
-
- internal bool OnSaveBlock(ZipEntry entry, Int64 bytesXferred, Int64 totalBytesToXfer)
- {
- EventHandler sp = SaveProgress;
- if (sp != null)
- {
- var e = SaveProgressEventArgs.ByteUpdate(ArchiveNameForEvent, entry,
- bytesXferred, totalBytesToXfer);
- sp(this, e);
- if (e.Cancel)
- _saveOperationCanceled = true;
- }
- return _saveOperationCanceled;
- }
-
- private void OnSaveEntry(int current, ZipEntry entry, bool before)
- {
- EventHandler sp = SaveProgress;
- if (sp != null)
- {
- var e = new SaveProgressEventArgs(ArchiveNameForEvent, before, _entries.Count, current, entry);
- sp(this, e);
- if (e.Cancel)
- _saveOperationCanceled = true;
- }
- }
-
- private void OnSaveEvent(ZipProgressEventType eventFlavor)
- {
- EventHandler sp = SaveProgress;
- if (sp != null)
- {
- var e = new SaveProgressEventArgs(ArchiveNameForEvent, eventFlavor);
- sp(this, e);
- if (e.Cancel)
- _saveOperationCanceled = true;
- }
- }
-
- private void OnSaveStarted()
- {
- EventHandler sp = SaveProgress;
- if (sp != null)
- {
- var e = SaveProgressEventArgs.Started(ArchiveNameForEvent);
- sp(this, e);
- if (e.Cancel)
- _saveOperationCanceled = true;
- }
- }
- private void OnSaveCompleted()
- {
- EventHandler sp = SaveProgress;
- if (sp != null)
- {
- var e = SaveProgressEventArgs.Completed(ArchiveNameForEvent);
- sp(this, e);
- }
- }
- #endregion
-
-
- #region Read
- ///
- /// An event handler invoked before, during, and after the reading of a zip archive.
- ///
- ///
- ///
- ///
- /// Depending on the particular event being signaled, different properties on the
- /// parameter are set. The following table
- /// summarizes the available EventTypes and the conditions under which this
- /// event handler is invoked with a ReadProgressEventArgs with the given EventType.
- ///
- ///
- ///
- ///
- /// value of EntryType
- /// Meaning and conditions
- ///
- ///
- /// -
- /// ZipProgressEventType.Reading_Started
- /// Fired just as ZipFile.Read() begins. Meaningful properties: ArchiveName.
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Reading_Completed
- /// Fired when ZipFile.Read() has completed. Meaningful properties: ArchiveName.
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Reading_ArchiveBytesRead
- /// Fired while reading, updates the number of bytes read for the entire archive.
- /// Meaningful properties: ArchiveName, CurrentEntry, BytesTransferred, TotalBytesToTransfer.
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Reading_BeforeReadEntry
- /// Indicates an entry is about to be read from the archive.
- /// Meaningful properties: ArchiveName, EntriesTotal.
- ///
- ///
- ///
- /// -
- /// ZipProgressEventType.Reading_AfterReadEntry
- /// Indicates an entry has just been read from the archive.
- /// Meaningful properties: ArchiveName, EntriesTotal, CurrentEntry.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public event EventHandler ReadProgress;
-
- private void OnReadStarted()
- {
- EventHandler rp = ReadProgress;
- if (rp != null)
- {
- var e = ReadProgressEventArgs.Started(ArchiveNameForEvent);
- rp(this, e);
- }
- }
-
- private void OnReadCompleted()
- {
- EventHandler rp = ReadProgress;
- if (rp != null)
- {
- var e = ReadProgressEventArgs.Completed(ArchiveNameForEvent);
- rp(this, e);
- }
- }
-
- internal void OnReadBytes(ZipEntry entry)
- {
- EventHandler rp = ReadProgress;
- if (rp != null)
- {
- var e = ReadProgressEventArgs.ByteUpdate(ArchiveNameForEvent,
- entry,
- ReadStream.Position,
- LengthOfReadStream);
- rp(this, e);
- }
- }
-
- internal void OnReadEntry(bool before, ZipEntry entry)
- {
- EventHandler