Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ vendor/
modules/all-modules.go
server.crt
server.key
tmp-gomud.exe
__debug*
11 changes: 8 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,20 @@ clean:
## Run Targets

.PHONY: run
run: ### Build and run server.
run: generate ### Build and run server.
go build -o tmp-gomud.exe
make ungenerate
./tmp-gomud.exe

.PHONY: run-docker
run-docker: ### Build and run server in docker.
$(DOCKER_COMPOSE) up --build --remove-orphans server


.PHONY: client
client: ### Build and run client terminal client
$(DOCKER_COMPOSE) run --rm terminal telnet go-mud-server 33333



.PHONY: image_tag
image_tag:
@echo $(VERSION)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ require (
)

require (
github.com/GoMudEngine/ansitags v0.0.0-20250414221109-c8b646c08209
github.com/GoMudEngine/ansitags v1.0.0
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/GoMudEngine/ansitags v0.0.0-20250414221109-c8b646c08209 h1:J8ncO2tq5p6hcXp5+Ahj/k2xfIp3Xe1+z8rcbDLekNI=
github.com/GoMudEngine/ansitags v0.0.0-20250414221109-c8b646c08209/go.mod h1:McpBTRYx4TE/+aVbK4veo7z6mDNrpi3Lka88FenWa3A=
github.com/GoMudEngine/ansitags v1.0.0 h1:YvZpmQUAvWtKV4TK60LVknqZGM0I9S6ClTjpg6dBoVU=
github.com/GoMudEngine/ansitags v1.0.0/go.mod h1:McpBTRYx4TE/+aVbK4veo7z6mDNrpi3Lka88FenWa3A=
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
Expand Down
27 changes: 27 additions & 0 deletions internal/connections/connectiondetails.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,33 @@ type ConnectionDetails struct {
heartbeat *heartbeatManager
}

func (cd *ConnectionDetails) IsLocal() bool {

remoteAddrStr := ``

if cd.wsConn == nil {
// Unix sockets are always local
if _, ok := cd.conn.(*net.UnixConn); ok {
return true
}
remoteAddrStr = cd.conn.RemoteAddr().String()
} else {
remoteAddrStr = cd.wsConn.RemoteAddr().String()
}

host, _, err := net.SplitHostPort(remoteAddrStr)
if err != nil {
// e.g. not “host:port” syntax
return false
}

ip := net.ParseIP(host)
if ip == nil {
return false
}
return ip.IsLoopback()
}

func (cd *ConnectionDetails) IsWebSocket() bool {
return cd.wsConn != nil
}
Expand Down
100 changes: 24 additions & 76 deletions internal/templates/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import (
"fmt"
"io/fs"
"os"
"strconv"
"strings"
"sync"
"text/template"
"time"

"github.com/GoMudEngine/GoMud/internal/colorpatterns"
"github.com/GoMudEngine/GoMud/internal/configs"
"github.com/GoMudEngine/GoMud/internal/fileloader"
"github.com/GoMudEngine/GoMud/internal/mudlog"
"github.com/GoMudEngine/GoMud/internal/users"
"github.com/GoMudEngine/ansitags"
"github.com/mattn/go-runewidth"
"gopkg.in/yaml.v2"

"github.com/GoMudEngine/GoMud/internal/util"
)
Expand Down Expand Up @@ -236,81 +239,6 @@ func Process(fname string, data any, receivingUserId ...int) (string, error) {
return fmt.Sprintf(`[TEMPLATE READ ERROR: FNF (%s) `, strings.Join(allFiles, `, `)), fmt.Errorf(`Files not found: %s`, strings.Join(allFiles, `, `))
}

func ProcessOld(name string, data any) (string, error) {
ansiLock.RLock()
defer ansiLock.RUnlock()

var buf bytes.Buffer

if fileBytes, err := readFile(util.FilePath(`templates`, `/`, name+`.template`)); err == nil {

tpl, err := template.New(name).Funcs(funcMap).Parse(string(fileBytes))
if err != nil {
return string(fileBytes), err
}

err = tpl.Execute(&buf, data)
if err != nil {
mudlog.Error("could not parse template file", "error", err)
return "[TEMPLATE ERROR]", err
}

// return the final data as a string, parse ansi tags if needed (No need to parse if it was preparsed)
return ansitags.Parse(buf.String()), nil

} else {
// All templates must end with .template
var fullPath string = util.FilePath(string(configs.GetFilePathsConfig().DataFiles), `/`, `templates`, `/`, name+`.template`)

fInfo, err := os.Stat(fullPath)
if err != nil {
//mudlog.Error("could not stat template file", "error", err)
return "[TEMPLATE READ ERROR]", err
}

var cache cacheEntry
var ok bool

cacheLock.Lock()
defer cacheLock.Unlock()

// check if the template is in the cache
if cache, ok = templateCache[name]; !ok || cache.older(fInfo.ModTime()) {

// Get the file contents
fileContents, err := os.ReadFile(fullPath)
if err != nil {
mudlog.Error("could not read template file", "error", err)
return "[TEMPLATE READ ERROR]", err
}

// parse the file contents as a template
tpl, err := template.New(name).Funcs(funcMap).Parse(string(fileContents))
if err != nil {
return string(fileContents), err
}

// add the template to the cache
cache = cacheEntry{tpl: tpl, modified: fInfo.ModTime()}
templateCache[name] = cache
}

// execute the template and store the results into a buffer

err = cache.tpl.Execute(&buf, data)
if err != nil {
mudlog.Error("could not parse template file", "error", err)
return "[TEMPLATE ERROR]", err
}

// return the final data as a string, parse ansi tags if needed (No need to parse if it was preparsed)
return ansitags.Parse(buf.String()), nil

}

return buf.String(), nil
}

func ProcessText(text string, data any, ansiFlags ...AnsiFlag) (string, error) {

var parseAnsiTags bool = false
Expand Down Expand Up @@ -493,7 +421,7 @@ func AnsiParse(input string) string {

// Loads the ansi aliases from the config file
// Only if the file has been modified since the last load
func LoadAliases() {
func LoadAliases(f ...fileloader.ReadableGroupFS) {

// Get the file info
fInfo, err := os.Stat(util.FilePath(string(configs.GetFilePathsConfig().DataFiles) + `/ansi-aliases.yaml`))
Expand All @@ -515,5 +443,25 @@ func LoadAliases() {
mudlog.Info("ansitags.LoadAliases()", "changed", true, "Time Taken", time.Since(start), "error", err.Error())
}

OLPath := util.FilePath(`data-overlays`, `/`, `ansi-aliases.yaml`)
for _, files := range f {
if b, err := files.ReadFile(OLPath); err == nil {

data := make(map[string]map[string]string, 100)
if err := yaml.Unmarshal(b, &data); err != nil {
continue
}

for aliasGroup, aliases := range data {
for alias, valStr := range aliases {
if valInt, err := strconv.Atoi(valStr); err == nil {
ansitags.SetAlias(alias, valInt, aliasGroup)
}
}
}

}
}

mudlog.Info("ansitags.LoadAliases()", "changed", true, "Time Taken", time.Since(start))
}
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ func loadAllDataFiles(isReload bool) {
mobs.LoadDataFiles()
pets.LoadDataFiles()
quests.LoadDataFiles()
templates.LoadAliases()
templates.LoadAliases(plugins.GetPluginRegistry())
keywords.LoadAliases(plugins.GetPluginRegistry())
mutators.LoadDataFiles()
colorpatterns.LoadColorPatterns()
Expand Down
24 changes: 15 additions & 9 deletions modules/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,21 @@ Extract any modules into this folder.

## Things Modules can do:

* Provide template files
* Add or Override user commands or mob commands
* Save/Load their own data
* Track their own config values
* Modify help menu
* Add help aliases
* Add command aliases
* Listen for/Handle events
* Access the rest of the code
* Access core GoMud code.
* Listen for, handle and/or cancel events (See `modules/auctions`)
* For example, run custom code every `NewRound{}` event, or do something whenever a `LevelUp{}` event is fired.
* Handle Telnet IAC commands (See `modules/gmcp`)
* Add a handler for new connections (See `modules/gmcp`)
* Add web pages to default web site (See `modules/leaderboards`)
* Web page template with custom data
* (optional) Add navigation links
* (optional) provide any downloadable/linkable assets (images, files, etc)
* Add/Over-write existing template files (See `modules/auctions`)
* Add/Over-write help files (See `modules/auctions`)
* Add/Over-write user or mob commands (See `modules/auctions`)
* Save/Load their own data (See `modules/leaderboards`)
* Track their own config values (See `modules/leaderboards`)
* Modify help menu items, command aliases, help aliases (See `modules/leaderboards`)

# Examples

Expand Down
2 changes: 1 addition & 1 deletion modules/all-modules.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions modules/auctions/files/data-overlays/ansi-aliases.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
color8:
auction-banner: 12
color256:
auction-banner: 12
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

<ansi fg="blue-bold">*******************************************************************************</ansi>
<ansi fg="blue-bold">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>
<ansi fg="auction-banner">*******************************************************************************</ansi>
<ansi fg="auction-banner">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>

{{ if .Anonymous }}Someone{{ else }}<ansi fg="username">{{ .HighestBidderName }}</ansi>{{ end }} has bid <ansi fg="gold">{{ .HighestBid }} gold</ansi>

<ansi fg="blue-bold">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>
<ansi fg="blue-bold">*******************************************************************************</ansi>
<ansi fg="auction-banner">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>
<ansi fg="auction-banner">*******************************************************************************</ansi>

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<ansi fg="blue-bold">*******************************************************************************</ansi>
<ansi fg="blue-bold">* * * AUCTION END * AUCTION END * AUCTION END * AUCTION END * AUCTION END * * *</ansi>
<ansi fg="auction-banner">*******************************************************************************</ansi>
<ansi fg="auction-banner">* * * AUCTION END * AUCTION END * AUCTION END * AUCTION END * AUCTION END * * *</ansi>

<ansi fg="yellow">The auction has <ansi fg="white-bold">ENDED!</ansi></ansi>

Expand All @@ -12,6 +12,6 @@

Type <ansi fg="command">help auction</ansi> to learn more about auctions.

<ansi fg="blue-bold">* * * AUCTION END * AUCTION END * AUCTION END * AUCTION END * AUCTION END * * *</ansi>
<ansi fg="blue-bold">*******************************************************************************</ansi>
<ansi fg="auction-banner">* * * AUCTION END * AUCTION END * AUCTION END * AUCTION END * AUCTION END * * *</ansi>
<ansi fg="auction-banner">*******************************************************************************</ansi>

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<ansi fg="blue-bold">*******************************************************************************</ansi>
<ansi fg="blue-bold">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>
<ansi fg="auction-banner">*******************************************************************************</ansi>
<ansi fg="auction-banner">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>

<ansi fg="yellow-bold">An auction has started!</ansi>
<ansi fg="yellow">The auction will end in <ansi fg="white-bold">{{ secondsFrom .EndTime }} seconds</ansi>!</ansi>
Expand All @@ -14,6 +14,6 @@

<ansi fg="command">bid <ansi fg="gold">(gold amount)</ansi></ansi> to bid on this auction.

<ansi fg="blue-bold">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>
<ansi fg="blue-bold">*******************************************************************************</ansi>
<ansi fg="auction-banner">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>
<ansi fg="auction-banner">*******************************************************************************</ansi>

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<ansi fg="blue-bold">*******************************************************************************</ansi>
<ansi fg="blue-bold">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>
<ansi fg="auction-banner">*******************************************************************************</ansi>
<ansi fg="auction-banner">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>

<ansi fg="yellow">The auction will end in <ansi fg="white-bold">{{ secondsFrom .EndTime }} seconds</ansi>!</ansi>

Expand All @@ -14,6 +14,6 @@
{{ end }}
<ansi fg="command">bid <ansi fg="gold">(gold amount)</ansi></ansi> to bid on this auction.

<ansi fg="blue-bold">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>
<ansi fg="blue-bold">*******************************************************************************</ansi>
<ansi fg="auction-banner">* * * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * AUCTION * * *</ansi>
<ansi fg="auction-banner">*******************************************************************************</ansi>

Loading