0

Python でオンラインで見つけた次のスクリプトがあります。まず「ハンドシェイク」を送信し、次にログイン要求を送信して、MineCraft サーバーに接続しようとします。プロトコル仕様はここにあります: http://wiki.vg/Protocol

とにかく、python スクリプトは正常に動作します。ただし、2 番目のパケットは間違ってエンコードされていると思います。送信時にサーバー コンソールに何も表示されないからです。プレーヤーが接続されていません。「クライアント」が時間内にログインしないため、最終的にタイムアウトして接続を閉じます。

基本的に、とにかく 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 に答える