/// <summary> /// Bans a client from the network when the kick button is pressed. /// </summary> /// <param name="sender">Object that invoked this event.</param> /// <param name="e">Reason why this event was invoked.</param> private void banPeerButton_Click(object sender, EventArgs e) { string selectedPeer = ""; int clientID = 0; if (peerListView.SelectedItems.Count != 0) selectedPeer = peerListView.SelectedItems[0].Text; if (int.TryParse(selectedPeer, out clientID) == false) return; // Open ban window. BanWindow banWindow = new BanWindow(); if (banWindow.ShowDialog(this) == DialogResult.OK) { NetworkPacket packet = new NetworkPacket(); packet.ID = "BAN".GetHashCode(); foreach (NetworkClient client in NetworkManager.Connection.ClientList) if (client.ID == clientID) { // Send it the explanation packet. client.Connection.SendPacket(packet); // Create a ban. NetworkBan ban = new NetworkBan("000.000.000.000", -1, banWindow.BanExpiration); NetworkManager.BansList.Add(ban); // Add its IP to the black list. if (banWindow.BanIP == true) { string currentIP = client.Connection.Socket.RemoteEndPoint.ToString(); if (currentIP.IndexOf(":") >= 0) currentIP = currentIP.Substring(0, currentIP.IndexOf(":")); ban.IP = currentIP; } // Ban its account (if its logged in). if (banWindow.BanAccount == true && client.LoggedIn == true) ban.AccountID = client.AccountID; // Close its connection. client.Connection.Close(); } DebugLogger.WriteLog("Banning client " + clientID + "."); } }
/// <summary> /// Invoked when this server recieves a packet from this client. /// </summary> /// <param name="asyn">Asyncronous state.</param> private void OnRecievePacket(IAsyncResult asyn) { if (_socket == null || (_socket.Connected == false && _isListening == false && _isConnected == true)) return; try { // Reading the header. if (_recieveBuffer.Length == NetworkPacket.HEADER_SIZE) { // Finish recieving. _socket.EndReceive(asyn); // Decode the header. _recievedPacket = new NetworkPacket(); _recievedPacket.Decode(_recieveBuffer, true, false); _globalBytesRecieved += _recieveBuffer.Length; _bytesRecieved += _recieveBuffer.Length; // No extra data? if (_recievedPacket.DataLength <= 0) { // Evaluate the packet. if (EvaluatePacket(_recievedPacket) == false) { if (PacketRecieved != null) PacketRecieved(this, _recievedPacket); if (_asyncRecievePacketID == -1 || _recievedPacket.ID == _asyncRecievePacketID) _asyncRecievePacket = _recievedPacket; _recievedPacket = null; } // Go back to recieving general data. BeginRecieving(NetworkPacket.HEADER_SIZE); } else { // Read in the rest of the packet. BeginRecieving(_recievedPacket.DataLength); } } // Reading the data. else { // Finish recieving. _socket.EndReceive(asyn); // Decode rest of data. _recievedPacket.Decode(_recieveBuffer, false, true); _globalBytesRecieved += _recieveBuffer.Length; _bytesRecieved += _recieveBuffer.Length; // Evaluate the packet. if (EvaluatePacket(_recievedPacket) == false) { if (PacketRecieved != null) PacketRecieved(this, _recievedPacket); if (_asyncRecievePacketID == -1 || _recievedPacket.ID == _asyncRecievePacketID) _asyncRecievePacket = _recievedPacket; _recievedPacket = null; } // Go back to recieving general data. BeginRecieving(NetworkPacket.HEADER_SIZE); } } catch (Exception) { } }
/// <summary> /// Invoked when a client attempts to connect to this server. /// </summary> /// <param name="asyn">Asyncronous state.</param> private void OnClientConnect(IAsyncResult asyn) { if (_socket == null || (_socket.Connected == false && _isListening == false && _isConnected == true)) return; lock (_clientList) { try { Socket clientSocket = _socket.EndAccept(asyn); NetworkConnection clientConnection = new NetworkConnection(clientSocket); // To many clients? if (_clientList.Count >= NetworkManager.MaximumClients) { DebugLogger.WriteLog("Denied connection from " + clientSocket.RemoteEndPoint.ToString() + ", maximum clients already connected."); NetworkPacket banPacket = new NetworkPacket(); banPacket.ID = "CONNECTION_RESULT".GetHashCode(); banPacket[0] = (byte)2; banPacket[1] = (int)0; clientConnection.SendPacket(banPacket); clientSocket.Close(); return; } // Is this IP banned? bool banned = false; string currentIP = clientSocket.RemoteEndPoint.ToString(); if (currentIP.IndexOf(":") >= 0) currentIP = currentIP.Substring(0, currentIP.IndexOf(":")); foreach (NetworkBan ban in NetworkManager.BansList) { if (ban.IsIPBanned(currentIP.ToLower())) { banned = true; break; } } if (banned == true) { DebugLogger.WriteLog("Denied connection from " + clientSocket.RemoteEndPoint.ToString() + ", IP address is banned."); NetworkPacket banPacket = new NetworkPacket(); banPacket.ID = "CONNECTION_RESULT".GetHashCode(); banPacket[0] = (byte)1; banPacket[1] = (int)0; clientConnection.SendPacket(banPacket); clientSocket.Close(); return; } // Work out a new unique ID for this client. int id = 0; while (true) { bool found = false; foreach (NetworkClient subclient in _clientList) if (subclient.ID == id) found = true; if (found == false) break; id++; } // Create a new client object to store details on this connection. NetworkClient client = new NetworkClient(); client.Connection = clientConnection; client.ID = id; _clientList.Add(client); // Ackowledge its existance. NetworkPacket helloPacket = new NetworkPacket(); helloPacket.ID = "CONNECTION_RESULT".GetHashCode(); helloPacket[0] = (byte)0; helloPacket[1] = id; client.Connection.SendPacket(helloPacket); // Log this connection. DebugLogger.WriteLog("Accepted connection from " + clientSocket.RemoteEndPoint.ToString() + ", connection assigned id " + id); // Throw an event. if (ClientConnected != null) ClientConnected(this, client); // Go back to waiting for client connections. _socket.BeginAccept(new AsyncCallback(OnClientConnect), null); } catch (Exception) { return; } } }
/// <summary> /// Evaluates a recieved packet to see if its a internal message. /// </summary> /// <param name="packet">Packet that has been recieved.</param> /// <returns>True if packet is an internal message.</returns> private bool EvaluatePacket(NetworkPacket packet) { if (packet.ID == "PONG".GetHashCode()) { _pingAverageCount++; _pingAverageCounter += (float)_pingTimer.DurationMillisecond; _ping = _pingAverageCounter / _pingAverageCount; _waitingForPong = false; return true; } else if (packet.ID == "PING".GetHashCode()) { NetworkPacket pongPacket = new NetworkPacket(); pongPacket.ID = "PONG".GetHashCode(); SendPacket(pongPacket); return true; } return false; }
/// <summary> /// Sends a packet down this connection. /// </summary> /// <param name="packet">Packet to send down this connection.</param> public void SendPacket(NetworkPacket packet) { if (_socket == null || (_socket.Connected == false && _isListening == false && _isConnected == true)) return; try { byte[] data = packet.Encode(); _socket.Send(data); _bytesSent += data.Length; _globalBytesSent += data.Length; } catch (Exception) {} }
/// <summary> /// Waits until a given packet is recieved and returns it. /// </summary> /// <param name="id">ID of packet to recieve. -1 for first available packet.</param> /// <param name="timeout">Maximum time to wait for packet.</param> /// <returns>Recieved packet.</returns> public NetworkPacket RecievePacket(int id, int timeout) { _asyncRecievePacketID = id; _asyncRecievePacket = null; HighPreformanceTimer timer = new HighPreformanceTimer(); while (true) { if (_asyncRecievePacket != null) return _asyncRecievePacket; Thread.Sleep(1); Application.DoEvents(); if (timer.DurationMillisecond > timeout) return null; } }
/// <summary> /// Updates this connection. /// </summary> public void Poll() { // Any clients disconnected? lock (_clientList) { ArrayList disconnectedList = new ArrayList(); foreach (NetworkClient client in _clientList) if (client.Connection.Connected == false) disconnectedList.Add(client); foreach (NetworkClient client in disconnectedList) { _clientList.Remove(client); // Well kiss my arse to. if (ClientDisconnected != null) ClientDisconnected(this, client); DebugLogger.WriteLog("Client, id " + client.ID + ", was disconnected."); } } // Have we disconnected? if (_socket.Connected == false && _isListening == false && _isConnected == true) { if (Disconnected != null) Disconnected(this); _isConnected = false; } if (_isConnected == true) { // Only bother with pings if we are not listening. if (_isListening == false) { // Not recieved a pong in the last (PingDelay * 2)? Something must have gone wrong, lets resend the packet. if (_pingTimer.DurationMillisecond > 60000 && _waitingForPong == true) _waitingForPong = false; // Time to sent a ping packet to this client? if (_pingDelayTimer.DurationMillisecond > (NetworkManager.PingDelay * 2) && _waitingForPong == false) { _pingTimer.Restart(); _pingDelayTimer.Restart(); _waitingForPong = true; // Lets send a pong message to the server. NetworkPacket pingPacket = new NetworkPacket(); pingPacket.ID = "PING".GetHashCode(); SendPacket(pingPacket); } } } }
/// <summary> /// Broadcasts a packet to all clients. /// </summary> /// <param name="packet">Packet to broadcast.</param> public void BroadcastPacket(NetworkPacket packet) { lock (_clientList) { foreach (NetworkClient client in _clientList) client.Connection.SendPacket(packet); } }
/// <summary> /// Invoked when a packet is recieved. /// </summary> /// <param name="connection">Connection that was disconnected.</param> /// <param name="packet">Packet that was recieved.</param> void OnPacketRecieved(object connection, NetworkPacket packet) { EvaluatePacket(packet); if (PacketRecieved != null) PacketRecieved(this, packet); }
/// <summary> /// Evaluates the given packet and executes the correct code based on what it contains. /// </summary> /// <param name="packet">Packet to evaluate.</param> public void EvaluatePacket(NetworkPacket packet) { }
/// <summary> /// Invoked when a packet is recieved. /// </summary> /// <param name="sender">Connection hat packet was recieved by.</param> /// <param name="packet">Packet that was recieved.</param> private static void OnPacketRecieved(object sender, NetworkPacket packet) { EvaluatePacket(packet); if (PacketRecieved != null) PacketRecieved(sender, packet); }
/// <summary> /// Evaluates the given packet and executes the correct code based on what it contains. /// </summary> /// <param name="packet">Packet to evaluate.</param> public static void EvaluatePacket(NetworkPacket packet) { if (packet.ID == "CONNECTION_RESULT".GetHashCode() && _isServer == false) { _connectionResult = (byte)packet[0]; switch ((byte)packet[0]) { case 0: // Success. _id = (int)packet[1]; break; case 1: // Banned. if (_connection.Connected == true) _connection.Close(); DebugLogger.WriteLog("Unable to connect to server, IP is banned.", BinaryPhoenix.Fusion.Runtime.Debug.LogAlertLevel.Warning); break; case 2: // To many clients. if (_connection.Connected == true) _connection.Close(); DebugLogger.WriteLog("Unable to connect to server, maximum amount of clients are already connected.", BinaryPhoenix.Fusion.Runtime.Debug.LogAlertLevel.Warning); break; } } else if (packet.ID == "CONSOLE_COMMAND".GetHashCode() && _isServer == false) { DebugLogger.WriteLog("Executing console command sent by server."); Runtime.Console.Console.ProcessCommand(packet[0].ToString()); } }
public NetworkPacketScriptObject(NetworkPacket packet) { _nativeObject = packet; }
/// <summary> /// Invoked when a packet is recieved by the network manager. /// </summary> /// <param name="sender">Connection that packet was connected from.</param> /// <param name="packet">Packet that was recieved.</param> void PacketRecieved(object sender, NetworkPacket packet) { foreach (ScriptProcess process in VirtualMachine.GlobalInstance.Processes) { NetworkPacketScriptObject packetSO = new NetworkPacketScriptObject(packet); NetworkConnectionScriptObject connectionSO = new NetworkConnectionScriptObject(sender as NetworkConnection); foreach (ScriptThread thread in process.Threads) { thread.PassParameter(connectionSO); thread.PassParameter(packetSO); thread.InvokeFunction("OnPacketRecieved", true, false); } } }
/// <summary> /// Kicks a client from the network when the kick button is pressed. /// </summary> /// <param name="sender">Object that invoked this event.</param> /// <param name="e">Reason why this event was invoked.</param> private void kickPeerButton_Click(object sender, EventArgs e) { string selectedPeer = ""; int clientID = 0; if (peerListView.SelectedItems.Count != 0) selectedPeer = peerListView.SelectedItems[0].Text; if (int.TryParse(selectedPeer, out clientID) == false) return; NetworkPacket packet = new NetworkPacket(); packet.ID = "KICK".GetHashCode(); foreach (NetworkClient client in NetworkManager.Connection.ClientList) if (client.ID == clientID) { client.Connection.SendPacket(packet); client.Connection.Close(); } DebugLogger.WriteLog("Kicking client " + clientID + "."); }
/// <summary> /// Executes the current console command on all remote machines. /// </summary> /// <param name="sender">Object that invoked this event.</param> /// <param name="e">Reason why this event was invoked.</param> private void consoleExecuteRemoteButton_Click(object sender, EventArgs e) { if (consoleClientIDCheckbox.Checked == true) { int clientID = 0; if (consoleClientIDTextBox.Text == "" || int.TryParse(consoleClientIDTextBox.Text, out clientID) == false) return; NetworkPacket packet = new NetworkPacket(); packet.ID = "CONSOLE_COMMAND".GetHashCode(); packet[0] = consoleTextBox.Text; foreach (NetworkClient client in NetworkManager.Connection.ClientList) if (client.ID == clientID) client.Connection.SendPacket(packet); DebugLogger.WriteLog("Executing remote console command '" + consoleTextBox.Text + "' on client "+clientID+"."); consoleTextBox.Text = ""; } else { NetworkPacket packet = new NetworkPacket(); packet.ID = "CONSOLE_COMMAND".GetHashCode(); packet[0] = consoleTextBox.Text; NetworkManager.Connection.BroadcastPacket(packet); DebugLogger.WriteLog("Executing remote console command '" + consoleTextBox.Text + "'."); consoleTextBox.Text = ""; } }