4

I am building a simple MinecraftClassic bot in Python. Right now I even can't login. Here is my code so far:

import socket
s = socket.socket()
KEY = "serverkey"
HOST = "68.53.14.13"
PORT = 25566
s.connect((HOST, PORT))
print 'connected'
START_LOGIN = s.sendall(chr(0x00)) # Start login packet
PROTOCOL    = s.sendall(chr(0x07)) # Send protocol version
USERNAME    = s.sendall("Vik2015") # Username
VERKEY      = s.sendall(KEY)       # Verification key
UNUSED      = ""                   # Unused byte
print 'sentall'
print s.recv(4096)
s.close()

But when I execute it, my client just sticks forever. It doesn't get any responses from the server. What I am doing wrong? I'd really like to write this bot.

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
JadedTuna
  • 1,783
  • 2
  • 18
  • 32
  • I assume you have sniffed the traffic to see what it is expecting? – cmd Nov 01 '13 at 20:44
  • @cmd, I tried to, but got no results (at least nothing worked). I am using http://minecraft.gamepedia.com/Classic_server_protocol now – JadedTuna Nov 01 '13 at 20:45
  • Try padding the USERNAME and VERKEY out to 64 characters with spaces. That doc you linked specifies that strings should be 64 character ASCII padded with spaces. Also, you have to send the UNUSED byte. – Silas Ray Nov 01 '13 at 20:51
  • according to the spec, strings are 64 bytes padded with spaces. "Vik2015" was only a partial string. Once you fix username and validation key, you'll also need to add one more chr at the end for the unused byte. – tdelaney Nov 01 '13 at 20:51
  • @tdelaney, I know that I have to add another, byte. It may sound stupid, but how do I add it? Is it `chr(0x00)` or what? – JadedTuna Nov 01 '13 at 20:53
  • @tdelaney, also, about padding. Should I add spaces before or after the username? I mean should it be `"(spaces)username"` or `"username(spaces)"` – JadedTuna Nov 01 '13 at 20:54
  • yes, `chr(0x00)` should work, padding could be `"%-64s" % username` – cmd Nov 01 '13 at 20:54
  • 1
    @Vik2015 - the spec isn't clear - 99% sure the pad is at the end (that's the normal way to do it) but you may have to tweak that. – tdelaney Nov 01 '13 at 20:57
  • @tdelaney, I modified code (as you said), but it isn't working. Client still freezes forever – JadedTuna Nov 01 '13 at 21:00
  • you need to actually send that unused byte, `s.sendall(chr(0x00))` – cmd Nov 01 '13 at 21:01
  • From looking at http://stackoverflow.com/a/9521925/600110, it appears that you need to send the `UNUSED` byte, and that null (0x00) is OK. – Sam Mussmann Nov 01 '13 at 21:02
  • @cmd, wow, thanks! I finally got it working. Silly me :) haven't noticed than I am not sending UNUSED byte – JadedTuna Nov 01 '13 at 21:03
  • 1
    @Vik2015 - um, you needed `s.sendall(chr(0x00))`, not sure why it worked for you. You can send it with far fewer calls by doing: `s.sendall('%c%c%-64s%-64s%c' % (0, 7, USERNAME, KEY, 0))`. – tdelaney Nov 01 '13 at 21:05
  • @tdelaney, I noticed that already. I am finally getting banner from the server :) Now I am going to work on movement – JadedTuna Nov 01 '13 at 21:08
  • Also, `sendall` is going to return `None` or raise an exception in all cases, so capturing the result to a variable won't be particularly useful. – Silas Ray Nov 01 '13 at 21:08
  • You can find your UUID at namemc.com Just search up your name and copy the strange random letters and numbers. – Yondering May 22 '18 at 21:29

1 Answers1

2

Putting the comments together, here's what you get:

import socket
s = socket.socket()
KEY = "ce73007bb263c20268da59eb9fb52b06" # If you want to help me, you can use this key to connect to the server
USERNAME = "Vik2015"
HOST = "68.53.14.13"
PORT = 25566
s.connect((HOST, PORT))
print 'connected'
# login packet (pkt id, protocol version, user name, verification key, pad)
s.sendall('%c%c%-64s%-64s%c' % (0, 7, USERNAME, KEY, 0))
print 'sentall'
print s.recv(4096)
s.close()
tdelaney
  • 73,364
  • 6
  • 83
  • 116