/// <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); } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
public static void HandleNewClients(SocketState s) { s.callMe = ReceiveName; Networking.GetData(s); }
/// <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); }
/// <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); }