コード例 #1
0
        public void InvalidInputTest()
        {
            var stack = new SortedStack <int>();

            TestHelpers.AssertExceptionThrown(() => stack.Peek(), typeof(InvalidOperationException));
            TestHelpers.AssertExceptionThrown(() => stack.Pop(), typeof(InvalidOperationException));
        }
コード例 #2
0
        protected virtual void ClientPacketReceived(object sender, PacketEventArgs e)
        {
            if (!(sender is ISocket socket))
            {
                return;
            }

            Stats.PacketsReceived++;
            Stats.AddInput(e.Transferred);

            //only allow connections from WebSockets?
            if (!Config.UseTcpSockets && !socket.IsWebSocket)
            {
                socket.Disconnect();
                return;
            }

            if ((AresId)e.Packet.Id == AresId.MSG_CHAT_CLIENT_LOGIN)
            {
                IClient user = Users.Find(s => s.Socket == socket);

                if (user == null)
                {
                    if (HandlePending(socket))
                    {
                        int id     = idpool.Pop();
                        var client = new AresClient(this, socket, (ushort)id);

                        if (IPAddress.IsLoopback(client.ExternalIp) ||
                            client.ExternalIp.Equals(ExternalIp) ||
                            LocalAddresses.Contains(client.ExternalIp) ||
                            (Config.LocalAreaIsHost && client.ExternalIp.IsLocalAreaNetwork()))
                        {
                            client.LocalHost = true;
                        }

                        lock (Users) {
                            Users.Add(client);
                            Users.Sort(sorter);
                            Stats.PeakUsers = Math.Max(Users.Count, Stats.PeakUsers);
                        }

                        client.HandleJoin(e);
                    }
                    else
                    {
                        socket.Disconnect();
                    }
                }
                else
                {
                    //sending too many login packets
                    SendAnnounce(user, Errors.LoginFlood);
                    Logging.Info("AresServer", "User '{0}' has been disconnected for login flooding.", user.Name);

                    user.Disconnect();
                }
            }
        }
コード例 #3
0
        private static void Validate <T>(SortedStack <T> stack, params T[] expectedValues)
            where T : IComparable <T>
        {
            foreach (var value in expectedValues)
            {
                Assert.IsFalse(stack.IsEmpty());
                Assert.AreEqual(value, stack.Pop());
            }

            Assert.IsTrue(stack.IsEmpty());
        }
コード例 #4
0
        protected virtual void ClientPacketReceived(object sender, PacketEventArgs e)
        {
            stats.PacketsReceived++;
            stats.AddInput(e.Transferred);

            var socket = sender as ISocket;

            if (socket == null)
            {
                return;
            }

            AresClient user = null;

            lock (users.SyncRoot)
                user = users.Find(s => s.Socket == socket);

            if (user == null)
            {
                if ((AresId)e.Packet.Id == AresId.MSG_CHAT_CLIENT_LOGIN)
                {
                    if (HandlePending(socket))
                    {
                        int id = idpool.Pop();
                        user = new AresClient(this, socket, (ushort)id);

                        if (user.ExternalIp.IsLocal() || user.ExternalIp.Equals(ExternalIp))
                        {
                            user.LocalHost = true;
                        }

                        lock (users.SyncRoot) {
                            users.Add(user);
                            users.Sort(sorter);
                            stats.PeakUsers = Math.Max(users.Count, stats.PeakUsers);
                        }

                        user.HandleJoin(e);
                    }
                    else
                    {
                        socket.Disconnect();
                    }
                }
            }
            else if ((AresId)e.Packet.Id == AresId.MSG_CHAT_CLIENT_LOGIN)
            {
                //sending too many login packets
                SendAnnounce(user, Errors.LoginFlood);
                user.Disconnect();
            }
            else if (user.LoggedIn && CheckCounters(user, e.Packet))
            {
                user.LastUpdate = TimeBank.CurrentTime;

                if (!user.HandlePacket(e) && plugins.OnBeforePacket(user, e.Packet))
                {
                    user.HandleOverridePacket(e);
                    plugins.OnAfterPacket(user, e.Packet);
                }
            }
        }
コード例 #5
0
ファイル: AresServer.cs プロジェクト: silverx69/Zorbo
        protected virtual void ClientPacketReceived(object sender, PacketEventArgs e)
        {
            if (!(sender is ISocket socket))
            {
                return;
            }

            Stats.PacketsReceived++;
            Stats.AddInput(e.Transferred);

            if (e.Packet.Id == (byte)AresId.MSG_CHAT_CLIENT_LOGIN)
            {
                IClient user = Users.Find(s => s.Socket == socket);

                if (user == null)
                {
                    if (HandlePending(socket))
                    {
                        if (idpool.Count == 0)
                        {
                            socket.SendAsync(new Announce(Errors.RoomFull));
                            socket.Disconnect();
                            Logging.Info(
                                "AresServer",
                                "Chatroom has reached capacity ({0}). If this happens frequently consider raising Max Clients",
                                Config.MaxClients
                                );
                        }
                        else
                        {
                            int id     = idpool.Pop();
                            var client = new AresClient(this, socket, (ushort)id);

                            if (IPAddress.IsLoopback(client.ExternalIp) ||
                                client.ExternalIp.Equals(ExternalIp) ||
                                LocalAddresses.Contains(client.ExternalIp) ||
                                (Config.LocalAreaIsHost && client.ExternalIp.IsLocalAreaNetwork()))
                            {
                                client.LocalHost = true;
                            }

                            lock (Users) {
                                Users.Add(client);
                                Users.Sort(sorter);
                                Stats.PeakUsers = Math.Max(Users.Count, Stats.PeakUsers);
                            }

                            client.HandleJoin(e);
                        }
                    }
                }
                else
                {
                    //sending too many login packets
                    SendAnnounce(user, Errors.LoginFlood);
                    Logging.Info("AresServer", "User '{0}' has been disconnected for login flooding.", user.Name);

                    user.Disconnect();
                }
            }
        }
コード例 #6
0
        //var s = Surfaces.Plane(50, 50).Mult(1.0 / 50).Move(-0.5, -0.5, 0).ToShape2().CutOutside(Polygons.Sinus(1, 3, 5, 500)).ToShape3();
        //var points = s.Points2;

        //var q2 = Math.Sqrt(2);

        //double Distance(int i, int j)
        //{
        //    var a = points[i];
        //    var b = points[j];

        //    var dx = Math.Abs(a.x - b.x);
        //    var dy = Math.Abs(a.y - b.y);

        //    var min = Math.Min(dx, dy);
        //    var max = Math.Max(dx, dy);

        //    return (max - min) + min * 2;

        //    //if (Math.Abs(a.x -b.x) < 0.00001 || Math.Abs(a.y - b.y) < 0.00001)
        //    return (b - a).Len;

        //    //return 0.99 * (b - a).Len;
        //}

        //var g = s.ToGraph();
        //var from = g.nodes[^1219];
        //var to = g.nodes[^835];

        //var(path, open, close, infos) = g.FindPathAStar((a, b) => Distance(a.i, b.i), from, to);

        //    var pathShape = new Shape()
        //    {
        //        Points = s.Points,
        //        Convexes = path.SelectPair((a, b) => new[] { a.i, b.i }).ToArray()
        //    };

        //var openShape = new Shape()
        //{
        //    Points = open.Select(n => s.Points[n.i] + new Vector4(0, 0, infos[n].PathDistance * 0.3, 0)).ToArray(),
        //};

        //var closeList = close.ToList();
        //var closeShape = new Shape()
        //{
        //    Points = close.Select(n => s.Points[n.i] + new Vector4(0, 0, infos[n].PathDistance * 0.3, 0)).ToArray(),
        //    Convexes = path.Select(n => closeList.IndexOf(n)).SelectPair((i, j) => new[] { i, j }).ToArray()
        //};

        //pathShape = pathShape.ToMetaShape3(0.2, 1, Color.Black, Color.Green);//.ApplyColor(Color.Red);//.ToLines3(1, Color.Blue);

        //    var shape = pathShape +
        //                openShape.ToSpots3(0.22, Color.Blue) +
        //                closeShape.ToMetaShape3(0.22, 1, Color.Red, Color.Green)


        // how to: https://www.youtube.com/watch?v=-L-WgKMFuhE
        // todo: можно оптимизировать заменив double на long, и для равноудаленных узлов брать ближайший к цели (как на видео)
        public (Node[] path, Node[] open, Node[] close, Dictionary <Node, Info> infos) FindPathAStar(Func <Node, Node, double> distanceFn, Node from = null, Node to = null)
        {
            from ??= nodes[0];
            to ??= nodes[^ 1];

            var infos    = new Dictionary <Node, Info>();
            var openSet  = new SortedStack <Node>(nodes.Count);
            var closeSet = new HashSet <Node>(nodes.Count);

            void UpdateOpenSetItem(Node prev, Node n)
            {
                var prevPathDistanceFrom = infos.TryGetValue(prev, out Info prevInfo) ? prevInfo.PathDistanceFrom : 0;
                var pathDistanceFrom     = prevPathDistanceFrom + distanceFn(prev, n);

                if (!infos.TryGetValue(n, out Info info))
                {
                    info = new Info()
                    {
                        DistanceTo       = distanceFn(n, to),
                        PathDistanceFrom = pathDistanceFrom,
                        Node             = n,
                        Prev             = prev
                    };
                    infos.Add(n, info);
                    openSet.Push(n, info.PathDistance);
                }
                else
                {
                    if (pathDistanceFrom < info.PathDistanceFrom)
                    {
                        info.PathDistanceFrom = pathDistanceFrom;
                        info.Prev             = prev;
                        openSet.Update(n, info.PathDistance);
                    }
                }
            }

            UpdateOpenSetItem(from, from);

            do
            {
                var n = openSet.Pop();
                closeSet.Add(n);

                if (n == to)
                {
                    break;
                }

                foreach (var nn in n.edges.Select(e => e.Another(n)).Where(node => !closeSet.Contains(node)))
                {
                    UpdateOpenSetItem(n, nn);
                }
            } while (!openSet.IsEmpty);

            Debug.WriteLine($"{openSet.Count} + {closeSet.Count} = {openSet.Count + closeSet.Count}");

            List <Node> path = new();

            var node = to;

            while (node != from)
            {
                var info = infos[node];
                Debug.WriteLine($"{node.i}: {info.DistanceTo:F3} + {info.PathDistanceFrom:F3} = {info.PathDistance:F3} ");

                path.Add(node);
                //yield return node;

                node = info.Prev;
            }

            var infoFrom = infos[from];

            Debug.WriteLine($"{node.i}: {infoFrom.DistanceTo:F3} + {infoFrom.PathDistanceFrom:F3} = {infoFrom.PathDistance:F3} ");

            path.Add(from);
            //yield return from;
            path.Reverse();

            return(path.ToArray(), openSet.ToArray(), closeSet.ToArray(), infos);
        }