/// <summary> /// callback method for Connect, used to send username /// </summary> /// <param name="state"></param> private void FirstContact(SocketState state) { theServer = state; // saves the state for later uses HandleConnectionError(state); // handles connection errors if occurred if (state.ErrorOccured) { return; // If an connection error occured do not allow the connection to continue; } state.OnNetworkAction = ReceiveStartup; Networking.Send(state.TheSocket, userName); Networking.GetData(state); }
/// <summary> /// Callback for Connect. Sets network action, sets server, sends playername, and finally starts receive /// </summary> private void FirstContact(SocketState state) { if (state.ErrorOccured) { return; } state.OnNetworkAction = ReceiveStartup; server = state; Networking.Send(state.TheSocket, PlayerName + "\n"); lock (state) { Networking.GetData(state); } }
/// <summary> /// This methods send the walls' coordinates information to the clients /// this will be sent only once when the client first joins /// </summary> /// <param name="state"></param> private void SendWalls(SocketState state) { lock (theServerWorld) { if (clients.Count > 0) { StringBuilder wallString = new StringBuilder(); foreach (Wall w in theServerWorld.Walls.Values) { wallString.Append(JsonConvert.SerializeObject(w) + "\n"); } Networking.Send(state.TheSocket, wallString.ToString()); } } }
/// <summary> /// When an Client connect to the server, send server player's name, and starting listening incoming data to set up walls /// </summary> /// <param name="state">SocketState</param> private void OnConnect(SocketState state) { if (state.ErrorOccured) { // inform the view Error("Error connecting to server"); return; } Networking.Send(state.TheSocket, playerName + "\n"); // Start to receive messages from the server state.OnNetworkAction = ReceiveStartUp; Networking.GetData(state); }
/// <summary> /// callback method to continuously receive data from server and send data to server /// </summary> /// <param name="state"></param> private void ReceiveWorld(SocketState state) { HandleConnectionError(state); if (state.ErrorOccured) { return; } string totalData = state.GetData(); string[] parts = Regex.Split(totalData, @"(?<=[\n])"); // 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; } ProcessMessage(p); if (UpdateArrived != null) { UpdateArrived(); } // Then remove it from the SocketState's growable buffer state.RemoveData(0, p.Length); } Networking.GetData(state); // Need to call this in order to get new string info into state control.Moving = moveArray[moveIndex]; // control's moving is set // Convert data need to send to server to JSON string string sendMessage = JsonConvert.SerializeObject(control) + "\n"; Networking.Send(state.TheSocket, sendMessage); // send data to server }
/// <summary> /// Send one json representing the world on current frame to all connected client /// </summary> private void SendWorldToClients() { string message = ""; //Send all tanks lock (theWorld.Tanks) { foreach (Tank tank in theWorld.Tanks.Values) { message += JsonConvert.SerializeObject(tank) + "\n"; } } //Send all projectiles foreach (Projectile proj in theWorld.Projectiles.Values) { message += JsonConvert.SerializeObject(proj) + "\n"; } //Send all powerups foreach (Powerup powerup in theWorld.Powerups.Values) { message += JsonConvert.SerializeObject(powerup) + "\n"; } //Send all beams foreach (Beam beam in theWorld.Beams.Values) { message += JsonConvert.SerializeObject(beam) + "\n"; } lock (_clients) { //Iterate through all clients foreach (SocketState client in _clients.Values) { if (!client.ErrorOccured) { Networking.Send(client.TheSocket, message); } } } }
/// <summary> /// Method to be invoked by the networking library when a connection is made /// </summary> /// <param name="state"></param> private void OnConnect(SocketState state) { if (state.ErrorOccured) { // inform the view Error("Error connecting to server"); return; } // inform the view Connected(); //Sets theServer with the state theServer = state; // Start an event loop to receive messages from the server state.OnNetworkAction = ReceiveStartup; Networking.Send(state.TheSocket, playerName + "\n"); Networking.GetData(state); }
/// <summary> /// OnConnect callback for Connect /// </summary> /// <param name="obj"></param> private void OnConnect(SocketState state) { if (state.ErrorOccured) { Error("Error while connecting to server"); return; } // Grab our current state theServer = state; lock (state) { // Send the player name to the server Networking.Send(state.TheSocket, PlayerName + "\n"); // Start an event loop to receive messages from the server state.OnNetworkAction = ReceiveMessage; Networking.GetData(state); } }
/// <summary> /// Once server connects, run this part of the handshake which sets server /// as a member variable representing the connection to the host /// </summary> /// <param name="ss"></param> Socket state to represent the server connection private void OnConnect(SocketState ss) { //Check if the socket state shows that an error occurred if (ss.ErrorOccured) { Error(ss.ErrorMessage); return; } //Set the callback to our startup world drawing method ss.OnNetworkAction = ReceiveStartup; //Send player name to socket Networking.Send(ss.TheSocket, playerName); //Server is now assigned to the SocketState server = ss; //Start receiving beginning setup Networking.GetData(ss); }
private void ReceivePlayerName(SocketState state) { lock (state) { if (state.ErrorOccured) { RemoveClient(state.ID); return; } string[] lines = state.GetData().Split('\n'); playerName = lines[0]; // save player name PlayerNames.Add(state.ID, playerName); state.RemoveData(0, playerName.Length); } Console.WriteLine(playerName + " joined the game."); // send ID and world size to client string sendMessage = state.ID + "\n" + theServerWorld.worldSize + "\n"; Networking.Send(state.TheSocket, sendMessage); // Save the client state // Need to lock here because clients can disconnect at any time lock (clients) { clients[state.ID] = state; } SendWalls(state); // send walls info to the client WallCollisionSize(); // extend the wall detection size Tank tank = new Tank((int)state.ID, playerName); RespawnTank(tank); theServerWorld.Tanks.Add((int)state.ID, tank); state.OnNetworkAction = ReceiveClientData; // Continue the event loop that receives messages from this client Networking.GetData(state); }
private void sendStartUpInfo(SocketState state) { if (state.ErrorOccured) { return; } ProcessMessage(state); if (users.ContainsKey(state)) { Networking.Send(state.TheSocket, users[state].ToString()); Networking.Send(state.TheSocket, world.GetSize().ToString()); state.OnNetworkAction = update; lock (state) { Networking.GetData(state); } } else { } }
/// <summary> /// We will receive the player's name and assign an ID number /// At this time we will also send to the client world size, the ID number /// and the walls /// </summary> /// <param name="client"></param> private void GetPlayerInfo(SocketState client) { //Check if error occured and write message to console if (client.ErrorOccured) { Console.WriteLine(client.ErrorMessage); } //Set the new callback action client.OnNetworkAction = GetActionDataFromClient; //Get the player name string playerName = client.GetData().Trim('\n'); //Create a new tank representing the player at a random location Tank newPlayer = new Tank(playerNumber, playerName, RandomLocationGenerator()) { //Allows the tank to fire upon spawn FrameCount = framesBetweenShot + 1 }; //We don't spawn on walls or powerups while (CheckForCollision(newPlayer, 1)) { newPlayer.Location = new Vector2D(RandomLocationGenerator()); } //Add player to our connections lock (connections) { //Send ID and worldsize info Networking.Send(client.TheSocket, playerNumber.ToString() + "\n" + serverWorld.Size.ToString() + "\n"); //Add socket state to the collection of players with their ID number connections.Add(client, playerNumber); } Console.WriteLine("Player " + playerNumber.ToString() + ": " + playerName + " has connected."); //Add player to server world lock (serverWorld.Tanks) { serverWorld.Tanks.Add(newPlayer.GetID(), newPlayer); //Increase player ID number playerNumber++; } //Create a string builder info to serialize and send all the walls StringBuilder wallinfo = new StringBuilder(); foreach (Wall wall in serverWorld.Walls.Values) { wallinfo.Append(JsonConvert.SerializeObject(wall) + "\n"); } //Send walls to the client Networking.Send(client.TheSocket, wallinfo.ToString()); //Empty the socket state of data client.ClearData(); //Begin receive loop Networking.GetData(client); }
private void SendTankControlCommand(TankControlCommand controlCommand) { string controlCommandJson = JsonConvert.SerializeObject(controlCommand) + "\n"; Networking.Send(serverSocketState.TheSocket, controlCommandJson); }
private void SendPlayerName() { string message = playerName + "\n"; Networking.Send(serverSocketState.TheSocket, message); }
private void SendStartupInfo(SocketState state, int playerID, int worldSize) { string message = playerID + "\n" + worldSize + "\n"; Networking.Send(state.TheSocket, message); }
//Send ControlCommand to server private void SendControlCommand(SocketState state) { string jsonData = JsonConvert.SerializeObject(command); Networking.Send(state.TheSocket, jsonData + "\n"); }
/// <summary> /// This method is called once per frame according to the settings. /// This method will update any projectiles, powerups and beams, /// then send all the information to each client in a Json message. /// Tank status is also updated /// </summary> private void UpdateWorld() { //Check proj collisions w/ tank or wall UpdateProjectileState(); //Create powerups to the world GeneratePowerUp(); //Build JSON and send to each client StringBuilder newWorld = new StringBuilder(); //Prepare JSON messages to be sent to each client lock (serverWorld.PowerUps) { foreach (PowerUp power in serverWorld.PowerUps.Values) { newWorld.Append(JsonConvert.SerializeObject(power) + "\n"); //Check if powerup was collected and remove if (power.collected) { serverWorld.PowerUps.Remove(power.getID()); } } } //JSON for tanks and firing logic lock (serverWorld.Tanks) { foreach (Tank t in serverWorld.Tanks.Values) { newWorld.Append(JsonConvert.SerializeObject(t) + "\n"); //Increment the framecounter for tank cooldown if it has fired if (t.HasFired) { t.FrameCount++; } //If the framecount exceeds frames per shot, we can reset and fire again if (t.FrameCount > framesBetweenShot) { t.FrameCount = 0; t.HasFired = false; } //Increment waitForRespawn level if waiting if (t.HealthLevel <= 0) { t.WaitRespawn++; //Tank is immediately alive so that animation plays only once t.HasDied = false; } //If player died, respawn after appropriate time if (t.WaitRespawn >= respawnRate) { RespawnPlayer(t); } //Check if tank has disconnected if (t.HasDisconnected) { serverWorld.Tanks.Remove(t.GetID()); } } } //JSON for projectiles lock (serverWorld.Projectiles) { foreach (Projectile p in serverWorld.Projectiles.Values) { newWorld.Append(JsonConvert.SerializeObject(p) + "\n"); //Remove from server world if dead if (p.Died) { serverWorld.Projectiles.Remove(p.getID()); } } } //JSON for beams lock (serverWorld.Beams) { foreach (Beam b in serverWorld.Beams.Values) { newWorld.Append(JsonConvert.SerializeObject(b) + "\n"); // Remove beam as soon as it has been shot for one frame serverWorld.Beams.Remove(b.GetID()); } } //JSON for powerups lock (serverWorld.PowerUps) { foreach (PowerUp p in serverWorld.PowerUps.Values) { newWorld.Append(JsonConvert.SerializeObject(p) + "\n"); //Remove from server world if collected if (p.collected) { serverWorld.PowerUps.Remove(p.getID()); } } } //Send the JSON message out to every connected client lock (connections) { foreach (SocketState clients in connections.Keys) { //Send only to connected clients if (clients.TheSocket.Connected) { Networking.Send(clients.TheSocket, newWorld.ToString()); } } } }
/// <summary> /// Method that informs the server /// </summary> public void Process() { lock (world) { String movingDir = ""; //If the keyPressed was up, then it sets moving dir to up if (keyPressedUp) { movingDir = "up"; } //If the keyPressed was left, then it sets moving dir to left if (keyPressedLeft) { movingDir = "left"; } //If the keyPressed was right, then it sets moving dir to right if (keyPressedRight) { movingDir = "right"; } //If the keyPressed was down, then it sets moving dir to down if (keyPressedDown) { movingDir = "down"; } //If the keyPressed was not pressed, then it sets moving dir to none if (!keyPressedLeft && !keyPressedDown && !keyPressedRight && !keyPressedUp) { movingDir = "none"; } String fireType = ""; //If the left mouse was pressed, sets fireType to main if (leftMousePressed) { fireType = "main"; } //If the right mouse was pressed, sets fireType to alt else if (rightMousePressed) { fireType = "alt"; } //If the left mouse and right mouse were not pressed, sets fireType to none else if (!leftMousePressed && !rightMousePressed) { fireType = "none"; } //Creates a new vector with the xCoord, and yCoord and normalizes the new vector created vec = new Vector2D(xCoord, yCoord); vec.Normalize(); //Passes this information in a ControlCommands ControlCommands c = new ControlCommands(movingDir, fireType, vec); //Serializes the control commands string serializedString = JsonConvert.SerializeObject(c); //If the server is open, then it passes the serialized string to the server if (theServer != null) { Networking.Send(theServer.TheSocket, serializedString + "\n"); } } }