- Added a new AGENTS.md file to document the project structure and conventions. - Updated .gitignore to include node_modules and refined cursor rules. - Introduced new backend and frontend components for improved map interactions, including context menus and controls. - Enhanced API composables for better admin and authentication functionalities. - Refactored existing components for cleaner code and improved user experience. - Updated README.md to clarify production asset serving and user setup instructions.
146 lines
3.4 KiB
Go
146 lines
3.4 KiB
Go
package app
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/andyleap/hnh-map/internal/app/store"
|
|
"go.etcd.io/bbolt"
|
|
)
|
|
|
|
type Config struct {
|
|
Title string `json:"title"`
|
|
Auths []string `json:"auths"`
|
|
}
|
|
|
|
func (a *App) canAccessMap(s *Session) bool {
|
|
return s != nil && (s.Auths.Has(AUTH_MAP) || s.Auths.Has(AUTH_ADMIN))
|
|
}
|
|
|
|
func (a *App) getChars(rw http.ResponseWriter, req *http.Request) {
|
|
s := a.getSession(req)
|
|
if !a.canAccessMap(s) {
|
|
rw.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
if !s.Auths.Has(AUTH_MARKERS) && !s.Auths.Has(AUTH_ADMIN) {
|
|
rw.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(rw).Encode([]interface{}{})
|
|
return
|
|
}
|
|
chars := []Character{}
|
|
a.chmu.RLock()
|
|
defer a.chmu.RUnlock()
|
|
for _, v := range a.characters {
|
|
chars = append(chars, v)
|
|
}
|
|
rw.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(rw).Encode(chars)
|
|
}
|
|
|
|
func (a *App) getMarkers(rw http.ResponseWriter, req *http.Request) {
|
|
s := a.getSession(req)
|
|
if !a.canAccessMap(s) {
|
|
rw.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
if !s.Auths.Has(AUTH_MARKERS) && !s.Auths.Has(AUTH_ADMIN) {
|
|
rw.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(rw).Encode([]interface{}{})
|
|
return
|
|
}
|
|
markers := []FrontendMarker{}
|
|
a.db.View(func(tx *bbolt.Tx) error {
|
|
b := tx.Bucket(store.BucketMarkers)
|
|
if b == nil {
|
|
return nil
|
|
}
|
|
grid := b.Bucket(store.BucketMarkersGrid)
|
|
if grid == nil {
|
|
return nil
|
|
}
|
|
grids := tx.Bucket(store.BucketGrids)
|
|
if grids == nil {
|
|
return nil
|
|
}
|
|
return grid.ForEach(func(k, v []byte) error {
|
|
marker := Marker{}
|
|
json.Unmarshal(v, &marker)
|
|
graw := grids.Get([]byte(marker.GridID))
|
|
if graw == nil {
|
|
return nil
|
|
}
|
|
g := GridData{}
|
|
json.Unmarshal(graw, &g)
|
|
markers = append(markers, FrontendMarker{
|
|
Image: marker.Image,
|
|
Hidden: marker.Hidden,
|
|
ID: marker.ID,
|
|
Name: marker.Name,
|
|
Map: g.Map,
|
|
Position: Position{
|
|
X: marker.Position.X + g.Coord.X*100,
|
|
Y: marker.Position.Y + g.Coord.Y*100,
|
|
},
|
|
})
|
|
return nil
|
|
})
|
|
})
|
|
rw.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(rw).Encode(markers)
|
|
}
|
|
|
|
func (a *App) getMaps(rw http.ResponseWriter, req *http.Request) {
|
|
s := a.getSession(req)
|
|
if !a.canAccessMap(s) {
|
|
rw.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
showHidden := s.Auths.Has(AUTH_ADMIN)
|
|
maps := map[int]*MapInfo{}
|
|
a.db.View(func(tx *bbolt.Tx) error {
|
|
mapB := tx.Bucket(store.BucketMaps)
|
|
if mapB == nil {
|
|
return nil
|
|
}
|
|
return mapB.ForEach(func(k, v []byte) error {
|
|
mapid, err := strconv.Atoi(string(k))
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
mi := &MapInfo{}
|
|
json.Unmarshal(v, &mi)
|
|
if mi.Hidden && !showHidden {
|
|
return nil
|
|
}
|
|
maps[mapid] = mi
|
|
return nil
|
|
})
|
|
})
|
|
rw.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(rw).Encode(maps)
|
|
}
|
|
|
|
func (a *App) config(rw http.ResponseWriter, req *http.Request) {
|
|
s := a.getSession(req)
|
|
if s == nil {
|
|
rw.WriteHeader(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
config := Config{
|
|
Auths: s.Auths,
|
|
}
|
|
a.db.View(func(tx *bbolt.Tx) error {
|
|
b := tx.Bucket(store.BucketConfig)
|
|
if b == nil {
|
|
return nil
|
|
}
|
|
title := b.Get([]byte("title"))
|
|
config.Title = string(title)
|
|
return nil
|
|
})
|
|
rw.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(rw).Encode(config)
|
|
}
|