Пример #1
0
        void Process(TimeSpan time)
        {
            while (!localPackets.IsEmpty && localPackets.TryDequeue(out var local))
            {
                LocalPlayer.ProcessPacket(local);
            }
            Action a;

            if (worldRequests.Count > 0 && worldRequests.TryDequeue(out a))
            {
                a();
            }
            //Update
            if (!(LocalPlayer?.World?.Paused ?? false))
            {
                LocalPlayer?.UpdateMissionRuntime(time.TotalSeconds);
            }
            ConcurrentBag <StarSystem> toSpinDown = new ConcurrentBag <StarSystem>();

            Parallel.ForEach(worlds, (world) =>
            {
                if (!world.Value.Update(time.TotalSeconds))
                {
                    toSpinDown.Add(world.Key);
                }
            });
            //Remove
            if (toSpinDown.Count > 0)
            {
                lock (availableWorlds)
                {
                    foreach (var w in toSpinDown)
                    {
                        if (worlds[w].PlayerCount <= 0)
                        {
                            worlds[w].Finish();
                            availableWorlds.Remove(w);
                            worlds.Remove(w);
                            FLLog.Info("Server", $"Shut down world {w.Nickname} ({w.Name})");
                        }
                    }
                }
            }
            processingLoop.TimeStep = worlds.Count > 0 ? RATE_60 : RATE_30;
            if (!running)
            {
                processingLoop.Stop();
            }
        }
Пример #2
0
        void NetThread()
        {
            EventBasedNetListener listener = new EventBasedNetListener();
            int unique = Environment.TickCount;

            listener.ConnectionRequestEvent += request =>
            {
                if (Server.ConnectedPeersCount > MaxConnections)
                {
                    request.Reject();
                }
                else
                {
                    request.AcceptIfKey(AppIdentifier);
                }
            };
            listener.PeerConnectedEvent += peer =>
            {
                FLLog.Info("Server", $"Connected: {peer.EndPoint}");
                BeginAuthentication(peer);
            };
            listener.PeerDisconnectedEvent += (peer, info) =>
            {
                FLLog.Info("Server", $"Disconnected: {peer.EndPoint}");
                if (peer.Tag is Player player)
                {
                    player.Disconnected();
                    lock (game.ConnectedPlayers)
                    {
                        game.ConnectedPlayers.Remove(player);
                    }
                }
            };
            listener.NetworkReceiveUnconnectedEvent += (point, reader, type) =>
            {
                try
                {
                    if (type == UnconnectedMessageType.Broadcast)
                    {
                        if (!reader.TryGetString(out string str))
                        {
                            return;
                        }
                        if (str != LNetConst.BROADCAST_KEY)
                        {
                            return;
                        }
                        var dw = new NetDataWriter();
                        dw.Put((int)1);
                        dw.Put(unique);
                        dw.Put(game.ServerName);
                        dw.Put(game.ServerDescription);
                        dw.Put(game.GameData.DataVersion);
                        dw.Put(Server.ConnectedPeersCount);
                        dw.Put(MaxConnections);
                        Server.SendUnconnectedMessage(dw, point);
                    }
                    else if (type == UnconnectedMessageType.BasicMessage)
                    {
                        if (!reader.TryGetUInt(out uint magic))
                        {
                            return;
                        }
                        if (magic != LNetConst.PING_MAGIC)
                        {
                            return;
                        }
                        var dw = new NetDataWriter();
                        dw.Put((int)0);
                        Server.SendUnconnectedMessage(dw, point);
                    }
                }
                finally
                {
                    reader.Recycle();
                }
            };
            listener.NetworkReceiveEvent += (peer, reader, channel, method) =>
            {
                try
                {
                    var pkt = Packets.Read(reader);
                    if (peer.Tag == TagConnecting)
                    {
                        if (pkt is AuthenticationReplyPacket)
                        {
                            var auth = (AuthenticationReplyPacket)pkt;
                            if (auth.Guid == Guid.Empty)
                            {
                                var dw = new NetDataWriter();
                                dw.Put("bad GUID");
                                peer.Disconnect(dw);
                            }
                            else
                            {
                                var p = new Player(new RemotePacketClient(peer),
                                                   game, auth.Guid);
                                peer.Tag = p;
                                Task.Run(() => p.DoAuthSuccess());
                                lock (game.ConnectedPlayers)
                                {
                                    game.ConnectedPlayers.Add(p);
                                }
                            }
                        }
                        else
                        {
                            var dw = new NetDataWriter();
                            dw.Put("Invalid packet");
                            peer.Disconnect(dw);
                        }
                    }
                    else
                    {
                        var player = (Player)peer.Tag;
                        //Task.Run(() => player.ProcessPacket(pkt));
                        player.ProcessPacket(pkt);
                    }
                }
                catch (Exception)
                {
                    throw;
                    var dw = new NetDataWriter();
                    dw.Put("Packet processing error");
                    peer.Disconnect(dw);
                    if (peer.Tag is Player p)
                    {
                        p.Disconnected();
                    }
                }
                finally
                {
                    reader.Recycle();
                }
            };
            listener.DeliveryEvent += (peer, data) =>
            {
                if (data is Action onAck)
                {
                    onAck();
                }
            };
            Server          = new NetManager(listener);
            Server.IPv6Mode = IPv6Mode.SeparateSocket;
            Server.UnconnectedMessagesEnabled = true;
            Server.BroadcastReceiveEnabled    = true;
            Server.ChannelsCount  = 3;
            Server.UnsyncedEvents = true;
            Server.Start(Port);
            FLLog.Info("Server", "Listening on port " + Port);
            var        sw       = Stopwatch.StartNew();
            var        last     = 0.0;
            ServerLoop sendLoop = null;

            sendLoop = new ServerLoop((time) =>
            {
                foreach (var p in Server.ConnectedPeerList)
                {
                    if (p.Tag is Player player)
                    {
                        (player.Client as RemotePacketClient)?.Update(time.TotalSeconds);
                    }
                }

                if (!running)
                {
                    sendLoop.Stop();
                }
            });
            sendLoop.Start();
            Server.Stop();
        }