update readme
This commit is contained in:
parent
728d7f972e
commit
fb8d34cf5f
22
Readme.md
22
Readme.md
|
@ -1,6 +1,18 @@
|
||||||
# bedrocktool
|
# 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>
|
Usage: bedrocktool <flags> <subcommand> <subcommand args>
|
||||||
|
@ -8,7 +20,8 @@ Usage: bedrocktool <flags> <subcommand> <subcommand args>
|
||||||
Subcommands:
|
Subcommands:
|
||||||
capture capture packets in a pcap file
|
capture capture packets in a pcap file
|
||||||
help describe subcommands and their syntax
|
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
|
packs download resource packs from a server
|
||||||
realms-token print xbl3.0 token for realms api
|
realms-token print xbl3.0 token for realms api
|
||||||
skins download all skins from players on a server
|
skins download all skins from players on a server
|
||||||
|
@ -17,6 +30,7 @@ Subcommands:
|
||||||
|
|
||||||
|
|
||||||
Top-level flags (use "bedrocktool flags" for a full list):
|
Top-level flags (use "bedrocktool flags" for a full list):
|
||||||
-debug=false: debug mode
|
-debug=false: debug mode (enables extra logging useful for finding bugs)
|
||||||
-dns=false: enable dns server for consoles
|
-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