/// <summary> /// Handles data from the client - this is a delegate callback for processing client direction commands. /// It processes the command, then asks for more data. /// </summary> /// <param name="client">The client.</param> private void ReceiveDirection(SocketState client) { lock (world) { // Process direction change requests. if (world.Snakes.ContainsKey(client.ID)) { // Get the x and y coordinates of the client snake's head. int snakesHeadX = world.Snakes[client.ID].Vertices.Last.Value._x; int snakesHeadY = world.Snakes[client.ID].Vertices.Last.Value._y; string s = Regex.Match(client.Messages[0], @"\(([^)]*)\)").Groups[1].Value; int direction; // Process the message as an integer representing the direction. if (int.TryParse(s, out direction)) { // Change the direction of the head on the world map. This allows us to // receive multiple direction requests during the same frame cycle and // save only the most recent one. int currentDirection = world.WorldMap[snakesHeadX, snakesHeadY].direction; if (!(currentDirection % 2 == 0 && direction % 2 == 0) && !(currentDirection % 2 == 1 && direction % 2 == 1)) { world.WorldMap[snakesHeadX, snakesHeadY].direction = direction; } } try { Network.GetData(client); } catch (SocketException e) { Debug.WriteLine("Could not receive from client due to disconnect. " + e); } } } }
/// <summary> /// Callback for receiving client name. /// </summary> /// <param name="ss">The ss.</param> private static void ReceiveName(SocketState ss) { // Extract name from received data string name = ss.Builder.ToString(); name = name.Remove(name.Length - 1); Console.WriteLine("Received name: " + name); Network.Send(ss.Socket, ss.ID + "\n" + world.WorldSize + "\n"); clients.Add(ss); Ship newShip = new Ship(ss.ID, name, random.Next(universeSize + 1) - (universeSize / 2), random.Next(universeSize + 1) - (universeSize / 2)); // Don't start ship in star's location while (Math.Abs(newShip.Loc.GetX()) < starSize && Math.Abs(newShip.Loc.GetX()) < starSize) { newShip.Loc = new Vector2D(random.Next(universeSize + 1) - (universeSize / 2), random.Next(universeSize + 1) - (universeSize / 2)); } world.AddShip(newShip); ss.CallMe = ReceiveMoveRequest; Network.GetData(ss); }
/// <summary> /// This is a delegate callback that handles the server's side of the initial handshake. /// It receives the player's name and sends the client startup data, then requests direciton /// change information from the client. /// </summary> /// <param name="client">The client.</param> private void ReceivePlayerName(SocketState client) { // Get player's name. string playerName = client.Messages[0]; // Create snake object corresponding to new player. CreateNewPlayerSnake(playerName); // Change callback to method that handles direction change requests. client.Callback = ReceiveDirection; // Store the assigned ID into the client state. client.ID = playerCount; // Send startup information to client. Network.Send(client.Socket, playerCount + "\n" + boardWidth + "\n" + boardHeight + "\n"); playerCount++; // Can't have the server modifying the clients list if it's braodcasting a message. lock (clients) { clients.Add(client); } try { Network.GetData(client); } catch (SocketException e) { Debug.WriteLine("Could not receive from client due to disconnect. " + e); client.Socket.Shutdown(SocketShutdown.Both); client.Socket.Close(); } }
/// <summary> /// Receives move requests from clients. /// </summary> /// <param name="ss">The ss.</param> private static void ReceiveMoveRequest(SocketState ss) { String request = ss.Builder.ToString(); string[] parts = Regex.Split(request, @"(?<=[\n])"); bool thrust = false; bool fire = false; int r = 0; int l = 0; foreach (string part in parts) { if (part.Length == 0) { continue; } if (part[part.Length - 1] != '\n') { break; } if (part.Contains("T")) { thrust = true; } if (part.Contains("F")) { fire = true; } if (part.Contains("R")) { r++; } if (part.Contains("L")) { l++; } ss.Builder.Remove(0, part.Length); } lock (world) { Ship ship = world.GetShip(ss.ID); if (ship.HP > 0) { if (thrust) { ship.Thrust = true; } else { ship.Thrust = false; } if (fire) { if (ship.Fire(shotDelay * msPerFrame)) { world.AddProjectile(ship.id, ship.Loc.GetX(), ship.Loc.GetY(), ship.Dir.GetX(), ship.Dir.GetY()); //DB - increase ShotsFired ship.ShotsFired++; } } if (r > l) { ship.ToTurn = 1; } else if (l > r) { ship.ToTurn = -1; } else { ship.ToTurn = 0; } } } Network.GetData(ss); }
/// <summary> /// Callback for handling new clients. /// </summary> /// <param name="ss">The ss.</param> private static void HandleNewClient(SocketState ss) { ss.CallMe = ReceiveName; Network.GetData(ss); }