Simple dice roller for D'n'D-like games. Golang >= 1.6
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

113 lines
2.4 KiB

package main
import (
"bytes"
"fmt"
"log"
"math/rand"
"net/http"
"regexp"
"runtime"
"strconv"
"time"
)
var version = "2020-11-02.21-43"
var rxDices = *regexp.MustCompile("(\\d+)d(\\d+)")
type route struct {
pattern *regexp.Regexp
handler http.Handler
}
type RegexpHandler struct {
routes []*route
}
func (h *RegexpHandler) Handler(pattern *regexp.Regexp, handler http.Handler) {
h.routes = append(h.routes, &route{pattern, handler})
}
func (h *RegexpHandler) HandleFunc(pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request)) {
h.routes = append(h.routes, &route{pattern, http.HandlerFunc(handler)})
}
func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for _, route := range h.routes {
if route.pattern.MatchString(r.URL.Path) {
route.handler.ServeHTTP(w, r)
return
}
}
// no pattern matched; send 404 response
http.NotFound(w, r)
}
func handleDices(res http.ResponseWriter, req *http.Request) {
res.Header().Set("Content-Type", "application/json")
res.Header().Set("X-Powered-By", "Roll-The-Dice-Bot/"+version+" GoLang/" + runtime.Version())
r := rxDices.FindAllStringSubmatch(req.URL.Path, -1)
if len(r) == 0 {
res.Write([]byte("0"))
return
}
valueN := 0
valueD := 0
for i := range r {
v1, err := strconv.ParseInt(r[i][1], 10, 32)
if err != nil {
log.Fatal("Convert string N to int: ", err)
continue
}
valueN = int(v1)
v2, err := strconv.ParseInt(r[i][2], 10, 32)
if err != nil {
log.Fatal("Convert string D to int: ", err)
continue
}
valueD = int(v2)
}
roll := int64(0)
var buffer bytes.Buffer
rand.Seed(time.Now().UnixNano())
for valueN > 0 {
valueN -= 1
d := int64(rand.Intn(valueD) + 1)
roll += d
}
buffer.WriteString(strconv.FormatInt(roll, 10))
res.Write(buffer.Bytes())
}
func main() {
handler := &RegexpHandler{}
reg1, _ := regexp.Compile("/\\d+d\\d+")
handler.HandleFunc(reg1, handleDices)
reg2, _ := regexp.Compile("/")
handler.HandleFunc(reg2, func (w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
w.Header().Set("X-Powered-By", "Roll-The-Dice-Bot/"+version+" GoLang/" + runtime.Version())
fmt.Fprintf(w, "<h2>Welcome to RollTheDice service!</h2><p>Call <b>/XdY</b> to to roll <i>X</i> dices with <i>Y</i> dimentions.<br>Output will be raw number.</p>")
})
err := http.ListenAndServe(":4000", handler)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}