Ein Problem mit Array. Ich kannst nicht lösen

  • Hallo,
    ich programmiere gerade Client-Server Spiel. Naja eher gesagt für testzwecken. Wie arbeitet ein Server mit Client zusammen. Was gibt Server her. Wie kann ein Client sie verarbeiten? Das hab ich mich gefragt und deswegen war ne Idee kleines Testprojekt zu starten. Doch bei eine Kleinigkeit komm ich nicht weiter.

    [autoit]


    Func SendData()
    local $DataStr = getAllPlayerInformationInStr()
    $PlayerCount = GetTrue2DArraySize($Player)
    for $i = 0 to $PlayerCount - 1
    if $Player[$i][7] == 0 Then
    $Ret = TCPSend($Player[$i][0], $DataStr)
    if not $Ret then
    ConsoleWrite("Error while sending data" & @CRLF)
    PlayerRemoveFromList($i) ; lösche ihn aus der Spielerliste
    ExitLoop
    else
    $Player[$i][7] = TimerInit()
    EndIf
    Else
    ; Überprüfe Timeout. Wenn Timeout, Spieler aus der liste löschen
    ; ansonsten Timer löschen bzw. auf 0 setzen
    $ClientTimeoutCount = TimerDiff($Player[$i][7])
    $RecvOk = TCPRecv($Player[$i][0], 10000)
    if $RecvOk == "" & @error Then
    PlayerRemoveFromList($i) ; lösche ihn aus der Spielerliste
    ExitLoop
    EndIf
    if StringInStr($RecvOk, "gotit") Then
    $Player[$i][7] = 0
    $ClientTimeoutCount = 0
    EndIf
    if $ClientTimeoutCount > 10000 Then
    TCPCloseSocket($Player[$i][0])
    PlayerRemoveFromList($i)
    ExitLoop
    EndIf
    EndIf
    Next
    EndFunc

    [/autoit]


    Diese Funktion sendet bzw. soll an alle Spieler Daten senden, die sie brauchen. Z.b. Spielerposition, Healthpoints usw.
    Dabei wird überprüft, ob ein Spieler überhaupt noch richtig existiert. Das heißt, kann Daten nicht gesendet werden heißt e sSpieler nicht ansprechbar. Raus aus dem Spiel^^. Gibt es ein Timout also überlengere Zeit keine Antwort vom Client dann ist es ebenfalls raus.
    Doch das Problem tritt genau da auf.
    Sobald ich aus array lösche mit arraydelete dann stürzt es ab.

    [autoit]


    func PlayerRemoveFromList($arIdx)
    $PlayerCount = GetTrue2DArraySize($Player)
    if $PlayerCount > 0 Then
    _ArrayDelete($Player, $arIdx)
    elseif $arIdx == 0 then
    $Player[0][0] = ""
    $Player[0][1] = ""
    $Player[0][2] = ""
    $Player[0][3] = ""
    $Player[0][4] = ""
    $Player[0][5] = ""
    $Player[0][6] = ""
    $Player[0][7] = ""
    else
    _ArrayDelete($Player, $arIdx)
    EndIf
    EndFunc

    [/autoit]


    Bis jetzt hab ich es mit ExitLoop gelöst, aber das wäre doof, dass die andern Clients, die eigentlich dran wären einen aussetzer bekommen.

    $Player[$i][7] ist einfach ein Timer. Wenn der Server etwas sendet wird ein timer auf $Player[$i][7] gesetzt. Ist es mehr als 10 sek dann fliegt der Client raus mit Begründung: Keine Rückmeldung.
    Ich habe mit $i -= 1 versucht aber ist immernoch das gleiche

  • wenn ein server daten auf verdacht schickt, weil da ja evtl. noch jemand sein könnte ist das nicht effizient.
    mach es lieber so das der server immer innerhalb von sagen wir mal 10 sekunden ein paket vom client erwartet.
    wenn das nicht kommt....... tschüss client.
    du ersparst dir damit evtl. sogar jede menge code.

    aus einer funktion geht man doch mit return beim abbruch raus, oder irre ich mich da?

    I spent 10 minutes reviewing code and thinking "What kind of drugs is this guy on?" before realizing it was something I wrote.

  • Dein Problem liegt darin dass du dein ArrayIndex Falsch angibst deine angabe wird wie folgt aussahen_ArrayDelete($Player, $arIdx) wobei $arIdx nur einem Indexeintrag entspricht da du aber ein Mehrdimensionales Array hast musst du auch die Dimension angeben ! _ArrayDelete($Player,[0] $aridx) bin mir natürlich nicht sicher wie deine Daten gespeichert denke du musst dann eine Schleife laufen lassen die alle Informationen zum User aus dem Array entfernt

    Gruß Marvin

  • Dein Problem liegt darin dass du dein ArrayIndex Falsch angibst deine angabe wird wie folgt aussahen_ArrayDelete($Player, $arIdx) wobei $arIdx nur einem Indexeintrag entspricht da du aber ein Mehrdimensionales Array hast musst du auch die Dimension angeben !

    Falsch! _ArrayDelete erwartet nur das Element und löscht dann diesen Eintrag in allen Dimensionen. Ausserdem tritt der Fehler nicht an der Stelle des Löschens (_arraydelete) sondern zuvor beim Vergleich (if $Player[$i][7] == 0) auf.

    MaZy: lass dir mal direkt davor mit _arrydisplay das Array $player anzeigen, dann sollte dir der Fehler förmlich in die AUgen springen. Er wird zwar sicherlich an einer anderen (nicht geposteten) Stelle verursacht aber dies kann ich ja nicht nachprüfen,

    mfg autoBert