/// <summary> /// Attempts to connect to the given hostname using the given nickname. /// </summary> /// <param name="hostname">The server address, excluding the port.</param> /// <param name="nickname">The nickname to use for the player connecting.</param> private void Connect(string hostname, string nickname) { // Connect to the server. ClientNetworking.ConnectToServer( hostname, 11000, state => { _socketState = state; // Listen for when data is received on the socket. _socketState.DataReceived += DataReceived; // Listen for when the socket disconnects. _socketState.Disconnected += () => { Disconnected?.Invoke(); }; // Send the nickname of the user. AbstractNetworking.Send(state, nickname + '\n'); // Wait for data. AbstractNetworking.GetData(state); }, reason => _connectionFailedCallback(reason) ); }
/// <summary> /// Receives boolean array of indicators of user input-movement for ships. Index 0 /// is the forward indicator, index 1 is the right indicator, index 2 is the left /// indicator, and index 3 is the firing indicator. /// Ships can move forward, left, right, and fire projectiles. /// Action instructions are sent to the Server through this method. /// </summary> /// <param name="indicators"></param> public void SendCommand(bool[] indicators) { if (!indicators[0] && !indicators[1] && !indicators[2] && !indicators[3]) { return; } var commandBuilder = new StringBuilder("("); if (indicators[0]) { commandBuilder.Append('T'); } if (indicators[1]) { commandBuilder.Append('R'); } if (indicators[2]) { commandBuilder.Append('L'); } if (indicators[3]) { commandBuilder.Append('F'); } commandBuilder.Append(')'); AbstractNetworking.Send(_socketState, commandBuilder + "\n"); }
/// <summary> /// Called when the world is updated by the server. /// </summary> /// <param name="world">The world that was updated.</param> private void OnWorldUpdated(World world) { // Serialize the World to JSON. var worldData = new StringBuilder(); foreach (var ship in world.GetComponents <Ship>()) { worldData.Append(JsonConvert.SerializeObject(ship)).Append("\n"); } foreach (var proj in world.GetComponents <Projectile>()) { worldData.Append(JsonConvert.SerializeObject(proj)).Append("\n"); } foreach (var star in world.GetComponents <Star>()) { worldData.Append(JsonConvert.SerializeObject(star)).Append("\n"); } // Clear the client's commands. foreach (var command in ClientCommands.Keys) { ClientCommands[command] = false; } AbstractNetworking.Send(_state, worldData.ToString()); }
/// <summary> /// This attempts to connect to the server at the ip provided. /// </summary> /// <param name="server">String ip of the server.</param> /// <param name="name">Name to send.</param> public void ConnectToServer(String server, String name = "Tarun") { // This is where we connect to the server for the first time. After the setup is done we // want our callback to be FirstContact. ClientNetworking.ConnectToServer(server, state => { SuccessfulConnection?.Invoke("Connected to host: " + server); _socketState = state; // Listen for when data is received on the socket. _socketState.DataReceived += DataReceived; // Listen for when the socket disconnects. _socketState.Disconnected += () => { Disconnected?.Invoke(); }; // Send the register message with the server. Debug.WriteLine(REGISTER, "sending register message"); AbstractNetworking.Send(state, REGISTER); // Wait for data. AbstractNetworking.GetData(state); }, reason => ErrorCallback?.Invoke(reason)); }
/// <summary> /// This method will be in charge of sending messages in a appropriate manner to the client. /// </summary> /// <param name="data"></param> public void SendMessage(string data) { if (_socketState != null) { data += END_OF_TEXT; AbstractNetworking.Send(_socketState, data); } }
/// <summary> /// Sends a message to the server requesting to load a spreadsheet of the parameter name. /// </summary> /// <param name="name"></param> public void Load(String name) { // protocol-specified string for a load message to the Server var loadMessage = LOAD_PREFIX + name + END_OF_TEXT; // sending the message to the Server AbstractNetworking.Send(_socketState, loadMessage); }
/// <summary> /// Sends the first packet that a client should receive. /// </summary> private void SendFirstPacket() { var packet = new StringBuilder(); // Player ID packet.Append(Id).Append('\n'); // World Size packet.Append(_gameServerController.Configuration.WorldSize).Append('\n'); // Send packet. AbstractNetworking.Send(_state, packet.ToString()); }
/// <summary> /// Disconnects from the server. /// This should reset this client to default state. /// </summary> public void Disconnect() { Debug.WriteLine("disconnecting"); // Sending disconnect message to the server, if state isn't null if (_socketState != null) { AbstractNetworking.Send(_socketState, DISCONNECT); } // stopping timers pingTimer?.Stop(); serverTimer?.Stop(); DisconnectSpreadsheetCallback?.Invoke(); }
/// <summary> /// Called when data is received on the socket. /// </summary> /// <param name="data">The data that was received.</param> public void DataReceived(string data) { // We know the first packet has been handled once the world is not null. if (GameWorld == null) { ParseFirstPacket(data); } else { ParseJsonPacket(data); } // Get new data. AbstractNetworking.GetData(_socketState); }
/// <summary> /// Called when data is received from the client. /// </summary> /// <param name="data">The data from the client.</param> private void OnDataReceived(string data) { // Check for nickname packet. if (!_nicknameReceived) { _nicknameReceived = true; // Trim newline from nickname and invoke event. var nickname = data.Replace("\n", ""); NicknameReceived?.Invoke(nickname); // Send the first packet to the client. SendFirstPacket(); // Listen for server events. _gameServerController.WorldUpdated += OnWorldUpdated; } else { // Thrust if (data.Contains("T")) { ClientCommands[Ship.Command.Thrust] = true; } // Left or Right if (data.Contains("L")) { ClientCommands[Ship.Command.Left] = true; } else if (data.Contains("R")) { ClientCommands[Ship.Command.Right] = true; } // Fire if (data.Contains("F")) { ClientCommands[Ship.Command.Fire] = true; } } AbstractNetworking.GetData(_state); }
/// <summary> /// Asynchronously begins listening for client data. /// </summary> public void BeginListeningAsync() { AbstractNetworking.GetData(_state); }
/// <summary> /// Sends an http response packet to the client, with the given data. /// </summary> /// <param name="data">The data of the response.</param> private void SendResponse(string data) { AbstractNetworking.Send( _state, Resources.Scoreboard_HTTP_Response_Prefix + data); }
/// <summary> /// Sends a message to the server requesting an Undo action. /// </summary> public void Undo() { AbstractNetworking.Send(_socketState, UNDO); }
/// <summary> /// Sends a message to the server requesting a Revert action with the specified cell. /// </summary> /// <param name="cell"></param> public void Revert(String cell) { AbstractNetworking.Send(_socketState, REVERT_PREFIX + cell + END_OF_TEXT); }
/// <summary> /// Sends a message to the server requesting an Edit action with the specified cell. /// </summary> /// <param name="cell"></param> public void Edit(String cell, string content) { AbstractNetworking.Send(_socketState, EDIT_PREFIX + cell + ":" + content + END_OF_TEXT); }
/// <summary> /// Called when data is received on the socket. /// </summary> /// <param name="data">The data that was received.</param> public void DataReceived(string data) { var commands = data.Split(Convert.ToChar(END_OF_TEXT)); foreach (var message in commands) { if (message.Trim() == "") { continue; } // Add back EOT after being split. var eotMessage = message + END_OF_TEXT; Debug.WriteLine(eotMessage, "data recieved from from server "); // If a disconnect message is received, Disconnect the client if (eotMessage.Equals(DISCONNECT)) { pingTimer.Stop(); serverTimer.Stop(); DisconnectSpreadsheetCallback?.Invoke(); } // If a ping is received from the Server, send a ping_response back if (eotMessage.Equals(PING)) { AbstractNetworking.Send(_socketState, PING_RESPONSE); } // If a ping response is received from the Server, the Server ping response timer is reset if (eotMessage.Equals(PING_RESPONSE)) { // timer ensuring Server is still up resets, Server has another 60 seconds until // another ping_response is necessary serverTimer.Stop(); serverTimer.Start(); } // We know the first packet has been handled once the world is not null. if (eotMessage.Equals(FILE_LOAD_ERROR) || eotMessage.StartsWith(CONNECTION_ACCEPTED_PREFIX)) { ParseFirstPacket(eotMessage); } else { // full_state is only received upon initial loading of spreadsheet // and the ping loop begins after the full_state message is received if (eotMessage.StartsWith(FULL_STATE_PREFIX)) { FullStateDocumentDocument(eotMessage); // if serverTimer reaches 60s, disconnect from the Server serverTimer = new Timer(60000) { Enabled = true, AutoReset = false }; serverTimer.Elapsed += Disconnect; // every 10 seconds (10000 milliseconds) another ping is sent to the Server pingTimer = new Timer(10000) { Enabled = true }; pingTimer.Elapsed += Ping; // ping loop begins as both timers are started pingTimer.Start(); serverTimer.Start(); } else if (eotMessage.StartsWith(CHANGE_PREFIX)) { ChangeDocument(eotMessage); } else if (eotMessage.StartsWith(FOCUS_PREFIX)) { Focus_Cell(eotMessage, FOCUS_PREFIX); } else if (eotMessage.StartsWith(UNFOCUS_PREFIX)) { Unfocus_Cell(eotMessage, UNFOCUS_PREFIX); } } } // Get new data. AbstractNetworking.GetData(_socketState); }
/// <summary> /// Sends a ping message to the Server, is the delegate used when the pingTimer's Elapse event occurs. /// </summary> public void Ping(object sender, ElapsedEventArgs e) { AbstractNetworking.Send(_socketState, PING); }
/// <summary> /// Sends a message to the server requesting a Unfocus action with the specified cell. /// Used so other clients may be notified that this client has stopped editing a cell. /// </summary> public void Unfocus() { AbstractNetworking.Send(_socketState, UNFOCUS_PREFIX + END_OF_TEXT); }
/// <summary> /// Sends a message to the server requesting a Focus action with the specified cell. /// Used so other clients may be notified that this client is editing a cell. /// </summary> /// <param name="cell"></param> public void Focus(String cell) { AbstractNetworking.Send(_socketState, FOCUS_PREFIX + cell + END_OF_TEXT); }