Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
bc0c48994b
46
Makefile
46
Makefile
|
@ -7,9 +7,51 @@
|
||||||
|
|
||||||
# goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows"
|
# goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows"
|
||||||
# goarchList = "386 amd64 amd64p32 arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32leppc s390 s390x sparc sparc64"
|
# goarchList = "386 amd64 amd64p32 arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32leppc s390 s390x sparc sparc64"
|
||||||
include make/Makefile.common
|
|
||||||
|
|
||||||
# Windows needs the .exe extension.
|
# Windows needs the .exe extension.
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
EXT=.exe
|
EXT=.exe
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
TAGS=
|
||||||
|
|
||||||
|
.PHONY: fmt vet get clean dev setdev test ServerMovieNight
|
||||||
|
|
||||||
|
all: fmt vet test MovieNight static/main.wasm settings.json
|
||||||
|
|
||||||
|
server: ServerMovieNight static/main.wasm
|
||||||
|
|
||||||
|
ServerMovieNight: *.go common/*.go
|
||||||
|
GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight $(TAGS)
|
||||||
|
|
||||||
|
setdev:
|
||||||
|
$(eval export TAGS=-tags "dev")
|
||||||
|
|
||||||
|
dev: setdev all
|
||||||
|
|
||||||
|
MovieNight: *.go common/*.go
|
||||||
|
GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight${EXT} $(TAGS)
|
||||||
|
|
||||||
|
static/js/wasm_exec.js:
|
||||||
|
cp $$(go$(GO_VERSION) env GOROOT)/misc/wasm/wasm_exec.js $@
|
||||||
|
|
||||||
|
static/main.wasm: static/js/wasm_exec.js wasm/*.go common/*.go
|
||||||
|
GOOS=js GOARCH=wasm go$(GO_VERSION) build -o $@ $(TAGS) wasm/*.go
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-rm MovieNight${EXT} ./static/main.wasm ./static/js/wasm_exec.js
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
gofmt -w .
|
||||||
|
|
||||||
|
vet:
|
||||||
|
go$(GO_VERSION) vet $(TAGS) ./...
|
||||||
|
GOOS=js GOARCH=wasm go$(GO_VERSION) vet $(TAGS) ./...
|
||||||
|
|
||||||
|
test:
|
||||||
|
go$(GO_VERSION) test $(TAGS) ./...
|
||||||
|
|
||||||
|
# Do not put settings_example.json here as a prereq to avoid overwriting
|
||||||
|
# the settings if the example is updated.
|
||||||
|
settings.json:
|
||||||
|
cp settings_example.json settings.json
|
||||||
|
|
12
Makefile.BSD
12
Makefile.BSD
|
@ -1,12 +0,0 @@
|
||||||
# If a different version of Go is installed (via `go get`) set the GO_VERSION
|
|
||||||
# environment variable to that version. For example, setting it to "1.13.7"
|
|
||||||
# will run `go1.13.7 build [...]` instead of `go build [...]`.
|
|
||||||
#
|
|
||||||
# For info on installing extra versions, see this page:
|
|
||||||
# https://golang.org/doc/install#extra_versions
|
|
||||||
|
|
||||||
# goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows"
|
|
||||||
# goarchList = "386 amd64 amd64p32 arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32leppc s390 s390x sparc sparc64"
|
|
||||||
include make/Makefile.common
|
|
||||||
|
|
||||||
GOOS=freebsd
|
|
|
@ -91,17 +91,20 @@ func (cl *Client) NewMsg(data common.ClientData) {
|
||||||
// because the /me command outputs to the messages
|
// because the /me command outputs to the messages
|
||||||
msg = addSpoilerTags(msg)
|
msg = addSpoilerTags(msg)
|
||||||
|
|
||||||
|
msgLen := len(msg)
|
||||||
|
|
||||||
// Don't send zero-length messages
|
// Don't send zero-length messages
|
||||||
if len(msg) == 0 {
|
if msgLen == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(msg, "/") {
|
if strings.HasPrefix(msg, "/") {
|
||||||
// is a command
|
// is a command
|
||||||
msg = msg[1:len(msg)]
|
msg = msg[1:msgLen]
|
||||||
fullcmd := strings.Split(msg, " ")
|
fullcmd := strings.Split(msg, " ")
|
||||||
cmd := strings.ToLower(fullcmd[0])
|
cmd := strings.ToLower(fullcmd[0])
|
||||||
args := fullcmd[1:len(fullcmd)]
|
fullcmdLen := len(fullcmd)
|
||||||
|
args := fullcmd[1:fullcmdLen]
|
||||||
|
|
||||||
response, err := commands.RunCommand(cmd, args, cl)
|
response, err := commands.RunCommand(cmd, args, cl)
|
||||||
if response != "" || err != nil {
|
if response != "" || err != nil {
|
||||||
|
@ -136,7 +139,7 @@ func (cl *Client) NewMsg(data common.ClientData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim long messages
|
// Trim long messages
|
||||||
if len(msg) > 400 {
|
if msgLen > 400 {
|
||||||
msg = msg[0:400]
|
msg = msg[0:400]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -277,11 +277,13 @@ var commands = &CommandControl{
|
||||||
cl.belongsTo.clientsMtx.Unlock()
|
cl.belongsTo.clientsMtx.Unlock()
|
||||||
|
|
||||||
// Just print max users and time alive here
|
// Just print max users and time alive here
|
||||||
return fmt.Sprintf("Current users in chat: <b>%d</b><br />Max users in chat: <b>%d</b><br />Server uptime: <b>%s</b><br />Stream uptime: <b>%s</b>",
|
return fmt.Sprintf("Current users in chat: <b>%d</b><br />Max users in chat: <b>%d</b><br />Server uptime: <b>%s</b><br />Stream uptime: <b>%s</b><br />Viewers: <b>%d</b><br />Max Viewers: <b>%d</b>",
|
||||||
users,
|
users,
|
||||||
stats.getMaxUsers(),
|
stats.getMaxUsers(),
|
||||||
time.Since(stats.start),
|
time.Since(stats.start),
|
||||||
stats.getStreamLength(),
|
stats.getStreamLength(),
|
||||||
|
stats.getViewerCount(),
|
||||||
|
stats.getMaxViewerCount(),
|
||||||
), nil
|
), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,6 +3,7 @@ package common
|
||||||
// Misc utils
|
// Misc utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -41,3 +42,20 @@ func Substr(input string, start int, length int) string {
|
||||||
|
|
||||||
return string(asRunes[start : start+length])
|
return string(asRunes[start : start+length])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the value of "Forwarded" or "X-Forwarded-For",
|
||||||
|
// if "Forwarded" & "X-Forwarded-For" are present then "Forwarded" value is returned.
|
||||||
|
// Return "" if "Forwarded" and "X-Forwarded-For" are absent.
|
||||||
|
func ExtractForwarded(r *http.Request) string {
|
||||||
|
f := r.Header.Get("Forwarded")
|
||||||
|
if f != "" {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
xff := r.Header.Get("X-Forwarded-For")
|
||||||
|
if xff != "" {
|
||||||
|
return xff
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
Conn: conn,
|
Conn: conn,
|
||||||
// If the server is behind a reverse proxy (eg, Nginx), look
|
// If the server is behind a reverse proxy (eg, Nginx), look
|
||||||
// for this header to get the real IP address of the client.
|
// for this header to get the real IP address of the client.
|
||||||
forwardedFor: r.Header.Get("X-Forwarded-For"),
|
forwardedFor: common.ExtractForwarded(r),
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -424,9 +424,14 @@ func handleLive(w http.ResponseWriter, r *http.Request) {
|
||||||
muxer := flv.NewMuxerWriteFlusher(writeFlusher{httpflusher: flusher, Writer: w})
|
muxer := flv.NewMuxerWriteFlusher(writeFlusher{httpflusher: flusher, Writer: w})
|
||||||
cursor := ch.que.Latest()
|
cursor := ch.que.Latest()
|
||||||
|
|
||||||
|
session, _ := sstore.Get(r, "moviesession")
|
||||||
|
stats.addViewer(session.ID)
|
||||||
avutil.CopyFile(muxer, cursor)
|
avutil.CopyFile(muxer, cursor)
|
||||||
|
stats.removeViewer(session.ID)
|
||||||
} else {
|
} else {
|
||||||
|
// Maybe HTTP_204 is better than HTTP_404
|
||||||
|
w.WriteHeader(http.StatusNoContent)
|
||||||
|
stats.resetViewers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
TAGS=
|
|
||||||
|
|
||||||
.PHONY: fmt vet get clean dev setdev test ServerMovieNight
|
|
||||||
|
|
||||||
all: fmt vet test MovieNight static/main.wasm settings.json
|
|
||||||
|
|
||||||
server: ServerMovieNight static/main.wasm
|
|
||||||
|
|
||||||
ServerMovieNight: *.go common/*.go
|
|
||||||
GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight $(TAGS)
|
|
||||||
|
|
||||||
setdev:
|
|
||||||
$(eval export TAGS=-tags "dev")
|
|
||||||
|
|
||||||
dev: setdev all
|
|
||||||
|
|
||||||
MovieNight: *.go common/*.go
|
|
||||||
GOOS=${TARGET} GOARCH=${ARCH} go$(GO_VERSION) build -o MovieNight${EXT} $(TAGS)
|
|
||||||
|
|
||||||
static/js/wasm_exec.js:
|
|
||||||
cp $$(go$(GO_VERSION) env GOROOT)/misc/wasm/wasm_exec.js $@
|
|
||||||
|
|
||||||
static/main.wasm: static/js/wasm_exec.js wasm/*.go common/*.go
|
|
||||||
GOOS=js GOARCH=wasm go$(GO_VERSION) build -o $@ $(TAGS) wasm/*.go
|
|
||||||
|
|
||||||
clean:
|
|
||||||
-rm MovieNight${EXT} ./static/main.wasm ./static/js/wasm_exec.js
|
|
||||||
|
|
||||||
fmt:
|
|
||||||
gofmt -w .
|
|
||||||
|
|
||||||
vet:
|
|
||||||
go$(GO_VERSION) vet $(TAGS) ./...
|
|
||||||
GOOS=js GOARCH=wasm go$(GO_VERSION) vet $(TAGS) ./...
|
|
||||||
|
|
||||||
test:
|
|
||||||
go$(GO_VERSION) test $(TAGS) ./...
|
|
||||||
|
|
||||||
# Do not put settings_example.json here as a prereq to avoid overwriting
|
|
||||||
# the settings if the example is updated.
|
|
||||||
settings.json:
|
|
||||||
cp settings_example.json settings.json
|
|
|
@ -37,15 +37,14 @@ You have to :
|
||||||
- download `git clone https://github.com/zorchenhimer/MovieNight`, go into the source directory `cd MovieNight`;
|
- download `git clone https://github.com/zorchenhimer/MovieNight`, go into the source directory `cd MovieNight`;
|
||||||
- choose your `TARGET` oneof "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows";
|
- choose your `TARGET` oneof "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows";
|
||||||
- choose your `ARCH` oneof "386 amd64 amd64p32 arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32leppc s390 s390x sparc sparc64";
|
- choose your `ARCH` oneof "386 amd64 amd64p32 arm arm64 ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32leppc s390 s390x sparc sparc64";
|
||||||
- build `make TARGET=plan9 ARCH=arm64`;
|
- build `make TARGET=plan9 ARCH=arm64` (On BSD systems use `gmake`);
|
||||||
- and run `./MovieNight`;
|
- and run `./MovieNight`;
|
||||||
|
|
||||||
Example :
|
Example :
|
||||||
```bash
|
```shell
|
||||||
$ git clone https://git.mentality.rip/sjw/MovieNight.git
|
$ git clone https://git.mentality.rip/sjw/MovieNight.git
|
||||||
$ cd MovieNight
|
$ cd MovieNight
|
||||||
$ make TARGET=linux ARCH=amd64
|
$ make TARGET=linux ARCH=amd64
|
||||||
$ ./MovieNight
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Docker build
|
### Docker build
|
||||||
|
|
76
stats.go
76
stats.go
|
@ -8,18 +8,50 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type streamStats struct {
|
type streamStats struct {
|
||||||
messageIn int
|
messageIn int
|
||||||
messageOut int
|
messageOut int
|
||||||
maxUsers int
|
maxUsers int
|
||||||
start time.Time
|
start time.Time
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
|
|
||||||
streamStart time.Time
|
streamStart time.Time
|
||||||
streamLive bool // True if live
|
streamLive bool // True if live
|
||||||
|
viewers map[string]int
|
||||||
|
maxViewers int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *streamStats) addViewer(id string) {
|
||||||
|
s.mutex.Lock()
|
||||||
|
s.viewers[id] = len(s.viewers)
|
||||||
|
size := len(s.viewers)
|
||||||
|
s.updateMaxViewers(size)
|
||||||
|
s.mutex.Unlock()
|
||||||
|
|
||||||
|
common.LogDebugf("[stats] %d viewer(s) connected\n", size)
|
||||||
|
}
|
||||||
|
func (s *streamStats) removeViewer(id string) {
|
||||||
|
s.mutex.Lock()
|
||||||
|
delete(s.viewers, id)
|
||||||
|
s.mutex.Unlock()
|
||||||
|
|
||||||
|
common.LogDebugf("[stats] One viewer left the stream\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *streamStats) updateMaxViewers(size int) {
|
||||||
|
if s.maxViewers < size {
|
||||||
|
s.maxViewers = size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *streamStats) resetViewers() {
|
||||||
|
s.viewers = sessionsMapNew()
|
||||||
|
}
|
||||||
|
|
||||||
|
func sessionsMapNew() map[string]int {
|
||||||
|
return make(map[string]int)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStreamStats() streamStats {
|
func newStreamStats() streamStats {
|
||||||
return streamStats{start: time.Now(), streamLive: false}
|
return streamStats{start: time.Now(), streamLive: false, viewers: sessionsMapNew()}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *streamStats) msgInInc() {
|
func (s *streamStats) msgInInc() {
|
||||||
|
@ -53,10 +85,11 @@ func (s *streamStats) Print() {
|
||||||
s.mutex.Lock()
|
s.mutex.Lock()
|
||||||
defer s.mutex.Unlock()
|
defer s.mutex.Unlock()
|
||||||
|
|
||||||
common.LogInfof("Messages In: %d\n", s.messageIn)
|
common.LogInfof("[stats] Messages In: %d\n", s.messageIn)
|
||||||
common.LogInfof("Messages Out: %d\n", s.messageOut)
|
common.LogInfof("[stats] Messages Out: %d\n", s.messageOut)
|
||||||
common.LogInfof("Max users in chat: %d\n", s.maxUsers)
|
common.LogInfof("[stats] Max users in chat: %d\n", s.maxUsers)
|
||||||
common.LogInfof("Total Time: %s\n", time.Since(s.start))
|
common.LogInfof("[stats] Total Time: %s\n", time.Since(s.start))
|
||||||
|
common.LogInfof("[stats] Max Stream Viewer: %d\n", s.maxViewers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *streamStats) startStream() {
|
func (s *streamStats) startStream() {
|
||||||
|
@ -83,3 +116,24 @@ func (s *streamStats) getStreamLength() time.Duration {
|
||||||
}
|
}
|
||||||
return time.Since(s.streamStart)
|
return time.Since(s.streamStart)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *streamStats) getViewerCount() int {
|
||||||
|
s.mutex.Lock()
|
||||||
|
defer s.mutex.Unlock()
|
||||||
|
|
||||||
|
return len(s.viewers)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *streamStats) getMaxViewerCount() int {
|
||||||
|
s.mutex.Lock()
|
||||||
|
defer s.mutex.Unlock()
|
||||||
|
|
||||||
|
return s.maxViewers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *streamStats) getViewers() map[string]int {
|
||||||
|
s.mutex.Lock()
|
||||||
|
defer s.mutex.Unlock()
|
||||||
|
|
||||||
|
return s.viewers
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue