diff options
Diffstat (limited to 'internal/admin/api_mobs.go')
| -rw-r--r-- | internal/admin/api_mobs.go | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/internal/admin/api_mobs.go b/internal/admin/api_mobs.go new file mode 100644 index 0000000..5fdfbc8 --- /dev/null +++ b/internal/admin/api_mobs.go @@ -0,0 +1,163 @@ +package admin + +import ( + "fmt" + "net/http" + "os" + "path/filepath" + "strings" +) + +func (s *AdminServer) handleMobs(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodGet: + ids, err := listYAMLFiles(s.dataDir, "mobs") + if err != nil { + writeJSON(w, map[string]any{"error": err.Error()}) + return + } + if ids == nil { + ids = []string{} + } + writeJSON(w, ids) + + case http.MethodPost: + s.createMob(w, r) + + default: + http.Error(w, `{"error":"method not allowed"}`, http.StatusMethodNotAllowed) + } +} + +func (s *AdminServer) handleMobByID(w http.ResponseWriter, r *http.Request) { + id := strings.TrimPrefix(r.URL.Path, "/api/mobs/") + if id == "" { + http.Error(w, `{"error":"missing mob id"}`, http.StatusBadRequest) + return + } + + switch r.Method { + case http.MethodGet: + s.getMob(w, r, id) + case http.MethodPut: + s.updateMob(w, r, id) + case http.MethodDelete: + s.deleteMob(w, r, id) + default: + http.Error(w, `{"error":"method not allowed"}`, http.StatusMethodNotAllowed) + } +} + +func (s *AdminServer) findMobFile(id string) ([]byte, string, error) { + data, path, err := readYAMLFile(s.dataDir, "mobs", id) + if err == nil { + return data, path, nil + } + return findYAMLFileInSubdirs(s.dataDir, "mobs", id) +} + +func (s *AdminServer) getMob(w http.ResponseWriter, r *http.Request, id string) { + data, path, err := s.findMobFile(id) + if err != nil { + http.Error(w, `{"error":"mob not found"}`, http.StatusNotFound) + return + } + m, err := yamlToMap(data) + if err != nil { + http.Error(w, `{"error":"failed to parse mob yaml"}`, http.StatusInternalServerError) + return + } + m["_path"] = path + m["_raw"] = string(data) + writeJSON(w, m) +} + +func (s *AdminServer) updateMob(w http.ResponseWriter, r *http.Request, id string) { + _, path, err := s.findMobFile(id) + if err != nil { + http.Error(w, `{"error":"mob not found"}`, http.StatusNotFound) + return + } + var m map[string]any + if err := readJSON(r, &m); err != nil { + http.Error(w, `{"error":"invalid json body"}`, http.StatusBadRequest) + return + } + m["id"] = id + + oldContent, err := snapshotFile(path) + if err != nil { + http.Error(w, `{"error":"failed to read existing mob"}`, http.StatusInternalServerError) + return + } + newContent, err := writeMapAsYAML(path, m) + if err != nil { + http.Error(w, `{"error":"failed to write mob"}`, http.StatusInternalServerError) + return + } + s.mobStore.ReloadDefs(s.dataDir) + s.undoStack.Push(ChangeDesc{ + Description: fmt.Sprintf("Update mob %s", id), + FilePath: path, + OldContent: oldContent, + NewContent: newContent, + }) + writeJSON(w, m) +} + +func (s *AdminServer) deleteMob(w http.ResponseWriter, r *http.Request, id string) { + _, path, err := s.findMobFile(id) + if err != nil { + http.Error(w, `{"error":"mob not found"}`, http.StatusNotFound) + return + } + + oldContent := backupFile(path) + + if err := os.Remove(path); err != nil { + http.Error(w, `{"error":"failed to delete mob"}`, http.StatusInternalServerError) + return + } + + s.mobStore.ReloadDefs(s.dataDir) + + s.undoStack.Push(ChangeDesc{ + Description: fmt.Sprintf("Delete mob %s", id), + FilePath: path, + OldContent: oldContent, + IsDelete: true, + }) + + writeJSON(w, map[string]any{"deleted": id}) +} + +func (s *AdminServer) createMob(w http.ResponseWriter, r *http.Request) { + var m map[string]any + if err := readJSON(r, &m); err != nil { + http.Error(w, `{"error":"invalid json body"}`, http.StatusBadRequest) + return + } + id, _ := m["id"].(string) + if strings.TrimSpace(id) == "" { + http.Error(w, `{"error":"missing mob id"}`, http.StatusBadRequest) + return + } + if _, _, err := s.findMobFile(id); err == nil { + http.Error(w, `{"error":"mob already exists"}`, http.StatusConflict) + return + } + path := filepath.Join(s.dataDir, "mobs", id+".yaml") + newContent, err := writeMapAsYAML(path, m) + if err != nil { + http.Error(w, `{"error":"failed to write mob"}`, http.StatusInternalServerError) + return + } + s.mobStore.ReloadDefs(s.dataDir) + s.undoStack.Push(ChangeDesc{ + Description: fmt.Sprintf("Create mob %s", id), + FilePath: path, + NewContent: newContent, + IsCreate: true, + }) + writeJSON(w, m) +} |
