0

我有以下脚本,我在网上找到了 Python。它所做的是尝试连接到 MineCraft 服务器,首先通过发送“握手”,然后发送登录请求。协议规范可以在这里找到:http ://wiki.vg/Protocol

无论如何,python脚本工作正常。但是,我认为第二个数据包编码错误,因为当它发送时,服务器控制台上什么也没有出现。播放器未连接或任何东西。由于“客户端”没有及时登录,它最终会超时并关闭连接。

基本上,无论如何,有 struct.pack() 经验的人应该能够在这里帮助我。我已经评论了我不确定我是否编码正确的行。有关打包数据的详细信息显示在上面的链接中。

任何帮助将不胜感激,我对编码/打包数据一无所知。:(

这是代码

import struct

import socket

import time

import urllib

import urllib2


host = str(raw_input('What is the host ip: '))

port = int(raw_input('What is the server port: '))

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.connect((host, port))


usrnm = str(raw_input('What is your username: '))

psswrd = str(raw_input('What is your password: '))


logindata = {'user':usrnm, 'password':psswrd, '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':usrnm,'host':host,'port':port}


enc_user = data['user'].encode('utf-16BE')

packfmt = '>bih{}shiibBB'.format(len(enc_user))

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

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=' + usrnm + '&sessionId=' + mcsessionid + '&serverId=' + connhash + '...')

req = urllib.urlopen('http://session.minecraft.net/game/joinserver.jsp?user=' + usrnm + '&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')

packfmt = '>bih{}shiibBB'.format(len(enc_user))

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

#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)
4

1 回答 1

1

是的,您正在发送字符串的长度,即字符数。相反,您应该发送编码字符串中的字节数。此外,您应该使用“!” 为了清楚起见,而不是“>”,作为“!” 用来表示“网络秩序”,就是这个。所以这...

structfmt = '>bh'

packetbytes = struct.pack(structfmt, 2, len(string))+string.encode('utf-16BE')

……改成这个……

structfmt = '!bh'

encoded = string.encode('utf-16BE')

packetbytes = struct.pack(structfmt, 2, len(encoded))+encoded
于 2012-07-05T20:26:49.307 回答