我有以下 Python 脚本。它的作用是尝试连接到 MineCraft 服务器,首先发送“握手”,然后发送登录请求。协议规范可以在这里找到:http://wiki.vg/协议 http://wiki.vg/Protocol
无论如何,python 脚本运行良好,并且没有错误。但是,我相当频繁地将第二个数据包编码错误,因为当它发送时,服务器控制台上没有显示任何内容。播放器未连接或任何其他东西。由于“客户端”未及时登录,它最终会超时并关闭连接。
基本上,无论如何,有 struct.pack() 经验的人应该能够在这里帮助我。我已经评论了我不确定我是否已正确编码所有内容的行。有关打包数据的详细信息显示在上面的链接中。
任何帮助都会greatly谢谢,我对编码/打包数据一无所知。 :(
import struct
import socket
import time
import urllib
import urllib2
host = "127.0.0.1"
port = 25566
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
logindata = {'user':'JackBeePee', 'password':'*******', 'version':'12'}
data = urllib.urlencode(logindata)
print('Sending data to login.minecraft.net...')
req = urllib2.Request('https://login.minecraft.net', data)
response = urllib2.urlopen(req)
returndata = response.read()
returndata = returndata.split(":")
mcsessionid = returndata[3]
del req
del returndata
print("Session ID: " + mcsessionid)
data = {'user':u'JackBeePee','host':u'127.0.0.1','port':25566}
stringfmt = u'%(user)s;%(host)s:%(port)d'
string = stringfmt % data
structfmt = '>bh'
packetbytes = struct.pack(structfmt, 2, len(string))+string.encode('utf-16BE')
s.send(packetbytes)
connhash = s.recv(1024)
print("Connection Hash: " + connhash)
print('Sending data to http://session.minecraft.net/game/joinserver.jsp?user=JackBeePee&sessionId=' + mcsessionid + '&serverId=' + connhash + '...')
req = urllib.urlopen('http://session.minecraft.net/game/joinserver.jsp?user=JackBeePee&sessionId=' + mcsessionid + '&serverId=' + connhash)
returndata = req.read()
if(returndata == 'OK'):
print('session.minecraft.net says everything is okay, proceeding to send data to server.')
else:
print('Oops, something went wrong.')
time.sleep(5)
# All above here works perfectly.
enc_user = data['user'].encode('utf-16BE')
#This line is probably where something's going wrong:
packetbytes = struct.pack('>bih', 1, 23, len(data['user'])) + data['user'].encode('utf-16BE') + struct.pack('>hiibBB', 2,0,0,0,0,0)
print(len(packetbytes))
print('Sending ' + packetbytes + ' to server.')
s.send(packetbytes)
while True:
data = s.recv(1024)
if data:
print(data)