init commit for ddServer
First commit with basic functionality for create a json-file from Input in the html form.
This commit is contained in:
commit
c251b553a1
3 changed files with 384 additions and 0 deletions
277
main.go
Normal file
277
main.go
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Monster struct für die Daten des Monsters
|
||||
type Monster struct {
|
||||
Name string `json:"name"`
|
||||
Source string `json:"source"`
|
||||
Size []string `json:"size"`
|
||||
Type string `json:"type"`
|
||||
Alignment []string `json:"alignment"`
|
||||
AC []AC `json:"ac"`
|
||||
HP HP `json:"hp"`
|
||||
Speed Speed `json:"speed"`
|
||||
Save Save `json:"save"`
|
||||
Skill Skill `json:"skill"`
|
||||
DamageRes []string `json:"damageResistances"`
|
||||
Senses []string `json:"senses"`
|
||||
Languages []string `json:"languages"`
|
||||
CR string `json:"cr"`
|
||||
Traits []Trait `json:"trait"`
|
||||
Actions []Action `json:"action"`
|
||||
Str int `json:"str"`
|
||||
Dex int `json:"dex"`
|
||||
Con int `json:"con"`
|
||||
Int int `json:"int"`
|
||||
Wis int `json:"wis"`
|
||||
Cha int `json:"cha"`
|
||||
}
|
||||
|
||||
type AC struct {
|
||||
AC int `json:"ac"`
|
||||
From []string `json:"from"`
|
||||
}
|
||||
|
||||
type HP struct {
|
||||
Average int `json:"average"`
|
||||
Formula string `json:"formula"`
|
||||
}
|
||||
|
||||
type Speed struct {
|
||||
Walk int `json:"walk"`
|
||||
}
|
||||
|
||||
type Save struct {
|
||||
Dex string `json:"dex"`
|
||||
Con string `json:"con"`
|
||||
Wis string `json:"wis"`
|
||||
}
|
||||
|
||||
type Skill struct {
|
||||
Perception string `json:"perception"`
|
||||
Stealth string `json:"stealth"`
|
||||
}
|
||||
|
||||
type Trait struct {
|
||||
Name string `json:"name"`
|
||||
Entries []string `json:"entries"`
|
||||
}
|
||||
|
||||
type Action struct {
|
||||
Name string `json:"name"`
|
||||
Entries []string `json:"entries"`
|
||||
}
|
||||
|
||||
// Character struct für die Daten des Charakters
|
||||
type Character struct {
|
||||
Meta Meta `json:"_meta"`
|
||||
Monster []Monster `json:"monster"`
|
||||
}
|
||||
|
||||
// Meta struct für Meta-Informationen
|
||||
type Meta struct {
|
||||
Sources []Source `json:"sources"`
|
||||
DateAdded int64 `json:"dateAdded"`
|
||||
DateLastModified int64 `json:"dateLastModified"`
|
||||
DateLastModifiedHash string `json:"_dateLastModifiedHash"`
|
||||
}
|
||||
|
||||
type Source struct {
|
||||
Json string `json:"json"`
|
||||
Abbreviation string `json:"abbreviation"`
|
||||
Authors []string `json:"authors"`
|
||||
ConvertedBy []string `json:"convertedBy"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
var (
|
||||
mu sync.Mutex
|
||||
chars []Character
|
||||
)
|
||||
|
||||
func main() {
|
||||
filename := ""
|
||||
|
||||
http.HandleFunc("/", formHandler(filename))
|
||||
http.HandleFunc("/submit", submitHandler(filename))
|
||||
|
||||
fmt.Println("Server gestartet, erreichbar unter http://localhost:8080")
|
||||
http.ListenAndServe(":8080", nil)
|
||||
}
|
||||
|
||||
// formHandler zeigt das Formular an
|
||||
func formHandler(filename string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
tmpl, err := template.ParseFiles("forms.html")
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
tmpl.Execute(w, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// submitHandler verarbeitet die Formulardaten
|
||||
func submitHandler(filename string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// Formulardaten parsen
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Monster-Objekt erstellen
|
||||
filename := r.FormValue("filename")
|
||||
monster := Monster{
|
||||
Name: r.FormValue("name"),
|
||||
Source: r.FormValue("source"),
|
||||
Size: []string{r.FormValue("size")},
|
||||
Type: r.FormValue("type"),
|
||||
Alignment: []string{r.FormValue("alignment")},
|
||||
AC: []AC{
|
||||
{
|
||||
AC: parseInt(r.FormValue("ac")),
|
||||
From: []string{r.FormValue("acFrom")},
|
||||
},
|
||||
},
|
||||
HP: HP{
|
||||
Average: parseInt(r.FormValue("hpAverage")),
|
||||
Formula: r.FormValue("hpFormula"),
|
||||
},
|
||||
Speed: Speed{
|
||||
Walk: parseInt(r.FormValue("speed")),
|
||||
},
|
||||
Str: parseInt(r.FormValue("str")),
|
||||
Dex: parseInt(r.FormValue("dex")),
|
||||
Con: parseInt(r.FormValue("con")),
|
||||
Int: parseInt(r.FormValue("int")),
|
||||
Wis: parseInt(r.FormValue("wis")),
|
||||
Cha: parseInt(r.FormValue("cha")),
|
||||
Save: Save{
|
||||
Dex: r.FormValue("saveDex"),
|
||||
Con: r.FormValue("saveCon"),
|
||||
Wis: r.FormValue("saveWis"),
|
||||
},
|
||||
Skill: Skill{
|
||||
Perception: r.FormValue("perception"),
|
||||
Stealth: r.FormValue("stealth"),
|
||||
},
|
||||
DamageRes: []string{r.FormValue("damageRes")},
|
||||
Senses: []string{r.FormValue("senses")},
|
||||
Languages: []string{r.FormValue("languages")},
|
||||
CR: r.FormValue("cr"),
|
||||
Traits: []Trait{
|
||||
{
|
||||
Name: r.FormValue("traitName"),
|
||||
Entries: []string{r.FormValue("traitEntry")},
|
||||
},
|
||||
},
|
||||
Actions: []Action{
|
||||
{
|
||||
Name: r.FormValue("actionName"),
|
||||
Entries: []string{r.FormValue("actionEntry")},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Charakter-Objekt erstellen oder aktualisieren
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
char := getOrCreateCharacter(filename)
|
||||
char.Monster = append(char.Monster, monster)
|
||||
|
||||
// Charakterdaten in JSON umwandeln
|
||||
charJSON, err := json.Marshal(char)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// JSON-Daten in die Datei schreiben
|
||||
err = writeToFile(filename, charJSON)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Erfolgsmeldung anzeigen
|
||||
fmt.Fprintf(w, "Monsterdaten erfolgreich gespeichert in %s: %s", filename, charJSON)
|
||||
}
|
||||
}
|
||||
|
||||
// writeToFile schreibt Daten in eine Datei
|
||||
func writeToFile(filename string, data []byte) error {
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
_, err = file.Write(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getOrCreateCharacter gibt das aktuelle Charakterobjekt zurück oder erstellt ein neues
|
||||
func getOrCreateCharacter(filename string) Character {
|
||||
for _, char := range chars {
|
||||
if char.Meta.DateLastModified == 0 {
|
||||
// Ein leeres Charakterobjekt wurde gefunden
|
||||
return char
|
||||
}
|
||||
}
|
||||
|
||||
// Erstelle ein neues Charakterobjekt
|
||||
now := time.Now().Unix()
|
||||
newChar := Character{
|
||||
Meta: Meta{
|
||||
Sources: []Source{
|
||||
{
|
||||
Json: "Malgorgon",
|
||||
Abbreviation: "MG",
|
||||
Authors: []string{"Krzysztof"},
|
||||
ConvertedBy: []string{"Krzysztof"},
|
||||
Version: "unknown",
|
||||
},
|
||||
},
|
||||
DateAdded: now,
|
||||
DateLastModified: now,
|
||||
DateLastModifiedHash: fmt.Sprintf("%x", now),
|
||||
},
|
||||
Monster: []Monster{},
|
||||
}
|
||||
|
||||
chars = append(chars, newChar)
|
||||
|
||||
return newChar
|
||||
}
|
||||
|
||||
// parseInt konvertiert einen String zu einem Integer und gibt 0 zurück, wenn die Konvertierung fehlschlägt
|
||||
func parseInt(s string) int {
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return i
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue