Skip to content

Commit

Permalink
Merge pull request #269 from supreme2580/main
Browse files Browse the repository at this point in the history
World Names
  • Loading branch information
b-j-roberts authored Dec 16, 2024
2 parents 091610c + 9b67f1e commit 26081ea
Show file tree
Hide file tree
Showing 17 changed files with 2,881 additions and 2,536 deletions.
59 changes: 38 additions & 21 deletions backend/routes/indexer/worlds.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,33 @@ import (

func processCanvasCreatedEvent(event IndexerEvent) {
canvasIdHex := event.Event.Keys[1]
host := event.Event.Data[0][2:] // Remove 0x prefix
nameHex := event.Event.Data[1][2:] // Remove 0x prefix
widthHex := event.Event.Data[2]
heightHex := event.Event.Data[3]
timeBetweenPixelsHex := event.Event.Data[4]
colorPaletteLenHex := event.Event.Data[5]
host := event.Event.Data[0][2:] // Remove 0x prefix
nameHex := event.Event.Data[1][2:] // Remove 0x prefix
uniqueNameHex := event.Event.Data[2][2:] // Remove 0x prefix
widthHex := event.Event.Data[3]
heightHex := event.Event.Data[4]
timeBetweenPixelsHex := event.Event.Data[5]
colorPaletteLenHex := event.Event.Data[6]

colorPaletteLen, err := strconv.ParseInt(colorPaletteLenHex, 0, 64)
if err != nil {
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse colorPaletteLenHex", canvasIdHex, host, nameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse colorPaletteLenHex", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
return
}
// Skip colors since they are processed in another event

startTimeHex := event.Event.Data[6+colorPaletteLen]
endTimeHex := event.Event.Data[7+colorPaletteLen]
startTimeHex := event.Event.Data[7+colorPaletteLen]
endTimeHex := event.Event.Data[8+colorPaletteLen]

canvasId, err := strconv.ParseInt(canvasIdHex, 0, 64)
if err != nil {
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse canvasIdHex", canvasIdHex, host, nameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse canvasIdHex", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
return
}

decodedName, err := hex.DecodeString(nameHex)
if err != nil {
PrintIndexerError("processCanvasCreatedEvent", "Failed to decode nameHex", canvasIdHex, host, nameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
PrintIndexerError("processCanvasCreatedEvent", "Failed to decode nameHex", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
return
}
trimmedName := []byte{}
Expand All @@ -55,40 +56,56 @@ func processCanvasCreatedEvent(event IndexerEvent) {
}
name := string(trimmedName)

decodedUniqueName, err := hex.DecodeString(uniqueNameHex)
if err != nil {
PrintIndexerError("processCanvasCreatedEvent", "Failed to decode uniqueNameHex", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
return
}
trimmedUniqueName := []byte{}
trimming = true
for _, b := range decodedUniqueName {
if b == 0 && trimming {
continue
}
trimming = false
trimmedUniqueName = append(trimmedUniqueName, b)
}
uniqueName := string(trimmedUniqueName)

width, err := strconv.ParseInt(widthHex, 0, 64)
if err != nil {
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse widthHex", canvasIdHex, host, nameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse widthHex", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
return
}

height, err := strconv.ParseInt(heightHex, 0, 64)
if err != nil {
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse heightHex", canvasIdHex, host, nameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse heightHex", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
return
}

timeBetweenPixels, err := strconv.ParseInt(timeBetweenPixelsHex, 0, 64)
if err != nil {
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse timeBetweenPixelsHex", canvasIdHex, host, nameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse timeBetweenPixelsHex", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
return
}

startTime, err := strconv.ParseInt(startTimeHex, 0, 64)
if err != nil {
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse startTimeHex", canvasIdHex, host, nameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse startTimeHex", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
return
}

endTime, err := strconv.ParseInt(endTimeHex, 0, 64)
if err != nil {
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse endTimeHex", canvasIdHex, host, nameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
PrintIndexerError("processCanvasCreatedEvent", "Failed to parse endTimeHex", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
return
}

// Insert into Worlds
_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "INSERT INTO Worlds (world_id, host, name, width, height, time_between_pixels, start_time, end_time) VALUES ($1, $2, $3, $4, $5, $6, TO_TIMESTAMP($7), TO_TIMESTAMP($8))", canvasId, host, name, width, height, timeBetweenPixels, startTime, endTime)
_, err = core.ArtPeaceBackend.Databases.Postgres.Exec(context.Background(), "INSERT INTO Worlds (world_id, host, name, unique_name, width, height, time_between_pixels, start_time, end_time) VALUES ($1, $2, $3, $4, $5, $6, $7, TO_TIMESTAMP($8), TO_TIMESTAMP($9))", canvasId, host, name, uniqueName, width, height, timeBetweenPixels, startTime, endTime)
if err != nil {
PrintIndexerError("processCanvasCreatedEvent", "Failed to insert into Worlds", canvasIdHex, host, nameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
PrintIndexerError("processCanvasCreatedEvent", "Failed to insert into Worlds", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
return
}

Expand All @@ -103,11 +120,11 @@ func processCanvasCreatedEvent(event IndexerEvent) {
canvas := make([]byte, totalByteSize)
err := core.ArtPeaceBackend.Databases.Redis.Set(context.Background(), canvasRedisKey, canvas, 0).Err()
if err != nil {
PrintIndexerError("processCanvasCreatedEvent", "Failed to set canvas in redis", canvasIdHex, host, nameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
PrintIndexerError("processCanvasCreatedEvent", "Failed to set canvas in redis", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
return
}
} else {
PrintIndexerError("processCanvasCreatedEvent", "Canvas already exists in redis", canvasIdHex, host, nameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
PrintIndexerError("processCanvasCreatedEvent", "Canvas already exists in redis", canvasIdHex, host, nameHex, uniqueNameHex, widthHex, heightHex, timeBetweenPixelsHex, colorPaletteLenHex, err)
}

// Create base directories if they don't exist
Expand All @@ -127,7 +144,7 @@ func processCanvasCreatedEvent(event IndexerEvent) {
}

generatedWorldImage := image.NewRGBA(image.Rect(0, 0, int(width), int(height)))
baseColorHex := event.Event.Data[6]
baseColorHex := event.Event.Data[7]
baseColor := baseColorHex[len(baseColorHex)-6:] // Remove prefix
baseColorR, err := strconv.ParseInt(baseColor[0:2], 16, 64)
if err != nil {
Expand Down
63 changes: 58 additions & 5 deletions backend/routes/worlds.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package routes

import (
"context"
"fmt"
"net/http"
"os"
"os/exec"
Expand All @@ -17,6 +16,7 @@ import (
// TODO: check-worlds-name-unique?
func InitWorldsRoutes() {
http.HandleFunc("/get-world-canvas", getWorldCanvas)
http.HandleFunc("/get-world-id", getWorldId)
http.HandleFunc("/get-world", getWorld)
http.HandleFunc("/get-worlds", getWorlds)
http.HandleFunc("/get-new-worlds", getNewWorlds)
Expand All @@ -29,6 +29,7 @@ func InitWorldsRoutes() {
http.HandleFunc("/get-worlds-colors", getWorldsColors)
http.HandleFunc("/get-worlds-pixel-count", getWorldsPixelCount)
http.HandleFunc("/get-worlds-pixel-info", getWorldsPixelInfo)
http.HandleFunc("/check-world-name", checkWorldName)
if !core.ArtPeaceBackend.BackendConfig.Production {
http.HandleFunc("/create-canvas-devnet", createCanvasDevnet)
http.HandleFunc("/favorite-world-devnet", favoriteWorldDevnet)
Expand Down Expand Up @@ -66,6 +67,7 @@ type WorldData struct {
WorldId int `json:"worldId"`
Host string `json:"host"`
Name string `json:"name"`
UniqueName string `json:"uniqueName"`
Width int `json:"width"`
Height int `json:"height"`
TimeBetweenPixels int `json:"timeBetweenPixels"`
Expand All @@ -75,6 +77,20 @@ type WorldData struct {
Favorited bool `json:"favorited"`
}

func getWorldId(w http.ResponseWriter, r *http.Request) {
worldName := r.URL.Query().Get("worldName")
if worldName == "" {
routeutils.WriteErrorJson(w, http.StatusBadRequest, "Missing worldName")
return
}
worldId, err := core.PostgresQueryOne[int]("SELECT world_id FROM worlds WHERE unique_name = $1", worldName)
if err != nil {
routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to retrieve World")
return
}
routeutils.WriteDataJson(w, strconv.Itoa(*worldId))
}

func getWorld(w http.ResponseWriter, r *http.Request) {
worldId := r.URL.Query().Get("worldId")
if worldId == "" {
Expand Down Expand Up @@ -173,7 +189,6 @@ func getNewWorlds(w http.ResponseWriter, r *http.Request) {
LIMIT $2 OFFSET $3`
worlds, err := core.PostgresQueryJson[WorldData](query, address, pageLength, offset)
if err != nil {
fmt.Println(err)
routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to retrieve Worlds")
return
}
Expand Down Expand Up @@ -459,9 +474,21 @@ func createCanvasDevnet(w http.ResponseWriter, r *http.Request) {

host := (*jsonBody)["host"]
name := (*jsonBody)["name"]
uniqueName := (*jsonBody)["unique_name"]

if host == "" || name == "" || uniqueName == "" {
routeutils.WriteErrorJson(w, http.StatusBadRequest, "Missing host or name or uniqueName")
return
}

if host == "" || name == "" {
routeutils.WriteErrorJson(w, http.StatusBadRequest, "Missing host or name")
// Check if world name already exists
exists, err := core.PostgresQueryOne[bool]("SELECT EXISTS(SELECT 1 FROM worlds WHERE unique_name = $1)", uniqueName)
if err != nil {
routeutils.WriteErrorJson(w, http.StatusInternalServerError, "World unique name check failed")
return
}
if *exists {
routeutils.WriteErrorJson(w, http.StatusBadRequest, "World name already exists")
return
}

Expand Down Expand Up @@ -512,7 +539,7 @@ func createCanvasDevnet(w http.ResponseWriter, r *http.Request) {
shellCmd := core.ArtPeaceBackend.BackendConfig.Scripts.CreateCanvasDevnet
contract := os.Getenv("CANVAS_FACTORY_CONTRACT_ADDRESS")

cmd := exec.Command(shellCmd, contract, "create_canvas", host, name, strconv.Itoa(width), strconv.Itoa(height), strconv.Itoa(timer), strconv.Itoa(len(palette)), paletteInput, strconv.Itoa(startTime), strconv.Itoa(endTime))
cmd := exec.Command(shellCmd, contract, "create_canvas", host, name, uniqueName, strconv.Itoa(width), strconv.Itoa(height), strconv.Itoa(timer), strconv.Itoa(len(palette)), paletteInput, strconv.Itoa(startTime), strconv.Itoa(endTime))
_, err = cmd.Output()
if err != nil {
routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to create canvas")
Expand Down Expand Up @@ -637,3 +664,29 @@ func placeWorldPixelDevnet(w http.ResponseWriter, r *http.Request) {

routeutils.WriteResultJson(w, "Pixel placed world")
}

func checkWorldName(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("uniqueName")
if name == "" {
routeutils.WriteErrorJson(w, http.StatusBadRequest, "Missing uniqueName parameter")
return
}

// Use the helper function
exists, err := doesWorldNameExist(name)
if err != nil {
routeutils.WriteErrorJson(w, http.StatusInternalServerError, "Failed to check world name")
return
}

routeutils.WriteDataJson(w, strconv.FormatBool(exists))
}

// Add a helper function to check if a world name exists
func doesWorldNameExist(name string) (bool, error) {
exists, err := core.PostgresQueryOne[bool]("SELECT EXISTS(SELECT 1 FROM worlds WHERE unique_name = $1)", name)
if err != nil {
return false, err
}
return *exists, nil
}
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ services:
- REACT_APP_ROUND_NUMBER=2
volumes:
- ./frontend/package.json:/app/package.json
- ./frontend/package-lock.json:/app/package-lock.json
- ./frontend/pnpm-lock.yaml:/app/pnpm-lock.yaml
- ./frontend/public/:/app/public
- ./frontend/src:/app/src
- configs:/app/src/configs
Expand Down
Loading

0 comments on commit 26081ea

Please sign in to comment.