From 6bd5365cc22f84c047c1585e3f54571af46f53e5 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Sun, 5 Jul 2026 18:52:51 -0400 Subject: feat: renameable directories and files in admin gui --- internal/admin/server.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 3 deletions(-) (limited to 'internal/admin/server.go') diff --git a/internal/admin/server.go b/internal/admin/server.go index 53dd5c8..e29de9a 100644 --- a/internal/admin/server.go +++ b/internal/admin/server.go @@ -117,30 +117,37 @@ func NewServer(cfg *config.Config, useTLS bool, accountStore *player.AccountStor apiMux.HandleFunc("/api/rooms", s.handleRooms) apiMux.HandleFunc("/api/rooms/new-empty", s.handleCreateEmptyRoom) apiMux.HandleFunc("/api/rooms/", s.handleRoomByID) + apiMux.HandleFunc("/api/objects/rename", s.handleEntityRename("objects")) apiMux.HandleFunc("/api/objects/move", s.handleEntityMove("objects")) apiMux.HandleFunc("/api/objects/dirs", s.handleEntityDirs("objects")) apiMux.HandleFunc("/api/objects", s.handleObjects) apiMux.HandleFunc("/api/objects/", s.handleObjectByID) + apiMux.HandleFunc("/api/items/rename", s.handleEntityRename("items")) apiMux.HandleFunc("/api/items/move", s.handleEntityMove("items")) apiMux.HandleFunc("/api/items/dirs", s.handleEntityDirs("items")) apiMux.HandleFunc("/api/items", s.handleItems) apiMux.HandleFunc("/api/items/", s.handleItemByID) + apiMux.HandleFunc("/api/mobs/rename", s.handleEntityRename("mobs")) apiMux.HandleFunc("/api/mobs/move", s.handleEntityMove("mobs")) apiMux.HandleFunc("/api/mobs/dirs", s.handleEntityDirs("mobs")) apiMux.HandleFunc("/api/mobs", s.handleMobs) apiMux.HandleFunc("/api/mobs/", s.handleMobByID) + apiMux.HandleFunc("/api/drops/rename", s.handleEntityRename("drops")) apiMux.HandleFunc("/api/drops/move", s.handleEntityMove("drops")) apiMux.HandleFunc("/api/drops/dirs", s.handleEntityDirs("drops")) apiMux.HandleFunc("/api/drops", s.handleDrops) apiMux.HandleFunc("/api/drops/", s.handleDropByID) + apiMux.HandleFunc("/api/hazards/rename", s.handleEntityRename("hazards")) apiMux.HandleFunc("/api/hazards/move", s.handleEntityMove("hazards")) apiMux.HandleFunc("/api/hazards/dirs", s.handleEntityDirs("hazards")) apiMux.HandleFunc("/api/hazards", s.handleHazards) apiMux.HandleFunc("/api/hazards/", s.handleHazardByID) + apiMux.HandleFunc("/api/techs/rename", s.handleEntityRename("techs")) apiMux.HandleFunc("/api/techs/move", s.handleEntityMove("techs")) apiMux.HandleFunc("/api/techs/dirs", s.handleEntityDirs("techs")) apiMux.HandleFunc("/api/techs", s.handleTechs) apiMux.HandleFunc("/api/techs/", s.handleTechByID) + apiMux.HandleFunc("/api/modules/rename", s.handleEntityRename("modules")) apiMux.HandleFunc("/api/modules/move", s.handleEntityMove("modules")) apiMux.HandleFunc("/api/modules/dirs", s.handleEntityDirs("modules")) apiMux.HandleFunc("/api/modules", s.handleModules) @@ -481,9 +488,10 @@ func (s *AdminServer) handleEntityDirs(entityType string) http.HandlerFunc { return } var body struct { - Action string `json:"action"` - Name string `json:"name"` - Dir string `json:"dir"` + Action string `json:"action"` + Name string `json:"name"` + Dir string `json:"dir"` + NewName string `json:"new_name"` } if err := readJSON(r, &body); err != nil { writeJSON(w, map[string]any{"error": "invalid"}) @@ -506,12 +514,50 @@ func (s *AdminServer) handleEntityDirs(entityType string) http.HandlerFunc { s.undoStack.Push(ch) } writeJSON(w, map[string]any{"ok": true, "moved": len(changes) - 1}) + case "rename_dir": + if err := renameEntityDir(s.dataDir, entityType, body.Dir, body.NewName); err != nil { + writeJSON(w, map[string]any{"error": err.Error()}) + return + } + writeJSON(w, map[string]any{"ok": true, "name": body.NewName}) default: writeJSON(w, map[string]any{"error": "unknown action"}) } } } +func (s *AdminServer) handleEntityRename(entityType 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 + } + var body struct { + ID string `json:"id"` + NewID string `json:"new_id"` + } + if err := readJSON(r, &body); err != nil || body.ID == "" || body.NewID == "" { + writeJSON(w, map[string]any{"error": "invalid"}) + return + } + oldPath, newPath, data, err := renameEntityFile(s.dataDir, entityType, body.ID, body.NewID) + if err != nil { + writeJSON(w, map[string]any{"error": err.Error()}) + return + } + desc := fmt.Sprintf("rename %s %s to %s", entityType, body.ID, body.NewID) + s.undoStack.Push(ChangeDesc{ + Description: desc, + FilePath: oldPath, + NewFilePath: newPath, + OldContent: data, + NewContent: data, + }) + s.invalidateEntityCaches(entityType) + writeJSON(w, map[string]any{"ok": true, "id": body.NewID}) + } +} + func (s *AdminServer) handleEntityMove(entityType string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { @@ -542,6 +588,7 @@ func (s *AdminServer) handleEntityMove(entityType string) http.HandlerFunc { OldContent: data, NewContent: data, }) + s.invalidateEntityCaches(entityType) writeJSON(w, map[string]any{"ok": true}) } } @@ -565,6 +612,28 @@ func (s *AdminServer) rebuildAfterUndo(change *ChangeDesc) { } } } + + for _, p := range changeFiles(change) { + s.invalidateEntityCacheForPath(p) + } +} + +func (s *AdminServer) invalidateEntityCaches(entityType string) { + switch entityType { + case "mobs": + s.mobStore.ReloadDefs(s.dataDir) + case "drops": + behavior.ClearDropIndex() + } +} + +func (s *AdminServer) invalidateEntityCacheForPath(path string) { + for _, subdir := range []string{"mobs", "drops"} { + rel, err := filepath.Rel(filepath.Join(s.dataDir, subdir), path) + if err == nil && !strings.HasPrefix(rel, "..") && rel != "." { + s.invalidateEntityCaches(subdir) + } + } } func changeFiles(change *ChangeDesc) []string { -- cgit v1.2.3