bedrocktool/skins-proxy.go

94 lines
1.8 KiB
Go

package main
import (
"context"
"errors"
"flag"
"fmt"
"os"
"github.com/sandertv/gophertunnel/minecraft"
)
func init() {
register_command("skins-proxy", "skin stealer (proxy)", skin_proxy_main)
}
func skin_proxy_main(ctx context.Context, args []string) error {
var server string
if len(args) >= 1 {
server = args[0]
args = args[1:]
}
flag.StringVar(&skin_filter_player, "player", "", "only download the skin of this player")
flag.CommandLine.Parse(args)
if G_help {
flag.Usage()
return nil
}
address, hostname, err := server_input(server)
if err != nil {
return err
}
listener, clientConn, serverConn, err := create_proxy(ctx, address)
if err != nil {
return err
}
defer listener.Close()
out_path := fmt.Sprintf("skins/%s", hostname)
println("Connected")
println("Press ctrl+c to exit")
os.MkdirAll(out_path, 0755)
errs := make(chan error, 2)
go func() { // server -> client
defer serverConn.Close()
defer listener.Disconnect(clientConn, "connection lost")
for {
pk, err := serverConn.ReadPacket()
if err != nil {
if disconnect, ok := errors.Unwrap(err).(minecraft.DisconnectError); ok {
_ = listener.Disconnect(clientConn, disconnect.Error())
}
return
}
process_packet_skins(clientConn, out_path, pk)
if err = clientConn.WritePacket(pk); err != nil {
return
}
}
}()
go func() { // client -> server
for {
pk, err := clientConn.ReadPacket()
if err != nil {
return
}
if err := serverConn.WritePacket(pk); err != nil {
if disconnect, ok := errors.Unwrap(err).(minecraft.DisconnectError); ok {
_ = listener.Disconnect(clientConn, disconnect.Error())
}
return
}
}
}()
for {
select {
case err := <-errs:
return err
case <-ctx.Done():
return nil
}
}
}