update readme

This commit is contained in:
olebeck 2022-08-16 19:40:07 +02:00
parent 728d7f972e
commit fb8d34cf5f
2 changed files with 191 additions and 4 deletions

View File

@ -1,6 +1,18 @@
# bedrocktool
a minecraft bedrock proxy that can among other things save worlds from servers
## [releases](https://github.com/bedrock-tool/bedrocktool/releases)
<br/>
## downloads:
### [here](https://github.com/bedrock-tool/bedrocktool/releases)
<br/>
## issues:
if you find an issue or a crash, please report it by opening a github issue with a screenshot of the crash or issue, thanks
<br/>
```
Usage: bedrocktool <flags> <subcommand> <subcommand args>
@ -8,7 +20,8 @@ Usage: bedrocktool <flags> <subcommand> <subcommand args>
Subcommands:
capture capture packets in a pcap file
help describe subcommands and their syntax
inject inject files into a minecraft install (USE WITH CAUTION)
list-realms prints all realms you have access to
merge merge 2 or more worlds
packs download resource packs from a server
realms-token print xbl3.0 token for realms api
skins download all skins from players on a server
@ -17,6 +30,7 @@ Subcommands:
Top-level flags (use "bedrocktool flags" for a full list):
-debug=false: debug mode
-dns=false: enable dns server for consoles
-debug=false: debug mode (enables extra logging useful for finding bugs)
-dns=false: enable dns server for consoles (use this if you need to connect on a console)
-preload=false: preload resourcepacks for proxy (use this if you need server resourcepacks while using the proxy)
```

173
bpio.go Normal file
View File

@ -0,0 +1,173 @@
package main
import (
"context"
"errors"
"flag"
"fmt"
"os"
"sync"
"time"
"github.com/google/subcommands"
buttplug "github.com/pidurentry/buttplug-go"
"github.com/sandertv/gophertunnel/minecraft"
"github.com/sandertv/gophertunnel/minecraft/protocol/packet"
)
type BpCMD struct {
server_address string
buttplugIP string
dev buttplug.DeviceManager
}
func (*BpCMD) Name() string { return "bpio" }
func (*BpCMD) Synopsis() string { return "buttplug.io intigration" }
func (c *BpCMD) SetFlags(f *flag.FlagSet) {
f.StringVar(&c.server_address, "address", "", "remote server address")
f.StringVar(&c.buttplugIP, "bpaddr", "192.168.178.50", "other address")
}
func (c *BpCMD) Usage() string {
return c.Name() + ": " + c.Synopsis() + "\n"
}
func (c *BpCMD) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
fmt.Println("connecting to buttplug server")
bp, err := buttplug.Dial(fmt.Sprintf("ws://%s:12345", c.buttplugIP))
if err != nil {
fmt.Fprintf(os.Stderr, "buttplug connect error: %s\n", err)
}
handler := buttplug.NewHandler(bp)
device_manager := buttplug.NewDeviceManager(handler)
c.dev = device_manager
scan := c.dev.Scan(30 * time.Second)
fmt.Println("Scanning for devices...")
go func() {
scan.Wait()
fmt.Println("Stopped scanning")
fmt.Println("Found: (")
for _, d := range c.dev.Devices() {
fmt.Printf("\t%s\n", d.DeviceName())
}
fmt.Println(")")
}()
address, _, err := server_input(c.server_address)
if err != nil {
fmt.Fprint(os.Stderr, err)
return 1
}
listener, clientConn, serverConn, err := create_proxy(ctx, address)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return 1
}
defer listener.Close()
println("Connected")
type vib struct {
v buttplug.Vibrate
end time.Time
}
vibrates := make(map[string]vib)
vib_mutex := &sync.Mutex{}
go func() {
for {
now := time.Now()
var to_clear []string
vib_mutex.Lock()
for name, v := range vibrates {
if now.After(v.end) {
fmt.Println("stopping vibrate")
v.v.Stop()
to_clear = append(to_clear, name)
}
}
for _, v := range to_clear {
delete(vibrates, v)
}
vib_mutex.Unlock()
time.Sleep(1 * time.Second)
}
}()
vibrate_ms := func(v buttplug.Vibrate, ms int) {
vib_mutex.Lock()
var name string = string(v.DeviceName())
t := time.Now()
if v_e, ok := vibrates[name]; ok {
t = v_e.end
}
vibrates[name] = vib{
v: v,
end: t.Add(time.Duration(ms) * time.Millisecond),
}
vib_mutex.Unlock()
}
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
}
if err = clientConn.WritePacket(pk); err != nil {
return
}
}
}()
go func() { // client -> server
for {
pk, err := clientConn.ReadPacket()
if err != nil {
return
}
switch pk := pk.(type) {
case *packet.Animate:
if pk.ActionType == packet.AnimateActionSwingArm {
devs := device_manager.Vibrators()
fmt.Printf("vibrating %d devices\n", len(devs))
for _, v := range devs {
vibrate_ms(v, 1000)
}
}
}
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:
fmt.Fprintln(os.Stderr, err)
return 1
case <-ctx.Done():
return 0
}
}
}
func init() {
register_command(&BpCMD{})
}