+ Client Property:Connected

+ Client Property:Connected

--- KcpServer/KcpClient/KcpClient.cs
+++ KcpServer/KcpClient/KcpClient.cs
@@ -25,6 +25,8 @@
         Thread IOThread;
         byte[] applicationData;
         byte[] heartbeatData = new byte[0];
+
+        bool _Connected = false;
         public KcpClient(byte a, byte b, byte c, byte d, int sid, byte[] appData)
         {
             defpb = new ToServerPackBuilder(a, b, c, d, sid);
@@ -64,11 +66,15 @@
         {
             debug?.Invoke($"{nameof(OnConnected)} {sid}");
         };
-
+
         public int SessionId { get; private set; }

         public void SendOperationRequest(byte[] buff)
         {
+            if (!Connected)
+            {
+                throw new InvalidOperationException("not connected");
+            }
             Outgoing.Enqueue(buff);
         }
         public void Service()
@@ -98,6 +104,8 @@
         uint _WSAIOW(uint x, uint y) => (IOC_IN | (x) | (y));
         //uint _WSAIORW(uint x, uint y) => (IOC_INOUT | (x) | (y));
         uint SIO_UDP_CONNRESET => _WSAIOW(IOC_VENDOR, 12);
+
+        public bool Connected { get => _Connected; private set => _Connected = value; }
         #endregion

         public void Connect(IPEndPoint ipep)
@@ -137,6 +145,7 @@
             udp.SendTo(sendbuff, remote_ipep);
             lastHandshakeTime = DateTime.Now;
             debug?.Invoke($"begin {nameof(Handshake)}");
+            _Connected = true;
         }

         DateTime lastHartbeatTime = DateTime.Now;
@@ -225,12 +234,14 @@

         private void InternalError(int datasize)
         {
+            Connected = false;
             var cec = (ClientErrorCode)datasize;
             switch (cec)
             {

                 case ClientErrorCode.SERVER_TIMEOUT:
                     Console.WriteLine("服务器认为你超时了");
+
                     OnDisconnect();

                     break;


more pluggable

more pluggable

--- CaptureSnippets/MarkdownProcessor.cs
+++ CaptureSnippets/MarkdownProcessor.cs
@@ -22,7 +22,7 @@
             }
         }

-        ProcessResult Apply(List<SnippetGroup> availableSnippets, IndexReader reader)
+        public ProcessResult Apply(List<SnippetGroup> availableSnippets, IndexReader reader)
         {
             var stringBuilder = new StringBuilder();
             var result = new ProcessResult();
@@ -51,17 +51,7 @@
                     continue;
                 }

-                foreach (var versionGroup in snippetGroup.Versions)
-                {
-                    if (versionGroup.Version != null)
-                    {
-                        stringBuilder.AppendLine("#### Version " + versionGroup.Version);
-                    }
-                    foreach (var snippet in versionGroup.Snippets)
-                    {
-                        AppendSnippet(snippet, stringBuilder);
-                    }
-                }
+                AppendGroup(snippetGroup, stringBuilder);
                 if (result.UsedSnippets.All(x => x != snippetGroup.Key))
                 {
                     result.UsedSnippets.Add(snippetGroup.Key);
@@ -71,7 +61,22 @@
             return result;
         }

-        public static void AppendSnippet(Snippet codeSnippet, StringBuilder stringBuilder)
+        public void AppendGroup(SnippetGroup snippetGroup, StringBuilder stringBuilder)
+        {
+            foreach (var versionGroup in snippetGroup.Versions)
+            {
+                if (versionGroup.Version != null)
+                {
+                    stringBuilder.AppendLine("#### Version " + versionGroup.Version);
+                }
+                foreach (var snippet in versionGroup.Snippets)
+                {
+                    AppendSnippet(snippet, stringBuilder);
+                }
+            }
+        }
+
+        public void AppendSnippet(Snippet codeSnippet, StringBuilder stringBuilder)
         {
             stringBuilder.AppendLine("```" + codeSnippet.Language);
             stringBuilder.AppendLine(codeSnippet.Value);


Remove pointless duplicate test (see `TestLoadExceptions.TestUnobservedException` for a better version)

--- osu.Framework.Tests/IO/TestLogging.cs
+++ osu.Framework.Tests/IO/TestLogging.cs
@@ -130,39 +130,6 @@
         }

         [Test]
-        public void TestGameUnobservedThrowsUnderNUnit()
-        {
-            Assert.Throws<TestException>(() =>
-            {
-                using (var host = new TestRunHeadlessGameHost())
-                {
-                    TaskCrashTestGame game = new TaskCrashTestGame();
-                    host.Run(game);
-                }
-            });
-        }
-
-        private class TaskCrashTestGame : Game
-        {
-            private int frameCount;
-
-            protected override void Update()
-            {
-                base.Update();
-
-                Task.Run(() => throw new TestException());
-
-                // only start counting frames once the task has completed, to allow some time for the unobserved exception to be handled.
-                if (frameCount++ > 10)
-                {
-                    collectAndFireUnobserved();
-
-                    Exit();
-                }
-            }
-        }
-
-        [Test]
         public void TestTaskExceptionLogging()
         {
             Exception resolvedException = null;


Remove redundant string interpolation

Remove redundant string interpolation

--- osu.Framework/Audio/AudioComponent.cs
+++ osu.Framework/Audio/AudioComponent.cs
@@ -32,10 +32,10 @@
             if (ThreadSafety.ExecutionMode == ExecutionMode.SingleThreaded)
             {
                 if (ThreadSafety.IsDrawThread)
-                    throw new InvalidOperationException($"Cannot perform audio operation from draw thread.");
+                    throw new InvalidOperationException("Cannot perform audio operation from draw thread.");

                 if (ThreadSafety.IsInputThread)
-                    throw new InvalidOperationException($"Cannot perform audio operation from input thread.");
+                    throw new InvalidOperationException("Cannot perform audio operation from input thread.");
             }

             if (ThreadSafety.IsAudioThread || (ThreadSafety.ExecutionMode == ExecutionMode.SingleThreaded && ThreadSafety.IsUpdateThread))


Move logic out of update (and simplify, hopefully)

--- osu.Game/Screens/Multi/Multiplayer.cs
+++ osu.Game/Screens/Multi/Multiplayer.cs
@@ -9,6 +9,7 @@
 using osu.Framework.Graphics.Shapes;
 using osu.Framework.Logging;
 using osu.Framework.Screens;
+using osu.Game.Beatmaps;
 using osu.Game.Graphics;
 using osu.Game.Graphics.Backgrounds;
 using osu.Game.Graphics.Containers;
@@ -185,6 +186,28 @@
         {
             this.FadeIn();
             waves.Show();
+
+            beginHandlingTrack();
+        }
+
+        public override void OnResuming(IScreen last)
+        {
+            this.FadeIn(250);
+            this.ScaleTo(1, 250, Easing.OutSine);
+
+            base.OnResuming(last);
+
+            beginHandlingTrack();
+        }
+
+        public override void OnSuspending(IScreen next)
+        {
+            this.ScaleTo(1.1f, 250, Easing.InSine);
+            this.FadeOut(250);
+
+            endHandlingTrack();
+
+            roomManager.TimeBetweenPolls = 0;
         }

         public override bool OnExiting(IScreen next)
@@ -192,13 +215,11 @@
             waves.Hide();

             this.Delay(WaveContainer.DISAPPEAR_DURATION).FadeOut();
-
-            cancelLooping();

             if (screenStack.CurrentScreen != null)
                 loungeSubScreen.MakeCurrent();

-            updatePollingRate(isIdle.Value);
+            endHandlingTrack();

             base.OnExiting(next);
             return false;
@@ -212,42 +233,44 @@
             logo.Delay(WaveContainer.DISAPPEAR_DURATION / 2).FadeOut();
         }

-        public override void OnResuming(IScreen last)
-        {
-            this.FadeIn(250);
-            this.ScaleTo(1, 250, Easing.OutSine);
-
-            base.OnResuming(last);
-
+        private void beginHandlingTrack()
+        {
+            Beatmap.BindValueChanged(updateTrack, true);
+        }
+
+        private void endHandlingTrack()
+        {
+            cancelLooping();
+            Beatmap.ValueChanged -= updateTrack;
+        }
+
+        private void screenPushed(IScreen lastScreen, IScreen newScreen) => subScreenChanged(newScreen);
+
+        private void screenExited(IScreen lastScreen, IScreen newScreen)
+        {
+            subScreenChanged(newScreen);
+
+            if (screenStack.CurrentScreen == null && this.IsCurrentScreen())
+                this.Exit();
+        }
+
+        private void subScreenChanged(IScreen newScreen)
+        {
             updatePollingRate(isIdle.Value);
-        }
-
-        public override void OnSuspending(IScreen next)
-        {
-            this.ScaleTo(1.1f, 250, Easing.InSine);
-            this.FadeOut(250);
-
-            cancelLooping();
-            roomManager.TimeBetweenPolls = 0;
-        }
-
-        private void cancelLooping()
-        {
-            var track = Beatmap?.Value?.Track;
-
-            if (track != null)
-                track.Looping = false;
-        }
-
-        protected override void Update()
-        {
-            base.Update();
-
-            if (!this.IsCurrentScreen()) return;
-
-            if (screenStack.CurrentScreen is MatchSubScreen)
-            {
-                var track = Beatmap.Value.Track;
+            createButton.FadeTo(newScreen is MatchSubScreen ? 0 : 1, 200);
+
+            updateTrack();
+        }
+
+        private void updateTrack(ValueChangedEvent<WorkingBeatmap> _ = null)
+        {
+            bool isMatch = screenStack.CurrentScreen is MatchSubScreen;
+
+            Beatmap.Disabled = isMatch;
+
+            if (isMatch)
+            {
+                var track = Beatmap.Value?.Track;

                 if (track != null)
                 {
@@ -257,25 +280,22 @@
                     if (!track.IsRunning)
                         track.Restart();
                 }
-
-                createButton.Hide();
-            }
-            else if (screenStack.CurrentScreen is LoungeSubScreen)
-                createButton.Show();
-        }
-
-        private void screenPushed(IScreen lastScreen, IScreen newScreen)
-            => updatePollingRate(isIdle.Value);
-
-        private void screenExited(IScreen lastScreen, IScreen newScreen)
-        {
-            if (lastScreen is MatchSubScreen)
+            }
+            else
+            {
                 cancelLooping();
-
-            updatePollingRate(isIdle.Value);
-
-            if (screenStack.CurrentScreen == null && this.IsCurrentScreen())
-                this.Exit();
+            }
+        }
+
+        private void cancelLooping()
+        {
+            var track = Beatmap?.Value?.Track;
+
+            if (track != null)
+            {
+                track.Looping = false;
+                track.RestartPoint = 0;
+            }
         }

         protected override void Dispose(bool isDisposing)


play/stops music when entering the pause overlay, instead of letting it play silently in the background

--- osu.Game/Screens/Play/PauseOverlay.cs
+++ osu.Game/Screens/Play/PauseOverlay.cs
@@ -38,13 +38,13 @@
                 {
                     Looping = true,
                 });
-                pauseLoop?.Play();
             }
         }

         protected override void PopIn()
         {
             base.PopIn();
+            pauseLoop?.Play();
             pauseLoop?.VolumeTo(1.0f, 400, Easing.InQuint);
         }

@@ -52,6 +52,7 @@
         {
             base.PopOut();
             pauseLoop?.VolumeTo(0.0f);
+            pauseLoop?.Stop();
         }
     }
 }


innerExceptions for NoHostAvaliable

innerExceptions for NoHostAvaliable

--- Cassandra.Native/CassandraSession.cs
+++ Cassandra.Native/CassandraSession.cs
@@ -124,7 +124,7 @@

         List<CassandraConnection> trahscan = new List<CassandraConnection>();

-        internal CassandraConnection connect(CassandraRoutingKey routingKey, ref Host current, bool getNext=false)
+        internal CassandraConnection connect(CassandraRoutingKey routingKey, ref Host current, bool getNext = false, Dictionary<IPAddress, Exception> innerExceptions = null)
         {
             checkDisposed();
             lock (trahscan)
@@ -150,7 +150,7 @@
                         {
                             if (getNext)
                                 if (!hostsIter.MoveNext())
-                                    throw new NoHostAvailableException(new Dictionary<IPAddress,Exception>());
+                                    throw new NoHostAvailableException(innerExceptions ?? new Dictionary<IPAddress, Exception>());
                             break;
                         }
                     }
@@ -225,7 +225,7 @@
                     }
                 }
             }
-            throw new NoHostAvailableException(new Dictionary<IPAddress, Exception>());
+            throw new NoHostAvailableException(innerExceptions ?? new Dictionary<IPAddress, Exception>());
         }

         internal void OnAddHost(IPAddress endpoint)
@@ -561,7 +561,7 @@
             public int queryRetries = 0;
             virtual public void Connect(Session owner, bool moveNext)
             {
-                connection = owner.connect(routingKey, ref current, moveNext);
+                connection = owner.connect(routingKey, ref current, moveNext, innerExceptions);
             }
             abstract public void Begin(Session owner);
             abstract public CassandraServerException Process(Session owner, IAsyncResult ar, out object value);


Force a selection after filtering to ensure correct difficulty is selected

--- osu.Game/Screens/Select/SongSelect.cs
+++ osu.Game/Screens/Select/SongSelect.cs
@@ -397,6 +397,8 @@
                 var criteria = FilterControl.CreateCriteria();
                 criteria.SelectedBeatmapSet = e.NewValue.BeatmapInfo.BeatmapSet;
                 Carousel.Filter(criteria);
+
+                Carousel.SelectBeatmap(e.NewValue.BeatmapInfo);
             }
         }


c# publisher improvement

c# publisher improvement

--- Cogs.Publishers/CsSchemaPublisher.cs
+++ Cogs.Publishers/CsSchemaPublisher.cs
@@ -83,10 +83,12 @@
                 newClass.Append("$#{");
                 foreach(var prop in item.Properties)
                 {
+                    // set c# datatype representation
+                    if (Translator.ContainsKey(prop.DataTypeName)) { prop.DataTypeName = Translator[prop.DataTypeName]; }
                     // create documentation for property
                     newClass.Append("$##/// <summary>$##/// " + prop.Description + "$##/// <summary>");
                     // create constraints
-                    if(prop.DataTypeName.Equals("string") || prop.DataTypeName.Equals("anyURI"))
+                    if(prop.DataTypeName.Equals("string") || prop.DataTypeName.Equals("Uri"))
                     {
                         if(prop.MinLength != null && prop.MaxLength != null)
                         {
@@ -120,10 +122,8 @@
                             {
                                 newClass.Append("$##[StringValidation(null, \"" + prop.Pattern + "\")]");
                             }
-
-
                         }
-                    }else if(!prop.DataTypeName.Equals("boolean") && !prop.DataType.Equals("language") && !prop.DataTypeName.Equals("cogsDate"))
+                    }else if(!prop.DataTypeName.Equals("bool") && !prop.DataTypeName.Equals("CogsDate"))
                     {
                         if (prop.MinInclusive != null || prop.MaxInclusive != null)
                         {
@@ -134,7 +134,6 @@
                             newClass.Append("$##[ExclusiveRange(" + prop.MinExclusive + ", " + prop.MaxExclusive + ")]");
                         }
                     }
-                    if (Translator.ContainsKey(prop.DataTypeName)) { prop.DataTypeName = Translator[prop.DataTypeName]; }
                     // if there can be at most one, create an instance variable
                     if (!prop.MaxCardinality.Equals("n") && Int32.Parse(prop.MaxCardinality) == 1)
                     {


Fixes divide by zero

Fixes divide by zero

--- Common/Securities/SecurityHolding.cs
+++ Common/Securities/SecurityHolding.cs
@@ -343,8 +343,8 @@
         {
             get
             {
-                if (AbsoluteHoldingsCost == 0) return 0m;
-                return UnrealizedProfit/AbsoluteHoldingsCost;
+                //somehow, was possible to divide by zero here.
+                return AbsoluteHoldingsCost != 0 ? UnrealizedProfit / AbsoluteHoldingsCost : 0m;
             }
         }


Remove excessive whitespace in NativeMethods.

--- Corale.Colore/Razer/NativeMethods.cs
+++ Corale.Colore/Razer/NativeMethods.cs
@@ -1,29 +1,29 @@
 // ---------------------------------------------------------------------------------------
 // <copyright file="NativeMethods.cs" company="Corale">
 //     Copyright © 2015 by Adam Hellberg and Brandon Scott.
-//
+//
 //     Permission is hereby granted, free of charge, to any person obtaining a copy of
 //     this software and associated documentation files (the "Software"), to deal in
 //     the Software without restriction, including without limitation the rights to
 //     use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 //     of the Software, and to permit persons to whom the Software is furnished to do
 //     so, subject to the following conditions:
-//
+//
 //     The above copyright notice and this permission notice shall be included in all
 //     copies or substantial portions of the Software.
-//
+//
 //     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 //     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 //     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 //     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 //     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 //     CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
+//
 //     Disclaimer: Corale and/or Colore is in no way affiliated with Razer and/or any
 //     of its employees and/or licensors. Corale, Adam Hellberg, and/or Brandon Scott
 //     do not take responsibility for any harm caused, direct or indirect, to any
 //     Razer peripherals via the use of Colore.
-//
+//
 //     "Razer" is a trademark of Razer USA Ltd.
 // </copyright>
 // ---------------------------------------------------------------------------------------