Skip to content

Commit d9b443e

Browse files
committed
fix: better packet handling for overly chatty servers like rust
1 parent 892f99a commit d9b443e

4 files changed

Lines changed: 62 additions & 29 deletions

File tree

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
RCON_PASSWORD=localpassword
22
RCON_PORT=7778
33

4+
5+
wire-podman-vlms:
6+
podman unshare chown 1000:1000 .serverdata/rust/common.cfg
7+
podman unshare chown 1000:1000 .serverdata/mh/common.cfg
8+
podman unshare chown 1000:1000 .serverdata/mh/Game.ini
9+
410
lift-mh-server:
511
docker compose run mh-server
612

cmd/main.go

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/UltimateForm/tcprcon-cli/internal/config"
1616
"github.com/UltimateForm/tcprcon/pkg/common_rcon"
1717
"github.com/UltimateForm/tcprcon/pkg/logger"
18-
"github.com/UltimateForm/tcprcon/pkg/packet"
1918
"github.com/UltimateForm/tcprcon/pkg/rcon"
2019
"golang.org/x/term"
2120
)
@@ -84,28 +83,6 @@ func determinePassword(currentPw string) (string, error) {
8483
return password, nil
8584
}
8685

87-
func execInputCmd(rcon *rcon.Client) error {
88-
logger.Debug.Println("executing input command: " + inputCmdParam)
89-
execPacket := packet.New(rcon.Id(), packet.SERVERDATA_EXECCOMMAND, []byte(inputCmdParam))
90-
fmt.Printf(
91-
"(%v): SND CMD %v\n",
92-
ansi.Format(strconv.Itoa(int(rcon.Id())), ansi.Green, ansi.Bold),
93-
ansi.Format(inputCmdParam, ansi.Blue),
94-
)
95-
rcon.Write(execPacket.Serialize())
96-
packetRes, err := packet.Read(rcon)
97-
if err != nil {
98-
return errors.Join(errors.New("error while reading from RCON client"), err)
99-
}
100-
fmt.Printf(
101-
"(%v): RCV PKT %v\n%v\n",
102-
ansi.Format(strconv.Itoa(int(rcon.Id())), ansi.Green, ansi.Bold),
103-
ansi.Format(strconv.Itoa(int(packetRes.Type)), ansi.Green, ansi.Bold),
104-
ansi.Format(strings.TrimRight(packetRes.BodyStr(), "\n\r"), ansi.Green),
105-
)
106-
return nil
107-
}
108-
10986
func Execute() {
11087
flag.Parse()
11188
logLevel := uint8(logLevelParam)
@@ -191,15 +168,16 @@ func Execute() {
191168
return
192169
}
193170

171+
ctx, cancel := context.WithCancel(context.Background())
172+
defer cancel()
173+
194174
if inputCmdParam != "" {
195-
if err := execInputCmd(rconClient); err != nil {
175+
if err := execInputCmd(ctx, rconClient); err != nil {
196176
logger.Critical.Println(err)
197177
}
198178
return
199179
} else {
200180
// could just rely on early return but i feel anxious :D
201-
ctx, cancel := context.WithCancel(context.Background())
202-
defer cancel()
203181
runRconTerminal(
204182
ctx,
205183
rconClient,

cmd/single.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package cmd
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"strconv"
8+
"strings"
9+
"time"
10+
11+
"github.com/UltimateForm/tcprcon-cli/internal/ansi"
12+
"github.com/UltimateForm/tcprcon/pkg/logger"
13+
"github.com/UltimateForm/tcprcon/pkg/packet"
14+
"github.com/UltimateForm/tcprcon/pkg/rcon"
15+
)
16+
17+
func execInputCmd(ctx context.Context, rcon *rcon.Client) error {
18+
logger.Debug.Println("executing input command: " + inputCmdParam)
19+
id := rcon.Id()
20+
execPacket := packet.New(id, packet.SERVERDATA_EXECCOMMAND, []byte(inputCmdParam))
21+
fmt.Printf(
22+
"(%v): SND CMD %v\n",
23+
ansi.Format(strconv.Itoa(int(id)), ansi.Green, ansi.Bold),
24+
ansi.Format(inputCmdParam, ansi.Blue),
25+
)
26+
rcon.Write(execPacket.Serialize())
27+
// not totally effective since response reader has its own internally defined timeout
28+
timeoutCtx, cancel := context.WithTimeout(ctx, time.Second*10)
29+
defer cancel()
30+
responseChan := packet.CreateResponseChannel(rcon, timeoutCtx)
31+
for {
32+
select {
33+
case <-timeoutCtx.Done():
34+
return errors.New("timeout while waiting for response")
35+
case pkt := <-responseChan:
36+
if pkt.Id != id {
37+
logger.Warn.Printf("ignoring a packet with mismatched ID: %v vs %v; possibly overly chatty server\n", id, pkt.Id)
38+
continue
39+
}
40+
fmt.Printf(
41+
"(%v): RCV PKT %v\n%v\n",
42+
ansi.Format(strconv.Itoa(int(pkt.Id)), ansi.Green, ansi.Bold),
43+
ansi.Format(strconv.Itoa(int(pkt.Type)), ansi.Green, ansi.Bold),
44+
ansi.Format(strings.TrimRight(pkt.BodyStr(), "\n\r"), ansi.Green),
45+
)
46+
return nil
47+
}
48+
}
49+
}

compose.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ services:
1919
start_period: 30s
2020
volumes:
2121
- linuxgsm-mh:/data
22-
- .serverdata/mh/common.cfg:/data/config-lgsm/mhserver/common.cfg
23-
- .serverdata/mh/Game.ini:/data/serverfiles/Mordhau/Saved/Config/LinuxServer/Game.ini
22+
- .serverdata/mh/common.cfg:/data/config-lgsm/mhserver/common.cfg:Z
23+
- .serverdata/mh/Game.ini:/data/serverfiles/Mordhau/Saved/Config/LinuxServer/Game.ini:Z
2424

2525
rust-server:
2626
image: ghcr.io/gameservermanagers/gameserver:rust
@@ -36,7 +36,7 @@ services:
3636
start_period: 30s
3737
volumes:
3838
- linuxgsm-rust:/data
39-
- .serverdata/rust/common.cfg:/data/config-lgsm/rustserver/common.cfg
39+
- .serverdata/rust/common.cfg:/data/config-lgsm/rustserver/common.cfg:Z
4040
network_mode: host
4141

4242
volumes:

0 commit comments

Comments
 (0)