//first connect to the server private void FirstContact(SocketState state) { state.callMe = ReceiveStartup; NController.Send(socket, name + "\n"); NController.GetData(state); }
/// <summary> /// there are four steps for the server /// (1) read xml to get necessary information /// (2)initalize a new world and add info to the new world /// (3)uisng serverawaitClientloop to awit client join in /// (4)using update method to send update info to the client /// </summary> /// <param name="args"></param> static void Main(string[] args) { xmlRead(); watch = new Stopwatch(); list = new LinkedList <SocketState>(); watch.Start(); liveStar = new Stopwatch(); liveStar.Start(); theworld = new world(); sta.setLoc(new Vector2D(200, -200)); star ss = new star(1, new Vector2D(200, 200), 0.01); theworld.addStar(sta); theworld.addStar(ss); theworld.setSize(UniverSize); theworld.setRespawn(RespawnRate); theworld.setFrame(MSperFrame); NController.ServerAwaitClientLoop(HandleNewClient); Console.WriteLine("our server start, and client could join in now"); //create a new thread to update the world and send the updated info to the client Task task = new Task(() => { while (true) { update(); } }); task.Start(); Console.Read(); }
/// <summary> /// deal with the iunput info about the operations of ship /// </summary> /// <param name="ss"></param> public static void userInput(SocketState ss) { String input = ss.sb.ToString(); String[] parts = input.Split('\n'); foreach (char temp in parts[0]) { if (temp != '(' && temp != ')') { if (temp != 'F') { lock (theworld) { theworld.getShip()[ss.uid].doOperate(temp); } } else { lock (theworld) { theworld.Fire(ss.uid); } } } ss.sb.Remove(0, 1); } ss.sb.Remove(0, 1); NController.GetData(ss); }
/// <summary> /// update method use to send info to the client /// </summary> public static void update() { // wait until enough time while (watch.ElapsedMilliseconds < MSperFrame) { } watch.Restart(); // use to append message StringBuilder sb = new StringBuilder(); lock (theworld) { theworld.update(); foreach (star s in theworld.getStar().Values) { sb.Append(s.ToString() + '\n'); } foreach (Ship s in theworld.getShip().Values) { sb.Append(s.ToString() + "\n"); } foreach (projectile s in theworld.getProj().Values) { sb.Append(s.ToString() + "\n"); } // clean up the unconnected ship and died stuffs theworld.cleanup(); } //check all client statuses lock (list) { foreach (SocketState ss in list.ToArray()) { if (ss.theSocket.Connected == true) { NController.Send(ss.theSocket, sb.ToString()); } // deal with the unconnected clients else { lock (theworld) { theworld.addLostID(ss.uid); theworld.getShip()[ss.uid].setLost(); } list.Remove(ss); } } } }
//get the response from the server and remove the processed message private void ReceiveStartup(SocketState state) { //String builder to receive the message StringBuilder strBuilder = state.sb; String[] group = strBuilder.ToString().Split('\n'); PlayerID = Int32.Parse(group[0]); size = Int32.Parse(group[1]); strBuilder.Remove(0, group[0].Length); strBuilder.Remove(0, group[1].Length); state.callMe = ReceiveWorld; Handlestep(); Handleresize(); NController.GetData(state); }
/// <summary> /// call back, if the client connects get the user name then generate a new ship, finally send back startup info,and add the client to the list /// </summary> public static void ReceiveName(SocketState ss) { String[] parts = ss.sb.ToString().Split('\n'); String name = parts[0]; Ship ship; lock (theworld) { ship = theworld.generateShip(name); ss.uid = ship.getID(); } lock (list) { list.AddLast(ss); Console.WriteLine("welcome player: " + ship.getName()); } NController.Send(ss.theSocket, ship.getID() + "\n" + UniverSize + "\n"); ss.sb.Clear(); ss.callMe = userInput; NController.GetData(ss); }
//the connect button to connect to the server public void ConnectButton(String ipaddress) { socket = NController.ConnectToServer(FirstContact, ipaddress); }
/// <summary> /// /// </summary> /// <param name="data"></param> public void sendData(String data) { NController.Send(socket, data + "\n"); }
//get the content information of the current world from the server // and using the JSon to get the objects private void ReceiveWorld(SocketState state) { string totalData = state.sb.ToString(); string[] parts = Regex.Split(totalData, @"(?<=[\n])"); // Loop until we have processed all messages. // We may have received more than one. Ship sp = null; star st = null; projectile pj = null; 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; } if (p[0] == '{' && p[p.Length - 2] == '}') { JObject jsonObject = JObject.Parse(p); JToken tokenShip = jsonObject["ship"]; //gte the ship object from the server JToken tokenStar = jsonObject["star"]; // get the star object from the server JToken tokenProj = jsonObject["proj"]; // get the projectiles from the server if (tokenShip != null) { sp = JsonConvert.DeserializeObject <Ship>(p);// if ship is not null,get the ship } if (tokenStar != null) { st = JsonConvert.DeserializeObject <star>(p);// if the star is not null, get the star } if (tokenProj != null) { pj = JsonConvert.DeserializeObject <projectile>(p);// if the projectile is not null, get the projectile } //avoid the race condition lock (theworld) { if (sp != null) { if (sp.getHp() > 0) { theworld.addShip(sp);// if the hp is greater than 0, add to the current world if (ships.Contains(sp.getID()) == false) { ships.Add(sp.getID()); handlescore(sp); } } else { handledie(sp); ships.Remove(sp.getID()); theworld.removeShip(sp);//remove the destoryed ship } } if (pj != null) { // if the projectile is still alive, add it to the projectils group if (pj.checkAlive() == true) { theworld.addproj(pj); } // if projectile is not alive, remove it from the projectile group else { theworld.removeProjectile(pj); } } //check the star then add to the star group if (st != null) { theworld.addStar(st); } } } // Then remove it from the SocketState's growable buffer state.sb.Remove(0, p.Length); frametick(); } state.callMe = ReceiveWorld; Handlekey(); NController.GetData(state); }
/// <summary> /// callback method will be called in accpeted new client method /// </summary> /// <param name="ss"></param> public static void HandleNewClient(SocketState ss) { ss.callMe = ReceiveName; NController.GetData(ss); }