Javaでマイクラのサーバーにパケット送りたくなった

2022-03-01Minecraft_Protocol

広告

初めに

マイクラの最新バージョンが1.18.2の時に書いているのでパケットの構造が変わっているかも
このサイトに作っているの入れてます(Java)<-命名規則全然守れてないです
wiki.vgのProtocolのサイトを見ながら作っています

準備

server(公式のやつのほうがいいけど、実験でProtocolLibとか使いたいときに使えないので、spigot系がおすすめ)<-offlineモードにすること
IntelliJ IDEA(Javaとmavenが使えたらなんでもいい)<-別言語で作りたかったら用意しなくてもいい
https://wiki.vgを開いといた方がいい

パケットの送り方とか

圧縮しないなら
1:パケットの合計の長さ(PacketIDの長さ+データの長さ)
2:PacketID(VarInt)
3:データ
の順番で送る

圧縮したデータを送る際は
1:パケットの合計の長さ(2,3,4の長さの合計)
2:非圧縮の場合のPacketIDとデータの長さの合計または0(0は非圧縮として扱われる)
3:圧縮したPacketIDとデータ
の順番で送ります

PacketIDとデータはzlibで圧縮してください
注意:非圧縮のPacketIDとデータがSetCompression(パケット)の値より小さかったら圧縮はしなくていいです(なので2番の値は0になる)

データの種類と送り方

に書いてあります
僕的にはVarInt,VarLongの長さを取得できるようにしとくといいのと
配列が出てくるときもあるので、配列の読み込む回数をどこかに保存させて配列を読み込むときにその回数読み込ませた方がいいかもしれない

その他

状態(state):サーバーやクライアントが相手の何を待っているかなどを表す
状態によってパケットの意味が変わってしまうことがある

このサイトにどんな順番でパケットが送られるなどが書いてあります

サーバーに接続する(Java)

Socket socket=new Socket(host,port);//終わるときにcloseすること host->例:localhost port->デフォルトは25565
DataOutputStream input=new DataOutputStream(socket.getOutputStream());//inputを使ってデータを書き込む

ログインさせる

HandShakeをまず送る
https://wiki.vg/Protocol#Handshake
を見ると(いろいろ文章変えています…)

状態はHandshaking,PacketIDは0x00です

名前メモ
Protocol VersionVarIntこのサイトに書いてあります
Server AddressString(max:255)接続をするときに使うサーバーアドレス(例:127.0.0.1やlocalhostなど) 公式のマイクラサーバーはこの情報は使わないらしい
Server PortUnsigned Shortサーバーのポート 公式のマイクラサーバーは使わないらしい。
デフォルトは25565
Next StateVarInt Enum次の状態 1=status,2=login

今回はログインさせるので
Next Stateは2にします(statusはサーバーの情報(今いるプレーヤー数とか)を取得できます)
送るパケットは圧縮するかしないかについては
今回は圧縮させるかを伝えるパケットはまだ送られてないので
圧縮はしなくていいです

次にLogin Startって名前のパケットを送ります

状態はlogin,PacketIDは0x00です
これも圧縮しなくていいです

名前メモ
NameString(max:16)プレーヤーの名まえ(ユーザーネーム)

これを送ったら、次に送る内容はサーバーが何を送るかによって変わります
下の3つの状態はすべてloginです
1:Encryption Request<-マイクラがofflineモードになってたら送られることはない
2:Set Compression<-圧縮が無効なら送られないか0以下の値です
3:Login Success<-これが来たら状態はplayに変わります

1:検証してないです(アカウントを一個しか持ってないから確認しずらい)

2:圧縮するかなど(PacketIDは0x03)
フィールド(パケットのデータの中身)はVARINTの一つだけ
このVARINTが0以下だったら圧縮はしないって意味、そもそもこのパケットが送られないこともある

3:パケットのデータの中身は下の図です

名前メモ
UUIDUUIDプレーヤーのUUID
UsernameString(max:16)プレーヤーの名まえ(ユーザーネーム)

注意点:3番が送られるの前に2番が送られている場合があります
その場合パケットのデータが圧縮されている可能性もあるので
パケットのデータが圧縮されていたらそのデータを解凍するのを忘れずに

Login Successがきたら状態はplayに変わるので次のパケットに注意しましょう

次に送られるパケットがNBTを渡してくるのでその記事が完成したら増やすかも…

Join Gameらへんから

こっからはwiki.vgを読んでいけば行けるはず(Chunkのは作成中)

広告

2022-03-01Minecraft_Protocol

Posted by koufu193