JRSmile Posted January 22, 2012 Author Posted January 22, 2012 (edited) currently it just crashes/freezeloops the client after login I can only work on this project in my sparetime, so expect slow progress... what i changed so far: expandcollapse popup#NoTrayIcon #include "TCP.au3" #Include "ZLIB.au3" ;~ ConsoleWrite(_MC_String_decrypt(Binary("0x0007006A00720073006D0069006C0065"))) ;~ Exit ; >>>>>>>>>> http://wiki.vg/Protocol $hServer = _TCP_Server_Create(25565); A MineCraftServer. Tadaa! _TCP_RegisterEvent($hServer, $TCP_NEWCLIENT, "NewClient") _TCP_RegisterEvent($hServer, $TCP_DISCONNECT, "Disconnect") _TCP_RegisterEvent($hServer, $TCP_RECEIVE, "Received") While 1 WEnd Func NewClient($hSocket, $iError) ;~ ToolTip("SERVER: New client connected.", 10, 30) EndFunc ;==>NewClient Func Disconnect($hSocket, $iError) ;~ ToolTip("SERVER: Client disconnected.", 10, 30) EndFunc ;==>Disconnect Func Received($hSocket, $sReceived, $iError) ConsoleWrite(">| " & Binary($sReceived) & @CRLF) Protocol(Binary($sReceived),$hSocket) EndFunc ;==>Disconnect Func Protocol($stream,$hSocket) switch BinaryMid($stream,1,1);StringLeft($stream,4) Case 0xFE ConsoleWrite("+| Server List Ping" & @CRLF) _TCP_Send($hSocket, 0xFF) Case 0x02 $username = _MC_String_decrypt(BinaryMid($stream,2)); all strings are UCS-2 encoded which is luckily the same as UTF-16 BigEndian. ConsoleWrite("+| Handshake by " & $username & @CRLF) _TCP_Send($hSocket, "0x020001002D"); StringToBinary("-",3) case 0x01 $loginname = _MC_String_decrypt(BinaryMid($stream,6)) ConsoleWrite("+| Login Request by " & $loginname & @CRLF) _TCP_Send($hSocket, "0x0100000148000060440b732bf1f642000000000001801406fffffbd600000040000001ef0400000000003fbb1503000800a7003500a7003600a7003400a70035") ; Login accepted _TCP_Send($hSocket, "0x05") ; Entity Equipment (Head,Body,pants,boots) ;EntitiyID (int), Slot 0= Hand 1-4 armor slot (short), Item ID (short), Damaged (short)... _TCP_Send($hSocket, "0x32000000001") ; Chunk init _TCP_Send($hSocket, "0x330000000000037F03") ; Chunk region data _TCP_Send($hSocket, "0x0D00000000000000000000000000000000000000001") ; player pos and Look case 0x03 $message = BinaryToString("0x" & StringTrimLeft($stream,5),3) ConsoleWrite("-| Chat: " & $message & @CRLF) case Else ConsoleWrite("!| Unimplemented Packettype! Player KICKED!" & @CRLF) _TCP_Send($hSocket, 0xFF) EndSwitch EndFunc Func _MC_String_Encrypt($sText) Local $iLen = StringLen($sText) Local $bLen = Binary("0x" & hex(StringLen($sText),4)) Local $bText = StringTrimLeft(StringToBinary($sText,3),2) Return Binary($bLen & $bText) EndFunc func _MC_String_decrypt($bin_str) Local $bLen = BinaryMid($bin_str,1,2) Local $bStr = BinaryMid($bin_str,3, _toInt($bLen)*2) Local $sStr = BinaryToString($bStr,3) Return $sStr EndFunc Func _toInt($2byte) Local $2 = int(BinaryMid($2byte,1,1)) Local $1 = int(BinaryMid($2byte,2,1)) if $2 > 0 Then $2 += 255 Return $1 + $2 EndFunc ;~ Dim $Compressed = _ZLIB_Compress($Original, 9) ;~ Dim $Decompressed = _ZLIB_Uncompress($Compressed) #cs What's the normal login sequence for a client? See Authentication for communication with minecraft.net The recommended login sequence looks like this, where C is the client and S is the server: C <> S : Connects C > S : Sends handshake C < S : Sends handshake response C > S : After authenticating (if needed), sends the login packet C < S : Either kicks (invalid login) or sends a login response C < S : Sends pre-chunks and chunks and entities C < S : Sends spawn position C < S : Sends inventory [Need to verify this since inventory changed] (beta 1.1_02: looks like Window items with type=0, then a Set slot with window id = -1 and slot = -1) C < S : Tell the client they're ready to spawn by sending a position + look packet. Note: The stance and Y should be swapped when the server sends it to the client (See Protocol Page)! C > S : Sends a position + look packet to confirm the spawn position, with the stance and Y swapped back to the correct positions I think I've done everything right, but… …my player isn't spawning! After sending the common-sense packets (Handshake, Login, Inventory, Compass and Pre-chunk/Chunk pairs) you need to finally send the player their initial position for them to leave the "Loading Map" screen. …my client isn't receiving complete map chunks! The standard Minecraft server server sends full chunks only when your client is sending player status update packets (any of Player (0x0A) through Player Position & Look (0x0D)). …all connecting clients spasm and jerk uncontrollably! For newer clients, your server needs to send 49 chunks ahead of time, not just one. Send a 7x7 square of chunks, centered on the connecting client's position, before spawning them. #ce Edited January 22, 2012 by JRSmile $a=StringSplit("547275737420796F757220546563686E6F6C75737421","") For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4) Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI" Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile; MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
SkinnyWhiteGuy Posted January 22, 2012 Posted January 22, 2012 I had some time, and some time to think: Local $bData = Binary("0x00000001") Local $sType = "int" ConsoleWrite(LittleEndian($bData, $sType) & @CRLF) ConsoleWrite(BigEndian($bData, $sType) & @CRLF) Func LittleEndian(ByRef $byte_stream, $type) Local $temp = DllStructCreate($type), $output = DllStructCreate("byte[" & DllStructGetSize($temp) & "]", DllStructGetPtr($temp)) DllStructSetData($output, 1, BinaryMid($byte_stream, 1, DllStructGetSize($temp))) ;~ $byte_stream = BinaryMid($byte_stream, 1 + DllStructGetSize($temp)) Return DllStructGetData($temp, 1) EndFunc Func BigEndian(ByRef $byte_stream, $type) Local $temp = DllStructCreate($type), $output = DllStructCreate("byte[" & DllStructGetSize($temp) & "]", DllStructGetPtr($temp)) For $i = DllStructGetSize($temp) To 1 Step -1 DllStructSetData($output, 1, BinaryMid($byte_stream, $i, 1), DllStructGetSize($temp) - $i + 1) Next ;~ $byte_stream = BinaryMid($byte_stream, 1 + DllStructGetSize($temp)) Return DllStructGetData($temp, 1) EndFunc Obviously, uncomment the lines in the functions to give it back the stream forwarding option the other one had.
JRSmile Posted January 22, 2012 Author Posted January 22, 2012 didn't know the byref is speed/performance critical when dealing with large amounts if data, thanks already for that. $a=StringSplit("547275737420796F757220546563686E6F6C75737421","") For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4) Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI" Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile; MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
Valik Posted January 23, 2012 Posted January 23, 2012 I don't think he needs to, because a bot is used to get advantage out of automation in a game, during the fact that this is a server you won't get any advantages out of it for the real game, except the fact that you can use it as GUI as intended.This is the second time you've made the same mistake most people make. I don't give a fuck if your code is malicious or not. What I do give a fuck about is how easily your code can be adapted to do malicious things. Also, just because you can't think of ways to use things maliciously doesn't mean I can't - or others can't. Anything created for good can be turned to evil. There are no exceptions.
JRSmile Posted January 23, 2012 Author Posted January 23, 2012 (edited) sad, but true :-( I will keep this in mind when developing further. Edited January 23, 2012 by JRSmile $a=StringSplit("547275737420796F757220546563686E6F6C75737421","") For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4) Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI" Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile; MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
JRSmile Posted January 25, 2012 Author Posted January 25, 2012 Progress ! Skinny did a perfect job by creating the BigEndian Functions, now packet structures are as easy to implement as candy. Skinny is now working on changing the packet stream, it looks like the client throws up two or more packets in the same reply when he wan'ts to so this has to be addressed. I'm working on implementing the zlib compression and chunk generation. At least the player now falls right to the level and keep-alive somehow works: expandcollapse popup;***************************************** ;AutoCraft.au3 by JRSmile & SkinnyWhiteGuy ;Erstellt mit ISN AutoIt Studio v. 0.76 BETA ;***************************************** #NoTrayIcon #include "Includes/TCP.au3" #include "Includes/ZLIB.au3" ; >>>>>>>>>> http://wiki.vg/Protocol Global $keep_alive = Binary("") $hServer = _TCP_Server_Create(25565) ; A MineCraftServer. Tadaa! _TCP_RegisterEvent($hServer, $TCP_NEWCLIENT, "NewClient") _TCP_RegisterEvent($hServer, $TCP_DISCONNECT, "Disconnect") _TCP_RegisterEvent($hServer, $TCP_RECEIVE, "Received") While 1 WEnd Func NewClient($hSocket, $iError) ;~ ToolTip("SERVER: New client connected.", 10, 30) EndFunc ;==>NewClient Func Disconnect($hSocket, $iError) ;~ ToolTip("SERVER: Client disconnected.", 10, 30) ;~ Exit EndFunc ;==>Disconnect Func Received($hSocket, $sReceived, $iError) ConsoleWrite(">| " & Binary($sReceived) & @CRLF) Protocol(Binary($sReceived), $hSocket) EndFunc ;==>Disconnect Func Protocol($stream, $hSocket) $org_packet = $stream Local $Packet = BinaryToBigEndian($stream, "byte") Switch $Packet Case 0xFE ConsoleWrite("+| Server List Ping" & @CRLF) _TCP_Send($hSocket, 0xFF) Case 0x02 Local $username = _MC_String_decrypt($stream) ; all strings are UCS-2 encoded which is luckily the same as UTF-16 BigEndian. ConsoleWrite("+| Handshake by " & $username & @CRLF) _TCP_Send($hSocket, BigEndianToBinary($Packet, "byte") & _MC_String_Encrypt("-")) ;"0x020001002D"); StringToBinary("-",3) Case 0x01 Local $ProtocolVersion = BinaryToBigEndian($stream, "int") Local $loginname = _MC_String_decrypt($stream) ConsoleWrite("+| Login Request by " & $loginname & @CRLF) ;Login Packet Return Local $LoginPacket = Binary("") $LoginPacket &= BigEndianToBinary($Packet, "byte") $LoginPacket &= BigEndianToBinary(328, "int") ; Entity ID $LoginPacket &= _MC_String_Encrypt("") ; Not Used $LoginPacket &= BigEndianToBinary(6936681915343828546, "int64") ; Map Seed $LoginPacket &= _MC_String_Encrypt("DEFAULT") ; Level-type, looks like JRSmile skips this $LoginPacket &= BigEndianToBinary(0, "int") ; Server Mode $LoginPacket &= BigEndianToBinary(0, "byte") ; Dimension $LoginPacket &= BigEndianToBinary(1, "byte") ; Difficulty $LoginPacket &= BigEndianToBinary(128, "byte") ; World Height $LoginPacket &= BigEndianToBinary(20, "byte") ; Max Players TCP_Send($hSocket, $LoginPacket) _TCP_Send($hSocket, "0x06fffffbd600000040000001ef") ; Spawn Position _TCP_Send($hSocket, "0x0400000000003fbb15") ; Time Update _TCP_Send($hSocket, "0x03000800a7003500a7003600a7003400a70035") ; Chat Message ;~ _TCP_Send($hSocket, "0x05") ; Entity Equipment (Head,Body,pants,boots) ;EntitiyID (int), Slot 0= Hand 1-4 armor slot (short), Item ID (short), Damaged (short)... ;~ _TCP_Send($hSocket, "0x32000000001") ; Chunk init ;~ _TCP_Send($hSocket, "0x330000000000037F03") ; Chunk region data ;~ _TCP_Send($hSocket, "0x0D00000000000000000000000000000000000000001") ; player pos and Look Case 0x03 ; Chat Message (from client) $message = BinaryToString("0x" & StringTrimLeft($stream, 5), 3) ConsoleWrite("-| Chat: " & $message & @CRLF) Case 0x0D ; Player Position & Look (from Client) Local $X = BinaryToBigEndian($stream, "double") Local $Y = BinaryToBigEndian($stream, "double") Local $Stance = BinaryToBigEndian($stream, "double") Local $Z = BinaryToBigEndian($stream, "double") Local $Yaw = BinaryToBigEndian($stream, "float") Local $Pitch = BinaryToBigEndian($stream, "float") Local $OnGround = BinaryToBigEndian($stream, "byte") ConsoleWrite("+| PositionLook Data: " & $X & @TAB & $Y & @TAB & $Stance & @TAB & $Z & @TAB & $Yaw & @TAB & $Pitch & @TAB & $OnGround & @CRLF) Case 0x0B ; Player Position (from Client) Local $X = BinaryToBigEndian($stream, "double") Local $Y = BinaryToBigEndian($stream, "double") Local $Stance = BinaryToBigEndian($stream, "double") Local $Z = BinaryToBigEndian($stream, "double") Local $OnGround = BinaryToBigEndian($stream, "byte") ConsoleWrite("+| Position Data : " & $X & @TAB & $Y & @TAB & $Stance & @TAB & $Z & @TAB & $OnGround & @CRLF) Case 0x00 If $org_packet <> $keep_alive Then Local $keeprandom = BigEndianToBinary(0,"byte") $keeprandom &= BigEndianToBinary(Random(100000000, 999999999, 1), "int") TCP_Send($hSocket, $keeprandom) $keep_alive = $keeprandom EndIf Case Else ConsoleWrite("!| Unimplemented Packettype! Player KICKED!" & @CRLF) TCP_Send($hSocket, $LoginPacket) EndSwitch EndFunc Func TCP_Send($Socket, $Data) ConsoleWrite("<| " & $Data & @CRLF) _TCP_Send($Socket, $Data) EndFunc Func _MC_String_Encrypt($sText) Local $bLen = BigEndianToBinary(StringLen($sText), "short") Local $bText = StringToBinary($sText, 3) Return Binary($bLen & $bText) EndFunc Func _MC_String_decrypt(ByRef $bin_str) Local $bLen = BinaryToBigEndian($bin_str, "short") Local $sStr = BinaryToString(BinaryToLittleEndian($bin_str, "byte[" & $bLen * 2 & "]"), 3) Return $sStr EndFunc Func BinaryToBigEndian(ByRef $byte_stream, $type) Local $temp = DllStructCreate($type), $output = DllStructCreate("byte[" & DllStructGetSize($temp) & "]", DllStructGetPtr($temp)) For $i = DllStructGetSize($temp) To 1 Step -1 DllStructSetData($output, 1, BinaryMid($byte_stream, $i, 1), DllStructGetSize($temp) - $i + 1) Next $byte_stream = BinaryMid($byte_stream, 1 + DllStructGetSize($temp)) Return DllStructGetData($temp, 1) EndFunc Func BigEndianToBinary($data, $type) If IsNumber($data) Then If DllStructGetSize(DllStructCreate($type)) * 2 <= 8 Then Return Binary("0x" & Hex($data, DllStructGetSize(DllStructCreate($type)) * 2)) Else Local $temp = DllStructCreate($type), $binary = DllStructCreate("byte[" & DllStructGetSize(DllStructCreate($type)) & "]", DllStructGetPtr($temp)) DllStructSetData($temp, 1, $data) ;~ ConsoleWrite(DllStructGetData($binary, 1) & @LF) Local $bData = Binary("") For $i = DllStructGetSize($binary) To 1 Step -1 $bData &= BigEndianToBinary(DllStructGetData($binary, 1, $i), "byte") Next ;~ ConsoleWrite($bData & @LF) Return $bData EndIf EndIf EndFunc Func BinaryToLittleEndian(ByRef $byte_stream, $type) Local $temp = DllStructCreate($type), $output = DllStructCreate("byte[" & DllStructGetSize($temp) & "]", DllStructGetPtr($temp)) DllStructSetData($output, 1, BinaryMid($byte_stream, 1, DllStructGetSize($temp))) $byte_stream = BinaryMid($byte_stream, 1 + DllStructGetSize($temp)) Return DllStructGetData($temp, 1) EndFunc ;~ Dim $Compressed = _ZLIB_Compress($Original, 9) ;~ Dim $Decompressed = _ZLIB_Uncompress($Compressed) #cs What's the normal login sequence for a client? See Authentication for communication with minecraft.net The recommended login sequence looks like this, where C is the client and S is the server: C <> S : Connects C > S : Sends handshake C < S : Sends handshake response C > S : After authenticating (if needed), sends the login packet C < S : Either kicks (invalid login) or sends a login response C < S : Sends pre-chunks and chunks and entities C < S : Sends spawn position C < S : Sends inventory [Need to verify this since inventory changed] (beta 1.1_02: looks like Window items with type=0, then a Set slot with window id = -1 and slot = -1) C < S : Tell the client they're ready to spawn by sending a position + look packet. Note: The stance and Y should be swapped when the server sends it to the client (See Protocol Page)! C > S : Sends a position + look packet to confirm the spawn position, with the stance and Y swapped back to the correct positions I think I've done everything right, but… …my player isn't spawning! After sending the common-sense packets (Handshake, Login, Inventory, Compass and Pre-chunk/Chunk pairs) you need to finally send the player their initial position for them to leave the "Loading Map" screen. …my client isn't receiving complete map chunks! The standard Minecraft server server sends full chunks only when your client is sending player status update packets (any of Player (0x0A) through Player Position & Look (0x0D)). …all connecting clients spasm and jerk uncontrollably! For newer clients, your server needs to send 49 chunks ahead of time, not just one. Send a 7x7 square of chunks, centered on the connecting client's position, before spawning them. #ce $a=StringSplit("547275737420796F757220546563686E6F6C75737421","") For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4) Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI" Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile; MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
JRSmile Posted January 25, 2012 Author Posted January 25, 2012 More Progress, the client can now connect and will login successfully, the only problem is that the Player will fall endlessly deep due to the fact that terrain isn't implemented yet. Skinny did an impressive job with the packetreading, which can be helpful in the future for anybody. if you want to stop the player from falling, simply change your handitem or press e or do anything except moving. the server will kick you and you can stop the server normally. expandcollapse popup;***************************************** ;AutoCraft.au3 by JRSmile & SkinnyWhiteGuy ;Erstellt mit ISN AutoIt Studio v. 0.76 BETA ;***************************************** #AutoIt3Wrapper_Change2CUI=y #NoTrayIcon #include "Includes/TCP.au3" #Include "Includes/ZLIB.au3" ; >>>>>>>>>> http://wiki.vg/Protocol Global $Types = ObjCreate("Scripting.Dictionary") $Types("byte") = "byte" $Types("short") = "short" $Types("int") = "int" $Types("long") = "int64" $Types("float") = "float" $Types("double") = "double" $Types("string") = "" $Types("bool") = "byte" $hServer = _TCP_Server_Create(25565); A MineCraftServer. Tadaa! _TCP_RegisterEvent($hServer, $TCP_NEWCLIENT, "NewClient") _TCP_RegisterEvent($hServer, $TCP_DISCONNECT, "Disconnect") _TCP_RegisterEvent($hServer, $TCP_RECEIVE, "Received") While 1 Sleep(1) WEnd Func NewClient($hSocket, $iError) ;~ ToolTip("SERVER: New client connected.", 10, 30) EndFunc ;==>NewClient Func Disconnect($hSocket, $iError) ;~ ToolTip("SERVER: Client disconnected.", 10, 30) ;~ exit EndFunc ;==>Disconnect Func Received($hSocket, $sReceived, $iError) Local $bReceived = Binary($sReceived) While BinaryLen($bReceived) ConsoleWrite(">| " & $bReceived & @CRLF) Protocol($bReceived, $hSocket) WEnd EndFunc ;==>Disconnect Func Protocol(ByRef $stream, $hSocket) Local $Packet = BinaryToBigEndian($stream, "byte") Switch $Packet Case 0x00 ; Keep Alive Local $KeepAliveID = _MC_Read_Packet($stream, "int") Debug_Print("Keep Alive ID", $KeepAliveID) Case 0x01 ; Login Request Local $LoginRequest = _MC_Read_Packet($stream, "int;string;long;string;int;byte;byte;byte;byte") ; Login Packet Local $LoginName = $LoginRequest[1] ConsoleWrite("+| Login Request by " & $LoginName & @CRLF) ;Login Packet Return Local $LoginResponse = _MC_Create_Packet("byte;int;string;long;string;int;byte;byte;byte;byte", _ $Packet, 328, "", 6936681915343828546, "DEFAULT", 0, 0, 1, 128, 20) TCP_Send($hSocket, $LoginResponse) TCP_Send($hSocket, "0x06fffffbd600000040000001ef") ; Spawn Position TCP_Send($hSocket, "0x0400000000003fbb15") ; Time Update TCP_Send($hSocket, "0x03000800a7003500a7003600a7003400a70035") ; Chat Message ;~ _TCP_Send($hSocket, "0x05") ; Entity Equipment (Head,Body,pants,boots) ;EntitiyID (int), Slot 0= Hand 1-4 armor slot (short), Item ID (short), Damaged (short)... ;~ _TCP_Send($hSocket, "0x32000000001") ; Chunk init ;~ _TCP_Send($hSocket, "0x330000000000037F03") ; Chunk region data Local $PlayerPosLook = _MC_Create_Packet("byte;double;double;double;double;float;float;byte", _ 0x0D, 6.5, 67.2400000095367, 65.6200000047684, 7.5, 0.0, 0.0, 1) TCP_Send($hSocket, $PlayerPosLook) Case 0x02 ; Handshake Local $HandshakeRequest = _MC_Read_Packet($stream, "string") ConsoleWrite("+| Handshake by " & $HandshakeRequest[0] & @CRLF) _TCP_Send($hSocket, _MC_Create_Packet("byte;string", $Packet, "-")) Case 0x03 ; Chat Message Local $Message = _MC_Read_Packet($stream, "string") ConsoleWrite("-| Chat: " & $Message[0] & @CRLF) Case 0x04 ; Time Update ; Server to Client Only Local $Time = _MC_Read_Packet($stream, "long") Debug_Print("Time", $Time) Case 0x05 ; Entity Equipment Local $Equipment = _MC_Read_Packet($stream, "int;short;short;short") Debug_Print("Equipment", $Equipment) Case 0x06 ; Spawn Position ; Server to Client only Local $Spawn = _MC_Read_Packet($stream, "int;int;int") Debug_Print("Spawn Position", $Spawn) Case 0x07 ; Use Entity ; Client to Server only Local $Use = _MC_Read_Packet($stream, "int;int;bool") Debug_Print("Use Entity", $Use) Case 0x08 Case 0x09 Case 0x0A ; Player ; Client to Server only Local $OnGround = _MC_Read_Packet($stream, "bool") Debug_Print("On Ground", $OnGround) Case 0x0B ; Player Position ; Client to Server Local $Position = _MC_Read_Packet($stream, "double;double;double;double;byte") Debug_Print("Position Data", $Position) Case 0x0C ; Player Look ; Client to Server Local $Look = _MC_Read_Packet($stream, "float;float;bool") Debug_Print("Look Data", $Look) Case 0x0D ; Player Position & Look Local $PositionLook = _MC_Read_Packet($stream, "double;double;double;double;float;float;byte") Debug_Print("PositionLook Data", $PositionLook) Case 0x0E Case 0x0F Case 0x10 Case 0x11 Case 0x12 Case 0x13 Case 0x14 Case 0x15 Case 0x16 Case 0x17 Case 0x18 Case 0x19 Case 0x1A Case 0x1C Case 0x1D Case 0x1E Case 0x1F Case 0x20 Case 0x21 Case 0x22 Case 0x26 Case 0x27 Case 0x28 Case 0x29 Case 0x2A Case 0x2B Case 0x32 Case 0x33 Case 0x34 Case 0x35 Case 0x36 Case 0x3C Case 0x3D Case 0x46 Case 0x47 Case 0x64 Case 0x65 Case 0x66 Case 0x67 Case 0x68 Case 0x69 Case 0x6A Case 0x6B Case 0x6C Case 0x82 Case 0x83 Case 0xC8 Case 0xC9 Case 0xFA Case 0xFE ; Server List Ping ConsoleWrite("+| Server List Ping" & @CRLF) _TCP_Send($hSocket, 0xFF) Case 0xFF ; Disconnect Local $Message = _MC_Read_Packet($stream, "string") ConsoleWrite("!| Client disconnected: " & $Message[0] & @CRLF) Case Else ConsoleWrite("!| Unimplemented Packettype! Player KICKED!" & @CRLF) _TCP_Send($hSocket, 0xFF) EndSwitch EndFunc Func TCP_Send($Socket, $Data) ConsoleWrite("<| " & $Data & @LF) _TCP_Send($Socket, $Data) EndFunc Func Debug_Print($header, $aInfo) ConsoleWrite("+| " & $header & ":") For $Part In $aInfo ConsoleWrite(@TAB & $Part) Next ConsoleWrite(@LF) EndFunc Func _MC_String_Encrypt($sText) Local $bLen = BigEndianToBinary(StringLen($sText),"short") Local $bText = StringToBinary($sText,3) Return Binary($bLen & $bText) EndFunc func _MC_String_decrypt(ByRef $bin_str) Local $bLen = BinaryToBigEndian($bin_str, "short") Local $sStr = BinaryToString(BinaryToLittleEndian($bin_str, "byte[" & $bLen * 2 & "]"), 3) Return $sStr EndFunc Func _MC_Read_Packet(ByRef $stream, $format) Local $aResults = StringSplit($format, ";", 2) For $i = 0 To UBound($aResults) - 1 Switch $aResults[$i] Case "string" $aResults[$i] = _MC_String_decrypt($stream) Case Else $aResults[$i] = BinaryToBigEndian($stream, $Types($aResults[$i])) EndSwitch Next Return $aResults EndFunc Func _MC_Create_Packet($format, $arg1, $arg2='', $arg3='', $arg4='', $arg5='', $arg6='', $arg7='', $arg8='', $arg9='', $arg10='', $arg11='', $arg12='') Local $bPacket = Binary("") Local $aTypes = StringSplit($format, ";", 2) If UBound($aTypes) <> @NumParams-1 Then Return SetError(1, 0, $bPacket) For $i = 0 To UBound($aTypes) - 1 Local $var = Eval("arg" & $i+1) Switch $aTypes[$i] Case "string" $bPacket &= _MC_String_Encrypt($var) Case Else $bPacket &= BigEndianToBinary($var, $Types($aTypes[$i])) EndSwitch Next Return $bPacket EndFunc Func BinaryToBigEndian(ByRef $byte_stream, $type) Local $temp = DllStructCreate($type), $output = DllStructCreate("byte[" & DllStructGetSize($temp) & "]", DllStructGetPtr($temp)) For $i = DllStructGetSize($temp) To 1 Step -1 DllStructSetData($output, 1, BinaryMid($byte_stream, $i, 1), DllStructGetSize($temp) - $i + 1) Next $byte_stream = BinaryMid($byte_stream, 1 + DllStructGetSize($temp)) Return DllStructGetData($temp, 1) EndFunc Func BigEndianToBinary($data, $type) If IsNumber($data) Then If DllStructGetSize(DllStructCreate($type))*2 <= 8 Then Return Binary("0x" & Hex($data, DllStructGetSize(DllStructCreate($type))*2)) Else Local $temp = DllStructCreate($type), $binary = DllStructCreate("byte[" & DllStructGetSize(DllStructCreate($type)) & "]", DllStructGetPtr($temp)) DllStructSetData($temp, 1, $data) ;~ ConsoleWrite(DllStructGetData($binary, 1) & @LF) Local $bData = Binary("") For $i = DllStructGetSize($binary) To 1 Step -1 $bData &= BigEndianToBinary(DllStructGetData($binary, 1, $i), "byte") Next ;~ ConsoleWrite($bData & @LF) Return $bData EndIf EndIf EndFunc Func BinaryToLittleEndian(ByRef $byte_stream, $type) Local $temp = DllStructCreate($type), $output = DllStructCreate("byte[" & DllStructGetSize($temp) & "]", DllStructGetPtr($temp)) DllStructSetData($output, 1, BinaryMid($byte_stream, 1, DllStructGetSize($temp))) $byte_stream = BinaryMid($byte_stream, 1 + DllStructGetSize($temp)) Return DllStructGetData($temp, 1) EndFunc ;~ Dim $Compressed = _ZLIB_Compress($Original, 9) ;~ Dim $Decompressed = _ZLIB_Uncompress($Compressed) #cs What's the normal login sequence for a client? See Authentication for communication with minecraft.net The recommended login sequence looks like this, where C is the client and S is the server: C <> S : Connects C > S : Sends handshake C < S : Sends handshake response C > S : After authenticating (if needed), sends the login packet C < S : Either kicks (invalid login) or sends a login response C < S : Sends pre-chunks and chunks and entities C < S : Sends spawn position C < S : Sends inventory [Need to verify this since inventory changed] (beta 1.1_02: looks like Window items with type=0, then a Set slot with window id = -1 and slot = -1) C < S : Tell the client they're ready to spawn by sending a position + look packet. Note: The stance and Y should be swapped when the server sends it to the client (See Protocol Page)! C > S : Sends a position + look packet to confirm the spawn position, with the stance and Y swapped back to the correct positions I think I've done everything right, but… …my player isn't spawning! After sending the common-sense packets (Handshake, Login, Inventory, Compass and Pre-chunk/Chunk pairs) you need to finally send the player their initial position for them to leave the "Loading Map" screen. …my client isn't receiving complete map chunks! The standard Minecraft server server sends full chunks only when your client is sending player status update packets (any of Player (0x0A) through Player Position & Look (0x0D)). …all connecting clients spasm and jerk uncontrollably! For newer clients, your server needs to send 49 chunks ahead of time, not just one. Send a 7x7 square of chunks, centered on the connecting client's position, before spawning them. #ce $a=StringSplit("547275737420796F757220546563686E6F6C75737421","") For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4) Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI" Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile; MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
OneManPen Posted January 25, 2012 Posted January 25, 2012 Very good progress... but the query for the MTOD and ammount of players in server list doesn't actaully work... any plans on adding it?
SkinnyWhiteGuy Posted January 25, 2012 Posted January 25, 2012 That is actually pretty easy. Just need to send back a string with the numbers delimited by 0xA7. The wiki referenced above has 3 different scripts that show how to do it, I just didn't do it yet.
OneManPen Posted January 25, 2012 Posted January 25, 2012 Kewl.... so when you're done creating this server... will you make it kind of like bukkit where you can make mods and plugins...? cuz I'm really hoping someone will make a server/mod where you download the mods that the server is using from the server... right when you join...
AdmiralAlkex Posted January 25, 2012 Posted January 25, 2012 cuz I'm really hoping someone will make a server/mod where you download the mods that the server is using from the server... right when you join...Maybe you already know, but Spout and Spoutcraft can give you something like that (in a limited way). .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface
OneManPen Posted January 25, 2012 Posted January 25, 2012 Yeah.... I know... but for me it's TOO limited....
JRSmile Posted January 26, 2012 Author Posted January 26, 2012 I may have to dissapoint you, this server isn't intended to be a Gameserver, you will never be able to really play the game on it due to the following reasons. 1. No multithreading for autoit, the language is to slow. 2. It is a fake server, it emulates a gameserver, but doesn't Act like one. 3. If you don't like 1 and 2 feel Free and go ahead, write your own server, but i would recomend another Programminglanguage. 4. No really its to slow. $a=StringSplit("547275737420796F757220546563686E6F6C75737421","") For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4) Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI" Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile; MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
OneManPen Posted January 26, 2012 Posted January 26, 2012 Awwwww... Disappointment city, shame... How ever when I was writing my TCP instant messenger server... I never had any "slowness" , But I guess thats because I was doing it wrong or something .
JRSmile Posted February 2, 2012 Author Posted February 2, 2012 Let me explain a bit, with your instant messanger if your doing it clever you get one packet for the message and maybe one or two for the replies from the server, with minecraft you get a packet for everything, turning the mouse one degree, walking one step, changing the item etc. So normally you get a constant stream of packets from the client which has to be analysed somehow, even pulling things like current cpu usage takes to long to keep the stream to the client in time ... Maybe there is a clue to provide the client with information already captured in memory from a different thread, but this is out of my mind right now, if someone has a clever idea how to do this feel free to comment. But good news ingame chatcommands work like expected now, and returning chat messages to the client works also. Skinny currently works on implementing the world itself, i wonder how far he already got. Best regards, j. $a=StringSplit("547275737420796F757220546563686E6F6C75737421","") For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4) Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI" Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile; MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
JRSmile Posted April 11, 2012 Author Posted April 11, 2012 update, due to protocol changes from 1.1 to 1.2.5 it is no longer possible to login with the new client, if you want to test the server, downgrade minecraft to 1.1 ! i may update the server to be able to connect with a 1.2.5 client but i don't see a reason, everything included in the 1.1 client is enough for the purpose of the project here. Regards, J. $a=StringSplit("547275737420796F757220546563686E6F6C75737421","") For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4) Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])));''Chr("a")&"HI" Next ;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile; MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now