Update
This commit is contained in:
parent
4e195c6ba3
commit
bf471b4934
7
.idea/inspectionProfiles/Project_Default.xml
Normal file
7
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="GoContextTodo" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="GoUnnecessarilyExportedIdentifiers" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
@ -1,2 +1,3 @@
|
|||||||
# telnetroulette
|
# Telnet roulette
|
||||||
|
# Just like Buckshot Roulette, but in telnet
|
||||||
|
|
||||||
|
63
client.go
63
client.go
@ -2,10 +2,12 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/BRNSystems/go-telnet"
|
"github.com/BRNSystems/go-telnet"
|
||||||
|
"math/rand"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Client struct {
|
type client struct {
|
||||||
Client *telnet.Client
|
Client *telnet.Client
|
||||||
Username string
|
Username string
|
||||||
ID int
|
ID int
|
||||||
@ -14,15 +16,15 @@ type Client struct {
|
|||||||
context *telnet.Context
|
context *telnet.Context
|
||||||
writer *telnet.Writer
|
writer *telnet.Writer
|
||||||
reader *telnet.Reader
|
reader *telnet.Reader
|
||||||
match *Match
|
match *match
|
||||||
isHost bool
|
isHost bool
|
||||||
HP int
|
HP int
|
||||||
items []Item
|
items []item
|
||||||
// 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()
|
||||||
clients = append(clients, &client)
|
clients = append(clients, &client)
|
||||||
@ -39,19 +41,22 @@ func NewClient(context *telnet.Context, writer *telnet.Writer, reader *telnet.Re
|
|||||||
return clientID
|
return clientID
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveClient(clientID int) {
|
func removeClient(clientID int) {
|
||||||
clientsMutex.Lock()
|
clientsMutex.Lock()
|
||||||
defer clientsMutex.Unlock()
|
defer clientsMutex.Unlock()
|
||||||
clients = append(clients[:clientID], clients[clientID+1:]...)
|
clients = append(clients[:clientID], clients[clientID+1:]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client Client) send(message string) {
|
func (client *client) send(message string) {
|
||||||
writer := *(client.writer)
|
writer := *(client.writer)
|
||||||
writer.Write([]byte(message))
|
_, err := writer.Write([]byte(message))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client Client) sendMessage(message string, sender *Client) {
|
func (client *client) sendMessage(message string, sender *client) {
|
||||||
client.send("\a\r\n<" + sender.Username + "(" + strconv.Itoa(sender.ID) + ")> " + message + "\r\n")
|
client.send("\a\r\n<" + sender.getMentionName() + "> " + message + "\r\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getIDByName(name string) int {
|
func getIDByName(name string) int {
|
||||||
@ -77,3 +82,41 @@ func getByIDOrName(by string) int {
|
|||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (client *client) renderHP() string {
|
||||||
|
var graphic strings.Builder
|
||||||
|
graphic.WriteString(strconv.Itoa(client.HP) + " / " + strconv.Itoa(client.match.maxHP) + " ")
|
||||||
|
for i := 1; i <= client.match.maxHP; i++ {
|
||||||
|
if client.HP >= i {
|
||||||
|
graphic.WriteString("█")
|
||||||
|
} else {
|
||||||
|
graphic.WriteString("░")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return graphic.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *client) renderItems() string {
|
||||||
|
if len(client.items) > 0 {
|
||||||
|
var out strings.Builder
|
||||||
|
for i := 0; i < len(client.items); i++ {
|
||||||
|
name := client.items[i].name()
|
||||||
|
out.WriteString(strconv.Itoa(i) + " - " + name + "\r\n")
|
||||||
|
}
|
||||||
|
return "My items are:\r\n" + out.String()
|
||||||
|
} else {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *client) getMentionName() string {
|
||||||
|
return client.Username + "(" + strconv.Itoa(client.ID) + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *client) giveItem() {
|
||||||
|
client.items = append(client.items, item{
|
||||||
|
kind: rand.Intn(client.match.itemCount),
|
||||||
|
match: client.match,
|
||||||
|
owner: client,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
128
commands.go
128
commands.go
@ -7,34 +7,34 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Command struct {
|
type command struct {
|
||||||
commandHandlerFunc CommandHandlerFunc
|
commandHandlerFunc commandHandlerFunc
|
||||||
description string
|
description string
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommandHandlerFunc func(args []string, clientID int) string
|
type commandHandlerFunc func(args []string, clientID int) string
|
||||||
|
|
||||||
type CommandRegistry struct {
|
type commandRegistry struct {
|
||||||
commands map[string]Command
|
commands map[string]command
|
||||||
mutex sync.Mutex // Mutex to safely access commands map
|
mutex sync.Mutex // Mutex to safely access commands map
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCommandRegistry() *CommandRegistry {
|
func newCommandRegistry() *commandRegistry {
|
||||||
return &CommandRegistry{
|
return &commandRegistry{
|
||||||
commands: make(map[string]Command),
|
commands: make(map[string]command),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr *CommandRegistry) RegisterCommand(command string, handler CommandHandlerFunc, desc string) {
|
func (cr *commandRegistry) registerCommand(commandName string, handler commandHandlerFunc, desc string) {
|
||||||
cr.mutex.Lock()
|
cr.mutex.Lock()
|
||||||
defer cr.mutex.Unlock()
|
defer cr.mutex.Unlock()
|
||||||
cr.commands[command] = Command{
|
cr.commands[commandName] = command{
|
||||||
commandHandlerFunc: handler,
|
commandHandlerFunc: handler,
|
||||||
description: desc,
|
description: desc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr *CommandRegistry) GetCommandHandler(command string, clientID int) (CommandHandlerFunc, bool, int) {
|
func (cr *commandRegistry) getCommandHandler(command string, clientID int) (commandHandlerFunc, bool, int) {
|
||||||
cr.mutex.Lock()
|
cr.mutex.Lock()
|
||||||
defer cr.mutex.Unlock()
|
defer cr.mutex.Unlock()
|
||||||
commandEntry, ok := cr.commands[command]
|
commandEntry, ok := cr.commands[command]
|
||||||
@ -42,20 +42,33 @@ func (cr *CommandRegistry) GetCommandHandler(command string, clientID int) (Comm
|
|||||||
return handler, ok, clientID
|
return handler, ok, clientID
|
||||||
}
|
}
|
||||||
|
|
||||||
func RegisterCommands(registry *CommandRegistry) {
|
func registerCommands(registry *commandRegistry) {
|
||||||
registry.RegisterCommand("clear", ClearCommand, `Clears your screen (clear)`)
|
registry.registerCommand("clear", clearCommand, `Clears your screen (clear)`)
|
||||||
registry.RegisterCommand("setname", SetNameCommand, `Sets your name (setname yourname[string])`)
|
registry.registerCommand("setname", setNameCommand, `Sets your name (setname yourname[string])`)
|
||||||
registry.RegisterCommand("list", ListClientsCommand, `Lists clients (list)`)
|
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("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("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("challenge", startCommand, `Challenge a client (challenge client[id or string{username}])`)
|
||||||
registry.RegisterCommand("accept", AcceptCommand, `Accepts a challenge (accept)`)
|
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("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])`)
|
registry.registerCommand("useitem", useItemCommand, `Uses an item in a match (useitem index[number])`)
|
||||||
|
registry.registerCommand("status", statusCommand, `Prints the game status (status)`)
|
||||||
// Add more commands here...
|
// Add more commands here...
|
||||||
}
|
}
|
||||||
|
|
||||||
func UseItemCommand(args []string, clientID int) string {
|
func statusCommand(_ []string, clientID int) string {
|
||||||
|
if clients[clientID].match != nil && clients[clientID].match.round > 0 {
|
||||||
|
clients[clientID].match.announceHP()
|
||||||
|
clients[clientID].match.announceItems()
|
||||||
|
clients[clientID].match.announceRounds()
|
||||||
|
clients[clientID].match.announceTurn()
|
||||||
|
return ""
|
||||||
|
} else {
|
||||||
|
return "Not in match"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func useItemCommand(args []string, clientID int) string {
|
||||||
param := -1
|
param := -1
|
||||||
itemID := -1
|
itemID := -1
|
||||||
if len(args) >= 2 {
|
if len(args) >= 2 {
|
||||||
@ -73,17 +86,18 @@ func UseItemCommand(args []string, clientID int) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if itemID >= 0 && itemID < clients[clientID].match.itemCount {
|
if itemID >= 0 && itemID < clients[clientID].match.itemCount {
|
||||||
|
clients[clientID].match.sendMessage("\r\nUsing item "+clients[clientID].items[itemID].name(), clients[clientID])
|
||||||
clients[clientID].items[itemID].useItem(param)
|
clients[clientID].items[itemID].useItem(param)
|
||||||
clients[clientID].match.SendMessage("\r\nUsing item "+clients[clientID].items[itemID].name(), clients[clientID])
|
|
||||||
return "Used"
|
return "Used"
|
||||||
} else {
|
} else {
|
||||||
return "ERROR using item"
|
return "ERROR using item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ShootCommand(args []string, clientID int) string {
|
func shootCommand(args []string, clientID int) string {
|
||||||
if clients[clientID].match != nil && clients[clientID].match.round > 0 && clients[clientID].match.Guestturn != clients[clientID].isHost {
|
if clients[clientID].match != nil && clients[clientID].match.round > 0 {
|
||||||
defer clients[clientID].match.CheckStatus()
|
if clients[clientID].match.guestsTurn != clients[clientID].isHost {
|
||||||
|
defer clients[clientID].match.checkStatus()
|
||||||
defer clients[clientID].match.announceHP()
|
defer clients[clientID].match.announceHP()
|
||||||
defer clients[clientID].match.announceRounds()
|
defer clients[clientID].match.announceRounds()
|
||||||
self := false
|
self := false
|
||||||
@ -95,15 +109,15 @@ func ShootCommand(args []string, clientID int) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var fired int
|
var fired int
|
||||||
var target *Client
|
var target *client
|
||||||
if self {
|
if self {
|
||||||
target = clients[clientID]
|
target = clients[clientID]
|
||||||
fired, clients[clientID].match.gun.magazine = clients[clientID].match.gun.Shoot(target)
|
fired = clients[clientID].match.gun.shoot(target)
|
||||||
if fired == 1 {
|
if fired == 1 {
|
||||||
clients[clientID].match.Guestturn = clients[clientID].isHost
|
clients[clientID].match.guestsTurn = clients[clientID].isHost
|
||||||
clients[clientID].match.SendMessage("Shot myself with a live", clients[clientID])
|
clients[clientID].match.sendMessage("Shot myself with a live", clients[clientID])
|
||||||
} else {
|
} else {
|
||||||
clients[clientID].match.SendMessage("Shot myself with a blank", clients[clientID])
|
clients[clientID].match.sendMessage("Shot myself with a blank", clients[clientID])
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if clients[clientID].isHost {
|
if clients[clientID].isHost {
|
||||||
@ -111,21 +125,26 @@ func ShootCommand(args []string, clientID int) string {
|
|||||||
} else {
|
} else {
|
||||||
target = clients[clientID].match.host
|
target = clients[clientID].match.host
|
||||||
}
|
}
|
||||||
fired, clients[clientID].match.gun.magazine = clients[clientID].match.gun.Shoot(target)
|
fired = clients[clientID].match.gun.shoot(target)
|
||||||
if fired == 1 {
|
if fired == 1 {
|
||||||
clients[clientID].match.Guestturn = clients[clientID].isHost
|
clients[clientID].match.guestsTurn = clients[clientID].isHost
|
||||||
clients[clientID].match.SendMessage("Shot "+target.Username+"("+strconv.Itoa(target.ID)+")"+"with a live", clients[clientID])
|
clients[clientID].match.sendMessage("Shot "+target.Username+"("+strconv.Itoa(target.ID)+")"+"with a live", clients[clientID])
|
||||||
} else {
|
} else {
|
||||||
clients[clientID].match.Guestturn = clients[clientID].isHost
|
clients[clientID].match.guestsTurn = clients[clientID].isHost
|
||||||
clients[clientID].match.SendMessage("Shot "+target.Username+"("+strconv.Itoa(target.ID)+")"+"with a blank", clients[clientID])
|
clients[clientID].match.sendMessage("Shot "+target.Username+"("+strconv.Itoa(target.ID)+")"+"with a blank", clients[clientID])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "SHOT"
|
return "SHOT"
|
||||||
|
} else {
|
||||||
|
return "It is not your turn"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "Your are not in a match"
|
||||||
|
|
||||||
}
|
}
|
||||||
return "Error"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func AcceptCommand(args []string, clientID int) string {
|
func acceptCommand(_ []string, clientID int) string {
|
||||||
clientsMutex.Lock()
|
clientsMutex.Lock()
|
||||||
defer clientsMutex.Unlock()
|
defer clientsMutex.Unlock()
|
||||||
matchesMutex.Lock()
|
matchesMutex.Lock()
|
||||||
@ -133,28 +152,29 @@ func AcceptCommand(args []string, clientID int) string {
|
|||||||
if clients[clientID].match != nil && clients[clientID].match.guest == clients[clientID] {
|
if clients[clientID].match != nil && clients[clientID].match.guest == clients[clientID] {
|
||||||
clients[clientID].match.host.sendMessage("Accepted", clients[clientID])
|
clients[clientID].match.host.sendMessage("Accepted", clients[clientID])
|
||||||
clients[clientID].isHost = false
|
clients[clientID].isHost = false
|
||||||
clients[clientID].match.Guestturn = false
|
clients[clientID].match.guestsTurn = false
|
||||||
clients[clientID].match.Start()
|
clients[clientID].match.start()
|
||||||
return "Accepted"
|
return "Accepted"
|
||||||
}
|
}
|
||||||
return "No match to accept"
|
return "No match to accept"
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartCommand(args []string, clientID int) string {
|
func startCommand(args []string, clientID int) string {
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
targetID := getByIDOrName(args[0])
|
targetID := getByIDOrName(args[0])
|
||||||
if targetID >= 0 && targetID != clientID && (clients[clientID].match == nil || clients[clientID].match.round <= 0) {
|
if targetID >= 0 && targetID != clientID && (clients[clientID].match == nil || clients[clientID].match.round <= 0) {
|
||||||
match := Match{
|
match := match{
|
||||||
host: clients[clientID],
|
host: clients[clientID],
|
||||||
guest: clients[targetID],
|
guest: clients[targetID],
|
||||||
round: 0,
|
round: 0,
|
||||||
gun: Gun{
|
gun: gun{
|
||||||
doubled: false,
|
doubled: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
clientsMutex.Lock()
|
clientsMutex.Lock()
|
||||||
clients[clientID].match = &match
|
clients[clientID].match = &match
|
||||||
clients[targetID].match = &match
|
clients[targetID].match = &match
|
||||||
|
match.itemCount = 8
|
||||||
clients[clientID].isHost = true
|
clients[clientID].isHost = true
|
||||||
clients[targetID].sendMessage("Type \"accept\" to accept a match.", clients[clientID])
|
clients[targetID].sendMessage("Type \"accept\" to accept a match.", clients[clientID])
|
||||||
clientsMutex.Unlock()
|
clientsMutex.Unlock()
|
||||||
@ -169,7 +189,7 @@ func StartCommand(args []string, clientID int) string {
|
|||||||
return "Invalid argument"
|
return "Invalid argument"
|
||||||
}
|
}
|
||||||
|
|
||||||
func RandomCommand(args []string, clientID int) string {
|
func randomCommand(args []string, _ int) string {
|
||||||
// Handle help command
|
// Handle help command
|
||||||
if len(args) == 2 {
|
if len(args) == 2 {
|
||||||
from, err1 := strconv.Atoi(args[0])
|
from, err1 := strconv.Atoi(args[0])
|
||||||
@ -185,12 +205,12 @@ func RandomCommand(args []string, clientID int) string {
|
|||||||
return "No range provided"
|
return "No range provided"
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClearCommand(args []string, clientID int) string {
|
func clearCommand(_ []string, _ int) string {
|
||||||
// Handle help command
|
// Handle help command
|
||||||
return "\033[H\033[2J\033[K"
|
return "\033[H\033[2J\033[K"
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetNameCommand(args []string, clientID int) string {
|
func setNameCommand(args []string, clientID int) string {
|
||||||
// Handle help command
|
// Handle help command
|
||||||
if len(args) >= 1 {
|
if len(args) >= 1 {
|
||||||
newName := args[0]
|
newName := args[0]
|
||||||
@ -200,28 +220,28 @@ func SetNameCommand(args []string, clientID int) string {
|
|||||||
return "No name provided"
|
return "No name provided"
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListClientsCommand(args []string, clientID int) string {
|
func listClientsCommand(_ []string, _ int) string {
|
||||||
message := ""
|
var message strings.Builder
|
||||||
for i, client := range clients {
|
for i, client := range clients {
|
||||||
message += strconv.Itoa(i) + ": " + client.Username + "\n"
|
message.WriteString(strconv.Itoa(i) + ": " + client.Username + "\n")
|
||||||
}
|
}
|
||||||
return message
|
return message.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 {
|
||||||
toClientID := getByIDOrName(args[0])
|
toClientID := getByIDOrName(args[0])
|
||||||
if toClientID >= 0 {
|
if toClientID >= 0 {
|
||||||
toClientName := clients[toClientID].Username
|
toClientName := clients[toClientID].Username
|
||||||
newMessage := ""
|
var newMessage strings.Builder
|
||||||
//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 {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
newMessage += arg + " "
|
newMessage.WriteString(arg + " ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clients[toClientID].sendMessage(newMessage, clients[clientID])
|
clients[toClientID].sendMessage(newMessage.String(), clients[clientID])
|
||||||
return "Message sent to " + toClientName
|
return "Message sent to " + toClientName
|
||||||
} else {
|
} else {
|
||||||
message = "Invalid recipient"
|
message = "Invalid recipient"
|
||||||
|
22
gun.go
22
gun.go
@ -2,16 +2,15 @@ package main
|
|||||||
|
|
||||||
import "math/rand"
|
import "math/rand"
|
||||||
|
|
||||||
type Gun struct {
|
type gun struct {
|
||||||
doubled bool
|
doubled bool
|
||||||
magazine []bool
|
magazine []bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// fire
|
func (g *gun) shoot(target *client) int {
|
||||||
func (g Gun) Shoot(target *Client) (int, []bool) {
|
|
||||||
shot := 2
|
shot := 2
|
||||||
if len(g.magazine) == 0 {
|
if len(g.magazine) == 0 {
|
||||||
return shot, g.magazine
|
return shot
|
||||||
}
|
}
|
||||||
shot = 0
|
shot = 0
|
||||||
if g.magazine[len(g.magazine)-1] {
|
if g.magazine[len(g.magazine)-1] {
|
||||||
@ -21,25 +20,24 @@ func (g Gun) Shoot(target *Client) (int, []bool) {
|
|||||||
} else {
|
} else {
|
||||||
target.HP -= 1
|
target.HP -= 1
|
||||||
}
|
}
|
||||||
target.send("\a")
|
target.send("\a\a")
|
||||||
target.match.Send("")
|
target.match.send("")
|
||||||
}
|
}
|
||||||
|
|
||||||
g.magazine = g.Rack()
|
g.rack()
|
||||||
|
|
||||||
g.doubled = false
|
g.doubled = false
|
||||||
return shot, g.magazine
|
return shot
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Gun) Rack() []bool {
|
func (g *gun) rack() {
|
||||||
g.magazine = g.magazine[:len(g.magazine)-1]
|
g.magazine = g.magazine[:len(g.magazine)-1]
|
||||||
return g.magazine
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g Gun) Reload(count int) []bool {
|
func (g *gun) reload(count int) []bool {
|
||||||
g.magazine = make([]bool, count)
|
g.magazine = make([]bool, count)
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
g.magazine[i] = rand.Intn(6) <= 2
|
g.magazine[i] = rand.Int63()&(1<<62) == 0
|
||||||
}
|
}
|
||||||
return g.magazine
|
return g.magazine
|
||||||
}
|
}
|
||||||
|
129
item.go
129
item.go
@ -1,33 +1,144 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
type Item struct {
|
import (
|
||||||
|
"math"
|
||||||
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type item struct {
|
||||||
kind int
|
kind int
|
||||||
match *Match
|
match *match
|
||||||
owner *Client
|
owner *client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i Item) name() string {
|
func (i *item) name() string {
|
||||||
switch i.kind {
|
switch i.kind {
|
||||||
case 0:
|
case 0:
|
||||||
return "Doubler"
|
return "Saw"
|
||||||
case 1:
|
case 1:
|
||||||
return "Beer"
|
return "Beer"
|
||||||
|
case 2:
|
||||||
|
return "Phone"
|
||||||
|
case 3:
|
||||||
|
return "Magnifying glass"
|
||||||
|
case 4:
|
||||||
|
return "Expired medicine"
|
||||||
|
case 5:
|
||||||
|
return "Cigarette pack"
|
||||||
|
case 6:
|
||||||
|
return "Inverter"
|
||||||
|
case 7:
|
||||||
|
return "Adrenaline"
|
||||||
default:
|
default:
|
||||||
return "None"
|
return "None"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i Item) useItem(param1 int) {
|
func (i *item) useItem(param1 int) {
|
||||||
|
successfully := false
|
||||||
|
if i.owner.isHost != i.owner.match.guestsTurn {
|
||||||
|
|
||||||
|
successfully = true
|
||||||
switch i.kind {
|
switch i.kind {
|
||||||
case 0:
|
case 0:
|
||||||
i.match.gun.doubled = true
|
i.match.gun.doubled = true
|
||||||
i.match.SendMessage("I doubled the damage for 1 round", i.owner)
|
i.match.sendMessage("I doubled the damage for 1 round by sawing the shotgun", i.owner)
|
||||||
break
|
break
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
i.match.gun.Rack()
|
i.match.gun.rack()
|
||||||
i.match.SendMessage("I rack the magazine", i.owner)
|
i.match.sendMessage("I rack the magazine", i.owner)
|
||||||
i.match.announceRounds()
|
i.match.announceRounds()
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
roundIndex := rand.Intn(len(i.match.gun.magazine) - 2)
|
||||||
|
round := i.match.gun.magazine[roundIndex]
|
||||||
|
roundString := ""
|
||||||
|
if round {
|
||||||
|
roundString = "live"
|
||||||
|
} else {
|
||||||
|
roundString = "blank"
|
||||||
|
}
|
||||||
|
roundForPlayer := int(math.Abs(float64(len(i.match.gun.magazine) - 2 - roundIndex)))
|
||||||
|
i.match.sendMessage("I used a phone", i.owner)
|
||||||
|
i.owner.send("The " + strconv.Itoa(roundForPlayer) + " round from now is " + roundString)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
round := i.match.gun.magazine[len(i.match.gun.magazine)-1]
|
||||||
|
roundString := ""
|
||||||
|
if round {
|
||||||
|
roundString = "live"
|
||||||
|
} else {
|
||||||
|
roundString = "blank"
|
||||||
|
}
|
||||||
|
i.match.sendMessage("I used a magnifying glass", i.owner)
|
||||||
|
i.owner.send("Next round is " + roundString)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
if rand.Int63()&(1<<62) == 0 {
|
||||||
|
for cnt := 0; cnt < 2; cnt++ {
|
||||||
|
if i.owner.HP < i.match.maxHP {
|
||||||
|
i.owner.HP++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i.owner.HP--
|
||||||
|
i.match.announceHP()
|
||||||
|
i.match.checkStatus()
|
||||||
|
}
|
||||||
|
i.match.sendMessage("I used an expired medicine", i.owner)
|
||||||
|
i.match.announceHP()
|
||||||
|
break
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
if i.owner.HP < i.match.maxHP {
|
||||||
|
i.owner.HP++
|
||||||
|
}
|
||||||
|
i.match.sendMessage("I used a pack of cigarettes", i.owner)
|
||||||
|
i.match.announceHP()
|
||||||
|
break
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
i.match.gun.magazine[len(i.match.gun.magazine)-1] = !i.match.gun.magazine[len(i.match.gun.magazine)-1]
|
||||||
|
i.match.sendMessage("I used an inverter", i.owner)
|
||||||
|
break
|
||||||
|
case 7:
|
||||||
|
var otherPlayer *client
|
||||||
|
if i.owner.isHost {
|
||||||
|
otherPlayer = i.match.guest
|
||||||
|
} else {
|
||||||
|
otherPlayer = i.match.host
|
||||||
|
}
|
||||||
|
if param1 < len(otherPlayer.items) {
|
||||||
|
i.owner.items = append(i.owner.items, otherPlayer.items[param1])
|
||||||
|
otherPlayer.items = append(otherPlayer.items[:param1], otherPlayer.items[param1:]...)
|
||||||
|
itemName := otherPlayer.items[param1].name()
|
||||||
|
if itemName[0] == 'a' || itemName[0] == 'e' || itemName[0] == 'i' || itemName[0] == 'o' || itemName[0] == 'u' || itemName[0] == 'y' {
|
||||||
|
itemName = " an " + itemName
|
||||||
|
} else {
|
||||||
|
itemName = " a " + itemName
|
||||||
|
}
|
||||||
|
i.match.sendMessage("I stole from "+otherPlayer.Username+"("+strconv.Itoa(otherPlayer.ID)+")"+itemName, i.owner)
|
||||||
|
} else {
|
||||||
|
i.owner.send("This requires another parameter")
|
||||||
|
successfully = false
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i.owner.send("It is not your turn")
|
||||||
|
}
|
||||||
|
if successfully {
|
||||||
|
for cnt, item := range i.owner.items {
|
||||||
|
if item.kind == i.kind {
|
||||||
|
i.owner.items = append(i.owner.items[:cnt], i.owner.items[cnt+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i.match.announceItems()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
main.go
10
main.go
@ -5,15 +5,15 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
var clients []*Client
|
var clients []*client
|
||||||
var clientsMutex sync.Mutex
|
var clientsMutex sync.Mutex
|
||||||
var matches []*Match
|
var matches []*match
|
||||||
var matchesMutex sync.Mutex
|
var matchesMutex sync.Mutex
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
addr := ":6969"
|
addr := ":6969"
|
||||||
commandRegistry := NewCommandRegistry()
|
commandRegistry := newCommandRegistry()
|
||||||
termHandler := NewInternalTerminalHandler("# ",
|
termHandler := newInternalTerminalHandler("# ",
|
||||||
` ____ _ _ ____ _ _ _
|
` ____ _ _ ____ _ _ _
|
||||||
/ ___|| |__ ___ | |_ __ _ _ _ _ __ | _ \ ___ _ _| | ___| |_| |_ ___
|
/ ___|| |__ ___ | |_ __ _ _ _ _ __ | _ \ ___ _ _| | ___| |_| |_ ___
|
||||||
\___ \| '_ \ / _ \| __/ _`+"`"+` | | | | '_ \ | |_) / _ \| | | | |/ _ \ __| __/ _ \
|
\___ \| '_ \ / _ \| __/ _`+"`"+` | | | | '_ \ | |_) / _ \| | | | |/ _ \ __| __/ _ \
|
||||||
@ -23,7 +23,7 @@ func main() {
|
|||||||
commandRegistry)
|
commandRegistry)
|
||||||
|
|
||||||
// Register commands
|
// Register commands
|
||||||
RegisterCommands(commandRegistry)
|
registerCommands(commandRegistry)
|
||||||
|
|
||||||
if err := telnet.ListenAndServe(addr, termHandler); nil != err {
|
if err := telnet.ListenAndServe(addr, termHandler); nil != err {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
124
match.go
124
match.go
@ -1,62 +1,59 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Match struct {
|
type match struct {
|
||||||
host *Client
|
host *client
|
||||||
guest *Client
|
guest *client
|
||||||
round int
|
round int
|
||||||
|
maxHP int
|
||||||
itemCount int
|
itemCount int
|
||||||
gun Gun
|
gun gun
|
||||||
Guestturn bool
|
guestsTurn bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) LoadGun() {
|
func (m *match) loadGun() {
|
||||||
switch m.round {
|
switch m.round {
|
||||||
case 1:
|
case 1:
|
||||||
m.gun.magazine = m.gun.Reload(4)
|
m.gun.magazine = m.gun.reload(4)
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
m.gun.magazine = m.gun.Reload(8)
|
m.gun.magazine = m.gun.reload(8)
|
||||||
break
|
break
|
||||||
case 3:
|
case 3:
|
||||||
m.gun.magazine = m.gun.Reload(16)
|
m.gun.magazine = m.gun.reload(16)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
m.gun.magazine = m.gun.Reload(1)
|
m.gun.magazine = m.gun.reload(1)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) Start() {
|
func (m *match) start() {
|
||||||
m.NextRound()
|
m.nextRound()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) resetHP() {
|
func (m *match) resetHP() {
|
||||||
|
HP := 1
|
||||||
switch m.round {
|
switch m.round {
|
||||||
case 1:
|
case 1:
|
||||||
m.host.HP = 5
|
HP = 5
|
||||||
m.guest.HP = 5
|
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
m.host.HP = 2
|
HP = 2
|
||||||
m.guest.HP = 2
|
|
||||||
break
|
break
|
||||||
case 3:
|
case 3:
|
||||||
m.host.HP = 4
|
HP = 4
|
||||||
m.guest.HP = 4
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
m.host.HP = 1
|
|
||||||
m.guest.HP = 1
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
m.host.HP = HP
|
||||||
|
m.guest.HP = HP
|
||||||
|
m.maxHP = HP
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) announceRounds() {
|
func (m *match) announceRounds() {
|
||||||
live := 0
|
live := 0
|
||||||
blank := 0
|
blank := 0
|
||||||
for _, round := range m.gun.magazine {
|
for _, round := range m.gun.magazine {
|
||||||
@ -70,19 +67,19 @@ func (m *Match) announceRounds() {
|
|||||||
doubled := "Shotgun is normal"
|
doubled := "Shotgun is normal"
|
||||||
|
|
||||||
if m.gun.doubled {
|
if m.gun.doubled {
|
||||||
doubled = "Shotgun is doubled"
|
doubled = "Shotgun is sawed"
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Send("\r\nRounds are:\r\nLive - " + strconv.Itoa(live) + "\r\nBlank - " + strconv.Itoa(blank) + "\r\n" + doubled)
|
m.send("\r\nRounds are:\r\nLive - " + strconv.Itoa(live) + "\r\nBlank - " + strconv.Itoa(blank) + "\r\n" + doubled)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) announceHP() {
|
func (m *match) announceHP() {
|
||||||
m.Send("\r\nHPs are:\r\n" +
|
m.send("\r\nHPs are:\r\n" +
|
||||||
m.host.Username + "(" + strconv.Itoa(m.host.ID) + ")" + " - " + strconv.Itoa(m.host.HP) + "\r\n" +
|
m.host.getMentionName() + " - " + m.host.renderHP() + "\r\n" +
|
||||||
m.guest.Username + "(" + strconv.Itoa(m.guest.ID) + ")" + " - " + strconv.Itoa(m.guest.HP))
|
m.guest.getMentionName() + " - " + m.guest.renderHP())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) giveItems() {
|
func (m *match) giveItems() {
|
||||||
count := 0
|
count := 0
|
||||||
switch m.round {
|
switch m.round {
|
||||||
case 2:
|
case 2:
|
||||||
@ -94,42 +91,25 @@ func (m *Match) giveItems() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
for i := 0; i < count; i++ {
|
||||||
m.host.items = append(m.host.items, Item{
|
m.host.giveItem()
|
||||||
kind: rand.Intn(m.itemCount), //currently only item 0 exists
|
m.guest.giveItem()
|
||||||
match: m,
|
|
||||||
owner: m.host,
|
|
||||||
})
|
|
||||||
m.guest.items = append(m.host.items, Item{
|
|
||||||
kind: rand.Intn(m.itemCount), //currently only item 0 exists
|
|
||||||
match: m,
|
|
||||||
owner: m.guest,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) announceItems() {
|
func (m *match) announceItems() {
|
||||||
out := ""
|
m.sendMessage(m.host.renderItems(), m.host)
|
||||||
for i := 0; i < len(m.host.items); i++ {
|
m.sendMessage(m.guest.renderItems(), m.guest)
|
||||||
name := m.host.items[i].name()
|
|
||||||
out += strconv.Itoa(i) + " - " + name + "\r\n"
|
|
||||||
}
|
|
||||||
m.SendMessage("My items:\r\n"+out, m.host)
|
|
||||||
|
|
||||||
out = ""
|
|
||||||
for i := 0; i < len(m.guest.items); i++ {
|
|
||||||
name := m.guest.items[i].name()
|
|
||||||
out += strconv.Itoa(i) + " - " + name + "\r\n"
|
|
||||||
}
|
|
||||||
m.SendMessage("My items:\r\n"+out, m.guest)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) NextRound() bool {
|
func (m *match) nextRound() bool {
|
||||||
|
defer m.announceTurn()
|
||||||
defer m.announceItems()
|
defer m.announceItems()
|
||||||
defer m.announceRounds()
|
defer m.announceRounds()
|
||||||
defer m.announceHP()
|
defer m.announceHP()
|
||||||
defer m.LoadGun()
|
defer m.loadGun()
|
||||||
defer m.resetHP()
|
defer m.resetHP()
|
||||||
defer m.giveItems()
|
defer m.giveItems()
|
||||||
|
m.guestsTurn = false
|
||||||
if m.round < 3 {
|
if m.round < 3 {
|
||||||
m.round++
|
m.round++
|
||||||
} else if m.round == 3 {
|
} else if m.round == 3 {
|
||||||
@ -138,42 +118,42 @@ func (m *Match) NextRound() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) Send(message string) {
|
func (m *match) send(message string) {
|
||||||
m.host.sendMessage(message, m.host)
|
m.host.sendMessage(message, m.host)
|
||||||
m.guest.sendMessage(message, m.guest)
|
m.guest.sendMessage(message, m.guest)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) SendMessage(message string, sender *Client) {
|
func (m *match) sendMessage(message string, sender *client) {
|
||||||
m.host.sendMessage(message, sender)
|
m.host.sendMessage(message, sender)
|
||||||
m.guest.sendMessage(message, sender)
|
m.guest.sendMessage(message, sender)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) announceTurn() {
|
func (m *match) announceTurn() {
|
||||||
if m.Guestturn {
|
if m.guestsTurn {
|
||||||
m.guest.sendMessage("It is your turn to shoot", m.host)
|
m.guest.sendMessage("It is your turn\a", m.host)
|
||||||
} else {
|
} else {
|
||||||
m.host.sendMessage("It is your turn to shoot", m.guest)
|
m.host.sendMessage("It is your turn\a", m.guest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Match) CheckStatus() {
|
func (m *match) checkStatus() {
|
||||||
if m.host.HP < 1 {
|
if m.host.HP < 1 {
|
||||||
m.SendMessage("I died", m.host)
|
m.sendMessage("I died", m.host)
|
||||||
m.SendMessage("I won", m.guest)
|
m.sendMessage("I won", m.guest)
|
||||||
}
|
}
|
||||||
if m.guest.HP < 1 {
|
if m.guest.HP < 1 {
|
||||||
m.SendMessage("I died", m.guest)
|
m.sendMessage("I died", m.guest)
|
||||||
m.SendMessage("I won", m.host)
|
m.sendMessage("I won", m.host)
|
||||||
}
|
}
|
||||||
if m.host.HP > 0 && m.guest.HP > 0 {
|
if m.host.HP > 0 && m.guest.HP > 0 {
|
||||||
if m.round >= 3 {
|
if m.round >= 3 {
|
||||||
m.SendMessage("I won", m.host)
|
m.sendMessage("I won", m.host)
|
||||||
m.SendMessage("I won", m.guest)
|
m.sendMessage("I won", m.guest)
|
||||||
} else {
|
} else {
|
||||||
m.announceTurn()
|
m.announceTurn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(m.gun.magazine) == 0 {
|
if len(m.gun.magazine) == 0 {
|
||||||
m.NextRound()
|
m.nextRound()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,29 +6,48 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InternalTerminalHandler struct {
|
type internalTerminalHandler struct {
|
||||||
ShellCharacter string
|
ShellCharacter string
|
||||||
WelcomeMessage string
|
WelcomeMessage string
|
||||||
CommandRegistry *CommandRegistry
|
CommandRegistry *commandRegistry
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInternalTerminalHandler(shellCharacter, welcomeMessage string, commandRegistry *CommandRegistry) *InternalTerminalHandler {
|
func newInternalTerminalHandler(shellCharacter, welcomeMessage string, commandRegistry *commandRegistry) *internalTerminalHandler {
|
||||||
return &InternalTerminalHandler{
|
return &internalTerminalHandler{
|
||||||
ShellCharacter: shellCharacter,
|
ShellCharacter: shellCharacter,
|
||||||
WelcomeMessage: welcomeMessage,
|
WelcomeMessage: welcomeMessage,
|
||||||
CommandRegistry: commandRegistry,
|
CommandRegistry: commandRegistry,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *InternalTerminalHandler) ServeTELNET(ctx telnet.Context, w telnet.Writer, r telnet.Reader) {
|
func clearLine(w telnet.Writer) {
|
||||||
clientID := NewClient(&ctx, &w, &r)
|
_, err := w.RawWrite([]byte{0x1B, 0x5B, 0x4B})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defer RemoveClient(clientID)
|
func (handler *internalTerminalHandler) ServeTELNET(ctx telnet.Context, w telnet.Writer, r telnet.Reader) {
|
||||||
w.RawWrite([]byte{0xff, 0xfb, 0x03}) //send char by char
|
clientID := newClient(&ctx, &w, &r)
|
||||||
w.RawWrite([]byte{0xff, 0xfb, 0x01}) //echo from server
|
|
||||||
w.Write([]byte(strings.ReplaceAll(handler.WelcomeMessage, "\n", "\r\n") + "\r\n"))
|
defer removeClient(clientID)
|
||||||
|
_, err := w.RawWrite([]byte{0xff, 0xfb, 0x03})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
} //send char by char
|
||||||
|
_, err = w.RawWrite([]byte{0xff, 0xfb, 0x01})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
} //echo from server
|
||||||
|
_, err = w.Write([]byte(strings.ReplaceAll(handler.WelcomeMessage, "\n", "\r\n") + "\r\n"))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
//replace every \n with \r\n in WelcomeMessage
|
//replace every \n with \r\n in WelcomeMessage
|
||||||
w.Write([]byte(handler.ShellCharacter))
|
_, err = w.Write([]byte(handler.ShellCharacter))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var lineBuffer []byte
|
var lineBuffer []byte
|
||||||
|
|
||||||
@ -56,8 +75,11 @@ func (handler *InternalTerminalHandler) ServeTELNET(ctx telnet.Context, w telnet
|
|||||||
clients[clientID].HistoryIndex++
|
clients[clientID].HistoryIndex++
|
||||||
}
|
}
|
||||||
lineBuffer = []byte(clients[clientID].History[clients[clientID].HistoryIndex])
|
lineBuffer = []byte(clients[clientID].History[clients[clientID].HistoryIndex])
|
||||||
w.RawWrite([]byte{0x1B, 0x5B, 0x4B}) //clear line
|
clearLine(w)
|
||||||
w.Write(lineBuffer)
|
_, err := w.Write(lineBuffer)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if CSISequence == 2 && b == 'B' {
|
} else if CSISequence == 2 && b == 'B' {
|
||||||
if len(lineBuffer) == 0 && len(clients[clientID].History) > 0 {
|
if len(lineBuffer) == 0 && len(clients[clientID].History) > 0 {
|
||||||
@ -65,23 +87,35 @@ func (handler *InternalTerminalHandler) ServeTELNET(ctx telnet.Context, w telnet
|
|||||||
clients[clientID].HistoryIndex--
|
clients[clientID].HistoryIndex--
|
||||||
}
|
}
|
||||||
lineBuffer = []byte(clients[clientID].History[clients[clientID].HistoryIndex])
|
lineBuffer = []byte(clients[clientID].History[clients[clientID].HistoryIndex])
|
||||||
w.RawWrite([]byte{0x1B, 0x5B, 0x4B}) //clear line
|
clearLine(w)
|
||||||
w.Write(lineBuffer)
|
_, err := w.Write(lineBuffer)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if b == 0x7F {
|
} else if b == 0x7F {
|
||||||
if len(lineBuffer) > 0 {
|
if len(lineBuffer) > 0 {
|
||||||
w.Write([]byte{0x08, 0x20, 0x08})
|
_, err := w.Write([]byte{0x08, 0x20, 0x08})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
lineBuffer = lineBuffer[:len(lineBuffer)-1]
|
lineBuffer = lineBuffer[:len(lineBuffer)-1]
|
||||||
}
|
}
|
||||||
} else if b != '\r' && b != '\n' && b != 0 {
|
} else if b != '\r' && b != '\n' && b != 0 {
|
||||||
CSISequence = 0
|
CSISequence = 0
|
||||||
lineBuffer = append(lineBuffer, b)
|
lineBuffer = append(lineBuffer, b)
|
||||||
w.RawWrite([]byte{b})
|
_, err := w.RawWrite([]byte{b})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
} else if b == '\r' {
|
} else if b == '\r' {
|
||||||
w.Write([]byte("\r\n"))
|
_, err := w.Write([]byte("\r\n"))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
command := string(lineBuffer)
|
command := string(lineBuffer)
|
||||||
args := strings.Fields(command)
|
args := strings.Fields(command)
|
||||||
var message string
|
var message strings.Builder
|
||||||
|
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
cmd := args[0]
|
cmd := args[0]
|
||||||
@ -91,32 +125,35 @@ func (handler *InternalTerminalHandler) ServeTELNET(ctx telnet.Context, w telnet
|
|||||||
return
|
return
|
||||||
} else if cmd == "help" {
|
} else if cmd == "help" {
|
||||||
internalCommand = true
|
internalCommand = true
|
||||||
commands := ""
|
var commands strings.Builder
|
||||||
for command, commandEntry := range handler.CommandRegistry.commands {
|
for command, commandEntry := range handler.CommandRegistry.commands {
|
||||||
commands += command + " - " + commandEntry.description + "\r\n"
|
commands.WriteString(command + " - " + commandEntry.description + "\r\n")
|
||||||
}
|
}
|
||||||
// Handle help command
|
// Handle help command
|
||||||
if len(clients) > 0 {
|
if len(clients) > 0 {
|
||||||
clients[clientID].send("Just help yourself, " + clients[clientID].Username + "\r\nCommands:\r\n" + commands)
|
clients[clientID].send("Just help yourself, " + clients[clientID].Username + "\r\nCommands:\r\n" + commands.String())
|
||||||
} else {
|
} else {
|
||||||
clients[clientID].send("No clients available" + "\r\nCommands:\r\n" + commands)
|
clients[clientID].send("No clients available" + "\r\nCommands:\r\n" + commands.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handlerFunc, ok, clientID := handler.CommandRegistry.GetCommandHandler(cmd, clientID)
|
handlerFunc, ok, clientID := handler.CommandRegistry.getCommandHandler(cmd, clientID)
|
||||||
clients[clientID].HistoryIndex = 0
|
clients[clientID].HistoryIndex = 0
|
||||||
if ok || internalCommand {
|
if ok || internalCommand {
|
||||||
if ok {
|
if ok {
|
||||||
message = handlerFunc(args[1:], clientID)
|
message.WriteString(handlerFunc(args[1:], clientID))
|
||||||
}
|
}
|
||||||
clients[clientID].History = append(clients[clientID].History, command)
|
clients[clientID].History = append(clients[clientID].History, command)
|
||||||
} else {
|
} else {
|
||||||
message = "Command not found"
|
message.WriteString("Command not found")
|
||||||
}
|
}
|
||||||
message += "\n" + handler.ShellCharacter
|
message.WriteString("\n" + handler.ShellCharacter)
|
||||||
} else {
|
} else {
|
||||||
message = handler.ShellCharacter
|
message.WriteString(handler.ShellCharacter)
|
||||||
|
}
|
||||||
|
_, err = oi.LongWrite(w, []byte(strings.ReplaceAll(message.String(), "\n", "\r\n")))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
oi.LongWrite(w, []byte(strings.ReplaceAll(message, "\n", "\r\n")))
|
|
||||||
lineBuffer = nil
|
lineBuffer = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
util.go
13
util.go
@ -1,14 +1 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
func isInt(s string) bool {
|
|
||||||
for _, c := range s {
|
|
||||||
if !unicode.IsDigit(c) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user