Programm Kommunikation
-
SendInfo(2009, INDY TCP); //
Der, der beitritt, dessen Programm friert IMMER ein, sobal ein Befehl gesendet wird die Lobby zu betreten.
Wenn der Spieler 1, und gleichzeitig der, der den Befehl sendet das Prog beendet, schmilzt der Frost bei Spieler 2 :). Und ist dies von BCB kommt die Fehlernachricht "Not-Connected".Begründung:
void __fastcall TWarInd::FormClose(TObject *Sender, TCloseAction &Action) { Spielvorbereitung->Mitgamer->Disconnect(); Spielvorbereitung->Game->Active = false; } //---------------------------------------------------------------------------
Aber ich lasse nirgends die Verbindung trennen ?.
Soll ich wirklich den ganze Quelltext posten ???
Ich hoffe, das stört nicht, aber beschränken kann ich nicht viel
cpp:Game = IdTCPServer
Mitgamer (eingentlich sollte es Mitspieler werden) = IdTCPClient.
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "GamePrepare.h" #include "LanLobby.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TSpielvorbereitung *Spielvorbereitung; Boolean OtherCon; Boolean SelfCon; Boolean Ready; Boolean MitspielerReady; int Player; //--------------------------------------------------------------------------- __fastcall TSpielvorbereitung::TSpielvorbereitung(TComponent* Owner) : TForm(Owner) { Player = 0; } //--------------------------------------------------------------------------- void __fastcall TSpielvorbereitung::GameExecute(TIdContext *AContext) { //Nothing OtherCon = true; String ReadLine = AContext->Connection->IOHandler->ReadLn(); String Wert = AContext->Connection->IOHandler->ReadLn(); if (ReadLine == "-command on name") { AContext->Connection->IOHandler->WriteLn("Spiel betreten"); } if (ReadLine != "-command LobbyShow") ServerHandle(ReadLine,Wert,AContext); if (ReadLine == "-command on name") { if (!SelfCon && OtherCon) { Status->SimpleText = ("Sie sind Spieler 2"); Lobby->Panel2->Enabled = false; Lobby->FraktionSpieler1->Enabled = false; Player = 2; } else { Status->SimpleText = "Sie sind Spieler 1"; Player = 1; Lobby->FraktionSpieler2->Enabled = false; } } if (ReadLine == "-command LobbyShow") { if (Ready) { AContext->Connection->IOHandler->WriteLn("Is Ready - Granted"); if (Player == 1) { GameStart->Show(); } } else { AContext->Connection->IOHandler->WriteLn("Not Ready - Denied"); Status->SimpleText = "Der Mitspieler ist Fertig !"; MitspielerReady = true; } } if (ReadLine == "-command ForceLobby") { if (Player == 1) { Lobby->Label2->Caption = Cname->Caption; Lobby->Label1->Caption = PlayerName->Text; } else { Lobby->Label1->Caption = Cname->Caption; Lobby->Label2->Caption = PlayerName->Text; Lobby->Panel1->Caption = "Bereit"; Lobby->Panel1->Visible = true; Lobby->redgreen->Enabled = true; } Spielvorbereitung->Hide(); Lobby->Show(); } } //--------------------------------------------------------------------------- void TSpielvorbereitung::ServerHandle(String Command, String Wert, TIdContext *AContext) { if (Command == "-command on name") { Label1->Caption = "Spieler gefunden"; Cname->Caption = Wert; Warten->Enabled = false; } if (Command == "-command LobbyShow") {} if (Command == "send changes") { if (Wert == "OK Ready") { Lobby->OK->Checked = true; } } } void __fastcall TSpielvorbereitung::MitgamerDisconnected(TObject *Sender) { Status->SimpleText = ("Die Verbindung wurde unterbrochen"); } //--------------------------------------------------------------------------- void __fastcall TSpielvorbereitung::HostenClick(TObject *Sender) { int Porter = StrToInt(Port->Text); Boolean Port_is_Blocked = true; while (Port_is_Blocked == true) { try { Game->DefaultPort = StrToInt(Port->Text); Game->Active = true; Label2->Caption = "Hosten auf Port: " + IntToStr(Game->DefaultPort); } catch(...) { Porter++; Port->Text = IntToStr(Porter); if (Porter > 2090) { ShowMessage("Kritischer Netzfehler - Unbekannte Ursache ???"); break; } } Port->Text = IntToStr(Porter); Port_is_Blocked = !Game->Active; } } //--------------------------------------------------------------------------- void __fastcall TSpielvorbereitung::MitspielenClick(TObject *Sender) { Mitgamer->Host = IP->Text; Mitgamer->Port = StrToInt(BindPort->Text); if (Mitgamer->Connected()) { Status->SimpleText = "Sie sind bereits verbunden"; } else { try { Mitgamer->Connect(); SelfCon = true; } catch(...) { Status->SimpleText = ("Ihr Gegenspieler ist noch nicht bereit"); SelfCon = false; } if (Mitgamer->Connected()) { Mitgamer->IOHandler->WriteLn("-command on name"); Mitgamer->IOHandler->WriteLn(PlayerName->Text); } Mitgamer->Disconnect(); } } //--------------------------------------------------------------------------- void __fastcall TSpielvorbereitung::FertigClick(TObject *Sender) { Ready = true; if (!MitspielerReady) { try { Mitgamer->Connect(); } catch(...) { Status->SimpleText = "Fehler beim verbinden"; } if (Label1->Caption == "Spieler gefunden" && Mitgamer->Connected()) { Mitgamer->IOHandler->WriteLn("-command LobbyShow"); Mitgamer->IOHandler->WriteLn("AmReady"); String Ready = Mitgamer->IOHandler->ReadLn(); Mitgamer->Disconnect(); if (Ready == "Is Ready - Granted") { if (Player == 1) { GameStart->Visible = true; } } else Status->SimpleText = "Der Mitspieler weiß nun, dass sie starten wollen, er kann das Spiel demnächst starten"; } } else { GameStart->Show(); } } //--------------------------------------------------------------------------- void __fastcall TSpielvorbereitung::GameStartClick(TObject *Sender) { // ---xXx--- try { Mitgamer->Connect(); } catch(...) { Status->SimpleText = "Fehler beim verbinden"; } if (Mitgamer->Connected()) { Mitgamer->IOHandler->WriteLn("-command ForceLobby"); Mitgamer->IOHandler->WriteLn("AllReady"); } Mitgamer->Disconnect(); if (Player == 1) { Lobby->Label2->Caption = Cname->Caption; Lobby->Label1->Caption = PlayerName->Text; } else { Lobby->Label1->Caption = Cname->Caption; Lobby->Label2->Caption = PlayerName->Text; Lobby->Panel1->Caption = "Bereit"; Lobby->Panel1->Visible = true; Lobby->redgreen->Enabled = true; } Spielvorbereitung->Hide(); Lobby->Show(); } //---------------------------------------------------------------------------
Nach Beenden der Anwendung bei Spieler 2 kommen 2 mal Problem bla bla Senden nicht Senden bla bla.
CIh tippe da wieder auf das OnClose event, aber wenn das nicht ist, dann kann ich auch nicht mehr schließen.
Ich glaube ich versuchs gleich mal immer zu disconnecten, wenn er fertig ist mit Hin- und Hersenden.EDIT: Rollentausch, habe jetzt den, der die Lobby Show Befehle kriegt im Debugger laufen, bekomme:
Erste Gelegenheit für Exception bei $7C812AFB. Exception-Klasse EOSError mit Meldung 'Systemfehler. Code: 1400.
Ungültiges Fensterhandle'. Prozess War_Industry.exe (2308)und dann unendlich oft:
Erste Gelegenheit für Exception bei $7C812AFB. Exception-Klasse EExternalException mit Meldung 'Externe Exception C0000025'. Prozess War_Industry.exe (2308)
Erste Gelegenheit für Exception bei $7C812AFB. Exception-Klasse EExternalException mit Meldung 'Externe Exception C0000025'. Prozess War_Industry.exe (2308)
Erste Gelegenheit für Exception bei $7C812AFB. Exception-Klasse EExternalException mit Meldung 'Externe Exception C0000025'. Prozess War_Industry.exe (2308)
Erste Gelegenheit für Exception bei $7C812AFB. Exception-Klasse EExternalException mit Meldung 'Externe Exception C0000025'. ProzessEDIT 2: Code Geupdated. Der Winter und der Frost sind weg.
Aber das Programm, auf das Connected wird Beendet sich immer noch komisch.
& ein Panel und eine Checkbox VERSCHWINDEN !!!
Das kann ich mir nicht erklären, das passt zu meinem zweiten Thread
-
Hab dieses Forum (thread) gefunden:
http://www.delphipraxis.net/topic16808.htmlAber was sagt mir das denn nun was die da sagen, ich hab kein Multithreading (glaub ich zumindest). Aber ich hab das Gefühl, dass das mit dem Fehlenden Panel und der Fehlenden Checkbox zusammenhängt, ich kann ja mal ein Bild posten.
http://www.bilderload.com/thumb/23639/disapearedP1MBL.jpg
Das finde ich äußerst merkwürdig, wo ich diese doch nie verstecken lasse !
(Ach und das die CheckBox nicht Enabled war ist normal, oben wird die Form angezeigt, ohne das eine Verbindung aufgebaut wurde)EDIT: Aber mir fällt grad ein, dass ich diese Elemente (ausschließlich diese) während der laufzeit ändern lasse, wenn das fenster gezeigt ist, aber das kann doch nicht der grund sein. außerdem wird das CheckBox->Checked = true. Da noch gar nicht ausgelöst, erst beim Klick aufs Panel, was ja gar nicht möglich ist, weil nicht zu sehen, es würde dort Bereit stehen, tut es aber nicht.
(Ist übrigens egal ob Host oder Mitspieler).
-
Tim06TR schrieb:
Aber was sagt mir das denn nun was die da sagen, ich hab kein Multithreading (glaub ich zumindest).
Indy ruft manche Event-Handler aus anderen Threads heraus auf. Details dazu liefert die Dokumentation.
-
Oh Super, das zu wissen ist schon mal gut, was ratet ihr mir ?
kann ich das auslagern ? Oder dies umgehen. könnt ich das evtl. mit nem Timer machen, den ich wieder abschalte, oder mach ich damit auch noch den Timer kaputt :). Threads sind ja noch nicht umbedingt mein Spezialgebiet.
Wie spreche die Elemente an ohne diese Konflikte zu verursachen ?
(solch ein problem hatte ich noch nie mit Indys)
-
Tim06TR schrieb:
Wie spreche die Elemente an ohne diese Konflikte zu verursachen ?
TThread::Synchronize().