使用Python将登录数据包发送到Minecraft服务器不起作用 [英] Sending Login Packet to Minecraft Server in Python Not Working

查看:258
本文介绍了使用Python将登录数据包发送到Minecraft服务器不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Python中具有以下脚本.它的作用是尝试先通过发送握手",然后发送登录请求来连接到MineCraft服务器.协议规范可以在这里找到: http://wiki.vg/Protocol

I have the following script in Python. What it does is tries to connect to a MineCraft server, first by sending a 'handshake', then sending a login request. The protocol specs can be found here: http://wiki.vg/Protocol

无论如何,python脚本可以正常工作,并且没有错误.但是,我相当习惯将第二个数据包编码错误,因为在发送第二个数据包时,服务器控制台上没有任何内容.播放器未连接或任何东西.最终由于客户端"未及时登录而最终超时并关闭了连接.

Anyway, the python script works fine, and there are no errors. However, I'm fairly use I encoded the second packet wrong, as when it is sent, nothing appears on the server console. The player isn't connected or anything. It just eventually times out and closes the connection due to the 'client' not logging in in time.

基本上,无论如何,对struct.pack()都有经验的人都应该可以在这里为我提供帮助.我在不确定我是否正确编码的那一行中发表了评论.打包数据的详细信息显示在上面的链接中.

Basically, anyway who has experience with struct.pack() should be able to help me here. I have commented the line where I am unsure of whether I have encoded everything right. The detailed information on packing the data is shown in the link above.

任何帮助都会得到我们的赞赏,我对编码/打包数据一无所知. :(

Any help would be greatly appreciated, I'm pretty clueless with encoding/packing data. :(

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)

推荐答案

似乎您没有添加字符串或空白字段;

It seems you're not adding the string or the empty fields;

packetbytes = struct.pack('>bihshiibBB', 1, 23, len(data['user']), enc_user, 0, 0, 0, 0, 0, 0)

关于打包格式中的第二个h,Minecraft字符串的长度大于或等于2个字节.因此,我假设一个空字符串只是一个值为0的short.

About the second h in the packing format, a Minecraft string is greater or equal than 2 bytes in length. So I'm assuming that an empty string is just a short with the value 0.

修改: 上述方法无效. s需要一个长度;

The abovementioned method doesn't work; the s needs a length;

packfmt = '>bih{}shiibBB'.format(len(enc_user))
packetbytes = struct.pack(packfmt, 1, 23, len(data['user']), enc_user, 0, 0, 0, 0, 0, 0)

这篇关于使用Python将登录数据包发送到Minecraft服务器不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆