1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
package game
import (
"fmt"
"strconv"
"strings"
"thirdcollapse/internal/net"
"thirdcollapse/internal/player"
)
func (g *Game) doOption(sess *net.Session, input string) {
p := sess.Player.(*player.Player)
if input == "" {
sess.WriteLine("")
table := &Table{
Columns: []string{"Option", "Value", "Valid", "Description"},
}
for _, def := range player.OptionDefs {
val := formatOptionValue(p, &def)
valid := formatValidValues(&def)
table.Rows = append(table.Rows, []string{def.Name, val, valid, def.Description})
}
for _, line := range table.Render(p.OptionBool("unicode")) {
sess.WriteLine(line)
}
return
}
parts := strings.Fields(input)
name := strings.ToLower(parts[0])
def := player.GetOptionDef(name)
if def == nil {
sess.WriteLine(fmt.Sprintf("\nUnknown option: %s", name))
return
}
if len(parts) == 1 {
val := formatOptionValue(p, def)
valid := formatValidValues(def)
sess.WriteLine(fmt.Sprintf("\n%s = %s [%s]", def.Name, val, valid))
sess.WriteLine(fmt.Sprintf(" %s", def.Description))
return
}
value := strings.ToLower(parts[1])
parsed, ok := parseOptionValue(def, value)
if !ok {
valid := formatValidValues(def)
sess.WriteLine(fmt.Sprintf("\nInvalid value for %s: %s [%s]", def.Name, value, valid))
return
}
if p.Options == nil {
p.Options = make(map[string]any)
}
p.Options[def.Name] = parsed
g.AccountStore.SaveCharacter(p)
sess.WriteLine(fmt.Sprintf("\n%s set to %s.", def.Name, formatOptionValue(p, def)))
}
func formatOptionValue(p *player.Player, def *player.OptionDef) string {
switch def.Type {
case player.OptBool:
if p.OptionBool(def.Name) {
return "on"
}
return "off"
case player.OptString:
return p.OptionString(def.Name)
case player.OptInt:
return strconv.Itoa(p.OptionInt(def.Name))
}
return ""
}
func formatValidValues(def *player.OptionDef) string {
switch def.Type {
case player.OptBool:
return "on/off"
case player.OptString:
if len(def.ValidValues) > 0 {
return strings.Join(def.ValidValues, "/")
}
return "string"
case player.OptInt:
return "num"
}
return ""
}
func parseOptionValue(def *player.OptionDef, input string) (any, bool) {
switch def.Type {
case player.OptBool:
switch input {
case "on", "true", "yes", "1":
return true, true
case "off", "false", "no", "0":
return false, true
}
return nil, false
case player.OptString:
if len(def.ValidValues) == 0 {
return input, true
}
for _, v := range def.ValidValues {
if strings.EqualFold(v, input) {
return v, true
}
}
return nil, false
case player.OptInt:
n, err := strconv.Atoi(input)
if err != nil {
return nil, false
}
return n, true
}
return nil, false
}
|