2

自動的にチャットをガードし、スパマーを禁止するために、Minecraft サーバー用のクライアント/ボットを作成しようとしています。(最初の成果)ここでいくつかのドキュメントを見つけ、ここから
データ型を実装しました(したがって、このように見えます-まだ完成していません)。今、私は次のように見えるはずの初期パケットを送信しようとしています:0x02

私のパケットフォーマット

size    value                comment

1       0x02                 Packet ID
2+?     string               Username (I send "jakub")
2+?     another string       Server host name - here, the program FAILS*
4       25565                Port number

*Fails は、bukkit サーバーがコンソールに次のように出力し、ソケットが閉じていることを意味します。

11:09:45 [情報] /127.0.0.1:51256接続が失われました

データ型が正しいかどうかをテストする方法がわかりましたが、問題なくユーザー名を送信しているように見えるため、正しい形式ではありますが、間違った情報を送信していると思います。

文字列の生成

とにかく、すべてを正しく行ったかどうかに興味があります。と のクラスがmc_shortありmc_stringます。これはmc_short、それ自体の 2 バイトを作成する方法です。

//mc_short::val is type of short 
void mc_short::asBytes(char* data) {  
    for (int i = 0; i < 2; i++)
       data[endianity?i:1-i] = (val >> (i * 8));  //Some magic with byteshifting.
       //endianity is set to false, because java uses BigEndian everywhere** (UNFRIENDLY PERSONS!!)
}

** http://wiki.vg/Data_Typesを参照してください:

Java (および Minecraft など) のすべての型はビッグエンディアンです。つまり、最上位バイトが最初に来ます。

次に、文字列自体がmc_shortandを使用して のstd::stringバイトを埋めますchar*

void mc_string::asBytes(char* data) {
    mc_short size((short)val.length());  //val is std::string
    size.endianity = endianity;          //mc_string::endianity is boolean, and is ony used to determine endianity of the first 2 bytes
    size.asBytes(data);  //Filling 2 bytes in data - length info
    for(short i=0; i<size.value(); i++) {
        data[i+2] = val[i];  //Copying std::string to data
    }
}

質問のまとめ

  1. 0x02 の 3 番目のフィールドである「サーバーのホスト名」として何を送信すればよいですか?
  2. 文字列を正しく送信していますか? 他に必要な変換はありませんか?

私の質問はあまり知られていないトピックに関するものであるため、回答もトピック自体も知らない可能性があることは承知しています。そのような状況では、質問を無視してください。

4

1 に答える 1

2

文字列は、ビッグ エンディアンの unicode (UTF-16、ただしビッグ エンディアン) でエンコードされます。Java を使用していない場合は、文字をメモリから直接マップすることはできません (まあ、各文字の間にゼロを書き込んで、それがくだらない方法だと認めれば、ごまかすことができます)。Minecraft の文字列をエンコードする C# の例がここにあります

その文字列の内容については、接続先のホスト名である必要があります。Google が Minecraft サーバーを実行している場合、その文字列はminecraft.google.com.

この実際のパケットを操作する例は、こちらです。

それで、あなたの質問に実際に答えて、いくつかのアドバイス。Minecraft のプロトコルはひどいものであり、クライアントを作成するには多くの作業が必要です。プロトコル内のすべてのパケット (はい、すべて) をサポートできる必要があり、基本的な物理演算を実装して地面に落下し、飛んで蹴られないようにする必要があります。最良の選択から最悪の選択の順に、いくつかのオプションがあります。

  • Bukkit を使用して、このためのプラグインを作成します
  • クライアントの代わりにプロキシを書く
  • あなたが今しようとしているように、クライアントを書きます

したがって、最初に行う場合は、Java でプラグインを作成する必要があります。私はこれについてあまり知りません。

後者の 2 つのオプションについてはよく知っています。私はCraft.Netのメンテナーです。これは、汎用ネットワーク ライブラリとクライアント ライブラリを含む一連のライブラリです。数時間でクライアントまたはプロキシをまとめることができます。クライアントの例は同じレポにあり、ここにプロキシがあります。これらはすべて C# を使用します。

それでも完全に自分でロールしたい場合は、幸運とゴッドスピード.

于 2013-03-22T03:28:20.987 に答える