예제 #1
0
파일: Server.cs 프로젝트: BHuenemann/CS3500
        /// <summary>
        /// This part sets up a tank with the player name and sends the startup info to the client including the world size, player ID,
        /// and walls.
        /// </summary>
        /// <param name="ss">Socket state for the connection</param>
        private static void SendStartupInfo(SocketState ss)
        {
            if (ss.ErrorOccured == true)
            {
                Console.WriteLine("Error occured while accepting: \"" + ss.ErrorMessage + "\"");
                return;
            }

            //Gets the name and ID from the socket and removes the name from the socket
            string tankName = ss.GetData();
            int    tankID   = (int)ss.ID;

            ss.RemoveData(0, tankName.Length);


            lock (TheWorld)
            {
                /*This sets up the tank, sets the cooldown frames so it can fire, adds a filler command to the dictionary, and
                 * spawns the tank at a random location.*/
                Tank t = new Tank(tankName.Substring(0, tankName.Length - 1), tankID);
                TheWorld.UpdateTank(t);
                TheWorld.TankSetCooldownFrames(t.ID, FramesPerShot);
                TheWorld.UpdateCommand(tankID, new ControlCommands());
                SpawnTank(t);

                Console.WriteLine("Player(" + tankID + ") " + "\"" + t.Name + "\" joined");
            }

            //Changes the delegate
            ss.OnNetworkAction = ReceiveCommandData;


            //Sends the tank ID and the world size
            string message = tankID + "\n" + UniverseSize.ToString() + "\n";

            if (!Networking.Send(ss.TheSocket, message))
            {
                Console.WriteLine("Error occured while sending data");
            }

            //Sends the walls to the client
            lock (TheWorld)
            {
                StringBuilder wallMessage = new StringBuilder();
                foreach (Wall w in TheWorld.Walls.Values)
                {
                    wallMessage.Append(JsonConvert.SerializeObject(w) + "\n");
                }
                if (!Networking.Send(ss.TheSocket, wallMessage.ToString()))
                {
                    Console.WriteLine("Error occured while sending data");
                }
            }


            //Adds the socket state to the list of connections
            SocketConnections.Add(ss);


            Networking.GetData(ss);
        }
예제 #2
0
 /// <summary>
 /// Starts the server and sets up the walls
 /// </summary>
 private void StartServer()
 {
     clients = new Dictionary <SocketState, Tank>();
     // start accepting clients
     theServer = Networking.StartServer(HandleNewClient, 11000);
 }
예제 #3
0
 /// <summary>
 /// Starts the server with Networking class.
 /// </summary>
 private void Start()
 {
     Networking.StartServer(HandleNewClient, 11000);
     Console.WriteLine("Server Is Running. Now Accepting New Clients.");
 }
예제 #4
0
파일: Server.cs 프로젝트: BHuenemann/CS3500
        /// <summary>
        /// Method for sending the data to the client sockets. It goes through the list of tanks, powerups, projectiles, and beams
        /// and appends them to a stringbuilder to send. It also handles sockets that have disconnected.
        /// </summary>
        private static void SendDataToSockets()
        {
            lock (TheWorld)
            {
                foreach (SocketState s in SocketConnections.ToList())
                {
                    if (!s.TheSocket.Connected)
                    {
                        int tankID = (int)s.ID;

                        //Makes sure that the dictionary contains the right key. If not, the tank must have died and rage quit
                        if (TheWorld.Tanks.ContainsKey(tankID))
                        {
                            Console.WriteLine("Player(" + tankID + ") " + "\"" + TheWorld.Tanks[(int)s.ID].Name + "\" disconnected");

                            TheWorld.TankDisconnect(tankID);
                            TheWorld.TankKill(tankID);
                        }

                        if (TheWorld.DeadTanks.ContainsKey(tankID))
                        {
                            Console.WriteLine("Player(" + tankID + ") " + "\"" + TheWorld.DeadTanks[(int)s.ID].Name + "\" disconnected");
                            TheWorld.TankDeadRemove(tankID);
                        }

                        SocketConnections.Remove(s);
                    }
                }

                foreach (SocketState s in SocketConnections.ToList())
                {
                    StringBuilder frameMessage = new StringBuilder();


                    lock (TheWorld)
                    {
                        foreach (Tank t in TheWorld.Tanks.Values)
                        {
                            frameMessage.Append(JsonConvert.SerializeObject(t) + "\n");
                        }

                        foreach (PowerUp p in TheWorld.PowerUps.Values)
                        {
                            frameMessage.Append(JsonConvert.SerializeObject(p) + "\n");
                        }

                        foreach (Projectile p in TheWorld.Projectiles.Values)
                        {
                            frameMessage.Append(JsonConvert.SerializeObject(p) + "\n");
                        }

                        foreach (Beam b in TheWorld.Beams.Values)
                        {
                            frameMessage.Append(JsonConvert.SerializeObject(b) + "\n");
                        }
                    }

                    if (!Networking.Send(s.TheSocket, frameMessage.ToString()))
                    {
                        Console.WriteLine("Error occured while sending data");
                    }
                }
            }
        }
예제 #5
0
        private static void Main(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.White;
            Console.Title           = "ENVIUM DEDICATED SERVER";

            Out.MsgC(ConsoleColor.Green, "Initializing the server ...");

            _buffer        = new byte[4096];
            _boundEndPoint = new IPEndPoint(IPAddress.Any, 644);

            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            _socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            try {
                _socket.Bind(_boundEndPoint);
            } catch (SocketException ex) {
                Out.Error("Network: Cannot bound at address {0}: {1}", _boundEndPoint, ex.Message);
                Console.ReadLine();
                return;
            }

            Out.Msg("Network: Socket bounded at {0}", _socket.LocalEndPoint as IPEndPoint);

            FrameSnapshotManager = new FrameSnapshotManager();
            ServerPluginHandler  = new ServerPlugin();
            Server = new GameServer(_socket)
            {
                State        = EServerState.Loading,
                TickInterval = GetTickInterval()
            };

            Networking.Initialize();

            new Thread(GameTick)
            {
                IsBackground = true
            }.Start();
            Server.State = EServerState.Active;
            Out.Msg("Done loading.");

            var clientEp = (EndPoint) new IPEndPoint(IPAddress.Any, 0);

            _socket.BeginReceiveFrom(_buffer, 0, _buffer.Length, SocketFlags.None, ref clientEp, DoReceiveFrom, clientEp);

            string read;

            while ((read = Console.ReadLine()) != "exit")
            {
                if (read == "help")
                {
                    continue;
                }

                if (read == "curtime")
                {
                    var time = Utils.SysTime();
                    Console.WriteLine("Current server time: {0}", time);
                    continue;
                }

                Console.WriteLine("Unknown command \"{0}\".", read);
            }
        }
 public void Attach(Networking Networking)
 {
     this.Networking = Networking;
     Networking.HookPacket <HelloPacket>(HelloPacketRecieved);
     Networking.ClientConnected += Networking_ClientConnected;
 }
예제 #7
0
 /// <summary>
 /// This method is called the first time a client connects
 /// </summary>
 /// <param name="state"></param>
 private static void RecieveStartupInfo(SocketState state)
 {
     controller.UpdateWorld(state);
     state.OnNetworkAction = ReceiveMessageFromClient;
     Networking.GetData(state);
 }
예제 #8
0
        public static void HandleNewClients(SocketState s)
        {
            s.callMe = ReceiveName;

            Networking.GetData(s);
        }
예제 #9
0
 /// <summary>
 /// starts the server on the specified port
 /// </summary>
 private static void StartServer()
 {
     Networking.StartServer(OnStart, 11000);
 }
예제 #10
0
        private void SendData()
        {
            while (true)
            {
                List <SocketState> playerSocketCopy = new List <SocketState>(playerSockets.Values);
                StringBuilder      sb           = new StringBuilder();
                List <long>        listToRemove = new List <long>();
                var prev = DateTime.Now;

                //For every socket connected to this server send a frame
                foreach (SocketState state in playerSocketCopy)
                {
                    foreach (Tank t in world.GetTanks())
                    {
                        t.projectileDelay += 1;
                    }
                    if (powerUpTracker < powerupCount)
                    {
                        timeSinceLastPowerUp += FPS;
                    }
                    if (timeSinceLastPowerUp > randPowerupTime)
                    {
                        SpawnPowerup();
                        randPowerupTime      = rand.Next(0, maxPowerupSpawnTime);
                        timeSinceLastPowerUp = 0;
                    }

                    //Seems innefficient to do this for every tank but.. TODO
                    lock (world)
                    {
                        foreach (Tank t in world.GetTanks())
                        {
                            sb.Append(JsonConvert.SerializeObject(t) + "\n");
                            if (t.IsDead())
                            {
                                RespawnTank(t);
                            }
                            if (t.IsDisconnected())
                            {
                                listToRemove.Add(t.GetID());
                            }
                        }

                        foreach (long ID in listToRemove)
                        {
                            world.RemoveTankByID((int)ID);
                        }
                        listToRemove.Clear();

                        foreach (Projectile p in world.GetProjectiles())
                        {
                            MoveProjectile(p);
                            sb.Append(JsonConvert.SerializeObject(p) + "\n");
                            if (p.IsDead())
                            {
                                listToRemove.Add(p.GetID());
                            }
                        }
                        foreach (long ID in listToRemove)
                        {
                            world.RemoveProjectile(ID);
                        }

                        listToRemove.Clear();
                        foreach (Beam b in world.GetBeams())
                        {
                            sb.Append(JsonConvert.SerializeObject(b) + "\n");
                            listToRemove.Add(b.GetID());
                        }
                        foreach (long ID in listToRemove)
                        {
                            world.RemoveBeam(ID);
                        }
                        listToRemove.Clear();
                        foreach (Powerup up in world.GetPowerups())
                        {
                            sb.Append(JsonConvert.SerializeObject(up) + "\n");
                            if (up.IsDead())
                            {
                                listToRemove.Add(up.GetID());
                            }
                        }
                        if (!working)
                        {
                            foreach (long ID in listToRemove)
                            {
                                world.RemovePowerup(ID);
                                powerUpTracker--;
                            }
                        }
                    }
                    listToRemove.Clear();
                    List <SocketState> mySockets = new List <SocketState>(playerSockets.Values);
                    foreach (SocketState player in mySockets)
                    {
                        Networking.Send(player.TheSocket, sb.ToString());
                    }

                    //Console.WriteLine(sb.ToString());
                    sb.Clear();
                }
                //managing the framerate for when this loop repeats
                var now = DateTime.Now;
                if (now <= prev.AddMilliseconds(FPS))
                {
                    TimeSpan timeSpan = prev.AddMilliseconds(FPS) - now;
                    System.Threading.Thread.Sleep((int)timeSpan.TotalMilliseconds);
                }
                prev = DateTime.Now;
            }
        }
예제 #11
0
        /// <summary>
        /// Detects the incoming messages of new players when they connect then calls Get Data in order to create an event loop to continue listening for
        /// new incoming players
        /// </summary>
        /// <param name="state">Connection of incoming player.</param>
        private void ProcessMessage(SocketState state)
        {
            string data;
            long   ID = state.ID;

            string[] movingCommands;

            if (state.ErrorOccured)
            {
                PlayerDisconnect(state);
                Networking.SendAndClose(state.TheSocket, "error");
                //Networking.GetData(state);
                return;
            }

            data = state.GetData();
            state.ClearData();
            if (String.IsNullOrEmpty(data))
            {
                Networking.GetData(state);
                return;
            }


            //checks to see if user is sending a user command or name
            if (data.StartsWith("{\"moving\""))
            {
                movingCommands = data.Split(',');
                foreach (string s in movingCommands)
                {
                    string[] command = s.Split(':');
                    foreach (string t in command)
                    {
                        string tempString      = t.Replace("\"", String.Empty);
                        string tempString2     = tempString.Replace("{", String.Empty);
                        string stringToCompare = tempString2.Replace("}", String.Empty);
                        switch (stringToCompare)
                        {
                        case "none":
                            break;

                        case "up":
                            MoveTank(new Vector2D(0, playerSpeed * -1), new Vector2D(0, -1), players[ID]);
                            break;

                        case "down":
                            MoveTank(new Vector2D(0, playerSpeed), new Vector2D(0, 1), players[ID]);
                            break;

                        case "left":
                            MoveTank(new Vector2D(playerSpeed * -1, 0), new Vector2D(-1, 0), players[ID]);
                            break;

                        case "right":
                            MoveTank(new Vector2D(playerSpeed, 0), new Vector2D(1, 0), players[ID]);
                            break;

                        case "main":
                            FireProjectile(players[ID]);
                            break;

                        case "alt":
                            FireBeam(players[ID]);
                            break;

                        case "x":
                            if (double.TryParse(command[2], out double anglex))
                            {
                                turretAimx = anglex;
                            }
                            break;

                        case "y":
                            if (command[1].Length > 4)
                            {
                                if (double.TryParse(command[1].Substring(0, command[1].Length - 5), out double angley))
                                {
                                    turretAimy = angley;
                                }
                                players[ID].SetAim(new Vector2D(turretAimx, turretAimy));
                            }
                            break;
                        }
                    }
                }
            }
            else if (!players.ContainsKey(ID))
            {
                Console.WriteLine("Player " + state.ID.ToString() + " Connected.");
                CreateTank(data, ID);
                Sendwalls(state);
                Networking.GetData(state);
                return;
            }
            Networking.GetData(state);
        }
예제 #12
0
        /// <summary>
        /// Invoked every iteration through the frame loop.
        /// Update World, then sends it to each client.
        /// </summary>
        private static void Update()
        {
            // Updated world
            StringBuilder sb = new StringBuilder();

            lock (World)
            {
                // For all Stars in World
                foreach (Star star in World.Stars.Values)
                {
                    // Append each Star
                    sb.Append(JsonConvert.SerializeObject(star) + "\n");

                    // Destroy all Ships colliding with Star
                    foreach (Ship ship in World.Ships.Values)
                    {
                        Vector2D distance = star.loc - ship.loc;
                        if (distance.Length() < StarSize)
                        {
                            ship.hp = 0;
                            if (GAMEMODE_RandomDeadlyStar)
                            {
                                ship.score--;
                            }
                            ship.alive = false;
                            DeadShips.Add(ship);
                        }
                    }

                    // Destroy all Projectiles colliding with Star
                    foreach (Projectile p in World.Projectiles.Values)
                    {
                        Vector2D distance = star.loc - p.loc;
                        if (distance.Length() < StarSize)
                        {
                            p.alive = false;
                            DeadProjectiles.Add(p.ID);
                        }
                    }
                }

                // For all Ships in World
                foreach (Ship ship in World.Ships.Values)
                {
                    // Thrust Ship
                    if (ship.up)
                    {
                        ship.thrust    = true;
                        ship.velocity += Acceleration(Thrust(ship.dir), Gravity(ship.loc));
                        ship.loc      += ship.velocity;
                        ship.up        = false;
                    }
                    // Non-thrusting Ship
                    else
                    {
                        ship.velocity += Gravity(ship.loc);
                        ship.loc      += ship.velocity;
                        ship.thrust    = false;
                    }
                    // Rotate Left
                    if (ship.left)
                    {
                        ship.dir  = RotateLeft(ship.dir);
                        ship.left = false;
                    }
                    // Rotate right
                    if (ship.right)
                    {
                        ship.dir   = RotateRight(ship.dir);
                        ship.right = false;
                    }
                    // Fire projectile
                    if (ship.space && ship.alive)
                    {
                        // Begin spacing projectiles
                        ship.projectileTimer++;
                        if (ship.projectileTimer >= ProjectileFiringDelay)
                        {
                            Projectile p = new Projectile();
                            p.ID    = ProjectileID;
                            p.loc   = ship.loc;
                            p.dir   = ship.dir;
                            p.alive = true;
                            p.owner = ship.ID;

                            p.velocity = (p.dir * ProjectileSpeed) + ship.velocity;

                            World.Projectiles.Add(p.ID, p);

                            ship.projFired++;
                            ship.projectileTimer = 0;
                            ProjectileID++;
                        }
                        ship.space = false;
                    }

                    // If Ship exits World's bounds
                    if (ship.loc.GetX() >= UniverseSize / 2 || ship.loc.GetX() <= -(UniverseSize / 2) ||
                        ship.loc.GetY() >= UniverseSize / 2 || ship.loc.GetY() <= -(UniverseSize / 2))
                    {
                        // Wrap around Ship
                        ship.loc = WrapAround(ship.loc);
                    }

                    // Destroy all Projectiles colliding with Ship and vise-versa
                    foreach (Projectile p in World.Projectiles.Values)
                    {
                        Vector2D distance = ship.loc - p.loc;

                        if (distance.Length() < ShipSize && ship.ID != p.owner && ship.alive)
                        {
                            p.alive = false;
                            ship.hp--;

                            ShipHits.Add(World.Ships[p.owner]);
                            if (ship.hp <= 0)
                            {
                                ship.alive = false;
                                DeadShips.Add(ship);
                                ScoringShips.Add(p.owner);
                            }
                            DeadProjectiles.Add(p.ID);
                        }
                    }

                    sb.Append(JsonConvert.SerializeObject(ship) + "\n");
                }

                // For all Projectiles in World
                foreach (Projectile p in World.Projectiles.Values)
                {
                    // Update projectile location with constant velocity
                    p.loc += p.velocity;

                    // If Projectile exits World's bounds
                    if (p.loc.GetX() >= UniverseSize / 2 || p.loc.GetX() <= -(UniverseSize / 2) ||
                        p.loc.GetY() >= UniverseSize / 2 || p.loc.GetY() <= -(UniverseSize / 2))
                    {
                        // Destroy Projectile
                        p.alive = false;
                        DeadProjectiles.Add(p.ID);
                    }

                    sb.Append(JsonConvert.SerializeObject(p) + "\n");
                }

                // All Projectiles-to-destroy are removed from World
                foreach (int i in DeadProjectiles)
                {
                    World.Projectiles.Remove(i);
                }
                DeadProjectiles.Clear();

                // All Ships-to-score have score increased
                foreach (int i in ScoringShips)
                {
                    Ship s = World.Ships.Values.ElementAt(i);
                    s.score++;
                }
                ScoringShips.Clear();

                // All Ships-to-destroy are removed from World and respawned
                foreach (Ship ship in DeadShips)
                {
                    if (ship.hp <= 0)
                    {
                        // Incremental value has a further effect on respawn rate
                        ship.respawnTimer += 20;
                    }
                    if (ship.respawnTimer >= RespawnDelay * TimePerFrame)
                    {
                        ship.respawnTimer = 0;
                        ResetShip(ship);
                        ResurrectedShips.Add(ship);
                    }
                }

                // Respawn dead Ship
                foreach (Ship ship in ResurrectedShips)
                {
                    DeadShips.Remove(ship);
                }
                ResurrectedShips.Clear();

                // Add hit projectiles to Ship
                foreach (Ship ship in ShipHits)
                {
                    World.Ships[ship.ID].projHit++;
                }
                ShipHits.Clear();

                // Each client is updated with appended World information
                foreach (SocketState state in Clients)
                {
                    Networking.Send(state.theSocket, sb.ToString());
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Main method responsible for running all server processes.
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            // Allowing the program to update the database when closed
            Program.SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);

            // Program start time
            LastAccessedTime = DateTime.Now;

            // XML Settings are read and adjusted...
            ReadSettings("...//...//...//Resources/settings.xml");

            World        = new World();
            Clients      = new List <SocketState>();
            ShipID       = 0;
            ProjectileID = 0;

            // Initial Star Creation
            Star star = new Star();

            // Game mode alteration
            if (GAMEMODE_RandomDeadlyStar)
            {
                Random rand = new Random();
                star.loc = new Vector2D(rand.Next(-(UniverseSize / 2), UniverseSize / 2),
                                        rand.Next(-(UniverseSize / 2), UniverseSize / 2));
            }
            else
            {
                star.loc = new Vector2D(StarX, StarY);
            }

            // Star added to World
            World.Stars.Add(0, star);


            // Temporary lists initialized
            DeadShips        = new HashSet <Ship>();
            ResurrectedShips = new List <Ship>();
            DeadProjectiles  = new List <int>();
            ScoringShips     = new HashSet <int>();
            ShipHits         = new List <Ship>();

            Watch = new Stopwatch();

            // Begin event-driven callback for handling new clients
            Networking.ServerAwaitingClientLoop(HandleNewClient);
            System.Console.Out.WriteLine("Server is running, awaiting first client...");

            // Begin forever loop which handles client data and updates and sends World data based on
            // result
            while (true)
            {
                Watch.Start();
                while (Watch.ElapsedMilliseconds < TimePerFrame)
                {
                }
                Watch.Reset();

                Update();
            }
        }