106 lines
3 KiB
Go
106 lines
3 KiB
Go
package command
|
|
|
|
import (
|
|
"code.haedhutner.dev/mvv/LastMUD/internal/game/logic/world"
|
|
"code.haedhutner.dev/mvv/LastMUD/internal/logging"
|
|
"regexp"
|
|
"time"
|
|
|
|
"code.haedhutner.dev/mvv/LastMUD/internal/ecs"
|
|
"code.haedhutner.dev/mvv/LastMUD/internal/game/data"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
func HandleSay(w *ecs.World, _ time.Duration, player ecs.Entity, args data.ArgsMap) (err error) {
|
|
playerRoom, ok := ecs.GetComponent[data.InRoomComponent](w, player)
|
|
|
|
if !ok {
|
|
return createCommandError("You aren't in a room!")
|
|
}
|
|
|
|
playerName, ok := ecs.GetComponent[data.NameComponent](w, player)
|
|
|
|
if !ok {
|
|
return createCommandError("You have no name!")
|
|
}
|
|
|
|
allPlayersInRoom := ecs.QueryEntitiesWithComponent(w, func(comp data.InRoomComponent) bool {
|
|
return comp.Room == playerRoom.Room
|
|
})
|
|
|
|
message, err := arg[string](args, data.ArgMessageContent)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if message == "" {
|
|
return nil
|
|
}
|
|
|
|
for p := range allPlayersInRoom {
|
|
world.SendMessageToPlayer(w, p, playerName.Name+": "+message)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func HandleQuit(w *ecs.World, _ time.Duration, player ecs.Entity, _ data.ArgsMap) (err error) {
|
|
connId, _ := ecs.GetComponent[data.ConnectionIdComponent](w, player)
|
|
|
|
world.CreateClosingGameOutput(w, connId.ConnectionId, []byte("Goodbye!"))
|
|
|
|
return
|
|
}
|
|
|
|
var usernameRegex = regexp.MustCompile(`^[a-zA-Z0-9_-]{1,16}$`)
|
|
var passwordRegex = regexp.MustCompile(`^[a-zA-Z0-9!@#$%^&*()_+\-=\[\]{}|;:',.<>/?]{6,12}$`)
|
|
|
|
func HandleRegister(w *ecs.World, delta time.Duration, player ecs.Entity, args data.ArgsMap) (err error) {
|
|
accountName, err := arg[string](args, data.ArgAccountName)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !usernameRegex.MatchString(accountName) {
|
|
world.SendMessageToPlayer(w, player, "Registration: Username must only contain letters, numbers, dashes (-) and underscores (_), and be at most 16 characters in length.")
|
|
return
|
|
}
|
|
|
|
accountPassword, err := arg[string](args, data.ArgAccountPassword)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if !passwordRegex.MatchString(accountPassword) {
|
|
world.SendMessageToPlayer(w, player, "Registration: Password must be between 6 and 12 characters in length")
|
|
return
|
|
}
|
|
|
|
// TODO: Validate username doesn't exist already
|
|
|
|
encryptedPassword, err := bcrypt.GenerateFromPassword([]byte(accountPassword), bcrypt.DefaultCost)
|
|
|
|
account := world.CreateAccount(w, accountName, encryptedPassword)
|
|
|
|
ecs.SetComponent(w, player, data.AccountComponent{Account: account})
|
|
|
|
world.SendMessageToPlayer(w, player, "Account created successfully! Welcome to LastMUD!")
|
|
|
|
defaultRoom, err := ecs.GetResource[ecs.Entity](w, data.ResourceDefaultRoom)
|
|
|
|
if err != nil {
|
|
logging.Error("Unable to locate default room")
|
|
world.SendMessageToPlayer(w, player, "Welcome to LastMUD! Your account was created, but you could not be joined to a room. Please try again later!")
|
|
return
|
|
}
|
|
|
|
ecs.SetComponent(w, player, data.NameComponent{Name: accountName})
|
|
ecs.SetComponent(w, player, data.InRoomComponent{Room: defaultRoom})
|
|
ecs.SetComponent(w, player, data.PlayerStateComponent{State: data.PlayerStatePlaying})
|
|
|
|
return
|
|
}
|