public void InvalidInputTest() { var stack = new SortedStack <int>(); TestHelpers.AssertExceptionThrown(() => stack.Peek(), typeof(InvalidOperationException)); TestHelpers.AssertExceptionThrown(() => stack.Pop(), typeof(InvalidOperationException)); }
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(); } } }
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()); }
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); } } }
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(); } } }
//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); }