Felder in ListView Komponente



  • @ Joe, genau in diesem Prinzip war mein erster Versuch, wie man an dem jpeg erkennt funktioniert es auch damit solange der Server die liste korrekt sendet.
    Das heisst wenn ein Eintrag fehlt hilft mir das sequenzielle durchgehen nichts mehr. Ohne Positionen und AnsiPos bin ich aufgeschmissen

    Was haltet ihr von diesem Quick and dirty Beispiel ? ist zwar absolut unsauber aber praktikable denk ich mal:

    for (e = 0; e < player->Count; e++)    //Durch Stringliste iterieren
           {
    
              if(player->Strings[e].AnsiPos("deaths_") == 1)   //Neuen Spieler in Liste erkennen und ID berechnen
              {
                rownumber++;
                ListView1->Items->Add();
                ListView1->Items->Item[rownumber]->Caption = rownumber + 1;
    
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
    
                ListView1->Items->Item[rownumber]->SubItems->Strings[0] = player->Strings[e + 1]; //Death
               }
    
               if(player->Strings[e].AnsiPos("playername_") == 1)
               ListView1->Items->Item[rownumber]->SubItems->Strings[1] = player->Strings[e + 1];  //Name
    
               if(player->Strings[e].AnsiPos("score_") == 1)
               ListView1->Items->Item[rownumber]->SubItems->Strings[2] = player->Strings[e + 1]; //Score
    

    EDIT: Ok, Joe, jetzt habe ich verstanden was du meinst, vergiss den Komentar oben. Vielen Dank euch allen ! 🙂



  • Nun habe ich ein ganz kurioses Problem. Der Quelltext oben funktioniert bei 50,30 ,20 Serveranfragen nur bei manchen Server wirft er eine AccessViolation. Habe rausgefunden das er eine Accessviolation nur dann auslöst wenn ich die Stringliste player mit player->Clear() vor jedem erneuten durchlauf lösche. wenn ich player->Clear weglasse läuft die Abfrage bei allen 1500 Server wie geschmiert.
    Ist halt klar das die Sringliste "player" pro Server wächst und wächst.

    Um die Lebensdauer über eine Funktion hinaus zu erhöhen habe ich die Stringliste global angelegt. Ich weiß das Globale Variablen nicht toll sind und in einer Klasse besser aufgehoben wären ,aber es funktioniert ja auch mal so zum Test.
    Leider gibt es ja auch nen dicken Fehler wenn ich die Globale mit delete während der Laufzeit freigeben möchte, logisch.

    Ich bin momentan so Hilflos das ich nicht mehr weiter weiß. Wenn doch der Code bei 50,100,150 Server problemlos die gesendete Liste auswertet und nur sporatisch bei einzelnen Server mit ner AccessViolation rausspringt. Weiß jemand Rat was ich tun kann ?? Wenn doch der Code grundliegend falsch wäre würde ich doch keine 100 Server Problemlos abfragen können, aber beim 101. oder 121. ist mit einem Schlag schluss und die Exeption wird geworfen 😞

    Was kann ich da nur tun



  • Von was wird die AccessViolation den geworfen?



  • @ Joe, wenn ich zu Hause bin kann ich dir die ganze Fehlermeldung mal hier Posten. Beim rausspringen makiert der Debugger mir die Zeile Blau. Wenn ich dann mit der maus drüber fahre bekomme ich einen Exxxxx Fehlercode mit einer genauen bezeichnung des Fehlers dahinter. Ich werde es später posten.

    Vielen Dank für deine Resonanz !



  • Also, der code Guard meldet "Access in invalid memory" und "Attempt to acces 4 bytes in 0x00000008". Egal ob Debugger Fehlermeldung und Code Guard, es taucht immer die gleiche Adresse "Read of 0x00000008" auf.

    Nach einem Klick auf eine ListBox hole ich mir IP+Port aus der Zeile

    void __fastcall TForm1::ListBox1Click(TObject *Sender)
    {
    
      char buf[20];
      String data = "\\status\\";
      int Size,lenght;
      String ip,iptemp = "",porttemp="";
    
      player->Clear();
    
      for(int i = 0; i < Form1->ListBox1->Items->Count; i++)
     {
    
        if(Form1->ListBox1->Selected[i])
        {
    
             ip = Form1->ListBox1->Items->Strings[i];
    
             for (int z = 1; z <= ip.Length(); z++)
           {
              if (ip[z] != ':')
              {
              iptemp = iptemp + ip[z];
              }
              else
              {
                z++;
                for(int a = z;a <= ip.Length();a++)
                {
                 porttemp = porttemp + ip[a];
                }
    
                z = ip.Length();
              }
            }
    
            Form1->UDPStatus1->RemoteHost = iptemp;
            Form1->UDPStatus1->RemotePort = StrToInt(porttemp);
            Form1->UDPStatus1->LocalPort = StrToInt(porttemp);
    
            strcpy(buf,data.c_str());
            Size = sizeof(buf);
            lenght = strlen(buf);
    
            Form1->UDPStatus1->SendBuffer(buf,Size,lenght);
    
        }
    
      }
    
    }
    

    Dieses Ereignis wird ausgelöst wenn das UDP Socket die Daten vom Server empfängt

    void __fastcall TForm1::UDPStatus1DataReceived(TComponent *Sender,
          int NumberBytes, AnsiString FromIP, int Port)
    {
    
      if (NumberBytes>-1 && NumberBytes<5000)
     {
    
        char buf[5000];
        int lenght,e;
        String data,temp = "";
        bool value = false;
        int rownumber = -1;
    
         Form1->UDPStatus1->ReadBuffer(buf,5000,lenght);
    
         data = buf;
    
         for (int r = 1;r <= strlen(data.c_str()) ;r++)
      {
    
         if(data[r] != '\\')
        {
    
           temp = temp + data[r];     //Zusammensetzen jeder Zeile
    
        }
    
         else
    
        {
          if (temp != "")
          {
            if(temp != "queryid")
            {
    
               if(temp.AnsiPos("final") == 1)
               {
               value = true;
               }
               else
               {
    
                player->Append(temp.c_str());    //Hinzufügen zu Player String Liste
                temp = "";
    
               }
            }
          }
        }
      }
    
       //-------------------------------------------------------
    
         if(value == true)   //Wenn die Liste fertig empfangen wurde
        {
    
            ListView1->Clear();   //säubern aller alten Einträge
    
        for (e = 0; e < player->Count; e++)    //Durch Stringliste iterieren
       {
    
              if(player->Strings[e].AnsiPos("deaths_") == 1)   //Neuen Spieler in Liste erkennen und ID berechnen
              {
    
                rownumber++;
    
                ListView1->Items->Add();
    
                ListView1->Items->Item[rownumber]->Caption = rownumber + 1;
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
                ListView1->Items->Item[rownumber]->SubItems->Add("");
    
                ListView1->Items->Item[rownumber]->SubItems->Strings[3] = player->Strings[e + 1]; //Death
    
              }
    
               if(player->Strings[e].AnsiPos("playername_") == 1 && ListView1->Items->Item[rownumber]->SubItems->Count <= 7)
               ListView1->Items->Item[rownumber]->SubItems->Strings[0] = player->Strings[e + 1];  //Name
    
               if(player->Strings[e].AnsiPos("score_") == 1 && ListView1->Items->Item[rownumber]->SubItems->Count <= 7)
               ListView1->Items->Item[rownumber]->SubItems->Strings[1] = player->Strings[e + 1]; //Score
    
               if(player->Strings[e].AnsiPos("kills_") == 1 && ListView1->Items->Item[rownumber]->SubItems->Count <= 7)
               ListView1->Items->Item[rownumber]->SubItems->Strings[2] = player->Strings[e + 1];  //Kills
    
               if (player->Strings[e].AnsiPos("ping_") == 1 && ListView1->Items->Item[rownumber]->SubItems->Count <= 7)
               ListView1->Items->Item[rownumber]->SubItems->Strings[4] = player->Strings[e + 1]; //Ping
    
               if (player->Strings[e].AnsiPos("team_") == 1 && ListView1->Items->Item[rownumber]->SubItems->Count <= 7)
               ListView1->Items->Item[rownumber]->SubItems->Strings[5] = player->Strings[e + 1]; //Team
    
               if(player->Strings[e].AnsiPos("keyhash_") == 1 && ListView1->Items->Item[rownumber]->SubItems->Count <= 7)
               ListView1->Items->Item[rownumber]->SubItems->Strings[6] = player->Strings[e + 1]; //Hashkey
    
           }
    
          //------------------------------------------------------
    
          value = false;
          Form1->Memo1->Clear();
          Form1->Memo1->Lines->AddStrings(player);
    
        }
    
      }
    }
    

    Wie gesagt klappt es bei einer Reihe von Server und bei manchen nicht.
    Der Server sendet im folgendem Format:

    \deaths_0\3\keyhash_0\ca2b68e180ce9d4e49910ca92a674626\kills_0\12\ping_0\43......
    

    ich hab echt keine Ahnung warum es Access Fehler gibt. Bitte helft mir damit ich Nachts wieder schlafen kann 😉



  • Joe_M. schrieb:

    Von was wird die AccessViolation den geworfen?

    Hi,
    ich schätze mal, Joe_M. meinte damit: In welcher Zeile tritt die AccessViolation auf? (Auf welcher Zeile steht der Debugger nach dem Stoppen?)

    MfG

    Alexander Sulfrian



  • Ab folgender Zeile:

    if(player->Strings[e].AnsiPos("kills_") == 1 && ListView1->Items->Item[rownumber]->SubItems->Count <= 7)
    ListView1->Items->Item[rownumber]->SubItems->Strings[2] = player->Strings[e + 1];
    

    Was ich merkwürdig finde ist, wenn ich player->Clear() im OnClick Ereignis weglasse das dann alles fehlerfrei läuft. Nur die Stringliste wird dann gigantisch groß. hab echt keinen Plan was das alles soll, wenn der Code so daneben wäre würde er mir doch nicht 100 Server fehlerfrei auswerten. Sporatisch steigt er bei dem ein oder anderen Server mit einer Access violation aus 😕



  • Mal ganz blöd gefragt:

    if(player->Strings[e].AnsiPos("playername_") == 1 && ListView1->Items->Item[rownumber]->SubItems->Count <= 7)
               ListView1->Items->Item[rownumber]->SubItems->Strings[0] = player->Strings[e + 1];  //Name
    

    Wie kannst du dir sicher sein, dass in der letzten Zeile e+1 in player Existiert? Schließlich leerst du ja vorher (oder sonst wann). (Wahrscheinlich Blödsinn. Aber vielleicht habe ich ja Glück und Recht. ;))



  • sobald AnsiPos("playername_") in der Stringliste vorkommt müsste logischerweiße ja auch der Name folgen,also [e + 1]



  • "sollte". Egal. Tut es das auch?! (Sorry, bei dem Chaos finde ich die richtige Exceptionmeldung nicht mehr...)

    Wenn die letzte Zeile von player playername_, score_, kill_, etc. enthält, kracht es auf jeden Fall.



  • Du hast auf jeden Fall recht, aber warum bekomme ich dann keinen Index out of bound Error ? oder hab ich da was falsch verstanden ?



  • if(player->Strings[e].AnsiPos("playername_") == 1 && e + 1 <= player->Count)
               ListView1->Items->Item[rownumber]->SubItems->Strings[0] = player->Strings[e + 1];  //Name
    

    hilft da auch nicht 😞



  • Ich glaube, (e+1) muss KLEINER als Count() sein...

    Ich dachte, dein Problem WAR ein OutOfBoundsError... 🙂 War aber wohl eine AV...

    Ausserdem fängst du nicht ab: Wenn warum auch immer "_deaths" einmal ausfällt, greifst du auf SubItems zu, die es nicht gibt, oder? //Edit: Ach so, fängst du ja ab. //Edit2: Nö, doch nicht. "<=7"?! Was soll das denn? Hast du Angst, du hast mehr als 7 Subitems?



  • Das stimmt schon -hatte mich mit dem Index geirrt, bringt aber auch nichts. Erst hatte ich nur "out of bound" errors.Sie treten jetzt nicht mehr auf, nur noch Access violation errors. Das death ausfallen kann habe ich soeben auch gemerkt. entweder ist bei der Serverprogrammierung bei Battlefield 1942 was schief gelaufen oder es liegt am UDP Protokoll das manchmal nicht alles ankommt. Aber das UDP so dermassen anfällig ist kann ich irgendwie nicht glauben weil ich schon so viel mit udp sockets gemacht habe und nie mit einer Fehlerhaften übertragung zu kämpfen hatte. Bei dem Battlefield servern sieht das irgendwie anders aus, die senden stellenweiße so einen müll wie z.b 3 mal den gleichen user oder hier und da fehlt was. Habe mir sogar schon ein dummy Programm gebastelt was einfach stur die Daten mit Append in ne MemoBox schreibt um wirklich zu überprüfen ob die fehlenden Daten nicht wegen meiner Programmierung aufgetreten sind, aber auch das ergab das der BF Server stellenweiße totaler mist sendet. Aber wie machen das die Profis von All Seeing Eye oder Gamespy ? Ich verwende ja auch das Gamespy Protokoll für die Kommunikation mit den Gameservern und dem GameSpyMaster Server um aktuelle Serverlisten abzurufen. Die müssen ja auch mit dem Arbeiten was der Server übermittelt.

    Echt mal Bahnhof 😕



  • Zero01 schrieb:

    ....es liegt am UDP Protokoll

    Naja es liegt an den Eigenschaften des Protokolls.
    😃


Anmelden zum Antworten