telnetroulette/commands.go

232 lines
7.0 KiB
Go
Raw Normal View History

2024-06-08 11:52:12 +02:00
package main
import (
"math/rand"
"strconv"
2024-06-08 13:52:22 +02:00
"strings"
2024-06-08 11:52:12 +02:00
"sync"
)
2024-06-08 23:23:20 +02:00
type Command struct {
commandHandlerFunc CommandHandlerFunc
description string
}
2024-06-08 11:52:12 +02:00
type CommandHandlerFunc func(args []string, clientID int) string
type CommandRegistry struct {
2024-06-08 23:23:20 +02:00
commands map[string]Command
2024-06-08 11:52:12 +02:00
mutex sync.Mutex // Mutex to safely access commands map
}
func NewCommandRegistry() *CommandRegistry {
return &CommandRegistry{
2024-06-08 23:23:20 +02:00
commands: make(map[string]Command),
2024-06-08 11:52:12 +02:00
}
}
2024-06-08 23:23:20 +02:00
func (cr *CommandRegistry) RegisterCommand(command string, handler CommandHandlerFunc, desc string) {
2024-06-08 11:52:12 +02:00
cr.mutex.Lock()
defer cr.mutex.Unlock()
2024-06-08 23:23:20 +02:00
cr.commands[command] = Command{
commandHandlerFunc: handler,
description: desc,
}
2024-06-08 11:52:12 +02:00
}
func (cr *CommandRegistry) GetCommandHandler(command string, clientID int) (CommandHandlerFunc, bool, int) {
cr.mutex.Lock()
defer cr.mutex.Unlock()
2024-06-08 23:23:20 +02:00
commandEntry, ok := cr.commands[command]
handler := commandEntry.commandHandlerFunc
2024-06-08 11:52:12 +02:00
return handler, ok, clientID
}
func RegisterCommands(registry *CommandRegistry) {
2024-06-08 23:23:20 +02:00
registry.RegisterCommand("clear", ClearCommand, `Clears your screen (clear)`)
registry.RegisterCommand("setname", SetNameCommand, `Sets your name (setname yourname[string])`)
registry.RegisterCommand("list", ListClientsCommand, `Lists clients (list)`)
registry.RegisterCommand("rng", RandomCommand, `Generates a random integer (rng from[int] to[int{bigger than from}], both need to be above zero)`)
registry.RegisterCommand("tell", TellClientCommand, `Tell a client (tell client[id or string{username}])`)
registry.RegisterCommand("challenge", StartCommand, `Challenge a client (challenge client[id or string{username}])`)
registry.RegisterCommand("accept", AcceptCommand, `Accepts a challenge (accept)`)
registry.RegisterCommand("shoot", ShootCommand, `Shoots at a client (shoot target[int or string], accepts self as a parameter) {Shooting self with a blank keeps your turn}`)
registry.RegisterCommand("useitem", UseItemCommand, `Uses an item in a match (useitem index[number])`)
2024-06-08 11:52:12 +02:00
// Add more commands here...
}
2024-06-08 23:23:20 +02:00
func UseItemCommand(args []string, clientID int) string {
param := -1
itemID := -1
if len(args) >= 2 {
var err error
param, err = strconv.Atoi(args[1])
if err != nil {
param = -1
}
}
if len(args) >= 1 {
var err error
itemID, err = strconv.Atoi(args[0])
if err != nil {
itemID = -1
}
}
if itemID >= 0 && itemID < clients[clientID].match.itemCount {
clients[clientID].items[itemID].useItem(param)
clients[clientID].match.SendMessage("\r\nUsing item "+clients[clientID].items[itemID].name(), clients[clientID])
return "Used"
} else {
return "ERROR using item"
}
}
2024-06-08 13:52:22 +02:00
func ShootCommand(args []string, clientID int) string {
2024-06-08 23:23:20 +02:00
if clients[clientID].match != nil && clients[clientID].match.round > 0 && clients[clientID].match.Guestturn != clients[clientID].isHost {
defer clients[clientID].match.CheckStatus()
defer clients[clientID].match.announceHP()
defer clients[clientID].match.announceRounds()
2024-06-08 13:52:22 +02:00
self := false
if len(args) == 1 {
if strings.ToLower(args[0]) == "self" {
self = true
} else if getByIDOrName(args[0]) == clientID {
self = true
}
}
2024-06-08 23:23:20 +02:00
var fired int
var target *Client
2024-06-08 13:52:22 +02:00
if self {
2024-06-08 23:23:20 +02:00
target = clients[clientID]
fired, clients[clientID].match.gun.magazine = clients[clientID].match.gun.Shoot(target)
if fired == 1 {
clients[clientID].match.Guestturn = clients[clientID].isHost
clients[clientID].match.SendMessage("Shot myself with a live", clients[clientID])
2024-06-08 13:52:22 +02:00
} else {
2024-06-08 23:23:20 +02:00
clients[clientID].match.SendMessage("Shot myself with a blank", clients[clientID])
2024-06-08 13:52:22 +02:00
}
} else {
if clients[clientID].isHost {
2024-06-08 23:23:20 +02:00
target = clients[clientID].match.guest
2024-06-08 13:52:22 +02:00
} else {
2024-06-08 23:23:20 +02:00
target = clients[clientID].match.host
2024-06-08 13:52:22 +02:00
}
2024-06-08 23:23:20 +02:00
fired, clients[clientID].match.gun.magazine = clients[clientID].match.gun.Shoot(target)
if fired == 1 {
clients[clientID].match.Guestturn = clients[clientID].isHost
clients[clientID].match.SendMessage("Shot "+target.Username+"("+strconv.Itoa(target.ID)+")"+"with a live", clients[clientID])
2024-06-08 13:52:22 +02:00
} else {
2024-06-08 23:23:20 +02:00
clients[clientID].match.Guestturn = clients[clientID].isHost
clients[clientID].match.SendMessage("Shot "+target.Username+"("+strconv.Itoa(target.ID)+")"+"with a blank", clients[clientID])
2024-06-08 13:52:22 +02:00
}
}
2024-06-08 23:23:20 +02:00
return "SHOT"
2024-06-08 13:52:22 +02:00
}
return "Error"
}
func AcceptCommand(args []string, clientID int) string {
clientsMutex.Lock()
defer clientsMutex.Unlock()
matchesMutex.Lock()
defer matchesMutex.Unlock()
2024-06-08 23:23:20 +02:00
if clients[clientID].match != nil && clients[clientID].match.guest == clients[clientID] {
2024-06-08 13:52:22 +02:00
clients[clientID].match.host.sendMessage("Accepted", clients[clientID])
clients[clientID].isHost = false
2024-06-08 23:23:20 +02:00
clients[clientID].match.Guestturn = false
clients[clientID].match.Start()
2024-06-08 13:52:22 +02:00
return "Accepted"
}
return "No match to accept"
}
func StartCommand(args []string, clientID int) string {
if len(args) == 1 {
targetID := getByIDOrName(args[0])
2024-06-08 23:23:20 +02:00
if targetID >= 0 && targetID != clientID && (clients[clientID].match == nil || clients[clientID].match.round <= 0) {
2024-06-08 13:52:22 +02:00
match := Match{
host: clients[clientID],
guest: clients[targetID],
2024-06-08 23:23:20 +02:00
round: 0,
2024-06-08 13:52:22 +02:00
gun: Gun{
doubled: false,
},
}
clientsMutex.Lock()
clients[clientID].match = &match
clients[targetID].match = &match
2024-06-08 23:23:20 +02:00
clients[clientID].isHost = true
2024-06-08 13:52:22 +02:00
clients[targetID].sendMessage("Type \"accept\" to accept a match.", clients[clientID])
clientsMutex.Unlock()
matchesMutex.Lock()
matches = append(matches, &match)
matchesMutex.Unlock()
2024-06-08 23:23:20 +02:00
return "Successfully challenged"
2024-06-08 13:52:22 +02:00
} else {
return "Unknown user"
}
}
return "Invalid argument"
}
2024-06-08 11:52:12 +02:00
func RandomCommand(args []string, clientID int) string {
// Handle help command
if len(args) == 2 {
from, err1 := strconv.Atoi(args[0])
to, err2 := strconv.Atoi(args[1])
if err1 != nil || err2 != nil {
return "Invalid argument"
}
if to-from <= 0 {
return "Invalid range"
}
return "The number is " + strconv.Itoa(rand.Intn(to-from)+from)
}
return "No range provided"
}
func ClearCommand(args []string, clientID int) string {
// Handle help command
return "\033[H\033[2J\033[K"
}
func SetNameCommand(args []string, clientID int) string {
// Handle help command
2024-06-08 23:23:20 +02:00
if len(args) >= 1 {
2024-06-08 11:52:12 +02:00
newName := args[0]
clients[clientID].Username = newName
return "Name set to " + newName
}
return "No name provided"
}
func ListClientsCommand(args []string, clientID int) string {
message := ""
for i, client := range clients {
message += strconv.Itoa(i) + ": " + client.Username + "\n"
}
return message
}
func TellClientCommand(args []string, clientID int) string {
message := "Message not delivered"
if len(args) >= 2 {
2024-06-08 13:52:22 +02:00
toClientID := getByIDOrName(args[0])
if toClientID >= 0 {
toClientName := clients[toClientID].Username
2024-06-08 11:52:12 +02:00
newMessage := ""
//all the remaining arguments are a part of the message, join them with space
for i, arg := range args {
if i > 0 {
newMessage += arg + " "
}
}
2024-06-08 13:52:22 +02:00
clients[toClientID].sendMessage(newMessage, clients[clientID])
2024-06-08 11:52:12 +02:00
return "Message sent to " + toClientName
} else {
message = "Invalid recipient"
}
}
return message
}