Esempio n. 1
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);
        }