initial commit
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
package wire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// Writer builds redapricot/Minecraft primitive types into a byte slice.
|
||||
type Writer struct {
|
||||
buf []byte
|
||||
}
|
||||
|
||||
func NewWriter() *Writer { return &Writer{} }
|
||||
|
||||
func (w *Writer) U8(v byte) *Writer { w.buf = append(w.buf, v); return w }
|
||||
func (w *Writer) VarInt(v int) *Writer { w.buf = AppendVarInt(w.buf, v); return w }
|
||||
func (w *Writer) U16(v uint16) *Writer { w.buf = append(w.buf, byte(v>>8), byte(v)); return w }
|
||||
func (w *Writer) Bytes(p []byte) *Writer { w.buf = append(w.buf, p...); return w }
|
||||
|
||||
func (w *Writer) I64(v int64) *Writer {
|
||||
var b [8]byte
|
||||
binary.BigEndian.PutUint64(b[:], uint64(v))
|
||||
w.buf = append(w.buf, b[:]...)
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *Writer) String(s string) *Writer {
|
||||
w.VarInt(len(s))
|
||||
w.buf = append(w.buf, s...)
|
||||
return w
|
||||
}
|
||||
|
||||
// Out returns the built bytes.
|
||||
func (w *Writer) Out() []byte { return w.buf }
|
||||
|
||||
// Reader consumes redapricot/Minecraft primitive types from a byte slice.
|
||||
type Reader struct {
|
||||
buf []byte
|
||||
pos int
|
||||
}
|
||||
|
||||
func NewReader(b []byte) *Reader { return &Reader{buf: b} }
|
||||
|
||||
var errUnderflow = errors.New("wire: read underflow")
|
||||
|
||||
func (r *Reader) U8() (byte, error) {
|
||||
if r.pos >= len(r.buf) {
|
||||
return 0, errUnderflow
|
||||
}
|
||||
v := r.buf[r.pos]
|
||||
r.pos++
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (r *Reader) VarInt() (int, error) {
|
||||
br := bytes.NewReader(r.buf[r.pos:])
|
||||
before := br.Len()
|
||||
v, err := ReadVarInt(br)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
r.pos += before - br.Len()
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (r *Reader) U16() (uint16, error) {
|
||||
if r.pos+2 > len(r.buf) {
|
||||
return 0, errUnderflow
|
||||
}
|
||||
v := binary.BigEndian.Uint16(r.buf[r.pos:])
|
||||
r.pos += 2
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (r *Reader) I64() (int64, error) {
|
||||
if r.pos+8 > len(r.buf) {
|
||||
return 0, errUnderflow
|
||||
}
|
||||
v := int64(binary.BigEndian.Uint64(r.buf[r.pos:]))
|
||||
r.pos += 8
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (r *Reader) Bytes(n int) ([]byte, error) {
|
||||
if n < 0 || r.pos+n > len(r.buf) {
|
||||
return nil, errUnderflow
|
||||
}
|
||||
out := make([]byte, n)
|
||||
copy(out, r.buf[r.pos:r.pos+n])
|
||||
r.pos += n
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (r *Reader) String() (string, error) {
|
||||
n, err := r.VarInt()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
b, err := r.Bytes(n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
// Remaining returns the unread bytes (a copy is not made).
|
||||
func (r *Reader) Remaining() []byte { return r.buf[r.pos:] }
|
||||
|
||||
// BuildHandshake produces a full uncompressed Minecraft Handshake packet
|
||||
// (length-prefixed, packet id 0x00).
|
||||
func BuildHandshake(protocolVersion int, address string, port uint16, intent int) []byte {
|
||||
body := NewWriter().
|
||||
VarInt(0x00). // packet id
|
||||
VarInt(protocolVersion).
|
||||
String(address).
|
||||
U16(port).
|
||||
VarInt(intent).
|
||||
Out()
|
||||
out := AppendVarInt(nil, len(body))
|
||||
return append(out, body...)
|
||||
}
|
||||
Reference in New Issue
Block a user