Compare commits

..

No commits in common. 'develop' and 'feature/nightly-build' have entirely different histories.

  1. 1
      .gitignore
  2. 32
      Makefile
  3. 8
      config.gcfg
  4. 29
      deps/Dockerfile
  5. 5
      deps/chowner.sh
  6. 30
      deps/clean.sh
  7. 28
      deps/link_sotw.sh
  8. 4
      deps/nethackrc
  9. BIN
      deps/scores.dat
  10. 16
      go.mod
  11. 95
      go.sum
  12. 19
      nethack-launcher/cleanup.go
  13. 5
      nethack-launcher/create_initial_files.go
  14. 23
      nethack-launcher/create_user_files.go
  15. 144
      nethack-launcher/library.go
  16. 4
      nethack-launcher/nethack-launcher.go
  17. 1
      nethack-launcher/print_login_screen.go
  18. 3
      nethack-launcher/print_progress_screen.go
  19. 59
      nethack-launcher/print_user_screen.go
  20. 9
      nethack-launcher/print_welcome_screen.go
  21. 23
      nethack-launcher/run_game.go

1
.gitignore vendored

@ -2,4 +2,3 @@
hack/
stage.tmp/
bin/
deps/shadow-of-the-wyrm-release-*.tar.gz

32
Makefile

@ -11,11 +11,9 @@ all: stat
run:
go run \
nethack-launcher/check_dir.go \
nethack-launcher/cleanup.go \
nethack-launcher/create_initial_files.go \
nethack-launcher/create_user_files.go \
nethack-launcher/janitor.go \
nethack-launcher/library.go \
nethack-launcher/nethack-launcher.go \
nethack-launcher/print_change_password_screen.go \
nethack-launcher/print_high_scores.go \
@ -28,15 +26,16 @@ run:
nethack-launcher/run_game.go \
nethack-launcher/start_watcher.go
stat:
mkdir -p bin/
$(CGOR) $(GOC) $(GOFLAGS) -o bin/nethack-launcher nethack-launcher/*.go
dependencies:
go mod init git.bitnuke.io/mfaltys/nethack-launcher
go mod tidy
go get github.com/gorilla/mux
build_docker: fetch_sotw
build_docker:
mkdir -p stage.tmp/
cp deps/Dockerfile stage.tmp/
cp config.gcfg stage.tmp/config.gcfg
@ -47,28 +46,17 @@ build_docker: fetch_sotw
cp deps/chowner.sh stage.tmp/
cp deps/run_nethack.sh stage.tmp/
cp deps/reclist.c stage.tmp/
cp deps/link_sotw.sh stage.tmp/
cp deps/clean.sh stage.tmp/
cp deps/scores.dat stage.tmp/
cd stage.tmp/ && \
$(OS_PERMS) docker build -t $(IMAGE_NAME) .
fetch_sotw:
mkdir -p stage.tmp/
cp deps/shadow-of-the-wyrm-release-1.6.5.tar.gz stage.tmp/sotw.tar.gz
run_docker:
$(OS_PERMS) docker run \
-d \
-p 2223:22 \
--name=nethackdev \
-v $(NETHACK_DIR):/hack-dev:rw \
--restart always \
$(IMAGE_NAME)
stop_docker:
$(OS_PERMS) docker stop -t 0 nethackdev
$(OS_PERMS) docker rm nethackdev
-d \
-p 2222:22 \
--name=nethack \
-v $(NETHACK_DIR):/hack:rw \
--restart always \
$(IMAGE_NAME)
clean:
rm -rf bin/

8
config.gcfg

@ -1,15 +1,11 @@
[nethacklauncher]
loglevel = "debug"
serverdisplay = "bitnuke.io underground nethack server"
nethackversion = "3.6.7-0"
serverdisplay = "unixvoid.com underground nethack server"
nethackversion = "3.7.0-nightly"
hackdir = "/hack"
nhdatlocation = "/NetHack/dat/nhdat"
recoverbinary = "/NetHack/util/recover"
sysconflocation = "/NetHack/sys/unix/sysconf"
ttyreccache = "10"
sotwversion = "1.6.5"
sotwroot = "/sotw"
sotwdumpcache = "5"
bootstrapdelay = 1
[redis]

29
deps/Dockerfile vendored

@ -1,13 +1,14 @@
FROM debian:stable-slim
FROM debian
# install needed packages
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
redis-server \
openssh-server \
curl \
autoconf \
bison \
bsdmainutils \
bzip2 \
flex \
gcc \
gdb \
@ -15,26 +16,14 @@ RUN apt-get update && \
groff \
libncursesw5-dev \
libsqlite3-dev \
libboost-all-dev \
libncurses5-dev \
libncursesw5-dev \
lua5.1 \
liblua5.1-0-dev \
libsdl2-dev \
libsdl2-image-2.0-0 \
libsdl2-mixer-2.0-0 \
libsdl2-image-dev \
libxerces-c-dev \
make \
ncurses-dev \
premake4 \
sqlite3 \
redis-server \
tar \
telnetd \
xinetd \
locales \
wget \
git \
vim
RUN apt-get clean
@ -43,13 +32,13 @@ RUN apt-get clean
#
RUN git clone https://github.com/NetHack/NetHack.git
RUN cd NetHack && \
git checkout NetHack-3.6 && \
sed -i 's/#ifndef SYSCF/#ifdef SYSCF/g' include/config.h && \
sys/unix/setup.sh sys/unix/hints/linux && \
sed -i '/POSTINSTALL=/d' Makefile && \
sed -i 's/.*-DSYSCF -DSYSCF_FILE=.*/CFLAGS+=-DSECURE/' Makefile && \
sed -i 's/#CFLAGS+=-DSCORE_ON_BOTL/CFLAGS+=-DSCORE_ON_BOTL/' Makefile && \
cat Makefile && \
make fetch-Lua && \
make all && \
make install
RUN find /* -name nethack
@ -108,13 +97,5 @@ COPY run.sh /
COPY chowner.sh /bin/
COPY nethackrc /.nethackrc
COPY run_nethack.sh /
COPY link_sotw.sh /bin/
COPY clean.sh /bin/
ADD sotw.tar.gz /
RUN mv /shadow-of-the-wyrm* /sotw/
COPY scores.dat /sotw/
# update ini to match current season by default
RUN cd /sotw && \
sed -i 's/current_month_is_start_month=0/current_month_is_start_month=1/g' swyrm.ini
CMD ["/run.sh"]

5
deps/chowner.sh vendored

@ -2,12 +2,7 @@
while :
do
# chown nethack directory
chown -R nethack:nethack /hack 2> /dev/null
chmod -R 744 /hack 2> /dev/null
# chown sotw directory
chown -R nethack:nethack /sotw 2> /dev/null
chmod -R 744 /sotw 2> /dev/null
sleep 2
done

30
deps/clean.sh vendored

@ -1,30 +0,0 @@
#!/bin/bash
HACKDIR=$1
USERDIR=$2
TTYRECCACHE=$3
SOTWDUMPCACHE=$4
###
# clean old ttyrecs
###
cd /$HACKDIR/user/$USERDIR/ttyrec/
ls -1tr | head -n -$TTYRECCACHE | xargs -d '\n' rm -f --
###
# clean sotw files
###
cd /$HACKDIR/user/$USERDIR/sotw/
# there are always 4 symlinked files
# leave 5 of the latest dumps
DUMPFILES=$(expr $SOTWDUMPCACHE + 4)
FILES=$(ls -1tr *.txt | head -n -$DUMPFILES)
for f in $FILES; do
#test -h $f || echo "removing old file $f"
if [ ! -h $f ]; then
rm -rf $f
fi
done

28
deps/link_sotw.sh vendored

@ -1,28 +0,0 @@
#!/bin/bash
FILES=/sotw/*
USERDIR=$1
HACKDIR=$2
# create initial dir if it does not exist
mkdir -p $USERDIR/sotw/
# link all game files to user dir
for f in $FILES
do
echo "linking $f"
ln -s $f $USERDIR/sotw/
done
# remove inital score file
rm -rf $USERDIR/sotw/scores.dat
# link in shared score file from hackdir
ln -s $HACKDIR/scores.dat $USERDIR/sotw/
## remove initial config file
rm -rf $USERDIR/sotw/swyrm.ini
## copy in sotw config file
cp /sotw/swyrm.ini $USERDIR/sotw/swyrm.ini
# sed find and replace swyrm.ini to set users dir
sed -i "s:userdata_dir=:userdata_dir=${USERDIR}/sotw/:g" $USERDIR/sotw/swyrm.ini

4
deps/nethackrc vendored

@ -25,8 +25,8 @@ OPTIONS=showexp,time
OPTIONS=sortloot:full
# curses interface
OPTIONS=windowtype:curses
OPTIONS=perm_invent
#OPTIONS=windowtype:curses
#OPTIONS=perm_invent
###

BIN
deps/scores.dat vendored

Binary file not shown.

16
go.mod

@ -1,16 +0,0 @@
module git.bitnuke.io/mfaltys/nethack-launcher
go 1.22.1
require (
golang.org/x/crypto v0.26.0
gopkg.in/gcfg.v1 v1.2.3
gopkg.in/redis.v5 v5.2.9
)
require (
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.34.1 // indirect
golang.org/x/sys v0.23.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
)

95
go.sum

@ -1,95 +0,0 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/redis.v5 v5.2.9 h1:MNZYOLPomQzZMfpN3ZtD1uyJ2IDonTTlxYiV/pEApiw=
gopkg.in/redis.v5 v5.2.9/go.mod h1:6gtv0/+A4iM08kdRfocWYB3bLX2tebpNtfKlFT6H4mY=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

19
nethack-launcher/cleanup.go

@ -1,19 +0,0 @@
package main
import (
"fmt"
"os/exec"
)
func runCleanup(username string) {
// clean up ttyrecs in /<hackdir>/user/<username>/ttyrec/
// clean up sotw dumps, aka:
// non-symlinked .txt files in /<hackdir>/user/<username>/sotw/
// run cleanup file
out, err := exec.Command("/bin/clean.sh", config.NethackLauncher.HackDir, username, config.NethackLauncher.TTYRecCache, config.NethackLauncher.SotwDumpCache).Output()
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s\n", out)
}

5
nethack-launcher/create_initial_files.go

@ -51,9 +51,4 @@ func createInitialFiles() {
}
}
// make sure initial sotw scores file exists
if _, err := os.Stat(fmt.Sprintf("%s/scores.dat", config.NethackLauncher.HackDir)); os.IsNotExist(err) {
exec.Command("cp", fmt.Sprintf("%s/scores.dat", config.NethackLauncher.SotwRoot), config.NethackLauncher.HackDir).Run()
}
}

23
nethack-launcher/create_user_files.go

@ -1,7 +1,6 @@
package main
import (
"errors"
"fmt"
"os"
"os/exec"
@ -12,15 +11,10 @@ func createUserFiles(username string) {
userPath := fmt.Sprintf("%s/user/%s/ttyrec/", config.NethackLauncher.HackDir, username)
exec.Command("mkdir", "-p", userPath).Run()
// copy in rc file if it does not exist
// copy in rc file
hackRCLoc := fmt.Sprintf("%s/.nethackrc", config.NethackLauncher.HackDir)
if _, err := os.Stat(fmt.Sprintf("%s/user/%s/.nethackrc", config.NethackLauncher.HackDir, username)); errors.Is(err, os.ErrNotExist) {
println(fmt.Sprintf("%s/user/%s/.nethackrc does not exist, copying it.", config.NethackLauncher.HackDir, username))
hackRCDest := fmt.Sprintf("%s/user/%s/.nethackrc", config.NethackLauncher.HackDir, username)
exec.Command("cp", hackRCLoc, hackRCDest).Run()
} else {
println(fmt.Sprintf("%s/.nethackrc exists, not overwriting.", config.NethackLauncher.HackDir))
}
hackRCDest := fmt.Sprintf("%s/user/%s/.nethackrc", config.NethackLauncher.HackDir, username)
exec.Command("cp", hackRCLoc, hackRCDest).Run()
// create necessary directories if they dont exist
userpath := fmt.Sprintf("%s/user/%s", config.NethackLauncher.HackDir, username)
@ -45,15 +39,4 @@ func createUserFiles(username string) {
// move in nhdat file if it does not exist
exec.Command("cp", fmt.Sprintf("%s/nhdat", config.NethackLauncher.HackDir), userpath).Run()
// run sotw prep script
if _, err := os.Stat(fmt.Sprintf("%s/sotw/", userpath)); os.IsNotExist(err) {
println("running /bin/link_sotw.sh")
out, err := exec.Command("/bin/link_sotw.sh", userpath, config.NethackLauncher.HackDir).Output()
if err != nil {
println("ope: ")
fmt.Sprintf("%s", err)
}
println(string(out))
}
}

144
nethack-launcher/library.go

@ -1,144 +0,0 @@
package main
import (
"bufio"
"fmt"
"io/ioutil"
"os"
"os/exec"
"strconv"
"strings"
"gopkg.in/redis.v5"
)
func printLibraryScreen(redisClient *redis.Client, username string) {
// print header
fmt.Printf(" %s\n", config.NethackLauncher.ServerDisplay)
println("")
println(" Choose a users library to view ('enter' without selection returns)")
println("")
us, err := ioutil.ReadDir(fmt.Sprintf("/%s/user", config.NethackLauncher.HackDir))
if err != nil {
println(" No users exist ('enter' without selection returns)")
panic(err)
}
users := make(map[int]string)
usersTimer := 1
for _, u := range us {
fmt.Printf(" %d) %s\n", usersTimer, u.Name())
// add user to line map
users[usersTimer] = fmt.Sprintf("%s", u.Name())
usersTimer++
}
fmt.Println("")
fmt.Printf(">> ")
// start user input
// disable input buffering
exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
// do not display entered characters on the screen
exec.Command("stty", "-F", "/dev/tty", "-echo").Run()
var b []byte = make([]byte, 1)
for {
os.Stdin.Read(b)
s, _ := strconv.Atoi(string(b))
// check if user is trying to navigate
if string(b) == "\n" {
exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run()
clearScreen()
if username == "" {
clearScreen()
printWelcomeScreen(redisClient)
} else {
clearScreen()
printUserScreen(redisClient, username)
}
}
// check if selection is in out map
if users[s] != "" {
user := strings.Split(users[s], ":")
fmt.Printf("going to spectate '%s'\n", user[0])
clearScreen()
printUserLibraryScreen(redisClient, username, user[0])
}
}
}
func printUserLibraryScreen(redisClient *redis.Client, username, currentUser string) {
// print header
fmt.Printf(" %s\n", config.NethackLauncher.ServerDisplay)
println("")
println(" Choose a ttyrec to view ('enter' without selection returns)")
println(" The following keybinds are available during playback:")
println(" • + or f: double the speed of playback")
println(" • - or s: halve the speed of playback")
println(" • 0: set playback speed to 0, pausing playback")
println(" • 1: set playback speed to 1 again")
println("")
t, err := ioutil.ReadDir(fmt.Sprintf("/%s/user/%s/ttyrec", config.NethackLauncher.HackDir, currentUser))
if err != nil {
println(" No ttyrecs exist ('enter' without selection returns)")
panic(err)
}
ttyrecs := make(map[int]string)
ttyrecsTimer := 1
for _, ty := range t {
fmt.Printf(" %d) %s\n", ttyrecsTimer, ty.Name())
// add user to line map
ttyrecs[ttyrecsTimer] = fmt.Sprintf("%s", ty.Name())
ttyrecsTimer++
}
fmt.Println("")
fmt.Printf(">> ")
// start user input
// disable input buffering
exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
// enable showing input on screen
exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run()
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
if scanner.Text() == "" {
clearScreen()
printLibraryScreen(redisClient, username)
}
// save input
s := scanner.Text()
sel, err := strconv.Atoi(s)
if err != nil {
fmt.Printf(" There was a problem with your last entry.\n>> ")
}
// check if selection is in our map
if ttyrecs[sel] != "" {
fmt.Printf("going to watch '%s'\n", ttyrecs[sel])
clearScreen()
// set ttyrec path
ttyrecPath := fmt.Sprintf("%s/user/%s/ttyrec/%s", config.NethackLauncher.HackDir, username, ttyrecs[sel])
tp := exec.Command("ttyplay", ttyrecPath)
tp.Stdout = os.Stdout
tp.Stdin = os.Stdin
tp.Stderr = os.Stderr
err := tp.Run()
if err != nil {
fmt.Print(err)
}
}
clearScreen()
printUserLibraryScreen(redisClient, username, currentUser)
}
}

4
nethack-launcher/nethack-launcher.go

@ -20,10 +20,6 @@ type Config struct {
NhdatLocation string
RecoverBinary string
SysconfLocation string
TTYRecCache string
SotwVersion string
SotwRoot string
SotwDumpCache string
BootstrapDelay time.Duration
}

1
nethack-launcher/print_login_screen.go

@ -52,7 +52,6 @@ func printLoginScreen(redisClient *redis.Client) {
typedHash := sha3.Sum512([]byte(typedAuth))
if fmt.Sprintf("%x", typedHash) == storedHash {
// user authed
createUserFiles(username)
printUserScreen(redisClient, username)
noPass = false
} else {

3
nethack-launcher/print_progress_screen.go

@ -75,12 +75,11 @@ func printProgressScreen(redisClient *redis.Client, username string) {
// set ttyrec path
ttyName, _ := redisClient.Get(fmt.Sprintf("inprogress:%s", user[0])).Result()
ttyrecPath := fmt.Sprintf("%s/user/%s/ttyrec/%s.ttyrec", config.NethackLauncher.HackDir, user[0], ttyName)
fullCommand := fmt.Sprintf("ttyplay -n %s && ttyplay -p %s", ttyrecPath, ttyrecPath)
// restart display
exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run()
clearScreen()
nh := exec.Command("bash", "-c", fullCommand)
nh := exec.Command("ttyplay", "-p", ttyrecPath)
nh.Stdout = os.Stdout
nh.Stdin = os.Stdin
nh.Stderr = os.Stderr

59
nethack-launcher/print_user_screen.go

@ -12,25 +12,17 @@ import (
func printUserScreen(redisClient *redis.Client, username string) string {
clearScreen()
fmt.Printf(" %s\n", config.NethackLauncher.ServerDisplay)
println("")
fmt.Printf(" Logged in as: %s\n", username)
println("")
println("Global")
println(" l) Logout")
println(" c) Change password")
println(" w) Watch games in progress")
println(" x) Browse library of ttyrecs")
println("")
println("Shadow of the Wyrm")
println(" f) Edit SOTW config")
fmt.Printf(" o) Play Shadow of the Wyrm %s\n", config.NethackLauncher.SotwVersion)
println("")
println("Nethack")
println(" h) View NetHack highscores")
println(" a) View all NetHack scores")
println(" e) Edit NetHack config")
println(" r) Recover NetHack from crash")
println(" h) View highscores")
println(" a) View all scores")
println(" e) Edit config")
println(" r) Recover from crash")
fmt.Printf(" p) Play NetHack %s\n", config.NethackLauncher.NethackVersion)
println("")
println(" q) Quit")
println("")
fmt.Printf(">> ")
@ -53,32 +45,7 @@ func printUserScreen(redisClient *redis.Client, username string) string {
hackRCLoc := fmt.Sprintf("%s/user/%s/.nethackrc", config.NethackLauncher.HackDir, username)
exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run()
clearScreen()
nh := exec.Command("vim", "-i", "NONE", "-Z", hackRCLoc)
nh.Stdout = os.Stdout
nh.Stdin = os.Stdin
nh.Stderr = os.Stderr
nh.Run()
clearScreen()
printUserScreen(redisClient, username)
case "f":
// check if the file has been uplifted
SOTWLoc := fmt.Sprintf("%s/user/%s/sotw/swyrm.ini", config.NethackLauncher.HackDir, username)
//il, _ := os.Lstat(SOTWLoc)
//if il.Mode()&os.ModeSymlink == os.ModeSymlink {
// // the file is still a legacy symlink, remove and recopy
// err := os.Remove(SOTWLoc)
// if err != nil {
// fmt.Println(err)
// }
// SOTWOrigin := fmt.Sprintf("%s/swyrm.ini", config.NethackLauncher.SotwRoot)
// exec.Command("cp", SOTWOrigin, SOTWLoc).Run()
//}
//SOTWOrigin := fmt.Sprintf("%s/swyrm.ini", config.NethackLauncher.SotwRoot)
//exec.Command("cp", SOTWOrigin, SOTWLoc).Run()
exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run()
clearScreen()
nh := exec.Command("vim", "-i", "NONE", "-Z", SOTWLoc)
nh := exec.Command("vim", "-Z", hackRCLoc)
nh.Stdout = os.Stdout
nh.Stdin = os.Stdin
nh.Stderr = os.Stderr
@ -91,9 +58,6 @@ func printUserScreen(redisClient *redis.Client, username string) string {
case "w":
clearScreen()
printProgressScreen(redisClient, username)
case "x":
clearScreen()
printLibraryScreen(redisClient, username)
case "h":
clearScreen()
printHighScores(redisClient, username)
@ -105,17 +69,6 @@ func printUserScreen(redisClient *redis.Client, username string) string {
currentTime := time.Now().UTC()
fulltime := currentTime.Format("2006-01-02.03:04:05")
go runGame(username, fulltime)
go runCleanup(username)
watcher := startWatcher(username, fulltime, redisClient)
wg.Wait()
close(watcher)
printUserScreen(redisClient, username)
case "o":
wg.Add(1)
currentTime := time.Now().UTC()
fulltime := currentTime.Format("2006-01-02.03:04:05")
go runSotwGame(username, fulltime)
go runCleanup(username)
watcher := startWatcher(username, fulltime, redisClient)
wg.Wait()
close(watcher)

9
nethack-launcher/print_welcome_screen.go

@ -11,11 +11,14 @@ import (
func printWelcomeScreen(redisClient *redis.Client) string {
clearScreen()
fmt.Printf(" %s\n", config.NethackLauncher.ServerDisplay)
println("")
println(" Not logged in.")
println("")
println(" l) Login")
println(" r) Register new user")
println(" w) Watch games in progress")
println(" h) View highscores")
println(" a) View all scores")
println(" q) Quit")
println("")
fmt.Printf(">> ")
@ -42,6 +45,12 @@ func printWelcomeScreen(redisClient *redis.Client) string {
case "w":
clearScreen()
printProgressScreen(redisClient, "")
case "h":
clearScreen()
printHighScores(redisClient, "")
case "a":
clearScreen()
printAllScores(redisClient, "")
case "q":
exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run()
clearScreen()

23
nethack-launcher/run_game.go

@ -40,29 +40,6 @@ func runGame(username, timestamp string) {
wg.Done()
}
func runSotwGame(username, timestamp string) {
exec.Command("stty", "-F", "/dev/tty", "echo", "-cbreak").Run()
clearScreen()
// put together users home dir
//homeDir := fmt.Sprintf("%s/user/%s/", config.NethackLauncher.HackDir, username)
ttyrecPath := fmt.Sprintf("%s/user/%s/ttyrec/%s.ttyrec", config.NethackLauncher.HackDir, username, timestamp)
nh := exec.Command("ttyrec", "-f", ttyrecPath, "--", "./ShadowOfTheWyrm")
//nh := exec.Command("./ShadowOfTheWyrm")
nh.Dir = (fmt.Sprintf("%s/user/%s/sotw/", config.NethackLauncher.HackDir, username))
//nh.Dir = (config.NethackLauncher.SotwRoot)
nh.Stdout = os.Stdout
nh.Stdin = os.Stdin
nh.Stderr = os.Stderr
err := nh.Run()
if err != nil {
fmt.Print(err)
}
exec.Command("exit").Run()
wg.Done()
}
func runtimeRecover(username string) {
fmt.Printf(" %s\n", config.NethackLauncher.ServerDisplay)
println("")

Loading…
Cancel
Save