~nromdotcom/gemif

ref: 4537a2f30ac534f927315780f6176cd14ba1cbe4 gemif/pkg/gemserver/routes.go -rw-r--r-- 3.1 KiB
4537a2f3Norm MacLennan Update story 1 year, 1 month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package gemserver

import (
	"fmt"
	"io/ioutil"
	"net/url"
	"path"
	"path/filepath"
	"sort"

	"git.sr.ht/~nromdotcom/gemif/pkg/gamemanager"
	"git.sr.ht/~nromdotcom/gemif/pkg/scenerenderer"
	"github.com/markbates/pkger"
	"github.com/pitr/gig"
)

func handleStatic(c gig.Context) error {
	p, err := url.PathUnescape(c.Param("*"))
	if err != nil {
		return fmt.Errorf("unable to parse url: %w", err)
	}

	if p == "/" {
		p = "/index.gmi"
	}

	name := filepath.Join("/static/docs", path.Clean("/"+p))

	f, fileErr := pkger.Open(name)
	if fileErr != nil {
		return fmt.Errorf("couldn't open file: %w", fileErr)
	}

	sl, readErr := ioutil.ReadAll(f)
	if readErr != nil {
		return fmt.Errorf("couldn't read file: %w", readErr)
	}

	return c.Gemini(string(sl))
}

func handleHome(gm *gamemanager.GameManager, version string) func(gig.Context) error {
	return func(c gig.Context) error {
		stories := gm.GetStories()

		// startStates, startErr := gm.ConstructStartingState(stories)
		// if startErr != nil {
		// 	return fmt.Errorf("couldn't load game: %w", startErr)
		// }

		sort.Slice(stories, func(a int, b int) bool {
			return stories[a].Name < stories[b].Name
		})

		return c.Render("git.sr.ht/~nromdotcom/gemif:/static/templates/index.gmi.tmpl", map[string]interface{}{
			"Stories": stories,
			"Banner":  getRandomBanner(),
			"Version": version,
		})
	}
}

func handleStory(gm *gamemanager.GameManager) func(gig.Context) error {
	return func(c gig.Context) error {
		story := gm.Book.Stories[c.Param("storyid")]

		startState, startErr := gm.ConstructStartingState(story.Metadata)
		if startErr != nil {
			return fmt.Errorf("couldn't load game: %w", startErr)
		}

		return c.Render("git.sr.ht/~nromdotcom/gemif:/static/templates/story.gmi.tmpl", map[string]interface{}{
			"Metadata":      story.Metadata,
			"StartingState": startState,
		})
	}
}

func handleGame(gm *gamemanager.GameManager, renderer scenerenderer.Template) func(gig.Context) error {
	return func(c gig.Context) error {
		gameState, gameErr := gm.DeserializeState(c.Param("statetoken"))
		if gameErr != nil {
			return fmt.Errorf("could not deserialized game state: %w", gameErr)
		}

		currentRoom, roomErr := gm.GetRoomByID(gameState.StoryID, gameState.CurrentRoom)
		if roomErr != nil {
			return fmt.Errorf("could not find room: %w", roomErr)
		}

		roomDesc := currentRoom.Description

		if gm.EngineConfig.RenderDescriptions {
			renderedRoom, renderErr := renderer.ExecuteTemplate(gameState, currentRoom.Description)
			if renderErr != nil {
				return fmt.Errorf("could not render room %w", renderErr)
			}

			roomDesc = renderedRoom
		}

		speculativeStates, speculationErr := gm.ConstructSpeculativeStates(gameState, currentRoom)
		if speculationErr != nil {
			return fmt.Errorf("unable to render exits: %w", speculationErr)
		}

		return c.Render("git.sr.ht/~nromdotcom/gemif:/static/templates/room.gmi.tmpl", map[string]interface{}{
			"RoomName":    currentRoom.Name,
			"Description": roomDesc,
			"Actions":     speculativeStates,
		})
	}
}

func handleRobots(c gig.Context) error {
	return c.Text(`User-agent: *
Disallow: /game/`)
}

func handleFavicon(c gig.Context) error {
	return c.Text("📚")
}