- Updated the backend documentation in CONTRIBUTING.md and README.md to reflect changes in application structure and API endpoints. - Enhanced the frontend components in MapView.vue for better handling of context menu actions. - Added new types and interfaces in TypeScript for improved type safety in the frontend. - Introduced new utility classes for managing characters and markers in the map. - Updated .gitignore to include .vscode directory for better development environment management.
189 lines
3.9 KiB
Go
189 lines
3.9 KiB
Go
package app
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"go.etcd.io/bbolt"
|
|
)
|
|
|
|
func (a *App) wipeTile(rw http.ResponseWriter, req *http.Request) {
|
|
if a.requireAdmin(rw, req) == nil {
|
|
return
|
|
}
|
|
mraw := req.FormValue("map")
|
|
mapid, err := strconv.Atoi(mraw)
|
|
if err != nil {
|
|
http.Error(rw, "coord parse failed", http.StatusBadRequest)
|
|
return
|
|
}
|
|
xraw := req.FormValue("x")
|
|
x, err := strconv.Atoi(xraw)
|
|
if err != nil {
|
|
http.Error(rw, "coord parse failed", http.StatusBadRequest)
|
|
return
|
|
}
|
|
yraw := req.FormValue("y")
|
|
y, err := strconv.Atoi(yraw)
|
|
if err != nil {
|
|
http.Error(rw, "coord parse failed", http.StatusBadRequest)
|
|
return
|
|
}
|
|
c := Coord{
|
|
X: x,
|
|
Y: y,
|
|
}
|
|
|
|
a.db.Update(func(tx *bbolt.Tx) error {
|
|
grids := tx.Bucket([]byte("grids"))
|
|
if grids == nil {
|
|
return nil
|
|
}
|
|
ids := [][]byte{}
|
|
err := grids.ForEach(func(k, v []byte) error {
|
|
g := GridData{}
|
|
err := json.Unmarshal(v, &g)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if g.Coord == c && g.Map == mapid {
|
|
ids = append(ids, k)
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, id := range ids {
|
|
grids.Delete(id)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
a.SaveTile(mapid, c, 0, "", -1)
|
|
for z := 1; z <= 5; z++ {
|
|
c = c.Parent()
|
|
a.updateZoomLevel(mapid, c, z)
|
|
}
|
|
rw.WriteHeader(200)
|
|
}
|
|
|
|
func (a *App) setCoords(rw http.ResponseWriter, req *http.Request) {
|
|
if a.requireAdmin(rw, req) == nil {
|
|
return
|
|
}
|
|
mraw := req.FormValue("map")
|
|
mapid, err := strconv.Atoi(mraw)
|
|
if err != nil {
|
|
http.Error(rw, "coord parse failed", http.StatusBadRequest)
|
|
return
|
|
}
|
|
fxraw := req.FormValue("fx")
|
|
fx, err := strconv.Atoi(fxraw)
|
|
if err != nil {
|
|
http.Error(rw, "coord parse failed", http.StatusBadRequest)
|
|
return
|
|
}
|
|
fyraw := req.FormValue("fy")
|
|
fy, err := strconv.Atoi(fyraw)
|
|
if err != nil {
|
|
http.Error(rw, "coord parse failed", http.StatusBadRequest)
|
|
return
|
|
}
|
|
fc := Coord{
|
|
X: fx,
|
|
Y: fy,
|
|
}
|
|
|
|
txraw := req.FormValue("tx")
|
|
tx, err := strconv.Atoi(txraw)
|
|
if err != nil {
|
|
http.Error(rw, "coord parse failed", http.StatusBadRequest)
|
|
return
|
|
}
|
|
tyraw := req.FormValue("ty")
|
|
ty, err := strconv.Atoi(tyraw)
|
|
if err != nil {
|
|
http.Error(rw, "coord parse failed", http.StatusBadRequest)
|
|
return
|
|
}
|
|
tc := Coord{
|
|
X: tx,
|
|
Y: ty,
|
|
}
|
|
|
|
diff := Coord{
|
|
X: tc.X - fc.X,
|
|
Y: tc.Y - fc.Y,
|
|
}
|
|
tds := []*TileData{}
|
|
a.db.Update(func(tx *bbolt.Tx) error {
|
|
grids := tx.Bucket([]byte("grids"))
|
|
if grids == nil {
|
|
return nil
|
|
}
|
|
tiles := tx.Bucket([]byte("tiles"))
|
|
if tiles == nil {
|
|
return nil
|
|
}
|
|
mapZooms := tiles.Bucket([]byte(strconv.Itoa(mapid)))
|
|
if mapZooms == nil {
|
|
return nil
|
|
}
|
|
mapTiles := mapZooms.Bucket([]byte("0"))
|
|
err := grids.ForEach(func(k, v []byte) error {
|
|
g := GridData{}
|
|
err := json.Unmarshal(v, &g)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if g.Map == mapid {
|
|
g.Coord.X += diff.X
|
|
g.Coord.Y += diff.Y
|
|
raw, _ := json.Marshal(g)
|
|
grids.Put(k, raw)
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = mapTiles.ForEach(func(k, v []byte) error {
|
|
td := &TileData{}
|
|
err := json.Unmarshal(v, &td)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
td.Coord.X += diff.X
|
|
td.Coord.Y += diff.Y
|
|
tds = append(tds, td)
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = tiles.DeleteBucket([]byte(strconv.Itoa(mapid)))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
needProcess := map[zoomproc]struct{}{}
|
|
for _, td := range tds {
|
|
a.SaveTile(td.MapID, td.Coord, td.Zoom, td.File, time.Now().UnixNano())
|
|
needProcess[zoomproc{c: Coord{X: td.Coord.X, Y: td.Coord.Y}.Parent(), m: td.MapID}] = struct{}{}
|
|
}
|
|
for z := 1; z <= 5; z++ {
|
|
process := needProcess
|
|
needProcess = map[zoomproc]struct{}{}
|
|
for p := range process {
|
|
a.updateZoomLevel(p.m, p.c, z)
|
|
needProcess[zoomproc{p.c.Parent(), p.m}] = struct{}{}
|
|
}
|
|
}
|
|
rw.WriteHeader(200)
|
|
}
|