mirror of
https://github.com/hamburghammer/grcon.git
synced 2024-05-10 05:15:27 +02:00
Augusto Dwenger J.
7b8e1bbe41
Minecraft (spigot) behaves differently. It does not support empty requests. This is a deal breaker for the SimpleClient implementation. The implementation is mutch simpler but in limits the exec support to not support multi packet responses.
85 lines
2.4 KiB
Go
85 lines
2.4 KiB
Go
package client
|
|
|
|
import (
|
|
"github.com/hamburghammer/grcon"
|
|
"github.com/hamburghammer/grcon/util"
|
|
)
|
|
|
|
// NewMinecraftClient is a constructor for the MinecraftClient struct.
|
|
// The util.GenerateNewId can be used as idGenFunc.
|
|
func NewMinecraftClient(r util.RemoteConsole, idGenFunc func() grcon.PacketId) MinecraftClient {
|
|
return MinecraftClient{RemoteConsole: r, IdGenFunc: idGenFunc}
|
|
}
|
|
|
|
// MinecraftClient is a wrapper for a RemoteConsole that provides some utility functions.
|
|
// It simplifies the interaction with a remote console of a minecraft server.
|
|
type MinecraftClient struct {
|
|
// RemoteConsole is the console to use for the interactions.
|
|
util.RemoteConsole
|
|
// IdGenFunc is the function to use to generate ids.
|
|
IdGenFunc func() grcon.PacketId
|
|
}
|
|
|
|
// Auth should be used to authenticate the connection.
|
|
//
|
|
// It can return following errors:
|
|
// - InvalidResponseTypeError
|
|
// - ResponseIdMismatchError
|
|
// - AuthFailedError
|
|
func (sc MinecraftClient) Auth(password string) error {
|
|
reqID := sc.IdGenFunc()
|
|
err := sc.Write(grcon.Packet{Id: reqID, Type: grcon.SERVERDATA_AUTH, Body: []byte(password)})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
packet, err := sc.Read()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if packet.Type != grcon.SERVERDATA_AUTH_RESPONSE {
|
|
return newInvalidResponseTypeError(grcon.SERVERDATA_AUTH_RESPONSE, packet.Type)
|
|
}
|
|
if packet.Id == -1 {
|
|
return newAuthFailedError()
|
|
}
|
|
if packet.Id != reqID {
|
|
return newResponseIdMismatchError(reqID, packet.Id)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Exec executes the command on the given RemoteConsole implementation and
|
|
// waits till the response is read returns it.
|
|
//
|
|
// Errors:
|
|
// Returns all errors returned from the Write and Read methode from the RemoteConsole implementation.
|
|
// Can also return an InvalidResponseTypeError if the response is not of the type
|
|
// grcon.SERVERDATA_RESPONSE_VALUE.
|
|
func (sc MinecraftClient) Exec(cmd string) ([]byte, error) {
|
|
cmdPacket := grcon.Packet{
|
|
Id: sc.IdGenFunc(),
|
|
Type: grcon.SERVERDATA_EXECCOMMAND,
|
|
Body: []byte(cmd),
|
|
}
|
|
err := sc.Write(cmdPacket)
|
|
if err != nil {
|
|
return []byte{}, err
|
|
}
|
|
|
|
packet, err := sc.Read()
|
|
if err != nil {
|
|
return []byte{}, err
|
|
}
|
|
if packet.Type != grcon.SERVERDATA_RESPONSE_VALUE {
|
|
return []byte{}, newInvalidResponseTypeError(grcon.SERVERDATA_RESPONSE_VALUE, packet.Type)
|
|
}
|
|
|
|
if packet.Id != cmdPacket.Id {
|
|
return []byte{}, newResponseIdMismatchError(cmdPacket.Id, packet.Id)
|
|
}
|
|
|
|
return packet.Body, nil
|
|
}
|