Пример #1
0
        /// <summary>
        /// Gets initial data from the client, more specifically the player name. Sends initial game info to the client.
        /// </summary>
        /// <param name="state"></param>
        private static void ReceivePlayerName(SocketState state)
        {
            try
            {
                // This block splits up the server data within the StringBuilder, and places it into initialInfo.
                StringBuilder sb          = state.sb;
                char[]        separator   = new char[] { '\n' };
                string[]      initialInfo = sb.ToString().Split(separator, StringSplitOptions.RemoveEmptyEntries);

                // Assigns the ID sent by the server to the socket state for uniqie identification of connections.
                state.sb.Remove(0, initialInfo[0].Length + 1);
                string name = initialInfo[0];

                Ship newShip;
                lock (theWorld)
                {
                    newShip = theWorld.AddShipRandomPosition(name, settings.GetShotDelay(), settings.GetThrustStrength(), settings.GetTurningRate(), settings.GetStartingHP(), settings.GetShipHitBoxSize());
                }

                state.ClientCallback = HandleClientRequest;
                state.ID             = newShip.GetID();

                Networking.SendSocket(state.theSocket, "" + newShip.GetID() + "\n" + theWorld.GetSize() + "\n");

                lock (clients)
                {
                    clients.AddLast(state);
                }

                Networking.GetData(state);
            }
            catch (Exception e)
            {
                Console.WriteLine("EXCEPTION: " + e.Message);
            }
        }
Пример #2
0
        /// <summary>
        /// Callback method for any commands the player sends to the controller
        /// </summary>
        /// <param name="sock">The socketstate the connection is on</param>
        static void CommandRequestHandler(SocketState sock)
        {
            Tank main;

            //If the tank is not currently connected, don't listen to any commands from that client
            if (tanks.ContainsKey((int)sock.ID))
            {
                main = tanks[(int)sock.ID];
            }
            else
            {
                return;
            }

            // Split the command by its \n's
            string[] commands = Regex.Split(sock.GetData(), @"(?<=[\n])");
            if (commands.Length == 1)
            {
                return;
            }

            //Deserialize the command
            ControllerObject command = JsonConvert.DeserializeObject <ControllerObject>(commands[commands.Length - 2]);

            //If there is nothing in command then ignore it
            if (command == null)
            {
                return;
            }

            //If the tank is currently alive and has made it this far, listen to its commands
            if (main.hitPoints != 0)
            {
                //Process the fire status of the tank and either fire a projectile, beam, or do nothing
                switch (command.getFireStatus())
                {
                case "none":
                    break;

                case "main":
                    if (main.shotTimer > 0)
                    {
                        break;
                    }
                    Projectile shot = new Projectile();
                    main.tankTotalShots++;
                    shot.orientation = main.aiming;
                    shot.location    = main.location;
                    shot.tankID      = main.ID;
                    shot.ID          = shotCount;
                    shotCount++;
                    lock (projectiles)
                    {
                        projectiles.Add(shot.ID, shot);
                    }
                    main.shotTimer = FramesPerShot;
                    break;

                case "alt":
                    if (main.railgunShots > 0)
                    {
                        main.railgunShots--;
                        Beam railBeam = new Beam();
                        main.tankTotalShots++;
                        railBeam.direction = main.aiming;
                        railBeam.origin    = main.location;
                        railBeam.tankID    = main.ID;
                        railBeam.ID        = shotCount;
                        lock (beams)
                        {
                            beams.Add(railBeam.ID, railBeam);
                        }
                        shotCount++;
                    }

                    break;
                }

                //Variables used to track where the tank will be after the command is implemented
                double tankLocAfterMoveY;
                double tankLocAfterMoveX;

                //Process the tank's move command and update it's location based on the button that was pressed
                switch (command.getMoveDirection())
                {
                case "none":
                    main.tankVelocity = new Vector2D(0, 0);
                    break;

                case "up":
                    main.tankVelocity = new Vector2D(0, -EngineStrength);
                    tankLocAfterMoveY = main.location.GetY() + main.tankVelocity.GetY();
                    tankLocAfterMoveX = main.location.GetX() + main.tankVelocity.GetX();

                    //If the tank will hit a wall with this move, don't move it
                    if (collisionCheck(tankLocAfterMoveX, tankLocAfterMoveY))
                    {
                        main.tankVelocity = new Vector2D(0, 0);
                    }
                    //If the tank is at the edge of the world after this move, teleport it to the other side
                    else if (tankLocAfterMoveY < -serverWorld.worldSize / 2)
                    {
                        tankLocAfterMoveY = serverWorld.worldSize / 2 - 5;
                        main.location     = new Vector2D(main.location.GetX(), tankLocAfterMoveY);
                        main.orientation  = new Vector2D(0, -1);
                    }
                    //If the tank won't hit a wall or the edge, move it
                    else
                    {
                        main.location    = main.location + main.tankVelocity;
                        main.orientation = new Vector2D(0, -1);
                    }
                    break;

                case "down":
                    main.tankVelocity = new Vector2D(0, EngineStrength);
                    tankLocAfterMoveY = main.location.GetY() + main.tankVelocity.GetY();
                    tankLocAfterMoveX = main.location.GetX() + main.tankVelocity.GetX();

                    //If the tank will hit a wall with this move, don't move it
                    if (collisionCheck(tankLocAfterMoveX, tankLocAfterMoveY))
                    {
                        main.tankVelocity = new Vector2D(0, 0);
                    }
                    //If the tank is at the edge of the world after this move, teleport it to the other side
                    else if (tankLocAfterMoveY > serverWorld.worldSize / 2)
                    {
                        tankLocAfterMoveY = -serverWorld.worldSize / 2 + 5;
                        main.location     = new Vector2D(main.location.GetX(), tankLocAfterMoveY);
                        main.orientation  = new Vector2D(0, 1);
                    }
                    //If the tank won't hit a wall or the edge, move it
                    else
                    {
                        main.location    = main.location + main.tankVelocity;
                        main.orientation = new Vector2D(0, 1);
                    }
                    break;

                case "left":
                    main.tankVelocity = new Vector2D(-EngineStrength, 0);
                    tankLocAfterMoveY = main.location.GetY() + main.tankVelocity.GetY();
                    tankLocAfterMoveX = main.location.GetX() + main.tankVelocity.GetX();

                    //If the tank will hit a wall with this move, don't move it
                    if (collisionCheck(tankLocAfterMoveX, tankLocAfterMoveY))
                    {
                        main.tankVelocity = new Vector2D(0, 0);
                    }
                    //If the tank is at the edge of the world after this move, teleport it to the other side
                    else if (tankLocAfterMoveX < -serverWorld.worldSize / 2)
                    {
                        tankLocAfterMoveX = serverWorld.worldSize / 2 - 5;
                        main.location     = new Vector2D(tankLocAfterMoveX, main.location.GetY());
                        main.orientation  = new Vector2D(-1, 0);
                    }
                    //If the tank won't hit a wall or the edge, move it
                    else
                    {
                        main.location    = main.location + main.tankVelocity;
                        main.orientation = new Vector2D(-1, 0);
                    }
                    break;

                case "right":
                    main.tankVelocity = new Vector2D(EngineStrength, 0);
                    tankLocAfterMoveY = main.location.GetY() + main.tankVelocity.GetY();
                    tankLocAfterMoveX = main.location.GetX() + main.tankVelocity.GetX();

                    //If the tank will hit a wall with this move, don't move it
                    if (collisionCheck(tankLocAfterMoveX, tankLocAfterMoveY))
                    {
                        main.tankVelocity = new Vector2D(0, 0);
                    }
                    //If the tank is at the edge of the world after this move, teleport it to the other side
                    else if (tankLocAfterMoveX > serverWorld.worldSize / 2)
                    {
                        tankLocAfterMoveX = -serverWorld.worldSize / 2 + 5;
                        main.location     = new Vector2D(tankLocAfterMoveX, main.location.GetY());
                        main.orientation  = new Vector2D(1, 0);
                    }
                    //If the tank won't hit a wall or the edge, move it
                    else
                    {
                        main.location    = main.location + main.tankVelocity;
                        main.orientation = new Vector2D(1, 0);
                    }
                    break;
                }
                //Aim the turret the direction it should be facing
                main.aiming = command.getTurretDirection();
            }

            //Remove the data that has been processed and ask for more data
            sock.RemoveData(0, sock.GetData().Length);
            Networking.GetData(sock);
        }
Пример #3
0
 /// <summary>
 /// Callback method for http Connections
 /// </summary>
 /// <param name="obj">The socketstate the connection is on</param>
 private static void HandleHttpConnection(SocketState obj)
 {
     //Change the callback method then ask for more data
     obj.OnNetworkAction = ServeHttpRequest;
     Networking.GetData(obj);
 }
Пример #4
0
 /// <summary>
 /// Handler for when a client established a connection with the server.
 /// </summary>
 /// <param name="state"></param>
 private static void HandleNewClient(SocketState state)
 {
     state.ClientCallback = ReceivePlayerName;
     Networking.GetData(state);
 }
Пример #5
0
        /// <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);
        }
Пример #6
0
        public static void HandleNewClients(SocketState s)
        {
            s.callMe = ReceiveName;

            Networking.GetData(s);
        }
Пример #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
        /// <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);
        }