108 lines
2.0 KiB
Go
108 lines
2.0 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
|
|
}
|
|
|
|
_status := minecraft.NewStatusProvider("Server")
|
|
listener, err := minecraft.ListenConfig{
|
|
StatusProvider: _status,
|
|
}.Listen("raknet", ":19132")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer listener.Close()
|
|
|
|
fmt.Printf("Listening on %s\n", listener.Addr())
|
|
|
|
c, err := listener.Accept()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
conn := c.(*minecraft.Conn)
|
|
|
|
hostname, serverConn, err := connect_server(ctx, server)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
out_path := fmt.Sprintf("skins/%s", hostname)
|
|
|
|
if err := spawn_conn(ctx, conn, serverConn); err != nil {
|
|
return err
|
|
}
|
|
|
|
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(conn, "connection lost")
|
|
for {
|
|
pk, err := serverConn.ReadPacket()
|
|
if err != nil {
|
|
if disconnect, ok := errors.Unwrap(err).(minecraft.DisconnectError); ok {
|
|
_ = listener.Disconnect(conn, disconnect.Error())
|
|
}
|
|
return
|
|
}
|
|
process_packet_skins(conn, out_path, pk)
|
|
|
|
if err = conn.WritePacket(pk); err != nil {
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
go func() { // client -> server
|
|
for {
|
|
pk, err := conn.ReadPacket()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if err := serverConn.WritePacket(pk); err != nil {
|
|
if disconnect, ok := errors.Unwrap(err).(minecraft.DisconnectError); ok {
|
|
_ = listener.Disconnect(conn, disconnect.Error())
|
|
}
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
for {
|
|
select {
|
|
case err := <-errs:
|
|
return err
|
|
case <-ctx.Done():
|
|
return nil
|
|
}
|
|
}
|
|
}
|