v1.2 EDIT ALL THE THINGS

v1.2 EDIT ALL THE THINGS

Added an Edit All parameters button and fixed saving bugs and other misc
bugs.

--- ContractController/HeadMaster.cs
+++ ContractController/HeadMaster.cs
@@ -26,7 +26,7 @@
         //Per-type blocks and prefers

         ApplicationLauncherButton CCButton = null;
-        private Rect mainGUI = new Rect(100, 100, 250, 575);
+        private Rect mainGUI = new Rect(100, 100, 250, 625);

         private bool showGUI = true;
         int mainGUID;
@@ -44,6 +44,20 @@
         int autoStringGuid;
         int autoStringListGuid;

+        int editAllGuid;
+        int allparameterGuid;
+        int allparameterListGuid;
+        int allautoParameterGuid;
+        int allautoParameterListGuid;
+        int allbodyGuid;
+        int allbodyListGuid;
+        int allautoBodyGuid;
+        int allautoBodyListGuid;
+        int allstringGuid;
+        int allstringListGuid;
+        int allautoStringGuid;
+        int allautoStringListGuid;
+
         Vector2 scrollPosition;
         Vector2 scrollPosition2;
         Vector2 scrollPosition3;
@@ -54,6 +68,17 @@
         Vector2 scrollPosition8;
         Vector2 scrollPosition9;
         Vector2 scrollPosition10;
+        Vector2 scrollPosition11;
+        Vector2 scrollPosition12;
+        Vector2 scrollPosition13;
+        Vector2 scrollPosition14;
+        Vector2 scrollPosition15;
+        Vector2 scrollPosition16;
+        Vector2 scrollPosition17;
+        Vector2 scrollPosition18;
+        Vector2 scrollPosition19;
+        Vector2 scrollPosition20;
+        Vector2 scrollPosition21;

         Type editingType;

@@ -69,6 +94,42 @@
         bool showStringBlacklistGUI = false;
         bool showStringWhitelistGUI = false;

+        bool showAllParameterChangeGUI = false;
+        bool showAllParameterListGUI = false;
+        bool showAllAutoParamGUI = false;
+        bool showAllBodyBlacklistGUI = false;
+        bool showAllBodyAutoListGUI = false;
+        bool showAllStringBlacklistGUI = false;
+        bool showAllStringWhitelistGUI = false;
+
+        public String minFundsAdvanceString = "0";
+        public String maxFundsAdvanceString = "100000";
+        public String minFundsCompleteString = "0";
+        public String maxFundsCompleteString = "100000";
+        public String minFundsFailureString = "0";
+        public String maxFundsFailureString = "100000";
+
+        public String minRepCompleteString = "0";
+        public String maxRepCompleteString = "100000";
+        public String minRepFailureString = "0";
+        public String maxRepFailureString = "100000";
+
+        public String minScienceCompleteString = "0";
+        public String maxScienceCompleteString = "100000";
+
+        public String minParamsString = "0";
+        public String maxParamsString = "20";
+        public String minPrestiegeString = "0";
+        public String maxPrestiegeString = "2";
+
+        List<Type> blockedParams = new List<Type>();
+        List<Type> whiteParams = new List<Type>();
+        List<String> blackBodies = new List<String>();
+        List<String> whiteBodies = new List<String>();
+        List<String> blackStrings = new List<String>();
+        List<String> whiteStrings = new List<String>();
+
+        bool showEditAllGUI;

         String statusString = "";
         double timeTillIdle = 15000;
@@ -86,7 +147,7 @@

         void Awake()
         {
-
+
             DontDestroyOnLoad(this);
             Debug.Log("*yawn* I'm awake");
             mainGUID = Guid.NewGuid().GetHashCode();
@@ -103,12 +164,26 @@
             stringListGuid = Guid.NewGuid().GetHashCode();
             autoStringGuid = Guid.NewGuid().GetHashCode();
             autoStringListGuid = Guid.NewGuid().GetHashCode();
+            editAllGuid = Guid.NewGuid().GetHashCode();
+
+            allparameterGuid = Guid.NewGuid().GetHashCode();
+            allparameterListGuid = Guid.NewGuid().GetHashCode();
+            allautoParameterGuid = Guid.NewGuid().GetHashCode();
+            allautoParameterListGuid = Guid.NewGuid().GetHashCode();
+            allbodyGuid = Guid.NewGuid().GetHashCode();
+            allbodyListGuid = Guid.NewGuid().GetHashCode();
+            allautoBodyGuid = Guid.NewGuid().GetHashCode();
+            allautoBodyListGuid = Guid.NewGuid().GetHashCode();
+            allstringGuid = Guid.NewGuid().GetHashCode();
+            allstringListGuid = Guid.NewGuid().GetHashCode();
+            allautoStringGuid = Guid.NewGuid().GetHashCode();
+            allautoStringListGuid = Guid.NewGuid().GetHashCode();
             //Debug.Log("Active+Enabled?: " + ContractSystem.Instance.isActiveAndEnabled);
             //done = false;

             if (buttonNeedsInit && HighLogic.LoadedScene == GameScenes.SPACECENTER)
             {
-
+
                 Debug.Log("Initing buttons");
                 InitButtons();
             }
@@ -162,7 +237,7 @@
                                 //check blocked agents
                                 //check intParams
                                 //check finances
-
+

                                 if (checkForBlockedType(c)) { toDelete.Add(c); }

@@ -215,7 +290,7 @@
                         acceptWhitedContracts(toAccept);
                     }
                 }
-                if(idleWatch.ElapsedMilliseconds >= 25000 && !isSorting)
+                if (idleWatch.ElapsedMilliseconds >= 25000 && !isSorting)
                 {
                     statusString = "Idling";
                 }
@@ -223,13 +298,13 @@
             else
             {
                 showGUI = false;
-
+
             }
         }
         void OnAppButtonReady()
         {
             //Note: do tracking station check
-            if(HighLogic.LoadedScene == GameScenes.SPACECENTER && CCButton == null)
+            if (HighLogic.LoadedScene == GameScenes.SPACECENTER && CCButton == null)
             {
                 Debug.Log("App launcher Ready");
                 if (ApplicationLauncher.Ready)
@@ -246,17 +321,17 @@
                         (Texture)GameDatabase.Instance.GetTexture("ContractFilter/Textures/appButton", false));
                 }
             }
-
+
         }

         private void ShowGUI()
         {
             Debug.Log("ShowGUI");
-            if(HighLogic.LoadedScene == GameScenes.SPACECENTER)
+            if (HighLogic.LoadedScene == GameScenes.SPACECENTER)
             {
                 showGUI = true;
             }
-
+
         }

         private void HideGUI()
@@ -272,18 +347,18 @@

         void OnAppLaunchToggleOn()
         {
-            if(HighLogic.LoadedScene == GameScenes.SPACECENTER)
+            if (HighLogic.LoadedScene == GameScenes.SPACECENTER)
             {
                 showGUI = true;
             }
-
+
         }

         void DummyVoid() { }

         void InitButtons()
         {
-            if(HighLogic.LoadedScene == GameScenes.SPACECENTER)
+            if (HighLogic.LoadedScene == GameScenes.SPACECENTER)
             {
                 Debug.Log("Init Buttons");
                 if (CCButton == null)
@@ -301,7 +376,7 @@

                 buttonNeedsInit = false;
             }
-
+
         }

         void DestroyButtons()
@@ -447,7 +522,11 @@
                         }
                         else if (line.StartsWith("`"))
                         { //black body
-                            tp.blockedBodies.Add(line.Substring(1));
+                            if(!tp.blockedBodies.Contains(line.Substring(1)))
+                            {
+                                tp.blockedBodies.Add(line.Substring(1));
+                            }
+
                         }
                         else if (line.StartsWith("!"))
                         {
@@ -469,11 +548,11 @@
                     statusString = "Loaded!";
                 }
             }
-            catch(Exception e)
+            catch (Exception e)
             {
                 statusString = "Load Failed!";
             }
-
+

         }
         internal void mySave()
@@ -573,11 +652,11 @@
                     file.Close();
                 }
             }
-            catch(Exception e)
+            catch (Exception e)
             {
                 statusString = "Save failed!";
             }
-
+
         }
         void OnGUI()
         {
@@ -600,6 +679,7 @@
                             showParameterListGUI = false;
                             showStringBlacklistGUI = false;
                             showStringWhitelistGUI = false;
+                            showEditAllGUI = false;
                             Rect rect1 = new Rect(rect.right, rect.top, 250, 300);
                             rect1 = GUI.Window(parameterGuid, rect1, changeParameterGUI, "Parameter List~");
                             Rect rect2 = new Rect(rect.right, rect.top + rect.height - 185, 250, 300);
@@ -615,6 +695,7 @@
                             showParameterListGUI = false;
                             showStringBlacklistGUI = false;
                             showStringWhitelistGUI = false;
+                            showEditAllGUI = false;
                             Rect rect1 = new Rect(rect.right, rect.top, 250, 300);
                             rect1 = GUI.Window(autoParameterGuid, rect1, autoParameterListGUI, "Auto-Parameter List~");
                             Rect rect2 = new Rect(rect.right, rect.top + rect.height - 185, 250, 300);
@@ -629,6 +710,7 @@
                             showParameterListGUI = false;
                             showStringBlacklistGUI = false;
                             showStringWhitelistGUI = false;
+                            showEditAllGUI = false;
                             Rect rect1 = new Rect(rect.right, rect.top, 250, 300);
                             rect1 = GUI.Window(bodyGuid, rect1, bodyBlacklistGUI, "Body List~");
                             Rect rect2 = new Rect(rect.right, rect.top + rect.height - 185, 250, 300);
@@ -643,6 +725,7 @@
                             showParameterListGUI = false;
                             showStringBlacklistGUI = false;
                             showStringWhitelistGUI = false;
+                            showEditAllGUI = false;
                             Rect rect1 = new Rect(rect.right, rect.top, 250, 300);
                             rect1 = GUI.Window(autoBodyGuid, rect1, autoBodyListGUI, "Body List~");
                             Rect rect2 = new Rect(rect.right, rect.top + rect.height - 185, 250, 300);
@@ -657,6 +740,7 @@
                             showParameterListGUI = false;
                             //showStringBlacklistGUI = false;
                             showStringWhitelistGUI = false;
+                            showEditAllGUI = false;
                             Rect rect1 = new Rect(rect.right, rect.top, 250, 300);
                             rect1 = GUI.Window(stringGuid, rect1, stringBlackListGUI, "Blacklisted Strings~");
                             //Rect rect2 = new Rect(rect.right, rect.top + rect.height - 180, 250, 300);
@@ -670,18 +754,514 @@
                             showBodyBlacklistGUI = false;
                             showAutoParamGUI = false;
                             showParameterListGUI = false;
+                            showEditAllGUI = false;
                             //showStringWhitelistGUI = false;
                             Rect rect1 = new Rect(rect.right, rect.top, 250, 300);
                             rect1 = GUI.Window(autoStringGuid, rect1, stringAutoListGUI, "Whitelisted Strings~");
                             //Rect rect2 = new Rect(rect.right, rect.top + rect.height - 180, 250, 300);
                             //rect2 = GUI.Window(autoStringListGuid, rect2, userStringAutoListGUI, "AutoListed Strings~");
                         }
-                    }
-                }
-            }
-
-
-
+
+                    }
+                    if (showEditAllGUI)
+                    {
+                        showParameterChangeGUI = false;
+                        showStringBlacklistGUI = false;
+                        showBodyAutoListGUI = false;
+                        showBodyBlacklistGUI = false;
+                        showAutoParamGUI = false;
+                        showParameterListGUI = false;
+                        showStringWhitelistGUI = false;
+
+                        Rect rect1 = new Rect(mainGUI.right, mainGUI.top, 250, 460);
+                        rect1 = GUI.Window(editAllGuid, rect1, editAllWindow, "Edit All~");
+
+                        if (showAllParameterChangeGUI)
+                        {
+                            //showParameterChangeGUI = false;
+                            showAllBodyBlacklistGUI = false;
+                            showAllBodyAutoListGUI = false;
+                            showAllAutoParamGUI = false;
+                            showAllParameterListGUI = false;
+                            showAllStringBlacklistGUI = false;
+                            showAllStringWhitelistGUI = false;;
+                            Rect rect2 = new Rect(rect1.right, rect1.top, 250, 300);
+                            rect2 = GUI.Window(allparameterGuid, rect2, allParamWindow, "Parameter List~");
+                            Rect rect3 = new Rect(rect1.right, rect1.top + rect1.height - 160, 250, 300);
+                            rect3 = GUI.Window(allparameterListGuid, rect3, allParamListWindow, "Blacklisted Parameters~");
+
+                        }
+                        if (showAllAutoParamGUI)
+                        {
+                            showAllParameterChangeGUI = false;
+                            showAllBodyBlacklistGUI = false;
+                            showAllBodyAutoListGUI = false;
+                            //showAutoParamGUI = false;
+                            showAllParameterListGUI = false;
+                            showAllStringBlacklistGUI = false;
+                            showAllStringWhitelistGUI = false;
+                            Rect rect2 = new Rect(rect1.right, rect1.top, 250, 300);
+                            rect2 = GUI.Window(allautoParameterGuid, rect2, allAutoParameterListGUI, "Auto-Parameter List~");
+                            Rect rect3 = new Rect(rect1.right, rect1.top + rect1.height - 160, 250, 300);
+                            rect3 = GUI.Window(allautoParameterListGuid, rect3, allAutoListParameterGUI, "AutoParameters~");
+                        }
+                        if (showAllBodyBlacklistGUI)
+                        {
+                            showAllParameterChangeGUI = false;
+                            //showBodyBlacklistGUI = false;
+                            showAllBodyAutoListGUI = false;
+                            showAllAutoParamGUI = false;
+                            showAllParameterListGUI = false;
+                            showAllStringBlacklistGUI = false;
+                            showAllStringWhitelistGUI = false;
+                            Rect rect2 = new Rect(rect1.right, rect1.top, 250, 300);
+                            rect2 = GUI.Window(allbodyGuid, rect2, allBodyBlacklistGUI, "Body List~");
+                            Rect rect3 = new Rect(rect1.right, rect1.top + rect1.height - 160, 250, 300);
+                            rect3 = GUI.Window(allbodyListGuid, rect3, allUserBodyBlackListGUI, "Blacklisted Bodies~");
+                        }
+                        if (showAllBodyAutoListGUI)
+                        {
+                            showAllParameterChangeGUI = false;
+                            showAllBodyBlacklistGUI = false;
+                            //showBodyAutoListGUI = false;
+                            showAllAutoParamGUI = false;
+                            showAllParameterListGUI = false;
+                            showAllStringBlacklistGUI = false;
+                            showAllStringWhitelistGUI = false;
+                            Rect rect2 = new Rect(rect1.right, rect1.top, 250, 300);
+                            rect2 = GUI.Window(allautoBodyGuid, rect2, allAutoBodyListGUI, "Body List~");
+                            Rect rect3 = new Rect(rect1.right, rect1.top + rect1.height - 160, 250, 300);
+                            rect3 = GUI.Window(allautoBodyListGuid, rect3, allUserAutoBodyListGUI, "AutoListed Bodies~");
+                        }
+                        if (showAllStringBlacklistGUI)
+                        {
+                            showAllParameterChangeGUI = false;
+                            showAllBodyBlacklistGUI = false;
+                            showAllBodyAutoListGUI = false;
+                            showAllAutoParamGUI = false;
+                            showAllParameterListGUI = false;
+                            //showStringBlacklistGUI = false;
+                            showAllStringWhitelistGUI = false;
+                            Rect rect2 = new Rect(rect1.right, rect1.top, 250, 300);
+                            rect2 = GUI.Window(allstringGuid, rect2, allStringBlackListGUI, "Blacklisted Strings~");
+                            //Rect rect2 = new Rect(rect.right, rect.top + rect.height - 180, 250, 300);
+                            //rect2 = GUI.Window(stringListGuid, rect2, userStringBlackListGUI, "Blacklisted Strings~");
+                        }
+                        if (showAllStringWhitelistGUI)
+                        {
+                            showAllParameterChangeGUI = false;
+                            showAllStringBlacklistGUI = false;
+                            showAllBodyAutoListGUI = false;
+                            showAllBodyBlacklistGUI = false;
+                            showAllAutoParamGUI = false;
+                            showAllParameterListGUI = false;
+                            //showStringWhitelistGUI = false;
+                            Rect rect2 = new Rect(rect1.right, rect1.top, 250, 300);
+                            rect2 = GUI.Window(allautoStringGuid, rect2, allStringWhiteListGUI, "Whitelisted Strings~");
+                            //Rect rect2 = new Rect(rect.right, rect.top + rect.height - 180, 250, 300);
+                            //rect2 = GUI.Window(autoStringListGuid, rect2, userStringAutoListGUI, "AutoListed Strings~");
+                        }
+                    }
+                }
+            }
+
+
+
+        }
+        public void editAllWindow(int windowID)
+        {
+            GUI.backgroundColor = new Color(0,0,0);
+            if(ContractSystem.Instance.isActiveAndEnabled && ContractSystem.Instance != null)
+            {
+                GUILayout.BeginVertical();
+                GUILayout.Label("");
+                scrollPosition11 = GUILayout.BeginScrollView(scrollPosition11, GUILayout.Width(235), GUILayout.Height(250));
+                //mainGUI.position = scrollPosition;
+                //Debug.Log("2");
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("minFundsAdvance:");
+                //minFundsAdvance = tp.minFundsAdvance.ToString();
+                minFundsAdvanceString = GUILayout.TextField(minFundsAdvanceString);
+                //tp.minFundsAdvance = float.Parse(minFundsAdvance);
+                //typePrefDict[tp][0] = GUILayout.TextField(typePrefDict[tp][0]); //this fucks up
+                GUILayout.EndHorizontal();
+                //Debug.Log("3");
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("maxFundsAdvance:");
+                maxFundsAdvanceString = GUILayout.TextField(maxFundsAdvanceString);
+                //tp.maxFundsAdvance = float.Parse(GUILayout.TextField(tp.maxFundsAdvance.ToString()));
+                GUILayout.EndHorizontal(); ;
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("minFundsComplete:");
+                minFundsCompleteString = GUILayout.TextField(minFundsCompleteString);
+                //tp.minFundsCompletion = float.Parse(GUILayout.TextField(tp.minFundsCompletion.ToString()));
+                GUILayout.EndHorizontal();
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("maxFundsComplete:");
+                maxFundsCompleteString = GUILayout.TextField(maxFundsCompleteString);
+                //tp.maxFundsCompletion = float.Parse(GUILayout.TextField(tp.maxFundsCompletion.ToString()));
+                GUILayout.EndHorizontal();
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("minFundsFailure:");
+                minFundsFailureString = GUILayout.TextField(minFundsFailureString);
+                //tp.minFundsFailure = float.Parse(GUILayout.TextField(tp.minFundsFailure.ToString()));
+                GUILayout.EndHorizontal();
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("maxFundsFailure:");
+                maxFundsFailureString = GUILayout.TextField(maxFundsFailureString);
+                //tp.maxFundsFailure = float.Parse(GUILayout.TextField(tp.maxFundsFailure.ToString()));
+                GUILayout.EndHorizontal();
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("minRepComplete:");
+                minRepCompleteString = GUILayout.TextField(minRepCompleteString);
+                //tp.minRepCompletion = float.Parse(GUILayout.TextField(tp.minRepCompletion.ToString()));
+                GUILayout.EndHorizontal();
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("maxRepComplete:");
+                maxRepCompleteString = GUILayout.TextField(maxRepCompleteString);
+                //tp.maxRepCompletion = float.Parse(GUILayout.TextField(tp.maxRepCompletion.ToString()));
+                GUILayout.EndHorizontal();
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("minRepFailure:");
+                minRepFailureString = GUILayout.TextField(minRepFailureString);
+                //tp.minRepFailure = float.Parse(GUILayout.TextField(tp.minRepFailure.ToString()));
+                GUILayout.EndHorizontal();
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("maxRepFailure:");
+                maxRepFailureString = GUILayout.TextField(maxRepFailureString);
+                //tp.maxRepFailure = float.Parse(GUILayout.TextField(tp.maxRepFailure.ToString()));
+                GUILayout.EndHorizontal();
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("minScienceComplete:");
+                minScienceCompleteString = GUILayout.TextField(minScienceCompleteString);
+                //tp.minScienceCompletion = float.Parse(GUILayout.TextField(tp.minScienceCompletion.ToString()));
+                GUILayout.EndHorizontal();
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("maxScienceComplete:");
+                maxScienceCompleteString = GUILayout.TextField(maxScienceCompleteString);
+                //tp.maxScienceCompletion = float.Parse(GUILayout.TextField(tp.maxScienceCompletion.ToString()));
+                GUILayout.EndHorizontal();
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("minParameters:");
+                minParamsString = GUILayout.TextField(minParamsString);
+                //tp.minParams = int.Parse(GUILayout.TextField(tp.minParams.ToString()));
+                GUILayout.EndHorizontal();
+                GUILayout.BeginHorizontal();
+                GUILayout.Label("maxParameters:");
+                maxParamsString = GUILayout.TextField(maxParamsString);
+                //tp.maxParams = int.Parse(GUILayout.TextField(tp.maxParams.ToString()));
+                GUILayout.EndHorizontal();
+
+                //Note: have in-scope strings which convert to float/int, as the above doesn't work
+                GUILayout.EndScrollView();
+
+                if (GUILayout.Button("Blacklist Parameters"))
+                {
+                    showAllParameterChangeGUI = !showAllParameterChangeGUI;
+                    showAllParameterListGUI = !showAllParameterListGUI;
+                }
+                if (GUILayout.Button("AutoAccept Parameters"))
+                {
+                    showAllAutoParamGUI = !showAllAutoParamGUI;
+
+                }
+                if (GUILayout.Button("Blacklist Bodies"))
+                {
+                    showAllBodyBlacklistGUI = !showAllBodyBlacklistGUI;
+                }
+                if (GUILayout.Button("AutoAccept Bodies"))
+                {
+                    showAllBodyAutoListGUI = !showAllBodyAutoListGUI;
+                }
+                if (GUILayout.Button("Blacklist Strings"))
+                {
+                    showAllStringBlacklistGUI = !showAllStringBlacklistGUI;
+                }
+                if (GUILayout.Button("Whitelist Strings"))
+                {
+                    showAllStringWhitelistGUI = !showAllStringWhitelistGUI;
+                }
+                if(GUILayout.Button("Close"))
+                {
+                    statusString = "Saving All...";
+                    //mySave();
+                    foreach (Type t in Contracts.ContractSystem.ContractTypes)
+                    {
+                        try
+                        {
+                            //Debug.Log(typePrefDict.Count);
+                            //Debug.Log(typePrefDict[typeMap[editingType]].Count);
+                            ///*
+                            TypePreference tp1 = typeMap[t];
+                            statusString = "Saving: " + t.Name;
+                            tp1.minFundsAdvance = float.Parse(minFundsAdvanceString);
+                            //Debug.Log("saving: " + tp.minFundsAdvance);
+                            tp1.maxFundsAdvance = float.Parse(maxFundsAdvanceString);
+                            tp1.minFundsCompletion = float.Parse(minFundsCompleteString);
+                            tp1.maxFundsCompletion = float.Parse(maxFundsCompleteString);
+                            tp1.minFundsFailure = float.Parse(minFundsFailureString);
+                            tp1.maxFundsFailure = float.Parse(maxFundsFailureString);
+
+                            tp1.minRepCompletion = float.Parse(minRepCompleteString);
+                            tp1.maxRepCompletion = float.Parse(maxRepCompleteString);
+                            tp1.minRepFailure = float.Parse(minRepFailureString);
+                            tp1.maxRepFailure = float.Parse(maxRepFailureString);
+
+                            tp1.minScienceCompletion = float.Parse(minScienceCompleteString);
+                            tp1.maxScienceCompletion = float.Parse(maxScienceCompleteString);
+
+                            tp1.minParams = int.Parse(minParamsString);
+                            tp1.maxParams = int.Parse(maxParamsString);
+                            tp1.minPrestiege = int.Parse(minPrestiegeString);
+                            tp1.maxPrestiege = int.Parse(maxPrestiegeString);
+
+
+
+                            tp1.autoParameters = whiteParams;
+                            tp1.blockedParameters = blockedParams;
+                            tp1.autoBodies = whiteBodies;
+                            tp1.blockedBodies = blackBodies;
+                            tp1.autoStrings = whiteStrings;
+                            tp1.blockedStrings = blackStrings;
+
+                            typeMap[t] = tp1;
+                            //tp = tp1;
+                            //*/
+                            //Debug.Log(tp.minFundsCompletion);
+                            statusString = "Saved!";
+
+                        }
+                        catch (Exception e)
+                        {
+                            statusString = "Failed to save!";
+                        }
+                    }
+                    Debug.Log("Settings Saved");
+                    statusString = "Saved!";
+                    //idleWatch.Restart();
+                    idleWatch.Reset();
+                    idleWatch.Start();
+
+                    showEditAllGUI = false;
+                }
+            }
+        }
+        public void allParamWindow(int windowID)
+        {
+            GUI.backgroundColor = new Color(0, 0, 0);
+            List<Type> bloop = blockedParams;
+            scrollPosition13 = GUILayout.BeginScrollView(scrollPosition13, GUILayout.Width(235), GUILayout.Height(290));
+            foreach (Type cp in ContractSystem.ParameterTypes)
+            {
+                if (!bloop.Contains(cp))
+                {
+                    if (GUILayout.Button("" + cp.Name))
+                    {
+                        blockedParams.Add(cp);
+
+                    }
+                }
+            }
+            GUILayout.EndScrollView();
+        }
+        public void allParamListWindow(int windowID)
+        {
+            GUI.backgroundColor = new Color(0, 0, 0);
+            List<Type> bloop = blockedParams;
+
+            scrollPosition14 = GUILayout.BeginScrollView(scrollPosition14, GUILayout.Width(235), GUILayout.Height(290));
+            foreach (Type cp in bloop)
+            {
+                if (GUILayout.Button(cp.Name))
+                {
+                    try
+                    {
+                        blockedParams.Remove(cp);
+                    }
+                    catch (Exception e)
+                    {
+
+                    }
+
+                }
+            }
+            GUILayout.EndScrollView();
+        }
+
+        public void allAutoParameterListGUI(int windowID)
+        {
+            GUI.backgroundColor = new Color(0, 0, 0);
+            List<Type> bloop = whiteParams;
+            scrollPosition13 = GUILayout.BeginScrollView(scrollPosition13, GUILayout.Width(235), GUILayout.Height(290));
+            foreach (Type cp in ContractSystem.ParameterTypes)
+            {
+                if (!bloop.Contains(cp))
+                {
+                    if (GUILayout.Button("" + cp.Name))
+                    {
+                        if (blockedParams.Contains(cp))
+                        {
+                            try
+                            {
+                                blockedParams.Remove(cp);
+                            }
+                            catch (Exception e)
+                            {
+
+                            }
+
+                        }
+                        whiteParams.Add(cp);
+
+                    }
+                }
+            }
+            GUILayout.EndScrollView();
+        }
+
+        public void allAutoListParameterGUI(int windowID)
+        {
+            GUI.backgroundColor = new Color(0, 0, 0);
+            List<Type> bloop = new List<Type>();
+            bloop = whiteParams;
+
+            scrollPosition14 = GUILayout.BeginScrollView(scrollPosition14, GUILayout.Width(235), GUILayout.Height(290));
+            foreach (Type cp in bloop)
+            {
+                if (GUILayout.Button(cp.Name))
+                {
+                    try
+                    {
+                        whiteParams.Remove(cp);
+                    }
+                    catch (Exception e)
+                    {
+
+                    }
+
+                }
+            }
+            GUILayout.EndScrollView();
+        }
+        public void allBodyBlacklistGUI(int windowID)
+        {
+            GUI.backgroundColor = new Color(0, 0, 0);
+            scrollPosition15 = GUILayout.BeginScrollView(scrollPosition15, GUILayout.Width(235), GUILayout.Height(290));
+            foreach (CelestialBody body in FlightGlobals.Bodies)
+            {
+                if (!blackBodies.Contains(body.name))
+                {
+                    if (GUILayout.Button(body.name))
+                    {
+                        blackBodies.Add(body.name);
+                    }
+                }
+            }
+            GUILayout.EndScrollView();
+        }
+        public void allUserBodyBlackListGUI(int windowID)
+        {
+            GUI.backgroundColor = new Color(0, 0, 0);
+            scrollPosition16 = GUILayout.BeginScrollView(scrollPosition16, GUILayout.Width(235), GUILayout.Height(290));
+            List<String> list = blackBodies;
+            foreach (String s in list)
+            {
+                if (GUILayout.Button(s))
+                {
+                    try
+                    {
+                        blackBodies.Remove(s);
+                    }
+                    catch (Exception e)
+                    {
+
+                    }
+
+                }
+            }
+            GUILayout.EndScrollView();
+        }
+        public void allAutoBodyListGUI(int windowID)
+        {
+            GUI.backgroundColor = new Color(0, 0, 0);
+            scrollPosition17 = GUILayout.BeginScrollView(scrollPosition17, GUILayout.Width(235), GUILayout.Height(290));
+            foreach (CelestialBody body in FlightGlobals.Bodies)
+            {
+                if (!whiteBodies.Contains(body.name))
+                {
+                    if (GUILayout.Button(body.name))
+                    {
+                        whiteBodies.Add(body.name);
+                    }
+                }
+            }
+            GUILayout.EndScrollView();
+        }
+        public void allUserAutoBodyListGUI(int windowID)
+        {
+            GUI.backgroundColor = new Color(0, 0, 0);
+            scrollPosition18 = GUILayout.BeginScrollView(scrollPosition18, GUILayout.Width(235), GUILayout.Height(290));
+            List<String> list = whiteBodies;
+            foreach (String s in list)
+            {
+                if (GUILayout.Button(s))
+                {
+                    try
+                    {
+                        whiteBodies.Remove(s);
+                    }
+                    catch (Exception e)
+                    {
+
+                    }
+
+                }
+            }
+            GUILayout.EndScrollView();
+        }
+        public void allStringBlackListGUI(int windowID)
+        {
+            GUI.backgroundColor = new Color(0, 0, 0);
+            GUILayout.Label("Note: The strings are case sensitive");
+            stringthing = GUILayout.TextField(stringthing);
+            if (GUILayout.Button("Add"))
+            {
+                if (!blackStrings.Contains(stringthing))
+                {
+                    blackStrings.Add(stringthing);
+                }
+            }
+            scrollPosition19 = GUILayout.BeginScrollView(scrollPosition19, GUILayout.Width(235), GUILayout.Height(290));
+            foreach (String s in blackStrings)
+            {
+                if (GUILayout.Button(s))
+                {
+                    blackStrings.Remove(s);
+                }
+            }
+            GUILayout.EndScrollView();
+        }
+        public void allStringWhiteListGUI(int windowID)
+        {
+            GUI.backgroundColor = new Color(0, 0, 0);
+            GUILayout.Label("Note: The strings are case sensitive");
+            stringthing1 = GUILayout.TextField(stringthing1);
+            if (GUILayout.Button("Add"))
+            {
+                if (!whiteStrings.Contains(stringthing1))
+                {
+                    whiteStrings.Add(stringthing1);
+                }
+            }
+            scrollPosition20 = GUILayout.BeginScrollView(scrollPosition20, GUILayout.Width(235), GUILayout.Height(290));
+            foreach (String s in whiteStrings)
+            {
+                if (GUILayout.Button(s))
+                {
+                    whiteStrings.Remove(s);
+                }
+            }
+            GUILayout.EndScrollView();
         }
         public void mainGUIWindow(int windowID)
         {
@@ -695,7 +1275,7 @@

                 foreach (Type t in Contracts.ContractSystem.ContractTypes)
                 {
-                    if(blockedTypes.Contains(t))
+                    if (blockedTypes.Contains(t))
                     {
                         GUI.backgroundColor = new Color(1.0f, 0.25f, 0.25f);
                         if (GUILayout.Button(t.Name))
@@ -705,6 +1285,7 @@
                             showParameterChangeGUI = false;
                             showParameterListGUI = false;
                             showAutoParamGUI = false;
+                            showEditAllGUI = false;
                         }
                         GUI.backgroundColor = new Color(0.0f, 0.0f, 0f);
                     }
@@ -718,13 +1299,22 @@
                             showParameterChangeGUI = false;
                             showParameterListGUI = false;
                             showAutoParamGUI = false;
+                            showEditAllGUI = false;
                         }
                         GUI.backgroundColor = new Color(0.0f, 0.0f, 0f);
                     }
-
+

                 }
                 GUILayout.EndScrollView();
+                if (GUILayout.Button("Edit All"))
+                {
+                    showEditAllGUI = !showEditAllGUI;
+                    showtypeprefeditor = false;
+                    showParameterChangeGUI = false;
+                    showParameterListGUI = false;
+                    showAutoParamGUI = false;
+                }
                 if (isSorting)
                 {
                     if (GUILayout.Button("Stop Sorting"))
@@ -781,7 +1371,7 @@

         public void editTypePrefGUI(int windowID)
         {
-            GUI.backgroundColor = new Color(0,0,0);
+            GUI.backgroundColor = new Color(0, 0, 0);
             if (ContractSystem.Instance.isActiveAndEnabled && ContractSystem.Instance != null)
             {
                 //minFunds
@@ -876,7 +1466,7 @@
                 GUILayout.EndVertical();
                 if (blockedTypes.Contains(editingType))
                 {
-
+
                     if (GUILayout.Button("Accept Type"))
                     {
                         blockedTypes.Remove(editingType);
@@ -1177,12 +1767,12 @@
         public void stringAutoListGUI(int windowID)
         {
             GUI.backgroundColor = new Color(0, 0, 0);
-            TypePreference tp = typeMap[editingType];
+            TypePreference tp = typeMap[editingType];
             GUILayout.Label("Note: The strings are case sensitive");
             stringthing1 = GUILayout.TextField(stringthing1);
             if (GUILayout.Button("Add"))
             {
-                if (!tp.blockedStrings.Contains(stringthing1))
+                if (!tp.autoStrings.Contains(stringthing1))
                 {
                     tp.autoStrings.Add(stringthing1);
                 }
@@ -1468,21 +2058,21 @@
         {
             Type t = c.GetType();
             TypePreference tp = typeMap[t];
-            foreach(String s in tp.autoBodies)
+            foreach (String s in tp.autoBodies)
             {
                 if (checkForString(c, s))
                 {
                     return true;
                 }
             }
-            if(tp.autoBodies.Contains("Kerbin"))
+            if (tp.autoBodies.Contains("Kerbin"))
             {
                 if (checkForString(c, "Launch Site"))
                 {
                     return true;
                 }
             }
-
+
             return false;
         }
         public bool checkForWhitedParameter(Contract c)
@@ -1600,14 +2190,14 @@
         {
             foreach (Contract c in contractList)
             {
-
-                if(c.ContractState == Contract.State.Offered)
+
+                if (c.ContractState == Contract.State.Offered)
                 {
                     Debug.Log("Removing: " + c.Title);
                     statusString = "Declining: " + c.Title;
                     c.Decline();
                 }
-
+
                 //Contracts.ContractSystem.Instance.Contracts.Remove(c);
             }
         }
@@ -1615,16 +2205,16 @@
         {
             foreach (Contract c in contractList)
             {
-
+
                 //Debug.Log(c.DateAccepted);
-                if(c.ContractState == Contract.State.Offered)
+                if (c.ContractState == Contract.State.Offered)
                 {
                     Debug.Log("Accepting: " + c.Title);
                     statusString = "Accepting: " + c.Title;
                     c.Accept();
                 }
-
-
+
+
                 //c.AutoAccept = true;
                 //c.AutoAccept = false;
             }


Go back to using PushStreamContent - it is much faster when dealing with cached files

--- Pablo.Gallery/Api/v0/Controllers/PackController.cs
+++ Pablo.Gallery/Api/v0/Controllers/PackController.cs
@@ -9,6 +9,7 @@
 using System.IO;
 using System.Threading.Tasks;
 using Pablo.Gallery.Logic.Converters;
+using Pablo.Gallery.Logic.Extractors;

 namespace Pablo.Gallery.Api.V0.Controllers
 {
@@ -71,32 +72,12 @@
 			return new FileDetail(file);
 		}

-		[HttpGet]
-		public async Task<HttpResponseMessage> Index([FromUri(Name = "id")]string packName, [FromUri(Name = "id2")] string fileName, string format, int? zoom = null, [FromUri(Name = "max-width")] int? maxWidth = null)
+
+		async Task GetStream(Stream outStream, string outFile, string packArchiveFileName, Models.File file, int? zoom, int? maxWidth)
 		{
-			fileName = Scanner.NormalizedPath(fileName);
-			var file = db.Files.FirstOrDefault(r => r.Pack.Name == packName && r.FileName == fileName);
-			if (file == null)
-				throw new HttpResponseException(HttpStatusCode.NotFound);
-
-			var raw = string.Equals(format, "raw", StringComparison.OrdinalIgnoreCase);
-
-			var packArchiveFileName = Path.Combine(Global.SixteenColorsArchiveLocation, file.Pack.NativeFileName);
-			var extractor = Logic.Extractors.ExtractorFactory.GetFileExtractor(packArchiveFileName);
-			var outFile = file.NativeFileName;
-
-			StreamContent content;
-			if (raw)
+			using (outStream)
 			{
-				content = new StreamContent(await extractor.ExtractFile(packArchiveFileName, file.FileName));
-			}
-			else
-			{
-				if (zoom != null)
-					outFile += ".z" + zoom.Value;
-				if (maxWidth != null)
-					outFile += ".x" + maxWidth.Value;
-				outFile += "." + format;
+				var extractor = ExtractorFactory.GetFileExtractor(packArchiveFileName);

 				var converter = ConverterFactory.GetConverter(file.FileName);
 				var convertInfo = new ConvertInfo
@@ -109,7 +90,46 @@
 					MaxWidth = maxWidth
 				};
 				var stream = await converter.Convert(convertInfo);
-				content = new StreamContent(stream);
+				stream.CopyTo(outStream);
+			}
+		}
+
+		async Task GetRawStream(Stream outStream, string packArchiveFileName, Models.File file)
+		{
+			using (outStream)
+			{
+				var extractor = ExtractorFactory.GetFileExtractor(packArchiveFileName);
+				var stream = await extractor.ExtractFile(packArchiveFileName, file.FileName);
+				stream.CopyTo(outStream);
+			}
+		}
+
+		[HttpGet]
+		public async Task<HttpResponseMessage> Index([FromUri(Name = "id")]string packName, [FromUri(Name = "id2")] string fileName, string format, int? zoom = null, [FromUri(Name = "max-width")] int? maxWidth = null)
+		{
+			fileName = Scanner.NormalizedPath(fileName);
+			var file = db.Files.FirstOrDefault(r => r.Pack.Name == packName && r.FileName == fileName);
+			if (file == null)
+				throw new HttpResponseException(HttpStatusCode.NotFound);
+
+			var raw = string.Equals(format, "raw", StringComparison.OrdinalIgnoreCase);
+
+			var packArchiveFileName = Path.Combine(Global.SixteenColorsArchiveLocation, file.Pack.NativeFileName);
+			var outFile = file.NativeFileName;
+
+			HttpContent content;
+			if (raw)
+			{
+				content = new PushStreamContent((s, hc, t) => GetRawStream(s, packArchiveFileName, file));
+			}
+			else
+			{
+				if (zoom != null)
+					outFile += ".z" + zoom.Value;
+				if (maxWidth != null)
+					outFile += ".x" + maxWidth.Value;
+				outFile += "." + format;
+				content = new PushStreamContent((s, hc, t) => GetStream(s, outFile, packArchiveFileName, file, zoom, maxWidth));
 			}

 			var mediaType = GetMediaType(format);


Move null check on StringSet to top of ReadString method

This way, if it's null, it will blow up before we read the encoded length of the string.

--- PerformanceTypes/ReusableStream.BinaryReadWrite.cs
+++ PerformanceTypes/ReusableStream.BinaryReadWrite.cs
@@ -275,6 +275,11 @@
         /// <returns>The string read from the stream.</returns>
         public unsafe string ReadString(bool nullable, Encoding encoding = null, StringSetOptions? setOptions = null)
         {
+            var stringSetOptions = setOptions ?? _defaultStringSetOptions;
+            var set = StringSet;
+            if (stringSetOptions.MaxEncodedSizeToLookupInSet > 0 && set == null)
+                throw new InvalidOperationException("StringSetOptions.MaxEncodedSizeToLookupInSet is greater than zero, but StringSet is null.");
+
             var encodedSize = (int)ReadVarUInt();

             if (encodedSize == 0)
@@ -290,10 +295,8 @@

             if (encoding == null)
                 encoding = DefaultEncoding;
-
-            var options = setOptions ?? _defaultStringSetOptions;
-
-            if (encodedSize > options.MaxEncodedSizeToLookupInSet)
+
+            if (encodedSize > stringSetOptions.MaxEncodedSizeToLookupInSet)
             {
                 // don't care about interning, just read the string
                 var str = encoding.GetString(Data, pos, encodedSize);
@@ -303,9 +306,6 @@
             }

             // we're going to use the StringSet as an intern pool
-            var set = StringSet;
-            if (set == null)
-                throw new InvalidOperationException("StringSetOptions.MaxEncodedSizeToLookupInSet is greater than zero, but StringSet is null.");

             var maxChars = encoding.GetMaxCharCount(encodedSize);
             var charBuffer = stackalloc char[maxChars];
@@ -317,7 +317,7 @@
             }

             // now that we've got the characters in a buffer, calculate the hash and see if it exists in the set
-            if (options.PerformDangerousAutoAddToSet)
+            if (stringSetOptions.PerformDangerousAutoAddToSet)
             {
                 string str;
                 set.Add(charBuffer, charsWritten, out str);


Move python kill to after stopping and removing salt service

--- CustomAction01/CustomAction01.cs
+++ CustomAction01/CustomAction01.cs
@@ -297,14 +297,14 @@
             if (bin_dir == "") bin_dir = @"C:\salt\bin";
             session.Log("bin_dir = " + bin_dir);

+            session.Log("Going to stop service salt-minion ...");
+            cutil.shellout(session, "sc stop salt-minion");
+
+            session.Log("Going to delete service salt-minion ...");
+            cutil.shellout(session, "sc delete salt-minion");
+
             session.Log("Going to kill ...");
             kill_python_exe(session);
-
-            session.Log("Going to stop service salt-minion ...");
-            cutil.shellout(session, "sc stop salt-minion");
-
-            session.Log("Going to delete service salt-minion ...");
-            cutil.shellout(session, "sc delete salt-minion");

             session.Log("Going to delete ARP registry entry ...");
             cutil.del_registry_SOFTWARE_key(session, ARPstring);


added compiler directive for validating the incoming xml against the given schema related to mono incompatibility

--- Plugins/GraphDS/IO/Implementation/XML_IO/XML_IO.cs
+++ Plugins/GraphDS/IO/Implementation/XML_IO/XML_IO.cs
@@ -363,7 +363,12 @@
             var evHandler = new ValidationEventHandler(ValidationEventHandler);
             xmlDocument.Schemas.Add(XmlSchema.Read(typeof(XML_IO).Assembly.GetManifestResourceStream("sones.Plugins.GraphDS.IOInterface.XML_IO.QueryResultSchema.xsd"), evHandler));

+            // As long as this doesn't work under mono, we can't validate the incoming xml against the given schema
+            // http://bugzilla.xamarin.com/show_bug.cgi?id=220
+#if __MonoCS__
             xmlDocument.Validate(evHandler);
+#endif
+

             var rootNode = xmlDocument.FirstChild.NextSibling;


Simplify code

Simplify code

--- WLEditor/MainForm.cs
+++ WLEditor/MainForm.cs
@@ -483,7 +483,7 @@
 						int x = (j % 4) * 16;
 						int y = (j / 4) * 16;

-						e.Graphics.FillRectangle(Brushes.DarkViolet, (j % 4) * 16 * zoom, (j / 4) * 16 * zoom, 16 * zoom, 16 * zoom);
+						e.Graphics.FillRectangle(Brushes.DarkViolet, x * zoom, y * zoom, 16 * zoom, 16 * zoom);

 						if(j == 0)
 						{


Modify Comment.ToString() to allow multiline comments.

--- SharpConfig/Comment.cs
+++ SharpConfig/Comment.cs
@@ -45,7 +45,14 @@
         /// </summary>
         public override string ToString()
         {
-            return string.Format("{0} {1}", Symbol, Value ?? string.Empty);
+            char symbol = Symbol;
+            return string.Join(
+                System.Environment.NewLine,
+                System.Array.ConvertAll(
+                    (Value ?? string.Empty).Split(new string[] { "\r\n", "\n" }, System.StringSplitOptions.None),
+                    s => string.Format("{0} {1}", symbol, s)
+                )
+            );
         }
     }
-}+}


Added documentation

Added documentation

--- SharpPhysFS/Interop.cs
+++ SharpPhysFS/Interop.cs
@@ -186,29 +186,38 @@

     public static void SetUpInterop()
     {
+      /* This method is used to dynamically load the physfs
+       * library. It works by detecting the current platform
+       * and deciding whether to use LoadLibrary/GetProcAddr
+       * on Windows or dlopen/dlsym on Linux and OSX.
+       * The the class is then scanned using reflection
+       * to populate all the callbacks with the right function
+       * pointers from the loaded library
+       */
+
       Func<string, IntPtr> loadLibrary;
       Func<IntPtr, string, IntPtr> loadSymbol;
+      string libraryName;

       IntPtr library;

       if (Environment.OSVersion.Platform == PlatformID.Win32NT)
       {
         loadLibrary = DynamicLoader.LoadLibrary;
-
         loadSymbol = DynamicLoader.GetProcAddress;
-
-        library = loadLibrary("physfs.dll");
+        libraryName = "physfs.dll";
       }
       else
       {
-        loadLibrary = n =>
-        {
-          return DynamicLoader.dlopen(n, 1);
-        };
-
+        loadLibrary = n => DynamicLoader.dlopen(n, 1);
         loadSymbol = DynamicLoader.dlsym;
-
-        library = loadLibrary("physfs.so");
+        libraryName = "physfs.so";
+      }
+
+      library = loadLibrary(libraryName);
+      if (library == IntPtr.Zero)
+      {
+        throw new PhysFSLibNotFound();
       }

       var fields = typeof(Interop).GetFields();


Added, but have not tested, a new parallelization approach.

--- Simulator/Simulator.cs
+++ Simulator/Simulator.cs
@@ -81,10 +81,75 @@
             StableStore.LoginAttempts = null;
         }

+        public static async Task ParallelRepeat(
+            ulong numberOfTimesToRepeat,
+            Action actionToRun,
+            Action<Exception> callOnException = null,
+            int maxConcurrentTasks = 1000)
+        {
+            Task[] activeTasks = new Task[maxConcurrentTasks];
+            Dictionary<Task, int> taskToIndex = new Dictionary<Task, int>();
+            HashSet<Task> exceptionHandlingTasks = new HashSet<Task>();
+
+            ulong tasksStarted = 0;
+            // Phase 1 -- start maxConcurrentTasks executing
+            while (tasksStarted < (ulong) activeTasks.Length && tasksStarted < numberOfTimesToRepeat)
+            {
+                Task startedTask = Task.Run(actionToRun);
+                activeTasks[tasksStarted] = startedTask;
+                taskToIndex[startedTask] = (int) tasksStarted;
+                tasksStarted++;
+            }
+
+            // Phase 2 -- A stable stat in which there are always the maximum number of tasks
+            //            in our array of active tasks
+            while (tasksStarted < numberOfTimesToRepeat)
+            {
+                // Wait for a task to complete
+                Task completedTask = await Task.WhenAny(activeTasks.ToArray());
+                int indexOfTaskToReplace = taskToIndex[completedTask];
+                // Replace the task that completed with a new task...
+                // If there was an exception, the replacement should be a task to handle
+                // that exception.  Otherwise, it should be the next work item.
+                bool callExceptionHandler = false;
+                if (callOnException != null)
+                {
+                    bool completedTaskWasExceptionHandler = exceptionHandlingTasks.Contains(completedTask);
+                    // We'll want to run a task with the caller's exception handler...
+                    callExceptionHandler = completedTask.IsFaulted;
+                    if (completedTaskWasExceptionHandler)
+                    {
+                        // unless it was the caller's exception handler that faulted
+                        exceptionHandlingTasks.Remove(completedTask);
+                        callExceptionHandler = false;
+                    }
+                }
+                Task replacementTask = callExceptionHandler
+                    ? Task.Run(() => callOnException(completedTask.Exception))
+                    : Task.Run(actionToRun);
+                // Put the replacement task at the same index in the array as the prior task
+                activeTasks[indexOfTaskToReplace] = replacementTask;
+                taskToIndex.Remove(completedTask);
+                taskToIndex[replacementTask] = indexOfTaskToReplace;
+                tasksStarted++;
+            }
+
+            // Phase 3 -- A final phase in which we empty out exceptions
+            Task.WaitAll(activeTasks);
+            if (callOnException != null)
+            {
+                foreach (Task exceptionTask in activeTasks.Where(t => t.IsFaulted))
+                    #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
+                    Task.Run(() => callOnException(exceptionTask.Exception));
+            }
+        }
+

         public static async Task RunWithMaxDegreeOfConcurrency<T>(
-   int maxDegreeOfConcurrency, IEnumerable<T> collection, Func<T, Task> taskFactory)
+            int maxDegreeOfConcurrency,
+            IEnumerable<T> collection,
+            Func<T, Task> taskFactory)
         {
             var activeTasks = new List<Task>(maxDegreeOfConcurrency);
             foreach (var task in collection.Select(taskFactory))


[tests,Test5] Demonstrate how to publish the C runtime library for VisualC next to the binary

--- tests/Test5/bam/Scripts/Test5.cs
+++ tests/Test5/bam/Scripts/Test5.cs
@@ -28,6 +28,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #endregion // License
 using Bam.Core;
+using System.Linq;
 namespace Test5
 {
     sealed class MyDynamicLibTestApp :
@@ -73,6 +74,16 @@

             var app = this.Include<MyDynamicLibTestApp>(C.ConsoleApplication.Key, EPublishingType.ConsoleApplication);
             this.Include<Test4.MyDynamicLib>(C.DynamicLibrary.Key, ".", app);
+
+            // copy the required runtime library next to the binary
+            if (this.BuildEnvironment.Platform.Includes(Bam.Core.EPlatform.Windows) &&
+                this.BuildEnvironment.Configuration != EConfiguration.Debug &&
+                (app.Module as MyDynamicLibTestApp).Linker is VisualCCommon.LinkerBase)
+            {
+                var visualCPackage = Bam.Core.Graph.Instance.Packages.Where(item => item.Name == "VisualC").First();
+                var runtimeLibrary = visualCPackage.MetaData as VisualCCommon.IRuntimeLibraryPathMeta;
+                this.IncludeFile(runtimeLibrary.MSVCR((app.Module as MyDynamicLibTestApp).BitDepth), ".", app);
+            }
         }
     }


Added extra unit test for the xc coder.

Added extra unit test for the xc coder.

--- tests/Magick.NET.Tests/Coders/TheXcCoder.cs
+++ tests/Magick.NET.Tests/Coders/TheXcCoder.cs
@@ -20,10 +20,19 @@
         [Fact]
         public void ShouldHandleSrgbaColor()
         {
-            using (var image = new MagickImage("xc:srgba(255,0,0,1", 1, 1))
+            using (var image = new MagickImage("xc:srgba(255,0,0,1)", 1, 1))
             {
                 ColorAssert.Equal(MagickColors.Red, image, 0, 0);
             }
         }
+
+        [Fact]
+        public void ShouldHandleRgbColor()
+        {
+            using (var image = new MagickImage("xc:rgb(0,50%,0)", 1, 1))
+            {
+                ColorAssert.Equal(new MagickColor("#000080000000"), image, 0, 0);
+            }
+        }
     }
 }


(#66) Set syncItems to true always

(#66) Set syncItems to true always

--- client/xamarin.forms/ZUMOAPPNAME/TodoList.xaml.cs
+++ client/xamarin.forms/ZUMOAPPNAME/TodoList.xaml.cs
@@ -34,7 +34,7 @@
             base.OnAppearing();

             // Set syncItems to true in order to synchronize the data on startup when running in offline mode
-            await RefreshItems(true, syncItems: false);
+            await RefreshItems(true, syncItems: true);
         }

         // Data methods


Fixed unicode encoding of HTML fragment

Fixed unicode encoding of HTML fragment

--- clients/v1/csharp/samples/merge_to_pdf/Program.cs
+++ clients/v1/csharp/samples/merge_to_pdf/Program.cs
@@ -1,85 +1,106 @@
-using Muhimbi.PDF.Online.Client.Api;
-using Muhimbi.PDF.Online.Client.Client;
-using Muhimbi.PDF.Online.Client.Model;
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Net;
-
-namespace sample
-{
-    class Program
-    {
-        // !!!! ENTER YOUR API KEY HERE !!!!
-        static string API_KEY = "";
-
-        static void Main(string[] args)
-        {
-            string testFile = null;
-
-            try
-            {
-                // ** Make sure an api key has been entered
-                if (API_KEY == string.Empty)
-                {
-                    Console.WriteLine("[ERROR] Please update the sample code and enter the API Key that came with your subscription.");
-                    return;
-                }
-
-                // ** Was a 'file to merge' specified on the command line?
-                if (args.Count() == 0)
-                {
-                    Console.WriteLine("[INFO] No file to merge specified, using default file.");
-                    testFile = Directory.GetFiles(".", "*.doc")[0];
-                }
-                else
-                    testFile = args[0];
-
-                // ** Specify the API key associated with your subscription.
-                Configuration.Default.AddApiKey("api_key", API_KEY);
-
-                // ** Accept all SSL Certificates, this makes life under mono a lot easier. This line is not needed on Windows
-                ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
-
-                // ** The service's host name is already set, but for debugging purposes you may want to switch between 'http' and 'https'.'
-                Configuration.Default.ApiClient.RestClient.BaseUrl = new Uri("https://api.muhimbi.com/api");
-
-                // ** We are dealing with merging, so instantiate the relevant class
-                MergeApi mergeApi = new MergeApi();
-
-                // ** Read the file we wish to Merge
-                byte[] sourceFile = File.ReadAllBytes(testFile);
-
-                // ** Fill out the data for the merge operation.
-                MergeToPdfData inputData = new MergeToPdfData(
-                    SourceFileName1: testFile + ";true;" + testFile,                                            // ** The name of the file to merge, always include the correct extension.
-                                                                                //    Optionally add ';true' to auto generate PDF bookmarks based on document structure,
-                                                                                //    optionally followed by a ';' and the PDF bookmark name of the document.
-                    SourceFileContent1: sourceFile,                                                             // ** Content of the file to merge.
-                    SourceFileName2: "test.html;true;Some HTML content",                                        // ** The same again, but as we are merging in HTML content, use a name with '.html' extension.
-                    SourceFileContent2: System.Text.Encoding.Unicode.GetBytes("
Merged HTML Content
"),  // ** HTML or URL to convert and merge.
-                    SourceFileName3: testFile + ";true;" + testFile + " (again).",                              // ** The same again for the 3rd file.
-                    SourceFileContent3: sourceFile,                                                             // ** Content of the 3rd file to merge.
-                    DocumentStartPage: MergeToPdfData.DocumentStartPageEnum.Nextpage                            // ** On what page should each merged document start (important for double sided docs and printing).
-                );
-
-                // ** Carry out the merge operation
-                Console.WriteLine("[INFO] Merging...");
-                var response = mergeApi.MergeToPdf(inputData);
-
-                // ** Write the results back to the file system
-                File.WriteAllBytes(@"result.pdf", response.ProcessedFileContent);
-
-                Console.WriteLine("[INFO] 'result.pdf' written to output folder.");
-
-                // ** On Windows open the generated file in the system PDF viewer
-                Process.Start(@"result.pdf");
-            }
-            catch (Exception ex)
-            {
-                Console.WriteLine(ex.ToString());
-            }
-        }
-    }
-}
+using Muhimbi.PDF.Online.Client.Api;
+using Muhimbi.PDF.Online.Client.Client;
+using Muhimbi.PDF.Online.Client.Model;
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+
+namespace sample
+{
+    class Program
+    {
+        // !!!! ENTER YOUR API KEY HERE !!!!
+        static string API_KEY = "";
+
+        static void Main(string[] args)
+        {
+            string testFile = null;
+
+            try
+            {
+                // ** Make sure an api key has been entered
+                if (API_KEY == string.Empty)
+                {
+                    Console.WriteLine("[ERROR] Please update the sample code and enter the API Key that came with your subscription.");
+                    return;
+                }
+
+                // ** Was a 'file to merge' specified on the command line?
+                if (args.Count() == 0)
+                {
+                    Console.WriteLine("[INFO] No file to merge specified, using default file.");
+                    testFile = Directory.GetFiles(".", "*.doc")[0];
+                }
+                else
+                    testFile = args[0];
+
+                // ** Specify the API key associated with your subscription.
+                Configuration.Default.AddApiKey("api_key", API_KEY);
+
+                // ** Accept all SSL Certificates, this makes life under mono a lot easier. This line is not needed on Windows
+                ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
+
+                // ** The service's host name is already set, but for debugging purposes you may want to switch between 'http' and 'https'.'
+                Configuration.Default.ApiClient.RestClient.BaseUrl = new Uri("https://api.muhimbi.com/api");
+
+                // ** We are dealing with merging, so instantiate the relevant class
+                MergeApi mergeApi = new MergeApi();
+
+                // ** Read the file we wish to Merge
+                byte[] sourceFile = File.ReadAllBytes(testFile);
+
+                // ** Fill out the data for the merge operation.
+                MergeToPdfData inputData = new MergeToPdfData(
+                    SourceFileName1: testFile + ";true;" + testFile,                                            // ** The name of the file to merge, always include the correct extension.
+                                                                                //    Optionally add ';true' to auto generate PDF bookmarks based on document structure,
+                                                                                //    optionally followed by a ';' and the PDF bookmark name of the document.
+                    SourceFileContent1: sourceFile,                                                             // ** Content of the file to merge.
+                    SourceFileName2: "test.html;true;Some HTML content",                                        // ** The same again, but as we are merging in HTML content, use a name with '.html' extension.
+                    SourceFileContent2: GetUnicodeBytesWithBom("
Merged HTML Content
"),          // ** HTML or URL to convert and merge.
+                    SourceFileName3: testFile + ";true;" + testFile + " (again).",                              // ** The same again for the 3rd file.
+                    SourceFileContent3: sourceFile,                                                             // ** Content of the 3rd file to merge.
+                    DocumentStartPage: MergeToPdfData.DocumentStartPageEnum.Nextpage                            // ** On what page should each merged document start (important for double sided docs and printing).
+                );
+
+                // ** Carry out the merge operation
+                Console.WriteLine("[INFO] Merging...");
+                var response = mergeApi.MergeToPdf(inputData);
+
+                // ** Write the results back to the file system
+                File.WriteAllBytes(@"result.pdf", response.ProcessedFileContent);
+
+                Console.WriteLine("[INFO] 'result.pdf' written to output folder.");
+
+                // ** On Windows open the generated file in the system PDF viewer
+                Process.Start(@"result.pdf");
+            }
+            catch (Exception ex)
+            {
+                Console.WriteLine(ex.ToString());
+            }
+        }
+
+        ///
+        /// Helper function to get the text as a byte array and add the 'Unicode Byte Order Mark'
+        /// See https://www.w3.org/International/questions/qa-byte-order-mark.
+        ///
+        protected static byte[] GetUnicodeBytesWithBom(string text)
+        {
+            // Use BOM when encoding
+            Encoding encodingWithBom = new UnicodeEncoding(false, true);
+
+            // Concatenate BOM bytes with content bytes
+            byte[] bom = encodingWithBom.GetPreamble();
+            byte[] content = encodingWithBom.GetBytes(text);
+            byte[] bytes = new byte[bom.Length + content.Length];
+            Buffer.BlockCopy(bom, 0, bytes, 0, bom.Length);
+            Buffer.BlockCopy(content, 0, bytes, bom.Length, content.Length);
+
+            return bytes;
+        }
+
+    }
+}


Added a mock RNG

Added a mock RNG

--- Source/Math/IRandom.cs
+++ Source/Math/IRandom.cs
@@ -192,4 +192,37 @@
             return null;
         }
     }
+
+    /// <summary>
+    /// Mock implementation of IRandom that produces values from the specified lists.
+    /// </summary>
+    public class RandomMock : IRandom
+    {
+        private const float UINT_MUL = (1.0f / 4294967296.0f);
+
+        public IList<uint> uints;
+        public int index;
+
+        public RandomMock (IList<uint> uints) {
+            this.uints = uints;
+        }
+
+        /// </inheritDoc>
+        public void Init (uint seed) {
+            // no op
+        }
+
+        /// </inheritDoc>
+        public uint Generate () {
+            uint result = uints[index++];
+            if (index >= uints.Count) { index = 0; }
+            return result;
+        }
+
+        /// </inheritDoc>
+        public float GenerateFloat () {
+            uint result = Generate();
+            return result * UINT_MUL;
+        }
+    }
 }


Fix console prints before font loading

Fix console prints before font loading

Printing a console message before the font has loaded (in game
initialization, for example) would cause ConsoleItem to throw a
NullReferenceException

--- Client/DeveloperConsole.cs
+++ Client/DeveloperConsole.cs
@@ -35,7 +35,7 @@
             ci.lifetime = Math.Min(5f + (text.Length * 0.05f), 30f);
             ci.opacity = 1f;
             ci.message = text; //Globals.WrapText(Globals.fontConsole, text, 800);
-            ci.height = (int)Assets.fontDefault.MeasureString(ci.message).Y;
+            ci.height = -1;
             ci.color = error ? Color.FromNonPremultiplied(255, 96, 96, 255) : Color.White;
             msgs.Add(ci);
         }
@@ -63,6 +63,8 @@
                 }

                 for (int i = 0; i < msgs.Count; i++) {
+                    if (msgs[i].height == -1)
+                        msgs[i].height = (int)Assets.fontDefault.MeasureString(msgs[i].message).Y;
                     spriteBatch.DrawString(Assets.fontDefault, msgs[i].message, new Vector2(9, y + 1), Color.Black * msgs[i].opacity);
                     spriteBatch.DrawString(Assets.fontDefault, msgs[i].message, new Vector2(8, y), msgs[i].color * msgs[i].opacity);
                     y += (msgs[i].height + 2); // (int)((msgs[i].height + 2) * msgs[i].opacity);


Recreate kerbals missing from vessels. Accidently wiped this workaround in the 31573de1a58c3dcaf875f146cbb298a2bc91f16b commit.

--- Client/KerbalReassigner.cs
+++ Client/KerbalReassigner.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Reflection;

 namespace DarkMultiPlayer
 {
@@ -9,6 +10,8 @@
         private bool registered = false;
         private Dictionary<Guid, List<string>> vesselToKerbal = new Dictionary<Guid, List<string>>();
         private Dictionary<string, Guid> kerbalToVessel = new Dictionary<string, Guid>();
+        private delegate bool AddCrewMemberToRosterDelegate(ProtoCrewMember pcm);
+        private AddCrewMemberToRosterDelegate AddCrewMemberToRoster;

         public static KerbalReassigner fetch
         {
@@ -157,6 +160,9 @@
                     else
                     {
                         takenKerbals.Add(currentKerbalName);
+                        CreateKerbalIfMissing(currentKerbalName, protovesselID);
+                        HighLogic.CurrentGame.CrewRoster[currentKerbalName].rosterStatus = ProtoCrewMember.RosterStatus.Assigned;
+                        HighLogic.CurrentGame.CrewRoster[currentKerbalName].seatIdx = crewIndex;
                     }
                     crewIndex++;
                 }
@@ -168,6 +174,27 @@
             }
         }

+        public void CreateKerbalIfMissing(string kerbalName, Guid vesselID)
+        {
+            if (!HighLogic.CurrentGame.CrewRoster.Exists(kerbalName))
+            {
+                if (AddCrewMemberToRoster == null)
+                {
+                    MethodInfo addMemberToCrewRosterMethod = typeof(KerbalRoster).GetMethod("AddCrewMember", BindingFlags.NonPublic | BindingFlags.Instance);
+                    AddCrewMemberToRoster = (AddCrewMemberToRosterDelegate)Delegate.CreateDelegate(typeof(AddCrewMemberToRosterDelegate), HighLogic.CurrentGame.CrewRoster, addMemberToCrewRosterMethod);
+                    if (AddCrewMemberToRoster == null)
+                    {
+                        throw new Exception("Failed to load AddCrewMember delegate!");
+                    }
+                }
+                ProtoCrewMember pcm = CrewGenerator.RandomCrewMemberPrototype(ProtoCrewMember.KerbalType.Crew);
+                pcm.name = kerbalName;
+                pcm.rosterStatus = ProtoCrewMember.RosterStatus.Assigned;
+                AddCrewMemberToRoster(pcm);
+                DarkLog.Debug("Created kerbal " + pcm.name + " for vessel " + vesselID + ", Kerbal was missing");
+            }
+        }
+
         public static void Reset()
         {
             lock (Client.eventLock)


SteamWeb.GetSteamId64().

--- SteamTrade/SteamWeb.cs
+++ SteamTrade/SteamWeb.cs
@@ -256,7 +256,7 @@
             {
                 throw new CryptographicException("Missing RSA key.");
             }
-
+
             byte[] encryptedPasswordBytes;
             using (var rsaEncryptor = new RSACryptoServiceProvider())
             {
@@ -518,14 +518,27 @@
         {
             return true;
         }
+        /// <summary>
+        /// Gets Steam ID from Cookies collection.
+        /// </summary>
+        /// <returns>64 bit Steam ID.</returns>
         public long GetSteamId64()
         {
-            var steamLoginCookie = Cookies.GetCookies(new Uri("https://steamcommunity.com")).Cast<Cookie>().FirstOrDefault(c => c.Name == "steamLogin");
+            var steamLoginCookie = Cookies.GetCookies(new Uri("https://steamcommunity.com")).Cast<Cookie>().FirstOrDefault(c => c.Name == "steamLogin") ?? Cookies.GetCookies(new Uri("https://steamcommunity.com")).Cast<Cookie>().FirstOrDefault(c => c.Name == "steamLoginSecure");
+            string value;
+            int index;
+            long steamId64;
             if (steamLoginCookie == null)
-                return default(long);
-            var value = steamLoginCookie.Value;
-            var index = value.IndexOf('%');
-            return long.TryParse(value.Substring(0, index), out var steamId64) ? steamId64 : throw new Exceptions.SteamWebNotLoggedInException();
+            {
+                var machineAuthCookie = Cookies.GetCookies(new Uri("https://steamcommunity.com")).Cast<Cookie>().FirstOrDefault(c => c.Name == "steamMachineAuth");
+                if (machineAuthCookie == null) return default;
+                value = machineAuthCookie.Value;
+                index = value.IndexOf('=');
+                return long.TryParse(value.Substring(0, index), out steamId64) ? steamId64 : throw new Exceptions.SteamWebNotLoggedInException();
+            }
+            value = steamLoginCookie.Value;
+            index = value.IndexOf('%');
+            return long.TryParse(value.Substring(0, index), out steamId64) ? steamId64 : throw new Exceptions.SteamWebNotLoggedInException();
         }
     }


[ClrPhTester] Support sxs redirection due to .manifest file in same folder

--- ClrPhTester/SxsManifest.cs
+++ ClrPhTester/SxsManifest.cs
@@ -128,6 +128,18 @@
             SxsEntries Entries = new SxsEntries();

             string RootPeFolder = Path.GetDirectoryName(Pe.Filepath);
+
+            // Look for overriding manifest file (named "{$name}.manifest)
+            string OverridingManifest = String.Format("{0:s}.manifest", Pe.Filepath);
+            if (File.Exists(OverridingManifest))
+            {
+                return ExtractDependenciesFromSxsManifestFile(
+                    OverridingManifest,
+                    RootPeFolder
+                );
+            }
+
+            // Retrieve embedded manifest
             string PeManifest = Pe.GetManifest();
             if (PeManifest.Length == 0)
                 return Entries;


Added SetScale methods, renamed Set methods to SetPosition

--- TransformExtensions.cs
+++ TransformExtensions.cs
@@ -1,7 +1,8 @@
 using UnityEngine;
 using System.Collections;

-public static class TransformExtensions {
+public static class TransformExtensions
+{

 	// Apply a transformation resembling a parenting relationship without setting up an actual parenting hierarchy
 	public static void SoftParent (this Transform child, Transform parent)
@@ -17,19 +18,16 @@
 		child.localScale.Scale (parent.localScale);
 	}

-
 	public static Transform FindParent (this Transform transform, string name)
 	{
 		Transform current = transform;
-		while (current.parent)
-		{
+		while (current.parent) {
 			current = current.parent;
 			if (current.name == name)
 				return current;
 		}
 		return null;
 	}
-

 	public static Transform FindSibling (this Transform transform, string name)
 	{
@@ -38,12 +36,10 @@
 		return null;
 	}

-
 	public static Transform FindFromRoot (this Transform transform, string name)
 	{
 		return transform.root.Find (name);
 	}
-

 	public static T GetComponentInParent<T> (this Transform transform)
 		where T : Component
@@ -58,22 +54,35 @@
 		return null;
 	}

+	public static void SetScaleX (this Transform trans, float value)
+	{
+		trans.localScale = new Vector3 (value, trans.localScale.y, trans.localScale.z);
+	}

-	public static void SetX (this Transform trans, float value)
+	public static void SetScaleY (this Transform trans, float value)
+	{
+		trans.localScale = new Vector3 (trans.localScale.x, value, trans.localScale.z);
+	}
+
+	public static void SetScaleZ (this Transform trans, float value)
+	{
+		trans.localScale = new Vector3 (trans.localScale.x, trans.localScale.y, value);
+	}
+
+	public static void SetPositionX (this Transform trans, float value)
 	{
 		trans.position = new Vector3 (value, trans.position.y, trans.position.z);
 	}

-	public static void SetY (this Transform trans, float value)
+	public static void SetPositionY (this Transform trans, float value)
 	{
 		trans.position = new Vector3 (trans.position.x, value, trans.position.z);
 	}

-	public static void SetZ (this Transform trans, float value)
+	public static void SetPositionZ (this Transform trans, float value)
 	{
 		trans.position = new Vector3 (trans.position.x, trans.position.y, value);
 	}
-

 	public static void SnapTo (this Transform self, Transform target)
 	{


Fix a race in SnippetCompiler by using a unique temporary directory for each compile.

--- Try/SnippetCompiler.cs
+++ Try/SnippetCompiler.cs
@@ -103,6 +103,7 @@
         public const int MaxPendingCompiles = 4;

         public static int NextDomainId = 0;
+        public static int NextTempDirId = 0;
         public static int PendingCompiles = 0;
         public static readonly AssemblyCache AssemblyCache = new AssemblyCache();
         public static volatile TypeInfoProvider TypeInfo = null;
@@ -174,139 +175,140 @@
                 OriginalSource = csharp
             };

-            var tempPath = Path.Combine(Path.GetTempPath(), "JSIL.Try");
-
-            if (Directory.Exists(tempPath)) {
+            int tempDirId = Interlocked.Increment(ref NextTempDirId);
+            var tempPath = Path.Combine(Path.GetTempPath(), "JSIL.Try", tempDirId.ToString());
+
+            if (!Directory.Exists(tempPath))
+                Directory.CreateDirectory(tempPath);
+
+            try {
+                string resultPath, entryPointName, compilerOutput, resultFullName;
+
+                long compileStarted = DateTime.UtcNow.Ticks;
+
+                CompileAssembly(
+                    tempPath, csharp,
+                    out compilerOutput, out resultPath,
+                    out resultFullName, out entryPointName
+                );
+
+                result.CompileElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - compileStarted).TotalSeconds;
+
+                if ((resultPath == null) || !File.Exists(resultPath)) {
+                    if (String.IsNullOrWhiteSpace(compilerOutput))
+                        throw new Exception("Compile failed with unknown error.");
+                    else
+                        throw new Exception(compilerOutput);
+                }
+
+                var translatorConfiguration = new Configuration {
+                    ApplyDefaults = false,
+                    Assemblies = {
+                        Stubbed = {
+                            "mscorlib,",
+                            "System.*",
+                            "Microsoft.*"
+                        },
+                        Ignored = {
+                            "Microsoft.VisualC,",
+                            "Accessibility,",
+                            "SMDiagnostics,",
+                            "System.EnterpriseServices,",
+                            "JSIL.Meta,"
+                        }
+                    },
+                    FrameworkVersion = 4.0,
+                    GenerateSkeletonsForStubbedAssemblies = false,
+                    GenerateContentManifest = false,
+                    IncludeDependencies = false,
+                    UseSymbols = true,
+                    UseThreads = false
+                };
+
+                var translatorOutput = new StringBuilder();
+
+                var typeInfo = TypeInfo;
+
+                using (var translator = new AssemblyTranslator(
+                    translatorConfiguration,
+                    // Reuse the cached type info provider, if one exists.
+                    typeInfo,
+                    // Can't reuse a manifest meaningfully here.
+                    null,
+                    // Reuse the assembly cache so that mscorlib doesn't get loaded every time.
+                    AssemblyCache
+                )) {
+                    translator.CouldNotDecompileMethod += (s, exception) => {
+                        lock (translatorOutput)
+                            translatorOutput.AppendFormat(
+                                "Could not decompile method '{0}': {1}{2}",
+                                s, exception.Message, Environment.NewLine
+                            );
+                    };
+
+                    translator.CouldNotResolveAssembly += (s, exception) => {
+                        lock (translatorOutput)
+                            translatorOutput.AppendFormat(
+                                "Could not resolve assembly '{0}': {1}{2}",
+                                s, exception.Message, Environment.NewLine
+                            );
+                    };
+
+                    translator.Warning += (s) => {
+                        lock (translatorOutput)
+                            translatorOutput.AppendLine(s);
+                    };
+
+                    var translateStarted = DateTime.UtcNow.Ticks;
+                    var translationResult = translator.Translate(resultPath, true);
+
+                    AssemblyTranslator.GenerateManifest(
+                        translator.Manifest, Path.GetDirectoryName(resultPath), translationResult
+                    );
+
+                    result.EntryPoint = String.Format(
+                        "{0}.{1}",
+                        translator.Manifest.GetPrivateToken(resultFullName).IDString,
+                        entryPointName
+                    );
+
+                    result.Warnings = translatorOutput.ToString().Trim();
+                    result.TranslateElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - translateStarted).TotalSeconds;
+                    result.JavaScript = translationResult.WriteToString();
+
+                    if (typeInfo != null) {
+                        // Remove the temporary assembly from the type info provider.
+                        typeInfo.Remove(translationResult.Assemblies.ToArray());
+                    } else {
+                        // We didn't have a type info provider to reuse, so store the translator's.
+                        typeInfo = translator.GetTypeInfoProvider();
+                        // We need to do a compare-exchange since another thread may have already made a provider.
+                        Interlocked.CompareExchange(ref TypeInfo, typeInfo, null);
+                    }
+
+                    /*
+                    result.Warnings += String.Format(
+                        "{1} assemblies loaded{0}",
+                        Environment.NewLine, AppDomain.CurrentDomain.GetAssemblies().Length
+                    );
+                     */
+
+                    /*
+                    result.Warnings += String.Format(
+                        "TypeInfo.Count = {1}{0}AssemblyCache.Count = {2}{0}",
+                        Environment.NewLine, TypeInfo.Count, AssemblyCache.Count
+                    );
+                        */
+                }
+
+                return result;
+            } finally {
                 try {
                     Directory.Delete(tempPath, true);
                 } catch (Exception exc) {
                     Console.WriteLine("Failed to empty temporary directory: {0}", exc.Message);
                 }
             }
-
-            if (!Directory.Exists(tempPath))
-                Directory.CreateDirectory(tempPath);
-
-            string resultPath, entryPointName, compilerOutput, resultFullName;
-
-            long compileStarted = DateTime.UtcNow.Ticks;
-
-            CompileAssembly(
-                tempPath, csharp,
-                out compilerOutput, out resultPath,
-                out resultFullName, out entryPointName
-            );
-
-            result.CompileElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - compileStarted).TotalSeconds;
-
-            if ((resultPath == null) || !File.Exists(resultPath)) {
-                if (String.IsNullOrWhiteSpace(compilerOutput))
-                    throw new Exception("Compile failed with unknown error.");
-                else
-                    throw new Exception(compilerOutput);
-            }
-
-            var translatorConfiguration = new Configuration {
-                ApplyDefaults = false,
-                Assemblies = {
-                    Stubbed = {
-                        "mscorlib,",
-                        "System.*",
-                        "Microsoft.*"
-                    },
-                    Ignored = {
-                        "Microsoft.VisualC,",
-                        "Accessibility,",
-                        "SMDiagnostics,",
-                        "System.EnterpriseServices,",
-                        "JSIL.Meta,"
-                    }
-                },
-                FrameworkVersion = 4.0,
-                GenerateSkeletonsForStubbedAssemblies = false,
-                GenerateContentManifest = false,
-                IncludeDependencies = false,
-                UseSymbols = true,
-                UseThreads = false
-            };
-
-            var translatorOutput = new StringBuilder();
-
-            var typeInfo = TypeInfo;
-
-            using (var translator = new AssemblyTranslator(
-                translatorConfiguration,
-                // Reuse the cached type info provider, if one exists.
-                typeInfo,
-                // Can't reuse a manifest meaningfully here.
-                null,
-                // Reuse the assembly cache so that mscorlib doesn't get loaded every time.
-                AssemblyCache
-            )) {
-                translator.CouldNotDecompileMethod += (s, exception) => {
-                    lock (translatorOutput)
-                        translatorOutput.AppendFormat(
-                            "Could not decompile method '{0}': {1}{2}",
-                            s, exception.Message, Environment.NewLine
-                        );
-                };
-
-                translator.CouldNotResolveAssembly += (s, exception) => {
-                    lock (translatorOutput)
-                        translatorOutput.AppendFormat(
-                            "Could not resolve assembly '{0}': {1}{2}",
-                            s, exception.Message, Environment.NewLine
-                        );
-                };
-
-                translator.Warning += (s) => {
-                    lock (translatorOutput)
-                        translatorOutput.AppendLine(s);
-                };
-
-                var translateStarted = DateTime.UtcNow.Ticks;
-                var translationResult = translator.Translate(resultPath, true);
-
-                AssemblyTranslator.GenerateManifest(
-                    translator.Manifest, Path.GetDirectoryName(resultPath), translationResult
-                );
-
-                result.EntryPoint = String.Format(
-                    "{0}.{1}",
-                    translator.Manifest.GetPrivateToken(resultFullName).IDString,
-                    entryPointName
-                );
-
-                result.Warnings = translatorOutput.ToString().Trim();
-                result.TranslateElapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - translateStarted).TotalSeconds;
-                result.JavaScript = translationResult.WriteToString();
-
-                if (typeInfo != null) {
-                    // Remove the temporary assembly from the type info provider.
-                    typeInfo.Remove(translationResult.Assemblies.ToArray());
-                } else {
-                    // We didn't have a type info provider to reuse, so store the translator's.
-                    typeInfo = translator.GetTypeInfoProvider();
-                    // We need to do a compare-exchange since another thread may have already made a provider.
-                    Interlocked.CompareExchange(ref TypeInfo, typeInfo, null);
-                }
-
-                /*
-                result.Warnings += String.Format(
-                    "{1} assemblies loaded{0}",
-                    Environment.NewLine, AppDomain.CurrentDomain.GetAssemblies().Length
-                );
-                 */
-
-                /*
-                result.Warnings += String.Format(
-                    "TypeInfo.Count = {1}{0}AssemblyCache.Count = {2}{0}",
-                    Environment.NewLine, TypeInfo.Count, AssemblyCache.Count
-                );
-                    */
-            }
-
-            return result;
         }
     }
 }


This seems to be WAY more stable.

This seems to be WAY more stable.

--- TwitchModel/Program.cs
+++ TwitchModel/Program.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using System.Net.Http;
 using System.Net.Http.Headers;
 using System.Threading;
@@ -74,22 +75,14 @@
             Logger.Debug(args.Thing.ID + " - " + (args.Thing.Boolean("live") ? "Online" : "Offline"));
         }

-        private static void UpdateApi(Object bcaster)
+        private static async Task UpdateApi(string broadcaster)
         {
-            var broadcaster = (String) bcaster;
-
-            var streamTask = GetStream(broadcaster);
-            streamTask.Wait(5000);
-
-            var streamObject = streamTask.Result;
+            var streamObject = await GetStream(broadcaster);
             if (streamObject == null) return;

             var live = (streamObject.stream != null);

-            var channelTask = GetChannel(broadcaster);
-            channelTask.Wait(5000);
-
-            var channelObject = channelTask.Result;
+            var channelObject = await GetChannel(broadcaster);
             if (channelObject == null) return;

             if (!live)
@@ -119,18 +112,15 @@
             Warehouse.Events.OnNew += LogEvent;
             Warehouse.Events.OnUpdate += LogEvent;

-            var timers = new List<Timer>();
-
-            foreach (var broadcaster in Configuration.Broadcasters)
+            var timer = new Timer(delegate
             {
-                timers.Add(new Timer(UpdateApi, broadcaster, 5000, 30000));
-                Thread.Sleep(1000);
-            }
+                var tasks = Configuration.Broadcasters.Select(UpdateApi).ToList();
+                Task.WaitAll(tasks.ToArray(), 10000);
+            }, null, 0, 10000);

             Console.CancelKeyPress += delegate
             {
-                foreach (var t in timers)
-                    t.Dispose();
+                timer.Dispose();

                 Client.Close();
             };


Changed JSON formatter to not do self-reference loops!

--- UI.MVC4/Global.asax.cs
+++ UI.MVC4/Global.asax.cs
@@ -6,6 +6,7 @@
 using System.Web.Mvc;
 using System.Web.Optimization;
 using System.Web.Routing;
+using Newtonsoft.Json;

 namespace UI.MVC4
 {
@@ -23,6 +24,9 @@
             RouteConfig.RegisterRoutes(RouteTable.Routes);
             BundleConfig.RegisterBundles(BundleTable.Bundles);
             AuthConfig.RegisterAuth();
+
+            //Turns off self reference looping when serializing models in API controlllers
+            GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
         }
     }
 }


Fixed mixed line endings.

Fixed mixed line endings.

--- UnitTests/TestSuite.cs
+++ UnitTests/TestSuite.cs
@@ -2226,7 +2226,7 @@
             Console.Out.WriteLine("PayloadBytes = {0}", BitConverter.ToString(test));

             //then
-            Assert.That(test, Is.EquivalentTo(new byte[] { 1, 2, 3, 4, 3, 2, 1 }));
+            Assert.That(test, Is.EquivalentTo(new byte[] { 1, 2, 3, 4, 3, 2, 1 }));
         }

         [Test]


Refactored Request / Response handling into there own methods

--- VndbSharp/VndbUtils.cs
+++ VndbSharp/VndbUtils.cs
@@ -31,60 +31,75 @@
             if (VndbUtils._lastTime ==null && DateTime.Now - VndbUtils._lastTime < TimeSpan.FromSeconds(60))
                 return null; //should we send a message of "too many requests" or similar here instead of null?

-            var request = (HttpWebRequest)WebRequest.Create(dumpUrl);
-            request.Method = WebRequestMethods.Http.Get;
-            request.Timeout = 20000;
-            request.Proxy = null;
-            request.UserAgent = $"{VndbUtils.ClientName} (v{VndbUtils.Version})";
+	        var request = VndbUtils.GetRequest(dumpUrl);
+	        var response = await VndbUtils.GetResponseAsync(request).ConfigureAwait(false);

-            HttpWebResponse response = null;
-            Stream responseStream = null;
-            MemoryStream responseContent = null;
+	        if (response == null)
+				return null;

-            try
-            {
-                response = (HttpWebResponse)await request.GetResponseAsync().ConfigureAwait(false);
-                responseStream = response.GetResponseStream();
-                responseContent = new MemoryStream();
+			VndbUtils._lastTime = DateTime.Now;
+			return JsonConvert.DeserializeObject<T>(response);
+		}

-                if (responseStream == null)
-                    return null;
+	    private static WebRequest GetRequest(String url)
+		{
+			var request = (HttpWebRequest)WebRequest.Create(url);
+			request.Method = WebRequestMethods.Http.Get;
+			request.Timeout = 20000;
+			request.Proxy = null;
+			request.UserAgent = $"{VndbUtils.ClientName} (v{VndbUtils.Version})";

-                //				var headers = response.Headers; // Not used
-                var buffer = new Byte[VndbUtils.BufferSize];
-                var encoding = String.IsNullOrWhiteSpace(response.CharacterSet)
-                    ? Encoding.UTF8
-                    : Encoding.GetEncoding(response.CharacterSet);
+			return request;
+		}
+
+		private static async Task<String> GetResponseAsync(WebRequest request)
+		{
+			HttpWebResponse response = null;
+			Stream responseStream = null;
+			MemoryStream responseContent = null;
+
+			try
+			{
+				response = (HttpWebResponse) await request.GetResponseAsync().ConfigureAwait(false);
+				responseStream = response.GetResponseStream();
+				responseContent = new MemoryStream();
+
+				if (responseStream == null)
+					return null;
+
+//				var headers = response.Headers; // Not used
+				var buffer = new Byte[VndbUtils.BufferSize];
+				var encoding = String.IsNullOrWhiteSpace(response.CharacterSet)
+					? Encoding.UTF8
+					: Encoding.GetEncoding(response.CharacterSet);

-                Int32 bytesRead;
-                while ((bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
-                    await responseContent.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false);
+				Int32 bytesRead;
+				while ((bytesRead = await responseStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
+					await responseContent.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false);

-                // Reset our position;
-                responseContent.Position = 0;
-                // Reset the buffer as well
-                buffer = new Byte[VndbUtils.BufferSize];
-                using (var gzipStream = new GZipStream(responseContent, CompressionMode.Decompress))
-                using (var finalStream = new MemoryStream())
-                {
-                    while ((bytesRead = await gzipStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
-                        await finalStream.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false);
-
-                    return JsonConvert.DeserializeObject<T>(encoding.GetString(finalStream.ToArray()));
-                }
-            }
-            catch (WebException) // Catch bad requests from vndb
-            {
-                return null;
-            }
-            finally
-            {
-                response?.Dispose();
-                responseStream?.Dispose();
-                responseContent?.Dispose();
-                VndbUtils._lastTime= DateTime.Now;
-            }
-        }
-    }
+				// Reset our position;
+				responseContent.Position = 0;
+				// Reset the buffer as well
+				buffer = new Byte[VndbUtils.BufferSize];
+				using (var gzipStream = new GZipStream(responseContent, CompressionMode.Decompress))
+				using (var finalStream = new MemoryStream())
+				{
+					while ((bytesRead = await gzipStream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
+						await finalStream.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false);
+					return encoding.GetString(finalStream.ToArray());
+				}
+			}
+			catch (WebException)
+			{
+				return null;
+			}
+			finally
+			{
+				response?.Dispose();
+				responseStream?.Dispose();
+				responseContent?.Dispose();
+			}
+		}
+	}
 }


Skip null check for entity connection string

Currently, if the entity connection string is empty, it will fail at
launch. However, for local dev, this string may not be set and shouldn't
fail until it is used. By using string.Empty, it will still fail, but
only at the point where it is used.

--- WWTMVC5/Global.asax.cs
+++ WWTMVC5/Global.asax.cs
@@ -62,21 +62,21 @@
         private static void RegisterUnityContainer()
         {
             _container = new UnityContainer();
-            var earthSettings = ConfigReader<string>.GetSetting("EarthOnlineEntities");

-            if (earthSettings is null)
-            {
-                throw new InvalidOperationException("Setting for EarthOnlineEntitites is unavailable");
-            }
-
-            var manager = new PerRequestLifetimeManager();
-            var constructor = new InjectionConstructor(earthSettings);
-            _container.RegisterType<EarthOnlineEntities>(manager, constructor);
-
+            RegisterEarthOnlineEntities(_container);
             RegisterRepositories(_container);
             RegisterServices(_container);

             DependencyResolver.SetResolver(new UnityDependencyResolver(_container));
+        }
+
+        private static void RegisterEarthOnlineEntities(UnityContainer container)
+        {
+            var earthSettings = ConfigReader<string>.GetSetting("EarthOnlineEntities") ?? string.Empty;
+            var manager = new PerRequestLifetimeManager();
+            var constructor = new InjectionConstructor(earthSettings);
+
+            container.RegisterType<EarthOnlineEntities>(manager, constructor);
         }

         /// <summary>