1package guildsv32import (3 "chain"4 "strings"5 bptree "gno.land/p/nt/bptree/v0"6 kourt "gno.land/r/g1leu8d2vsplhehcfkjg50mwgdpxdkt8tztu95wr/kourtv3"7)8type choice struct {9 guildID string10 by address11}12var guildOf = bptree.NewBPTree32()13func Set(cur realm, courtSlug, guildID string) {14 if !cur.IsCurrent() {15 panic("guilds: stale realm")16 }17 who := cur.Previous().Address()18 if !kourt.IsCourtMod(courtSlug, who) {19 panic("guilds: only a moderator of this court may set its server")20 }21 id := strings.TrimSpace(guildID)22 if id == "" {23 if _, removed := guildOf.Remove(courtSlug); removed {24 chain.Emit("GuildCleared", "court", courtSlug, "by", who.String())25 }26 return27 }28 if len(id) < 17 || len(id) > 20 {29 panic("guilds: a Discord server id is 17 to 20 digits")30 }31 for i := 0; i < len(id); i++ {32 if id[i] < '0' || id[i] > '9' {33 panic("guilds: a Discord server id is digits only")34 }35 }36 guildOf.Set(courtSlug, choice{guildID: id, by: who})37 chain.Emit("GuildSet", "court", courtSlug, "guild", id, "by", who.String())38}39func GuildOf(courtSlug string) string {40 c, ok := guildOf.Get(courtSlug).(choice)41 if !ok {42 return ""43 }44 return c.guildID45}46func Chosen(courtSlug string) (guildID, by string) {47 c, ok := guildOf.Get(courtSlug).(choice)48 if !ok {49 return "", ""50 }51 return c.guildID, c.by.String()52}53func Courts() []string {54 out := []string{}55 guildOf.Iterate("", "", func(k string, _ any) bool {56 out = append(out, k)57 return false58 })59 return out60}61func Render(path string) string {62 var b strings.Builder63 b.WriteString("# Court Discord servers\n\n")64 b.WriteString("Which Discord server each court's moderators chose. ")65 b.WriteString("Set by a moderator of the court, read by kourt.xyz.\n\n")66 n := 067 guildOf.Iterate("", "", func(k string, v any) bool {68 c, _ := v.(choice)69 b.WriteString("- **" + k + "** — `" + c.guildID + "` (set by " + c.by.String() + ")\n")70 n++71 return false72 })73 if n == 0 {74 b.WriteString("_No court has chosen one yet._\n")75 }76 return b.String()77}78Chosen(courtSlug string) (guildID string, by string)
Courts() []string
GuildOf(courtSlug string) string
Render(path string) string
Set(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, courtSlug string, guildID string)
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.