diff --git a/cmd/lastmudserver/main.go b/cmd/lastmudserver/main.go index 3e9abda..6beb05a 100644 --- a/cmd/lastmudserver/main.go +++ b/cmd/lastmudserver/main.go @@ -9,8 +9,10 @@ import ( "syscall" "time" - "code.haedhutner.dev/mvv/LastMUD/internal/server" + "net/http" + _ "net/http/pprof" + "code.haedhutner.dev/mvv/LastMUD/internal/server" "golang.org/x/term" ) @@ -27,6 +29,10 @@ func main() { log.Fatal(err) } + go func() { + log.Println(http.ListenAndServe("localhost:6060", nil)) + }() + processInput() } diff --git a/internal/game/game.go b/internal/game/game.go index a3dba59..436de7e 100644 --- a/internal/game/game.go +++ b/internal/game/game.go @@ -15,21 +15,12 @@ import ( const TickRate = time.Duration(50 * time.Millisecond) -const MaxEnqueuedOutputPerTick = 100 - type GameOutput struct { connId uuid.UUID contents []byte closeConnection bool } -func (game *LastMUDGame) CreateOutput(connId uuid.UUID, contents []byte) GameOutput { - return GameOutput{ - connId: connId, - contents: contents, - } -} - func (g GameOutput) Id() uuid.UUID { return g.connId } @@ -55,7 +46,7 @@ func CreateGame(ctx context.Context, wg *sync.WaitGroup) (game *LastMUDGame) { game = &LastMUDGame{ wg: wg, ctx: ctx, - output: make(chan GameOutput, MaxEnqueuedOutputPerTick), + output: make(chan GameOutput), world: data.CreateGameWorld(), } @@ -67,6 +58,7 @@ func CreateGame(ctx context.Context, wg *sync.WaitGroup) (game *LastMUDGame) { return } +// Will block if no output present func (game *LastMUDGame) ConsumeNextOutput() *GameOutput { select { case output := <-game.output: diff --git a/internal/game/systems/commands.go b/internal/game/systems/commands.go index fe50c8f..99c0370 100644 --- a/internal/game/systems/commands.go +++ b/internal/game/systems/commands.go @@ -36,6 +36,10 @@ func handleSayCommand(world *ecs.World, delta time.Duration, player ecs.Entity, return createCommandError("Can't interpret message as string") } + if message == "" { + return nil + } + for p := range allPlayersInRoom { connId, _ := ecs.GetComponent[data.ConnectionIdComponent](world, p) diff --git a/internal/game/systems/systems.go b/internal/game/systems/systems.go index 48eacfb..2408e13 100644 --- a/internal/game/systems/systems.go +++ b/internal/game/systems/systems.go @@ -9,7 +9,7 @@ type SystemPriorityOffset = int const ( EventOffset = 0 - CommandOffset = 1000 + CommandOffset = 10000 ) func CreateSystems() []*ecs.System { @@ -17,7 +17,6 @@ func CreateSystems() []*ecs.System { ecs.CreateSystem("PlayerConnectEventHandler", EventOffset+0, CreateEventHandler(data.EventPlayerConnect, handlePlayerConnectEvent)), ecs.CreateSystem("PlayerDisconnectEventHandler", EventOffset+1, CreateEventHandler(data.EventPlayerDisconnect, handlePlayerDisconnectEvent)), ecs.CreateSystem("PlayerCommandEventHandler", EventOffset+2, CreateEventHandler(data.EventPlayerCommand, handlePlayerCommandEvent)), - // ecs.CreateSystem("PlayerSayEventHandler", EventOffset+3, CreateEventHandler(data.EventPlayerSpeak, handlePlayerSayEvent)), ecs.CreateSystem("ParseCommandEventHandler", EventOffset+4, CreateEventHandler(data.EventParseCommand, parseCommand)), ecs.CreateSystem("SayCommandHandler", CommandOffset+0, CreateCommandHandler(data.CommandSay, handleSayCommand)), ecs.CreateSystem("QuitCommandHandler", CommandOffset+1, CreateCommandHandler(data.CommandQuit, handleQuitCommand)), diff --git a/internal/logging/logging_test.go b/internal/logging/logging_test.go new file mode 100644 index 0000000..a283af6 --- /dev/null +++ b/internal/logging/logging_test.go @@ -0,0 +1,67 @@ +package logging + +import ( + "bytes" + "os" + "path/filepath" + "regexp" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestLogLevelString(t *testing.T) { + assert.Equal(t, "DBG", DBG.String()) + assert.Equal(t, "INF", INF.String()) + assert.Equal(t, "WRN", WRN.String()) + assert.Equal(t, "ERR", ERR.String()) + assert.Equal(t, "99", LogLevel(99).String()) +} + +func TestCreateLogger_NoFile(t *testing.T) { + logger := CreateLogger(DBG, INF, "", "2006-01-02 15:04:05.000", "2006-01-02_15-04-05") + assert.NotNil(t, logger) + assert.Nil(t, logger.file) + assert.Equal(t, DBG, logger.maxFileLevel) + assert.Equal(t, INF, logger.maxDisplayedLevel) +} + +func TestCreateLogger_WithFile(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "test.log") + logger := CreateLogger(DBG, DBG, path, "2006-01-02 15:04:05.000", "2006-01-02_15-04-05") + assert.NotNil(t, logger) + assert.NotNil(t, logger.file) +} + +func TestLoggerMethods(t *testing.T) { + buf := &bytes.Buffer{} + logger := &Logger{ + file: nil, + timestampFormat: DefaultTimeFormat, + maxFileLevel: DBG, + maxDisplayedLevel: DBG, + } + oldStdout := os.Stdout + r, w, _ := os.Pipe() + os.Stdout = w + logger.Debug("debug message") + logger.Info("info message") + logger.Warn("warn message") + logger.Error("error message") + w.Close() + os.Stdout = oldStdout + buf.ReadFrom(r) + output := buf.String() + assert.Contains(t, output, "debug message") + assert.Contains(t, output, "info message") + assert.Contains(t, output, "warn message") + assert.Contains(t, output, "error message") +} + +func TestAnsiStripRegex(t *testing.T) { + input := "\033[31mHello\033[0m" + re := regexp.MustCompile(`\x1b\[[0-9;]*m`) + output := re.ReplaceAllString(input, "") + assert.Equal(t, "Hello", output) +}