Ejemplo n.º 1
0
        // these 3 functions are the callbacks we will use to process data
        /// <summary>
        /// call back used for first connection
        /// </summary>
        /// <param name="state"></param>
        private void firstContact(SocketState state)
        {
            //If we failed to connect, give error message here. else set up the first bit of communication
            if (state.getID() == -1 || state.theSocket == null)
            {
                //This doesn't show up. Need to fix this
                MessageBox.Show("Connection Failed. Please Re-Enter Host-Name", "Could not reach Host", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign);
                this.Invoke((Action)(() =>
                {
                    NameTextBox.Enabled = true;

                    ServerIPTextBox.Enabled = true;

                    ConnectButton.Enabled = true;
                }));
                return;
            }
            else if (!state.theSocket.Connected)
            {
                //This doesn't show up. Need to fix this
                MessageBox.Show("Connection Failed. Please Re-Enter Host-Name", "Could not reach Host", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign);
                this.Invoke((Action)(() =>
                {
                    NameTextBox.Enabled = true;

                    ServerIPTextBox.Enabled = true;

                    ConnectButton.Enabled = true;
                }));
                return;
            }
            else
            {
                Console.WriteLine("server connection");

                //Change callback to recieve the initial bit of our world and our given ID by server
                state.callBack = InitialReceive;
                //connect to given hostname and give our name to server
                NetworkController.NetworkHandler.Send(HostServer, NameTextBox.Text);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Used to continually recieve data, after everything has been loaded in and drawn initially.
        /// </summary>
        /// <param name="state"></param>
        private void ReceiveWorld(SocketState state)
        {
            //If the conncetion was lost
            if (state.getID() == -1 || state.theSocket == null)
            {
                MessageBox.Show("Connection with host was lost.", "Connection Failure", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign);
                this.Invoke((Action)(() =>
                {
                    NameTextBox.Enabled = true;

                    ServerIPTextBox.Enabled = true;

                    ConnectButton.Enabled = true;
                }));
                return;
            }


            //save the string to read in our data
            string message = state.sb.ToString();

            SnakeUtilities.Snake newSnake = null;
            SnakeUtilities.Food  newFood  = null;

            bool worldChange = false;

            string jsObj = null;

            //Used to seperate each line into our message array.
            string[] remove = { "\n" };



            try
            {
                // Console.WriteLine(state.sb.ToString());

                //Split the message in the sb, and deserialize the json objects.
                string[] theMsg = message.Split(remove, StringSplitOptions.RemoveEmptyEntries);

                //used to determine how much we should read.
                int totalMsg = theMsg.Length;



                //If the end of the message is not complete, we do not want to process it yet.
                if (state.sb.ToString()[state.sb.Length - 1] != '\n')
                {
                    totalMsg--;
                }

                //Loop through each obj in the message until complete.
                for (int iter = 0; iter < totalMsg; iter++)
                {
                    jsObj = theMsg[iter];

                    //Console.WriteLine(jsObj);

                    //If the message is contained in braces, it is a valid Json
                    if (jsObj[0] == '{' && jsObj[jsObj.Length - 1] == '}')
                    {
                        Console.WriteLine("JSON:" + jsObj);
                        //Parse the message and check for the attributes
                        JObject findAttr = JObject.Parse(jsObj);

                        JToken verts = findAttr["vertices"];

                        JToken foodloc = findAttr["loc"];

                        JToken removesnake = findAttr["rem"];

                        //Check if msg was a vertice or not
                        if (verts != null)
                        {
                            newSnake = JsonConvert.DeserializeObject <SnakeUtilities.Snake>(theMsg[iter]);
                            //    Console.WriteLine(theMsg[iter]);
                        }
                        //Check if msg was a food or not
                        if (foodloc != null)
                        {
                            newFood = JsonConvert.DeserializeObject <SnakeUtilities.Food>(jsObj);
                            //   Console.WriteLine(theMsg[iter]);
                        }

                        if (removesnake != null)
                        {
                            var    dict = JsonConvert.DeserializeObject <Dictionary <string, string> >(jsObj);
                            string tid  = dict["ID"];

                            int tempid;

                            if (Int32.TryParse(tid, out tempid))
                            {
                                Console.WriteLine("Removing from client world:" + tempid);

                                if (world.getAllSnakes().ContainsKey(tempid))
                                {
                                    world.getAllSnakes()[tempid].killSnake();
                                }
                            }
                        }



                        //Lock here due to drawing -- source of crazy race condition and weird bug with writing the json message to console.
                        lock (this.world)
                        {
                            if (newFood != null)
                            {
                                worldChange = true;

                                //Add food or delete it from world
                                if (newFood.isFoodAlive())
                                {
                                    //Set in our food dictionary
                                    world.getAllFood()[newFood.getID()] = newFood;
                                }
                                else
                                {
                                    //Remove from food dictionary so it is no longer redrawn.
                                    world.getAllFood().Remove(newFood.getID());
                                }
                            }
                            if (newSnake != null)
                            {
                                worldChange = true;
                                //Check if snake is alive or dead, then set it accordingly
                                if (newSnake.isSnakeAlive())
                                {
                                    world.getAllSnakes()[newSnake.getID()] = newSnake;
                                }
                                else
                                {
                                    world.getAllSnakes().Remove(newSnake.getID());
                                }
                            }
                        }


                        //Only remove if the message was indeed processed correctly
                        state.sb.Remove(0, jsObj.Length + 1);
                    }
                    else
                    {
                        //Console.WriteLine("MSG RET:" + theMsg[iter]);

                        if (theMsg[iter].Equals("!DIED!"))
                        {
                            this.Invoke((Action)(() =>
                            {
                                RespawnButton.Enabled = true;
                            }));
                        }

                        state.sb.Remove(0, theMsg[iter].Length + 1);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("EXCEPTION:" + e.Message);
            }

            //Only draw the panel if the world was changed in some form. Used specifically to not waste time invalidating the screen if the message was empty.
            if (worldChange)
            {
                this.Invoke((Action)(() =>
                {
                    drawingPanel.Invalidate();
                }

                                     ));
            }



            //Recieve more data.
            NetworkHandler.AwaitDataFromServer(state);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Used to recieve the first instructions from the server, specifically what to build in the world.
        /// </summary>
        /// <param name="state"></param>
        private void InitialReceive(SocketState state)
        {
            //I still need to figure out how to give a error message if the connection failed. This does not work
            if (state.getID() == -1 || state.theSocket == null)
            {
                MessageBox.Show("Connection with host was lost.", "Connection Failure", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign);
                this.Invoke((Action)(() =>
                {
                    NameTextBox.Enabled = true;

                    ServerIPTextBox.Enabled = true;

                    ConnectButton.Enabled = true;

                    return;
                }));
            }

            try
            {
                //Used to change how big the world is based on what the server tells us
                int width  = 0;
                int height = 0;
                int ourID  = 0;

                Console.WriteLine("Server sent data. " + state.sb);

                //Parse the message here, get the id, get the width, then get the heigth and then mvoe on to receiving all data from the world.

                string[] theMsg = state.sb.ToString().Split('\n');

                // Console.WriteLine(":::" + theMsg[0] + "..." + theMsg[1] + theMsg[2]);

                //if we didn't get the whole message we should wait for more, so somehow check that we got id and world sizes.

                //Assures that we have recieved the initial data from the server, and that it is complete. Process it, and then remove it from the string builder.
                if (theMsg.Length >= 3 && state.sb.ToString()[state.sb.Length - 1] == '\n')
                {
                    ourID = int.Parse(theMsg[0]);


                    state.sb.Remove(0, theMsg[0].Length);

                    width = int.Parse(theMsg[1]);

                    state.sb.Remove(0, theMsg[1].Length);

                    height = int.Parse(theMsg[2]);


                    state.sb.Remove(0, theMsg[2].Length);
                }
                else
                {
                    //If message is not complete, we wait for more data
                    NetworkController.NetworkHandler.AwaitDataFromServer(state);
                    return;
                }


                Console.WriteLine("Our ID:" + ourID + " Our World Width and Height:" + width + "," + height);

                //Create new world based on the given h and w by server
                world = new SnakeUtilities.World(width, height);

                //Invoke so we can draw the new world on the panel

                //Need to add here how to resize the client window if the world size is too big, or maybe if it is even smaller we can resize it to scale.
                //Draw the new world with the designated size given.
                this.Invoke((Action)(() =>
                {
                    drawingPanel.Size = new Size((world.width * SnakeUtilities.World.pixelsPerCell) + SCB_OFFSET, (SnakeUtilities.World.pixelsPerCell * world.height));
                    drawingPanel.SetWorld(world);



                    //Size panelSize = drawingPanel.Size;
                    //int panWidth = panelSize.Width;
                    //int panHeight = panelSize.Height;
                    drawingPanel.Invalidate();
                }

                                     ));

                //Change call back to receive world to continuously take data and then call receive world to begin.
                state.callBack = ReceiveWorld;
                ReceiveWorld(state);
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception:" + e.Message);
            }
        }