Multiplayer mode c#

di il
4 risposte

Multiplayer mode c#

Buonasera a tutti, apro questo thread inerente ad un piccolo gioco che sto sviluppando (l'impiccato) in una modalità client-server, per affinare uno dei rami dell'informatica che più mi appassiona. Premetto che qualche settimana fa avevo già aperto un thread inerente a tale programma ma per motivi di impegno non sono riuscito a continuare a lavorarci e quindi sono ancora con tanti dubbi in testa. Molto brevemente quello che ho fatto fino ad ora è creare un'applicazione console che funge da server, a cui arrivano tutte le richieste e le informazioni utili per il gioco (nomi dei player, ritorna gli index di posizione in una parola delle lettere ecc..) ma semplicemente in una modalità "Giocatore singolo". Il mio grande motivo per cui ho iniziato questo progetto è perchè volevo capire come poter programmare un giochino che contenesse la modalità "Multiplayer online", in particolare volevo che: questa modalità funzioni esclusivamente se presente una connessione internet e cosa importante, capire dove andare a documentarmi per lo sviluppo di un algoritmo che, quando un giocatore sceglie codesta modalità, crei una partita con il primo player in attesa di avversario e quindi creare una partita client vs client ovviamente facendo riferimento e inviando richieste al server.

Attualmente io utilizzo la classe socket per la connessione client-server e il codice di settaggio del server è:

 static void Main (string[] args)
        {
            Console.Title = "Server";
            ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            SetupUpServer();

            Console.ReadLine();
        } 
        
        private static  void SetupUpServer()
        {            
            Console.WriteLine("Server online");
            ServerSocket.Bind(new IPEndPoint(IPAddress.Any, 100));      //Cosa serve?
            ServerSocket.Listen(5);
            ServerSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);
        }       
        
        private static void AcceptCallBack(IAsyncResult e)      //accetta le connessioni dei client
        {  
            Socket socket = ServerSocket.EndAccept(e);            
            _clientSockets.Add(socket);
            socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);
            ServerSocket.BeginAccept(new AsyncCallback(AcceptCallBack),null);
            Console.WriteLine("Client connesso"); 
        }

        private static void ReceiveCallBack(IAsyncResult e)     
        {            
            Socket socket = (Socket)e.AsyncState;
            int received = socket.EndReceive(e);
            byte[]  dataBuff = new byte[received];
            Array.Copy(_buffer, dataBuff, received);
            
            string text = Encoding.ASCII.GetString(dataBuff);           
            Console.WriteLine("Client: " + text);   
            string response = string.Empty;               

            if (text.Contains("Ottieni lettera:"))      
            {
                text = text.Substring(16);
                bool presente = _parola.Contains(text);
                switch (presente)
                {
                    case true:
                        string index = string.Empty;
                        int giro = 0;
                        foreach (char l in _parola)
                        {
                            if (l.ToString() == text)
                            {                                
                               index += giro.ToString() + " ";                               
                            }
                            giro++;
                        }
                        string indexTrim = index.Trim();       //elimino lo spazio vuoto che c'è alla fine dell'ultima posizione
                        response = indexTrim;
                        Console.WriteLine(response);
                        break;
                    case false:
                        //ritorna come risposta il numero di errori del player + il turno per poter assegnare l'immagine di errore al player che sbaglia
                        int errori = m.AggiungiErrore();
                        if (errori < 6)
                        {
                            response = "Lettera assente. Errori commessi da " + m.OttieniNomePlayer(m.turno) + ":" + errori + "-" + m.turno;
                        }
                        else
                        {
                            response = "Fine partita";
                        }
                       
                        break;
                    default:
                        response = "Lettera assente";
                        break;
                }
            }  
            if (text.Contains("Ottieni nome giocatore"))
            {
                text = text.Substring(22);
                response = m.OttieniNomePlayer(Convert.ToInt32(text));
            }
            else if (text.Contains("Player name="))      //comando variabile per settaggio nick del player
            {
                text = text.Substring(12);
                m.SettaNomiPlayers(1, text);
                response = "Ok";
                Console.WriteLine("Numero giocatori scelti: " + m.nPlayers + "\nPlayer1's name: " + m.OttieniNomePlayer(1));
            }
            else
            {
                switch (text)               //comandi fissi
                {
                    case "Un giocatore":
                        m = new Motore(1);
                        response = "Inserire il nome del giocatore";
                        break;
                    case "Due giocatori":
                        m = new Motore(2);
                        response = "Inserire il nome dei giocatori";
                        break;                        
                    case "Apertura campo di gioco":
                        db = new SQL();         //non da errore solo se sulle proprieta è messa come piattaforma di destinazione x64 (rivedere)
                        db.ApriConnessione();                        
                        _parola = m.OttieniParola();
                        response = _parola;
                        Console.WriteLine("Connessione al database: " + db.statoConn);
                        break;
                    case "Prima lettera":
                        string index = "";
                        int giro = 0;
                        foreach (char v in _parola)
                        {
                            if (v == m.OttieniLettere(0))
                            {
                                index += giro.ToString() + " ";                                
                            }
                            giro++;
                        }
                        response = index.ToString();                      
                        break;
                    case "Ultima lettera":
                        string indexU = "";
                        int giroU = 0;
                        foreach (char v in _parola)
                        {
                            if (v == m.OttieniLettere(6))
                            {                                
                                indexU += giroU.ToString() + " ";                                
                            }
                            giroU++;
                        }
                        response = indexU.ToString();                        
                        break;
                    case "Cambia turno":                      
                        response = m.OttieniNomePlayer(m.CambiaTurno());                       
                        break;
                    case "Completa":
                       switch(m.nPlayers)
                        {
                            case 1:
                                parolaIndovinate++;
                                response = "Parola successiva!";
                                break;
                            case 2:
                                if (m.OttieniPunti(1) > m.OttieniPunti(2))
                                {
                                    response = "Complimenti " + m.OttieniNomePlayer(1) + ". Hai vinto";// + "\nPunti: " + m.OttieniPunti(1);
                                }
                                else if (m.OttieniPunti(1) < m.OttieniPunti(2))
                                {
                                    response = "Complimenti " + m.OttieniNomePlayer(2) + ". Hai vinto";// + "\nPunti: " + m.OttieniPunti(1) + "\nPunti: " + m.OttieniPunti(2);
                                }
                                else
                                {
                                    response = "Pareggio";
                                }
                                break;
                        }
                        break;
                    case "Fine partita":
                        if (parolaIndovinate == 10)
                        {
                            response = "Complimenti " + m.OttieniNomePlayer(1) + ". Hai indovinato tutte le parole!";
                        }
                        if (parolaIndovinate > 0)
                        {
                            response = "Complimenti " + m.OttieniNomePlayer(1) +  ". Parole indovinate: " + parolaIndovinate;
                        }
                        else
                        {
                            response = "Hai indovinato " + parolaIndovinate + " parole" + ", allenati per migliorare!";
                        }                        
                        break;
                    default:
                        m = new Motore();
                        response = "No";
                        break;
                }               
            }          
           
            byte[] data = Encoding.ASCII.GetBytes(response);
            socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallBack), socket);
            socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);           
        }

        private static void SendCallBack(IAsyncResult e)
        {
            Socket socket = (Socket)e.AsyncState;
            socket.EndSend(e);
        }
per il client invece:

Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

private void SendLoop(string message)
        {
            //while (true)
            //{                
            // string req = txtMessageSend.Text;            
                            

                //byte[] receiveddBuff = new byte[1024];
                //int record = clientSocket.Receive(receiveddBuff);
                //byte[] datta = new byte[record];
                //Array.Copy(receiveddBuff, datta, record);
                //txtRisposta.Text += Environment.NewLine + "Server: " + Encoding.ASCII.GetString(datta);
                //txtRisposta.Text += Environment.NewLine + "Server: Inserire una richiesta";
                //return;
            

            byte[] buffer = Encoding.ASCII.GetBytes(message);
                clientSocket.Send(buffer);         
            
                byte[] receivedBuff = new byte[1024];
               int rec =  clientSocket.Receive(receivedBuff);
                byte[] data = new byte[rec];
                Array.Copy(receivedBuff, data, rec);
                txtRisposta.Text += Environment.NewLine + "Server: " + Encoding.ASCII.GetString(data);             
                txtRisposta.Text += Environment.NewLine + "Server: Inserire una richiesta";           
            //}
        }

        private void LoopConnect()
        {
            int attempts = 0;
            
            while (!clientSocket.Connected)
            {
                try
                {
                    attempts++;
                    clientSocket.Connect(IPAddress.Loopback, 100);
                }
                catch (SocketException ex)
                {
                    MessageBox.Show("Tentativi di connessione: " + attempts);
                }
            }
            txtStatus.Text = "Connesso";
            txtRisposta.Text += "Server: Inserire una richiesta";
        }

        private void Client_DataReceveid(object sender, SimpleTCP.Message e)
        {           
           txtStatus.Invoke((MethodInvoker)delegate ()
            {
                txtStatus.Text += e.MessageString;               
            });
        }
P.s: i codici per la connessione client-server con le rispettive funzioni (LoopConnect, SendLoop ecc..) li ho visti da un video su youtube
Colgo l'occasione per ringraziare a chiunque mi aiuterà, spero di essere stato esaustivo con la richiesta

4 Risposte

  • Re: Multiplayer mode c#

    Data la curiosità, non ti basare su un video o un tutorial.

    Impara bene dai libri ... la programmazione di rete non è un argomento banale da affrontare con un copia incolla in un forum
  • Re: Multiplayer mode c#

    oregon ha scritto:


    Data la curiosità, non ti basare su un video o un tutorial.

    Impara bene dai libri ... la programmazione di rete non è un argomento banale da affrontare con un copia incolla in un forum

    No appunto non mi accontenterei mai di un video tutorial o un copia e incolla su un forum, e appunto per questo ho chiesto dove potermi documentare. Mi sai consigliare tu qualche libro che parli di ciò? Di sviluppo di applicativi di questo genere in c#? Grazie mille in anticipo
  • Re: Multiplayer mode c#

    Digita socket su google e tra i primi risultati ti escono varie guide e tutorial. Poi per i dettagli dei socket in c# consulta la documentazione Microsoft (documentazione tra l'altro facilmente accessibile da visual studio).

    Comunque hai detto che 2 metodi li hai presi da youtube, e in un altro c'è un commento in cui ti chiedi a cosa serve Bind, per cui sì, hai fatto copia incolla.
  • Re: Multiplayer mode c#

    dvaosta ha scritto:


    Digita socket su google e tra i primi risultati ti escono varie guide e tutorial. Poi per i dettagli dei socket in c# consulta la documentazione Microsoft (documentazione tra l'altro facilmente accessibile da visual studio).

    Comunque hai detto che 2 metodi li hai presi da youtube, e in un altro c'è un commento in cui ti chiedi a cosa serve Bind, per cui sì, hai fatto copia incolla.
    Ma infatti io l'ho dichiarato averlo visto da youtube e comunque il mio commento è appunto ideato in modo che quando mi sistemo più con il codice approfondisco e faccio ricerce su tutti gli aspetti che non mi sono chiari
Devi accedere o registrarti per scrivere nel forum
4 risposte