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)