コード例 #1
0
        /// <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)
                );
        }
コード例 #2
0
        /// <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");
        }
コード例 #3
0
        /// <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());
        }
コード例 #4
0
        /// <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));
        }
コード例 #5
0
 /// <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);
     }
 }
コード例 #6
0
        /// <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);
        }
コード例 #7
0
        /// <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());
        }
コード例 #8
0
        /// <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();
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
 /// <summary>
 /// Asynchronously begins listening for client data.
 /// </summary>
 public void BeginListeningAsync()
 {
     AbstractNetworking.GetData(_state);
 }
コード例 #12
0
 /// <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);
 }
コード例 #13
0
 /// <summary>
 /// Sends a message to the server requesting an Undo action.
 /// </summary>
 public void Undo()
 {
     AbstractNetworking.Send(_socketState, UNDO);
 }
コード例 #14
0
 /// <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);
 }
コード例 #15
0
 /// <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);
 }
コード例 #16
0
        /// <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);
        }
コード例 #17
0
 /// <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);
 }
コード例 #18
0
 /// <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);
 }
コード例 #19
0
 /// <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);
 }