Hallo Leute! Endlich poste ich mal wieder was. Ich hoffe es gefällt euch.
Also. Da ich gerne mal mit TCP rumspiele und auch mal Multiplayergames anfange zu programmieren, nervt es mich (bzw. ist zeitaufwendig) immer das ganze Zeugs mit den fetten (2D) Arrays zu machen. Also habe ich eine UDF geschrieben, die Variablen mit dem Empfänger austauscht.
Und zwar nimmt die SynVar UDF euch ein wenig Arbeit ab indem sie die Paketerstellung, Versand, Empfang und Verarbeitung macht. Also so ziemlich alles. Zusätzlich bietet die UDF eine Paketstrukturierung, die sehr effizient und effektiv ist.
Ich arbeite noch ein wenig an der UDF, denn wie man schnell feststellt, unterstützt es kein UDP. Bekannte Spiele wie Minecraft benutzen soweit ich weiß UDP zum übermitteln von Positionen etc. Ich möchte UDP einbauen, da ich in dem Beispielspiel wegen dem TCPRecv nur 10 FPS habe.
Ich habe das mit UDP noch nicht versucht, aber ich vermute es wird sehr schwierig, da UDP soweit ich weiß nur in eine Richtung geht. Deswegen frage ich euch mal: Wäre es möglich? Und wenn ja, dann auch ohne NAT traversal? Und wenn es nur mit NAT traversal geht, wie wäre es dann in AutoIt umsetzbar?
#cs ----------------------------------------------------------------------------
AutoIt Version: 3.3.12.0
Author: FacePalmMan
Credits to: owadziak
Script Function:
Easy synchronization of variables between server and client(s) (or possibly even between servers (e.g. login-®istration server))
Pros:
-Easy to use, and easy to add more variables to be synchronized
Cons:
-Can't use UDP yet.
Functions:
_SynVar_Add
_SynVar_Read
_SynVar_Set
_SynVar_Handle
#ce ----------------------------------------------------------------------------
TCPStartup()
Global Const $PACKETDELIM = Chr(2)
Global Const $PARAMDELIM = Chr(3)
;===============================================================================
;
; Description: Adds a variable to a socket
; Syntax: _SynVar_Add($hCon, $sVariableName[, $sContent[, $bProtected]])
; Parameter(s):
; $hCon - The connection socket you get from TCPAccept or TCPConnect
; $sVariableName - The name the variable should have
; $sContent - The content it should have. Leave empty if you just want to declare it without content
; $bProtected - If True, the socket you are connected to, will neither know about the variable nor be able to edit it
;
; Return Value(s): On Success - Returns 1
; On Failure - Returns 0 (error: 1 when UDP used)
;
;===============================================================================
Func _SynVar_Add($hCon, $sVariableName, $sContent = "", $bProtected = False)
If IsArray($hCon) Then Return SetError(1, 0, False)
Local $bReturn = Assign($hCon & "_" & $sVariableName, $sContent, 2)
If $bReturn Then
Assign("Protect_" & $sVariableName, $bProtected)
If Not $bProtected Then __SynVar_SendVar($hCon, $sVariableName, $sContent)
EndIf
Return $bReturn
EndFunc ;==>_SynVar_Add
;===============================================================================
;
; Description: Gets the value from the variable assigned to the given socket
; Syntax: _SynVar_Read($hCon, $sVariableName)
; Parameter(s):
; $hCon - The socket of the client the variable is assigned to
; $sVariableName - The name of the variable
;
;
; Return Value(s): On Success - Returns content
; On Failure - Returns False (error: 1 when UDP used)
;
; Note: If the variable contains an array, it will return it as an
; array too.
;
;===============================================================================
Func _SynVar_Read($hCon, $sVariableName)
If IsArray($hCon) Then Return SetError(1, 0, False)
Return Eval($hCon & "_" & $sVariableName)
EndFunc ;==>_SynVar_Read
;===============================================================================
;
; Description: Changes the content of the variable
; Syntax: _SynVar_Set($hCon, $sVariableName, $sContent)
; Parameter(s):
; $hCon - The socket of the client the variable is assigned to
; $sVariableName - The name of the variable
; $sContent - The content you want to put in there.
; You can also use (1D and 2D) arrays
;
; Return Value(s): On Success - Returns 1
; On Failure - Returns 0 (error: 1 when UDP used; or WSA errors if TCP error occurred)
;
;===============================================================================
Func _SynVar_Set($hCon, $sVariableName, $sContent)
If IsArray($hCon) Then Return SetError(1, 0, False)
Local $bChanged = $sContent <> Eval($hCon & "_" & $sVariableName)
If $bChanged Then
Assign($hCon & "_" & $sVariableName, $sContent, 2)
Local $bReturn = __SynVar_SendVar($hCon, $sVariableName, $sContent)
Return SetError(@error, @extended, $bReturn)
Else
Return True
EndIf
EndFunc ;==>_SynVar_Set
;===============================================================================
;
; Description: Receives and handles SynCon-relevant data and returns the rest
; Syntax: _SynVar_Handle($hCon)
; Parameter(s):
; $hCon - The socket of the client the variable is assigned to
;
; Return Value(s): On Success - Returns all remaining packets in an array
; [0] = index (the number of packets)
; [1] = the first remaining packet
; [2] = the second remaining packet
; ...
; On Failure - Returns emty string and an error
; (If there is a problem with the socket, a
; WSA error is returned (like for example 10054))
;
;===============================================================================
Func _SynVar_Handle($hCon)
Local $sRecv = TCPRecv($hCon, 1048576)
Local $aReturn[1] = [0]
If @error > 0 Then Return SetError(@error, @extended, "")
If $sRecv <> "" Then
$aPackets = StringSplit($sRecv, $PACKETDELIM)
For $i = 1 To $aPackets[0]
$aParams = StringSplit($aPackets[$i], $PARAMDELIM)
If $aParams[1] = "0" Then
If $aParams[0] < 3 Then
ConsoleWrite("Badly formated packet (<3 params): " & $aPackets[$i])
ContinueLoop
EndIf
If Eval("Protect_" & $hCon) = "True" Then ContinueLoop
Assign($hCon & "_" & $aParams[2], $aParams[3])
ElseIf $aParams[1] = "1" Then
If $aParams[0] < 4 Then
ConsoleWrite("Badly formated packet (<4 params): " & $aPackets[$i])
ContinueLoop
EndIf
Local $aTemp[$aParams[3]]
For $j = 0 To $aParams[3] - 1
$aTemp[$j] = $aParams[4 + $j]
Next
If Eval("Protect_" & $hCon) = "True" Then ContinueLoop
Assign($hCon & "_" & $aParams[2], $aTemp)
ElseIf $aParams[1] = "2" Then
If $aParams[0] < 5 Then
ConsoleWrite("Badly formated packet (<5 params): " & $aPackets[$i])
ContinueLoop
EndIf
Local $aTemp[$aParams[3]][$aParams[4]]
For $j = 0 To $aParams[3] - 1
For $k = 0 To $aParams[4] - 1
$aTemp[$j][$k] = $aParams[5 + $k + ($aParams[4] * $j)]
Next
Next
If Eval("Protect_" & $hCon) = "True" Then ContinueLoop
Assign($hCon & "_" & $aParams[2], $aTemp)
ElseIf $aParams[1] <> "" Then
$aReturn[0] += 1
ReDim $aReturn[$aReturn[0] + 1]
$aReturn[$aReturn[0]] = $aPackets[$i]
EndIf
Next
EndIf
Return $aReturn
EndFunc ;==>_SynVar_Handle
Func __SynVar_SendVar($hCon, $sVariableName, $sContent)
Local $i
If Not IsArray($sContent) Then
TCPSend($hCon, "0" & $PARAMDELIM & $sVariableName & $PARAMDELIM & $sContent & $PACKETDELIM)
Else
If UBound($sContent, 0) = 1 Then
Local $sString = "1" & $PARAMDELIM & $sVariableName & $PARAMDELIM & UBound($sContent, 1)
For $i = 0 To UBound($sContent, 1) - 1
$sString &= $PARAMDELIM & $sContent[$i]
Next
TCPSend($hCon, $sString & $PACKETDELIM)
ElseIf UBound($sContent, 0) = 2 Then
Local $sString = "2" & $PARAMDELIM & $sVariableName & $PARAMDELIM & UBound($sContent, 1) & $PARAMDELIM & UBound($sContent, 2)
For $i = 0 To UBound($sContent, 1) - 1
For $j = 0 To UBound($sContent, 2) - 1
$sString &= $PARAMDELIM & $sContent[$i][$j]
Next
Next
TCPSend($hCon, $sString & $PACKETDELIM)
EndIf
EndIf
Return SetError(@error, @extended, True)
EndFunc
Danke für die kleine Belehrung.
Ich hab mal in UDP wegen der Beidseitigkeit reingeschaut und rumprobiert. Ich habe erstmal ein wenig gebraucht, aber irgendwann wurde mir klar, dass der Server "zurückconnecten" muss. D.h. Der Client sendet ein Paket, der Server empfängt ihn mit flag 2, (zum Anzeigen von IP & Port des Clients) connected zum Client und kann ihm dann zurückschreiben.
Ich mach mich mal auf den Weg das Ganze auf UDP umzuschreiben. Am besten als "eigene" UDF. (Und am besten auch eine UDP hole punching UDF)
€dit:
Ich habe ein kleines Problem. Und zwar habe ich angefangen einen Testclient zu schreiben, mit dem ich dann die Verbindung testen kann. Ich habe aber dann, als ich es mit jemandem zwischengetestet habe, festgestellt, dass vom Masterserver keine Antwort kommt. Es hat sich herausgestellt, dass der Server anscheinend nur im lokalen Netz über UDP antworten kann. Was mache ich falsch? Und wie geht es richtig?
Hier die Scripts mit denen ich das auch getestet habe:
Client:
#include <Array.au3>
UDPStartup()
$hCon = UDPBind(@IPAddress1, 14159)
While 1
$sRecv = UDPRecv($hCon, 2048, 2)
ToolTip(@error, 0, 0)
If IsArray($sRecv) Then
MsgBox(0, "Server - Recv", $sRecv[0] & @CRLF & "from: " & $sRecv[1] & ":" & $sRecv[2])
$hOpen = UDPOpen($sRecv[1], $sRecv[2])
If @error Then MsgBox(0, "Server - Error", @error & @CRLF & @extended)
_ArrayDisplay($hOpen)
$iSent = UDPSend($hOpen, "Hello back ;)")
If @error Then MsgBox(0, "Server - Error2", @error & @CRLF & @extended)
EndIf
WEnd
€dit 2:
Problem gelöst. UDP hole punching scheint jetzt zu funktionieren. Muss nur noch testen, dann kann ich es in eine UDF klatschen, bzw. mein Projekt, welches UDP hole punching benötigt, fortführen.
[Selling] SW Lv.50 | Rare LnD nat 5 (Jaara) | 37x 6* | All core nat 4 | 5x nat 5s 02/03/2017 - Mobile Games Trading - 0 Replies Global
Payment : Paypal Only (Family and Friends)
Price : 130€
You have everything you need to do r5. Just need some better runes & adjustments and skillups
Contact :
Epvp PM
Skype : ibuflame
UniversnwMT2 - Directory Traversal & SQLi 08/24/2010 - Metin2 Private Server - 11 Replies Hallo,
ich möchte die Administration von UniversenwMT2 freundlich darauf hinweisen das sich auf der Website eine Sicherheitslücke befindet
Damit ist es möglich auf so ziemlich alle Datene vom Root Server zuzugreifen, da ihr Website und Gameserver ganz sparsam auf einem Root hostet ist das nicht sehr angenehm.
Weiterhin in eurem IS befindet sich eine weitere Sicherheitslücke, eine blind SQL Injection.
Was wie wo genau werde ich nun nicht weiter kommentieren
[UDF] Konsolen UDF 02/02/2010 - AutoIt - 8 Replies Ich habe mal eine kleine UDF geschrieben.
Es ist nicht viel und eine arbeit von 10 min aber
ich werde noch readline usw einbauen.
;================================================ ===============================
;
; Function Name: _ConsoleCreate ($Title)
; Description:: Erstellt eine Konsole mit schwarzem Hintergrund und weißer Schriftfarbe
; Parameter(s): $Title = Titel des Fensters der Konsole
; Ohne Titelangabe wird "Konsolen UDF by ScOrNi" verwendet