This commit is contained in:
Bruno Rybársky 2024-06-08 13:52:22 +02:00
parent 46f6c2cfec
commit 111564b666
7 changed files with 178 additions and 20 deletions

@ -6,18 +6,21 @@ import (
) )
type Client struct { type Client struct {
Client telnet.Client Client *telnet.Client
Username string Username string
ID int ID int
History []string History []string
HistoryIndex int HistoryIndex int
context telnet.Context context *telnet.Context
writer telnet.Writer writer *telnet.Writer
reader telnet.Reader reader *telnet.Reader
match *Match
isHost bool
hp int
// Add more fields as needed // Add more fields as needed
} }
func NewClient(context telnet.Context, writer telnet.Writer, reader telnet.Reader) int { func NewClient(context *telnet.Context, writer *telnet.Writer, reader *telnet.Reader) int {
client := Client{} client := Client{}
clientsMutex.Lock() clientsMutex.Lock()
@ -30,6 +33,8 @@ func NewClient(context telnet.Context, writer telnet.Writer, reader telnet.Reade
clients[clientID].context = context clients[clientID].context = context
clients[clientID].writer = writer clients[clientID].writer = writer
clients[clientID].reader = reader clients[clientID].reader = reader
clients[clientID].isHost = false
clients[clientID].hp = -1
return clientID return clientID
} }
@ -40,7 +45,12 @@ func RemoveClient(clientID int) {
} }
func (client Client) send(message string) { func (client Client) send(message string) {
client.writer.Write([]byte(message)) writer := *(client.writer)
writer.Write([]byte(message))
}
func (client Client) sendMessage(message string, sender *Client) {
client.send("\a\r\n<" + sender.Username + "(" + strconv.Itoa(sender.ID) + ")> " + message + "\r\n")
} }
func getIDByName(name string) int { func getIDByName(name string) int {
@ -53,3 +63,16 @@ func getIDByName(name string) int {
} }
return -1 return -1
} }
func getByIDOrName(by string) int {
//if integer assume clientID
var toClientID int
toClientID, err := strconv.Atoi(by)
if err != nil {
toClientID = getIDByName(by)
}
if toClientID < len(clients) && toClientID >= 0 {
return toClientID
}
return -1
}

@ -3,6 +3,7 @@ package main
import ( import (
"math/rand" "math/rand"
"strconv" "strconv"
"strings"
"sync" "sync"
) )
@ -39,9 +40,88 @@ func RegisterCommands(registry *CommandRegistry) {
registry.RegisterCommand("tell", TellClientCommand) registry.RegisterCommand("tell", TellClientCommand)
registry.RegisterCommand("clear", ClearCommand) registry.RegisterCommand("clear", ClearCommand)
registry.RegisterCommand("rng", RandomCommand) registry.RegisterCommand("rng", RandomCommand)
registry.RegisterCommand("challenge", StartCommand)
registry.RegisterCommand("accept", AcceptCommand)
registry.RegisterCommand("shoot", ShootCommand)
// Add more commands here... // Add more commands here...
} }
func ShootCommand(args []string, clientID int) string {
if clients[clientID].match.round >= 0 {
self := false
if len(args) == 1 {
if strings.ToLower(args[0]) == "self" {
self = true
} else if getByIDOrName(args[0]) == clientID {
self = true
}
}
var fired bool
if self {
fired = clients[clientID].match.gun.Shoot(clients[clientID])
if fired {
return "Shot self with a live"
} else {
return "Shot self with a blank"
}
} else {
if clients[clientID].isHost {
fired = clients[clientID].match.gun.Shoot(clients[clientID].match.guest)
} else {
fired = clients[clientID].match.gun.Shoot(clients[clientID].match.host)
}
if fired {
return "Shot " + args[0] + "with a live"
} else {
return "Shot " + args[0] + "with a blank"
}
}
}
return "Error"
}
func AcceptCommand(args []string, clientID int) string {
clientsMutex.Lock()
defer clientsMutex.Unlock()
matchesMutex.Lock()
defer matchesMutex.Unlock()
if clients[clientID].match.guest == clients[clientID] {
clients[clientID].match.round = 0
clients[clientID].match.host.sendMessage("Accepted", clients[clientID])
clients[clientID].isHost = false
clients[clientID].match.gun.Reload(8)
return "Accepted"
}
return "No match to accept"
}
func StartCommand(args []string, clientID int) string {
if len(args) == 1 {
targetID := getByIDOrName(args[0])
if targetID >= 0 {
match := Match{
host: clients[clientID],
guest: clients[targetID],
round: -1,
gun: Gun{
doubled: false,
},
}
clientsMutex.Lock()
clients[clientID].match = &match
clients[targetID].match = &match
clients[targetID].sendMessage("Type \"accept\" to accept a match.", clients[clientID])
clientsMutex.Unlock()
matchesMutex.Lock()
matches = append(matches, &match)
matchesMutex.Unlock()
} else {
return "Unknown user"
}
}
return "Invalid argument"
}
func HelpCommand(args []string, clientID int) string { func HelpCommand(args []string, clientID int) string {
// Handle help command // Handle help command
if len(clients) > 0 { if len(clients) > 0 {
@ -92,18 +172,9 @@ func ListClientsCommand(args []string, clientID int) string {
func TellClientCommand(args []string, clientID int) string { func TellClientCommand(args []string, clientID int) string {
message := "Message not delivered" message := "Message not delivered"
if len(args) >= 2 { if len(args) >= 2 {
clientTo := args[0] toClientID := getByIDOrName(args[0])
//if integer assume clientID if toClientID >= 0 {
var toClientID int toClientName := clients[toClientID].Username
var toClientName string
toClientID, err := strconv.Atoi(clientTo)
if err != nil {
toClientID = getIDByName(clientTo)
toClientName = clientTo
}
if toClientID < len(clients) && toClientID >= 0 {
toClientName = clients[toClientID].Username
myUsername := clients[clientID].Username
newMessage := "" newMessage := ""
//all the remaining arguments are a part of the message, join them with space //all the remaining arguments are a part of the message, join them with space
for i, arg := range args { for i, arg := range args {
@ -111,7 +182,7 @@ func TellClientCommand(args []string, clientID int) string {
newMessage += arg + " " newMessage += arg + " "
} }
} }
clients[toClientID].send("\a\r\n<" + myUsername + "(" + strconv.Itoa(clientID) + ")> " + newMessage + "\r\n") clients[toClientID].sendMessage(newMessage, clients[clientID])
return "Message sent to " + toClientName return "Message sent to " + toClientName
} else { } else {
message = "Invalid recipient" message = "Invalid recipient"

32
gun.go Normal file

@ -0,0 +1,32 @@
package main
import "math/rand"
type Gun struct {
doubled bool
magazine []bool
}
// fire
func (g Gun) Shoot(target *Client) bool {
shot := false
if g.magazine[len(g.magazine)-1] {
shot = true
if g.doubled {
target.hp -= 2
} else {
target.hp -= 1
}
}
g.magazine = g.magazine[:len(g.magazine)-1]
g.doubled = false
return shot
}
func (g Gun) Reload(count int) {
g.magazine = make([]bool, count)
for i := 0; i < count; i++ {
g.magazine[i] = rand.Intn(2) == 1
}
}

22
item.go Normal file

@ -0,0 +1,22 @@
package main
type Item struct {
kind int
match *Match
}
func (i Item) name() string {
switch i.kind {
case 0:
return "Doubler"
default:
return "None"
}
}
func (i Item) useItem(param1 int) {
switch i.kind {
case 0:
i.match.gun.doubled = true
}
}

@ -7,6 +7,8 @@ import (
var clients []*Client var clients []*Client
var clientsMutex sync.Mutex var clientsMutex sync.Mutex
var matches []*Match
var matchesMutex sync.Mutex
func main() { func main() {
addr := ":6969" addr := ":6969"

8
match.go Normal file

@ -0,0 +1,8 @@
package main
type Match struct {
host *Client
guest *Client
round int
gun Gun
}

@ -21,7 +21,7 @@ func NewInternalTerminalHandler(shellCharacter, welcomeMessage string, commandRe
} }
func (handler *InternalTerminalHandler) ServeTELNET(ctx telnet.Context, w telnet.Writer, r telnet.Reader) { func (handler *InternalTerminalHandler) ServeTELNET(ctx telnet.Context, w telnet.Writer, r telnet.Reader) {
clientID := NewClient(ctx, w, r) clientID := NewClient(&ctx, &w, &r)
defer RemoveClient(clientID) defer RemoveClient(clientID)
w.RawWrite([]byte{0xff, 0xfb, 0x03}) //send char by char w.RawWrite([]byte{0xff, 0xfb, 0x03}) //send char by char