update readme
This commit is contained in:
parent
728d7f972e
commit
fb8d34cf5f
22
Readme.md
22
Readme.md
|
@ -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)
|
||||
```
|
|
@ -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{})
|
||||
}
|
Loading…
Reference in New Issue