public void ReceiveData(SocketState state) { StringBuilder sb = state.sb; JsonSerializerSettings settings = new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error }; try { char[] separator = new char[] { '\n' }; string[] strArray = sb.ToString().Split(separator, StringSplitOptions.RemoveEmptyEntries); int length = strArray.Length; if (sb.ToString()[sb.Length - 1] != '\n') { length--; } List <Ship> list = new List <Ship>(); List <Ship> list2 = new List <Ship>(); for (int i = 0; i < length; i++) { string json = strArray[i]; if ((json[0] == '{') && (json[json.Length - 1] == '}')) { Ship item = null; Projectile projectile = null; Star star = null; JObject obj1 = JObject.Parse(json); JToken token = obj1["ship"]; JToken token2 = obj1["proj"]; if (token != null) { item = JsonConvert.DeserializeObject <Ship>(json, settings); } if (token2 != null) { projectile = JsonConvert.DeserializeObject <Projectile>(json, settings); } if (obj1["star"] != null) { star = JsonConvert.DeserializeObject <Star>(json, settings); } World world = this.world; lock (world) { if (item != null) { if (this.world.GetShips().ContainsKey(item.GetID())) { if (this.world.GetShips()[item.GetID()].Alive && !item.Alive) { list2.Add(item); } } else { list.Add(item); } this.world.GetShips()[item.GetID()] = item; } if (projectile != null) { if (projectile.IsAlive()) { this.world.GetProjectiles()[projectile.GetID()] = projectile; } else if (this.world.GetProjectiles().ContainsKey(projectile.GetID())) { this.world.GetProjectiles().Remove(projectile.GetID()); } } if (star != null) { this.world.GetStars()[star.GetID()] = star; } } sb.Remove(0, json.Length + 1); } } foreach (Ship ship2 in list2) { this.ShipDied(ship2); } foreach (Ship ship3 in list) { this.NewShip(ship3); } this.FrameTick(); } catch (JsonReaderException) { } catch (Exception) { } state.call_me = new Action <SocketState>(this.ReceiveData); Networking.RequestMoreData(state); }
/// <summary> /// Creates an instance from a connected client SocketState. /// </summary> /// <param name="scoreboardServerController">The scoreboard server controller instance.</param> /// <param name="state">The client's SocketState.</param> public ClientCommunicator(ScoreboardServerController scoreboardServerController, SocketState state) { _scoreboardServerController = scoreboardServerController; _state = state; // Listen for socket state events. _state.DataReceived += OnDataReceived; _state.Disconnected += OnDisconnected; }
/// <summary> /// Sends initial data to server and receives data back. /// </summary> /// <param name="state"></param> private void FirstContact(SocketState state) { Networking.Send(state.theSocket, textBox_Name.Text); state.callMe = ReceiveStartup; Networking.GetData(state); }
/// <summary> /// The function that will primarily be used to translate server information, after /// the initial connection with the server is made. /// </summary> /// <param name="state"></param> private void ProcessMessage(SocketState state) { // Lock world and the objects in it so that the enumeration loops will execute properly lock (world) { string totalData = state.sb.ToString(); // Messages are separated by newline string[] parts = Regex.Split(totalData, @"(?<=[\n])"); // Loop until we have processed all messages as we may have received more than one. foreach (string p in parts) { // Ignore empty strings added by the regex splitter if (p.Length == 0) { continue; } // The regex splitter will include the last string even if it doesn't end with a '\n', // So we need to ignore it if this happens if (p[p.Length - 1] != '\n') { break; } // Establish our JSON object tokens JObject obj = JObject.Parse(p); JToken ship = obj["ship"]; JToken star = obj["star"]; JToken Proj = obj["proj"]; // If there was a Star in this part of the message if (ship != null) { // Deserialize the JSON so we can create a Ship object within world Ship s = JsonConvert.DeserializeObject <Ship>(p); // New ship if (!world.Ships.ContainsKey(s.ID)) { world.Ships.Add(s.ID, s); world.Ships[s.ID].alive = true; } // Update ship else { world.Ships[s.ID] = s; world.Ships[s.ID].alive = true; } // Ship destroyed if (world.Ships[s.ID].hp == 0) { world.Ships[s.ID].alive = false; } // Update the Score Panel. SP.updateShips(world.Ships); } // If there was a Star in this part of the message // Follow the same premise from ship if (star != null) { Star s = JsonConvert.DeserializeObject <Star>(p); if (!world.Stars.ContainsKey(s.ID)) { world.Stars.Add(s.ID, s); } else { world.Stars[s.ID] = s; } } // If there was a Projectile in this part of the message // Follow the same premise from ship if (Proj != null) { Projectile pr = JsonConvert.DeserializeObject <Projectile>(p); if (!world.Projectiles.ContainsKey(pr.ID)) { world.Projectiles.Add(pr.ID, pr); } else { world.Projectiles[pr.ID] = pr; } // If the projectile is no longer alive, remove it from 'world'. if (!world.Projectiles[pr.ID].alive) { world.Projectiles.Remove(pr.ID); } } // Then remove the processed message from the SocketState's growable buffer state.sb.Remove(0, p.Length); } } // Draw the updated world on both the game and score panels Drawer(state); // Finally, ask for more data // This will start an event loop Networking.GetData(state); }
/// <summary> /// A helper function called by the client to receive more data /// </summary> /// <param name="state"></param> public static void GetData(SocketState ss) { // Start listening for more parts of a message, or more new messages ss.theSocket.BeginReceive(ss.messageBuffer, 0, ss.messageBuffer.Length, SocketFlags.None, ReceiveCallback, ss); }
/// <summary> /// This method is the final delegate method given to the Network Controller to process the /// data from the server. It gets all server information about the world and updates both the /// view and the world. /// </summary> /// <param name="ss"></param> public void ProcessData(SocketState ss) { lock (this) { this.ss = ss; string totalData = ss.sb.ToString(); string[] parts = Regex.Split(totalData, @"(?<=[\n])"); JObject blankJSonObject; string shipToken = "thrust"; string projectileToken = "owner"; string starToken = "mass"; // Loop until we have processed all messages. // We may have received more than one. foreach (string p in parts) { // Ignore empty strings added by the regex splitter if (p.Length == 0) { continue; } // The regex splitter will include the last string even if it doesn't end with a '\n', // So we need to ignore it if this happens. if (p[p.Length - 1] != '\n') { break; } blankJSonObject = JObject.Parse(p); JToken token = blankJSonObject[shipToken]; if (token != null) { Ship newShip = JsonConvert.DeserializeObject <Ship>(p); theWorld.addShip(newShip); } token = blankJSonObject[projectileToken]; if (token != null) { Projectile newProjectile = JsonConvert.DeserializeObject <Projectile>(p); if (!newProjectile.GetAlive()) { theWorld.removeProjectile(newProjectile); } else { theWorld.addProjectile(newProjectile); } } token = blankJSonObject[starToken]; if (token != null) { Star newStar = JsonConvert.DeserializeObject <Star>(p); theWorld.addStar(newStar); } // Then remove it from the SocketState's growable buffer ss.sb.Remove(0, p.Length); } // Call event to refresh view. UpdateArrived(); if (stringToSend != null) { UserInput(stringToSend); } Network.GetData(ss); } }
/// <summary> /// This is the delegate callback passed to the networking class to handle a new client connecting. /// </summary> /// <param name="state">the state the contains the socket for this new client</param> private void HandleNewClient(SocketState state) { state.callMe = ReceiveName; Networking.GetData(state); }