Example #1
0
        /// <summary>
        /// Starts a thread that times out connections or sends keep alive packets
        /// </summary>
        public void StartCleanupThread()
        {
            if (isDoingCleanup)
            {
                return;
            }

            isDoingCleanup = true;
            Task.Run(() =>
            {
                while (true)
                {
                    TimeoutConnections();
                    KeepClientAlivePacket kcap = new KeepClientAlivePacket();
                    lock (connected)
                    {
                        for (int i = 0; i < connected.Length; i++)
                        {
                            if (connected[i] != null && TimeUtils.GetTimestamp() - connected[i].LastSentPacketTimestamp > 1)
                            {
                                listener.Send(kcap, connected[i].Client);
                            }
                        }
                    }
                    Thread.Sleep(100);
                }
            }, cts.Token);
        }
Example #2
0
        /// <summary>
        /// Initializes serverobject with IP
        /// </summary>
        /// <param name="useLocalhost">Whether the server should use 127.0.0.1 ip or use its actual outgoing one</param>
        public Server(bool useLocalhost = false)
        {
            WorldManager.OnServer = true;

            isDisposed     = false;
            isDoingCleanup = false;

            IPAddress ip;

            if (useLocalhost)
            {
                ip = IPAddress.Parse("127.0.0.1");
            }
            else
            {
                ip = GetIP();
            }
            IPEndPoint iep = new IPEndPoint(ip, PORT);

            listener = new CustomUdpClient(PORT);
            listener.PacketRecieved += PacketReceived;

            pending   = new Connection[PENDING_SLOTS];
            connected = new Connection[CONNECTED_SLOTS];
            games     = new Game[GAME_SLOTS];

            packetCallbacks = new Dictionary <Type, Action <Packet> >()
            {
                {
                    typeof(StringPacket), (Packet p) =>
                    {
                        StringPacket sp = (StringPacket)p;
                        Console.WriteLine(sp.Content);
                    }
                },
                { typeof(ConnectPacket), (Packet p) =>
                  {
                      int             connectionIndex = GetConnectionIndexFromIEP(pending, p.Sender);
                      ChallengePacket challenge;
                      ConnectPacket   cp = (ConnectPacket)p;
                      if (connectionIndex == -1)
                      {
                          int i = GetFirstFreeIndex(pending);
                          if (i == -1)
                          {
                              listener.Send(new DeclineConnectPacket(), p.Sender);
                              return;
                          }

                          challenge  = new ChallengePacket(cp.ClientSalt);
                          pending[i] = new Connection(cp.Sender, cp.ClientSalt, challenge.ServerSalt);
                          pending[i].RefreshRecievedPacketTimestamp();
                      }
                      else
                      {
                          Connection c = pending[connectionIndex];
                          c.ClientSalt = cp.ClientSalt;
                          challenge    = new ChallengePacket(c.ClientSalt, c.ServerSalt);
                          c.RefreshRecievedPacketTimestamp();
                      }
                      listener.Send(challenge, p.Sender);
                  } },
                {
                    typeof(ChallengeResponsePacket), (Packet p) =>
                    {
                        int connectionIndex = GetConnectionIndexFromIEP(pending, p.Sender);
                        if (connectionIndex == -1)
                        {
                            return;
                        }
                        Connection c = pending[connectionIndex];
                        ChallengeResponsePacket crp = (ChallengeResponsePacket)p;
                        if (crp.Xored == c.Xored) // response packet was correct
                        {
                            pending[connectionIndex] = null;
                            connectionIndex          = GetFirstFreeIndex(connected);
                            if (connectionIndex == -1)
                            {
                                listener.Send(new DeclineConnectPacket(), p.Sender);
                                return;
                            }
                            connected[connectionIndex] = c;
                            c.RefreshRecievedPacketTimestamp();
                            KeepClientAlivePacket kcap = new KeepClientAlivePacket();
                            listener.Send(kcap, p.Sender);
                            return;
                        }
                        listener.Send(new DeclineConnectPacket(), p.Sender);
                    }
                }
            };

            connectedPacketCallbacks = new Dictionary <Type, Action <SaltedPacket, Connection> >()
            {
                {
                    typeof(KeepAlivePacket), (SaltedPacket p, Connection c) =>
                    {
                        c.RefreshRecievedPacketTimestamp();
                    }
                },
                {
                    typeof(QueuePacket), (SaltedPacket p, Connection c) =>
                    {
                        int gameIndex = GetGameIndexFromIep(p.Sender);
                        int gameId    = -1;
                        if (gameIndex != -1)
                        {
                            gameId = games[gameIndex].Id;
                        }
                        else
                        {
                            lock (games)
                            {
                                foreach (Game g in games)
                                {
                                    if (g != null && g.AddConnection(c))
                                    {
                                        gameId = g.Id;
                                        break;
                                    }
                                }


                                if (gameId == -1)
                                {
                                    int newGameIndex = GetFirstFreeIndex(games);
                                    if (newGameIndex != -1)
                                    {
                                        Game g = new Game();
                                        games[newGameIndex] = g;
                                        g.AddConnection(c);
                                        gameId = g.Id;
                                        g.StartHandle(SendPacket);
                                        g.GameEnded += (object sender, EventArgs e) =>
                                        {
                                            lock (games)
                                                games[newGameIndex] = null;
                                        };
                                    }
                                }
                            }
                        }

                        QueueResponsePacket qrp = new QueueResponsePacket(gameId);
                        listener.Send(qrp, p.Sender);
                        c.RefreshSentPacketTimestamp();
                    }
                },
                {
                    typeof(GetGameInfoPacket), (SaltedPacket p, Connection c) =>
                    {
                        int gameIndex = GetGameIndexFromIep(c.Client);
                        if (gameIndex == -1)
                        {
                            return;
                        }

                        Game           g    = games[gameIndex];
                        GameInfoPacket ggip = new GameInfoPacket(g);
                        listener.Send(ggip, p.Sender);
                        c.RefreshSentPacketTimestamp();
                    }
                },
                {
                    typeof(InputPacket), (SaltedPacket p, Connection c) =>
                    {
                        int gameIndex = GetGameIndexFromIep(c.Client);
                        if (gameIndex == -1)
                        {
                            SendPacket(new QueueResponsePacket(-1), c.Client);
                            return;
                        }

                        Game        g    = games[gameIndex];
                        InputPacket inpt = (InputPacket)p;
                        g.HandleInputPacket(inpt, c);
                    }
                }
            };
        }