// Closing connection public void CloseConnection(string caption, string text) { Data.UdpWorkSend = false; try { Data.LobbyLink.Dispatcher.Invoke(new Action(delegate() { // Clear list Data.gamerList.Clear(); Data.LobbyLink.Title = caption + ": " + text; })); try { Connected = false; if (_tcpStream != null) { _tcpStream.Flush(); _tcpStream.Close(); } if (_tcpServer != null) { _tcpServer.Close(); } if (srReceiver != null) { srReceiver.Close(); } } catch { } Data.LobbyLink.Dispatcher.Invoke(new Action(delegate() { Data.LobbyLink.Close(); Data.MainWin.Focus(); })); // Show message about reason of closing if (text != "The lobby is closed by host") { MainWin.Message(caption, text); } } catch { } Data.UdpWorkRec = false; if (Udp.receiver_server != null) { Udp.receiver_server.Close(); } }
// Create a lobby and lock the settings in the main window public void CreateLobby() { try { LobbyWin Lobby = new LobbyWin(); Lobby.Owner = Data.MainWin; Data.LobbyLink = Lobby; if (Data.LobbyTitle != null) { Lobby.Title = Data.LobbyTitle; } Data.LobbyLink.Show(); Lock(); } catch (Exception ex) { MainWin.Message("Internal error", "Try to reload the program"); } }
// Initialization public void InitializeConnection(string ip, int port) { _tcpServer = null; Set printData = new Set(); try { TryConectToRandomPortIteration(10); } // If it didn’t succeed in contacting the specified port, // the program tries random ports (10 iterations) catch (Exception ex) { if (!TryConectToRandomPortIteration(5)) { // If it didn’t turn out to find the port, we tell the player about it and exit MainWin.Message("TCP error", "Did not manage to pick up tcp port for a connection"); if (_tcpServer != null) { _tcpServer.Close(); } return; } } try { Connected = true; _ipHost = IPAddress.Parse(ip); IAsyncResult result = _tcpServer.BeginConnect(_ipHost, port, null, null); // Set timeout for connection bool success = result.AsyncWaitHandle.WaitOne(2000, true); if (!_tcpServer.Connected) { CloseConnection("Connection error", "You cannot join this lobby. Some problem with the TCP port"); return; } } // If it didn’t succeed in connecting, show a message catch (Exception ex) { CloseConnection("Connection error", "You cannot join this lobby. Some problem with the TCP"); return; } _tcpStream = _tcpServer.GetStream(); // Create an object for serialization: Gamers Gamer = new Gamers(); if (!Data.JoinToServer) { Gamer.Key = "yes"; } Gamer.Type = 0; Gamer.Name = Data.SettingCh.St.Name; Gamer.Status = 0; Gamer.Car = Data.SettingCh.St.Car; Gamer.Team = Data.SettingCh.St.Team; Gamer.Message = ip; if (Data.JoinToServer) { if (Data.webList[Data.LobbyNumber].PasswordInp == null) { Gamer.Password = ""; } else { Gamer.Password = Data.webList[Data.LobbyNumber].PasswordInp; } } // Sending to client _tcpStream.Write(Json.WriteClient(Gamer), 0, Json.WriteClient(Gamer).Length); _tcpStream.Flush(); // Open thread reciaving messages _thrMessaging = new Thread(new ThreadStart(ReceiveMessages)); _thrMessaging.Start(); }
// For receiving mssages private void ReceiveMessages() { int bufferSize = 8000; Set printData = new Set(); Set setGamer = new Set(); // Create a buffer for receiving byte[] bytes = new byte[bufferSize]; _tcpStream = _tcpServer.GetStream(); try { int bytesRead = _tcpStream.Read(bytes, 0, bytes.Length); } catch { } GamerList gamerTempList = new GamerList(); gamerTempList = Json.ReadHost(bytes); if (gamerTempList == null) { MainWin.Message("Connection error", "Connection error"); // Exit return; } switch (gamerTempList.Type) { // Error in nikename case -4: { CloseConnection("Connection error", "Invalid characters in name"); return; } // Closing room case -3: { CloseConnection("Connection error", "Lobby closed"); return; } // Wrong password case -2: { CloseConnection("Connection error", "Wrong password"); return; } // Name is already used case -1: { CloseConnection("Connection error", "Your name is already used"); return; } // If there are no errors and the request is accepted default: { Data.MainWin.Dispatcher.Invoke(new Action(delegate() { // Create lobby window Data.MainWin.CreateLobby(); })); // Accept the list of all players Data.GamersList = gamerTempList; printData.SetMassageInfo("You are logged in as " + Data.SettingCh.St.Name + "\r\n"); // Display the list in the table for (int i = 0; i < Data.GamersList.gamer.Count; i++) { setGamer.AddToGrid(i); } // Get your number Get getMyNumber = new Get(); getMyNumber.GetMyNamber(); Data.LobbyLink.Dispatcher.Invoke(new Action(delegate() { Get getMap = new Get(); // Set map Data.LobbyLink.ShowMap(Data.GamersList.Map); // Set score Data.LobbyLink.ScoreChange(Data.GamersList.Score); // Set header if (Data.JoinToServer) { string name; if (Data.webList[Data.LobbyNumber].Name.Length > 16) { name = Data.webList[Data.LobbyNumber].Name.Substring(0, 16) + "..."; } else { name = Data.webList[Data.LobbyNumber].Name; } Data.LobbyLink.Title = name + " [ " + Data.GamersList.ModOrig + " | " + Data.GamersList.LobbyType + " ]"; } else { Data.LobbyLink.Title = Data.GamersList.gamer[0].Name + "'s Lobby [ " + Data.GamersList.ModOrig + " | " + Data.GamersList.LobbyType + " ]"; } })); // Turn on UDP module Udp UdpOn = new Udp(); UdpOn.StartUDPModul(); srReceiver = new System.IO.StreamReader(_tcpStream); // While Connected == true accept messages while (Connected) { try { int byteRead; byte[] bytesHost = new byte[bufferSize]; byteRead = _tcpStream.Read(bytesHost, 0, bufferSize); if (byteRead != 0) { GamerList gamerList = new GamerList(); gamerList = Json.ReadHost(bytesHost); Data.LobbyLink.Dispatcher.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { gamerList }); } else { CloseConnection("Connection error", "The lobby is closed by host"); return; } } catch { return; } } return; } } }
// Listen and wait for messages public void ReceiveMessage() { receiver_server = null; Set printData = new Set(); int buffer_size = 256; bool firstMessLd = true; string time_now = ""; int real_ping; IPEndPoint LdIpPort = null; string message = ""; Get get_param = new Get(); // UDP port FROM FILE for listening from all IPs int portReciever = 0; if (Data.HostOrClient) { Int32.TryParse(Data.SettingCh.St.UdpPort, out portReciever); } else { Random randomUdpPort = new Random(); portReciever = randomUdpPort.Next(49152, 65535); } Data.UdpWorkRec = true; int num; try { receiver_server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); IPEndPoint localIP = new IPEndPoint(IPAddress.Any, portReciever); receiver_server.Bind(localIP); } catch (Exception ex) { MainWin.Message("Udp port error", "Failed to determine UDP port, specify it in the settings yourself"); } string[] parts; string[] partr; // Buffer for received data byte[] data = new byte[buffer_size]; byte[] data_ = new byte[6]; // Client for mailing to ld (for mailing to other players) UdpClient sendToLd = new UdpClient(); // The address from which the data came EndPoint remoteIp = new IPEndPoint(IPAddress.Any, 0); if (Data.HostOrClient) { num = 1; } else { num = 0; } try { int bytes; // UDP listening cycle starts immediately and works while there is a room // first listens to ping, then receives data from clients while (Data.UdpWorkRec == true) { try { // Get data _buffer = receiver_server.ReceiveFrom(data, buffer_size, SocketFlags.None, ref remoteIp); // } catch (Exception ex) { } if (data[0] == 's') { // Converted from bytes to string to parse message = Encoding.Unicode.GetString(data, 0, 6); parts = message.Split('s'); int number = 0; Int32.TryParse(parts[1], out number); Array.Clear(data, 0, buffer_size); string message2 = "r" + Data.MyNamber + "r"; data_ = Encoding.Unicode.GetBytes(message2); try { { receiver_server.SendTo(data_, remoteIp); } } catch (Exception ex) { } // When ping arrives, the host always updates its data if (Data.HostOrClient) { if (Data.LastNumber != 0) { Data.GamersList.gamer[number].Udp = remoteIp as IPEndPoint; // If there is ping with everyone if (get_param.GetReadyPing()) { Data.ChatStatic.Dispatcher.Invoke(new Action(delegate() { Data.GamersList.Type = 7; Host.SendAllThread(Data.GamersList); })); // After the exchange, discard the last player before another Data.LastNumber = 0; } } } } else if (data[0] == 'r') { // Get the first ping point time_now = DateTime.Now.ToString("ss.fff"); // Converted from bytes to string to parse message = Encoding.Unicode.GetString(data, 0, _buffer); partr = message.Split('r'); int number = 0; Int32.TryParse(partr[1], out number); time_now = time_now.Replace(".", ""); stop_point[number] = 0; Int32.TryParse(time_now, out stop_point[number]); real_ping = stop_point[number] - start_point[number]; try { if (Data.GamersList.gamer[number] != null) { if (real_ping >= 1000) { double _realPing = real_ping / 1000; Data.GamersList.gamer[number].GPing = _realPing.ToString("N2"); } else if (real_ping >= 10000) { double _realPing = real_ping / 1000; Data.GamersList.gamer[number].GPing = _realPing.ToString("N1"); } else if (real_ping >= 0) { Data.GamersList.gamer[number].GPing = real_ping.ToString(); } } // If the host then I check for ping always if (Data.HostOrClient) { Data.LobbyLink.Dispatcher.Invoke(new Action(delegate() { Data.LobbyLink.CheckPing(); })); } } catch { } Array.Clear(data, 0, buffer_size); } else if (data[0] == 'u') { Set messag = new Set(); messag.SetText("UDP port is open"); } else if (data[0] < 3) { data[0] += 5; // If the first message, then determine the address if (firstMessLd == true) { // We receive data about LD and we will send them from players LdIpPort = remoteIp as IPEndPoint; firstMessLd = false; } // Mailing to all players except yourself for (int i = num; i < Data.GamersList.gamer.Count; i++) { // Send a package to everyone except myself if (Data.MyNamber != i) { try { receiver_server.SendTo(data, Data.GamersList.gamer[i].Udp); } catch (Exception ex) { } } } // Clean the buffer Array.Clear(data, 0, buffer_size); } else { data[0] -= 5; if (LdIpPort != null) { sendToLd.Send(data, data.Length, LdIpPort); } // Clean the buffer Array.Clear(data, 0, buffer_size); } } // Exit the loop and close the listening socket if (receiver_server != null) { receiver_server.Close(); } // Close the send socket on ld if (sendToLd != null) { sendToLd.Close(); } } catch (Exception ex) { } }
// Starts the server and starts receiving clients public void StartListening(string port) { // Before determining its IP, this variable is false getMyIp = false; Set message = new Set(); int portInt32 = 0; Int32.TryParse(port, out portInt32); // Configure sockets over TCP, use IP and open TCP port try { tlsClient = new TcpListener(portInt32); } catch { MainWin.Message("Connection error", "Wrong Tcp port"); } // Add the first term equal to zero instead of ourselves tcpClients.Add(null); // Start to listen try { tlsClient.Start(); // Create lobby window Data.MainWin.CreateLobby(); Data.MyNamber = 0; message.SetMassageInfo("Waiting other players...\r\n"); // Set a unique session number and will transmit it Data.GamersList.IdSession = DateTime.Now.ToString("dd hh:mm:ss").Replace(" ", "").Replace(".", "").Replace(":", ""); //_____________ Connect the UDP module ___________ Udp UdpOn = new Udp(); UdpOn.StartUDPModul(); } catch { MainWin.Message("Connection error", "Wrong Tcp port [2]"); return; } // UDP port FROM FILE for listening from all IPs int portUdp = 0; Int32.TryParse(Data.SettingCh.St.UdpPort, out portUdp); IPEndPoint RemoteEndPoint = null; RemoteEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), portUdp); Data.GamersList.gamer.Add(new Gamers() { Type = 0, Ping = "", Name = Data.SettingCh.St.Name, Number = 0, Status = 0, Car = Data.SettingCh.St.Car, Team = Data.SettingCh.St.Team, Udp = null, Message = null, Password = null, }); Data.GamersList.Map = Data.SettingCh.St.Map; Data.GamersList.Score = Data.SettingCh.St.Score; // if created on the server, then enable updates to the server if (Data.CreateToServer) { // Create lobby Web createLobby = new Web(); // This variable is responsible for updating Data.FollowToLobby = true; // Start creating and updating the lobby in a new thread createLobby.CreateLobbyInThread(); } Data.gamerList.Add(Data.GamersList.gamer[0]); // Create a new thread for the connection wait loop thrListener = new Thread(KeepListening); thrListener.Start(); }