mirror of
https://github.com/hamburghammer/grcon.git
synced 2024-06-03 16:32:47 +02:00
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
|
||
|
}
|