main.go 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. package main
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "log"
  7. "os"
  8. "path/filepath"
  9. "strings"
  10. "time"
  11. door "git.red-green.com/RedGreen/doorgo"
  12. )
  13. var (
  14. d door.Door
  15. udb *UserDB
  16. u *User
  17. )
  18. func SaveTemp() {
  19. if d.Disconnected || udb == nil || u == nil {
  20. return
  21. }
  22. stat, err := os.Stat("nodes")
  23. if err != nil {
  24. if errors.Is(err, os.ErrNotExist) {
  25. err = os.Mkdir("nodes", 0775)
  26. if err != nil {
  27. fmt.Println("Err", err)
  28. return
  29. }
  30. } else {
  31. fmt.Println("Err", err)
  32. return
  33. }
  34. } else if !stat.IsDir() {
  35. err = os.Remove("nodes")
  36. if err != nil {
  37. fmt.Println("Err", err)
  38. return
  39. }
  40. err = os.Mkdir("nodes", 0775)
  41. if err != nil {
  42. fmt.Println("Err", err)
  43. return
  44. }
  45. }
  46. tname := filepath.Join("nodes", fmt.Sprintf("%d.json", d.Config.Node))
  47. payload, err := json.MarshalIndent(u, "", " ")
  48. if err != nil {
  49. fmt.Println("Err", err)
  50. return
  51. }
  52. err = os.WriteFile(tname, payload, 0666)
  53. if err != nil {
  54. fmt.Println("Err", err)
  55. }
  56. }
  57. func DropTemp() {
  58. if d.Disconnected {
  59. return
  60. }
  61. tname := filepath.Join("nodes", fmt.Sprintf("%d.json", d.Config.Node))
  62. err := os.Remove(tname)
  63. if err != nil {
  64. fmt.Println("Err", err)
  65. }
  66. }
  67. func GetTempByNode(node int) *User {
  68. tname := filepath.Join("nodes", fmt.Sprintf("%d.json", node))
  69. payload, err := os.ReadFile(tname)
  70. if err != nil {
  71. if !errors.Is(err, os.ErrNotExist) {
  72. fmt.Println("Err", err)
  73. }
  74. return nil
  75. }
  76. var u *User
  77. err = json.Unmarshal(payload, &u)
  78. if err != nil {
  79. fmt.Println("Err", err)
  80. return nil
  81. }
  82. return u
  83. }
  84. func UpdateTemp() {
  85. t := GetTempByNode(d.Config.Node)
  86. if t != nil {
  87. u = t
  88. }
  89. }
  90. func GetTempByName(name string) *User {
  91. ls, err := os.ReadDir("nodes")
  92. if err != nil {
  93. if !errors.Is(err, os.ErrNotExist) {
  94. fmt.Println("Err", err)
  95. }
  96. return nil
  97. }
  98. var u *User
  99. for _, entry := range ls {
  100. if entry.IsDir() {
  101. continue
  102. }
  103. if strings.HasPrefix(entry.Name(), ".") || !strings.HasSuffix(entry.Name(), ".json") {
  104. continue
  105. }
  106. fname := filepath.Join("nodes", entry.Name())
  107. payload, err := os.ReadFile(fname)
  108. if err != nil {
  109. fmt.Println("Err", fname, err)
  110. continue
  111. }
  112. err = json.Unmarshal(payload, &u)
  113. if err != nil {
  114. fmt.Println("Err", fname, err)
  115. continue
  116. }
  117. if strings.EqualFold(u.Name, name) {
  118. return u
  119. }
  120. }
  121. return nil
  122. }
  123. func main() {
  124. d.Init("Geode")
  125. defer d.Close()
  126. udb = &UserDB{}
  127. err := udb.Open("users.db3")
  128. if err != nil {
  129. fmt.Printf("UserDB.Open(filename='users.db3') > %v\r\n", err)
  130. return
  131. }
  132. d.WriteS(door.ColorTextS("BRI YEL ON BLA") + "Geode" + door.ColorTextS("WHI ON BLA") + " by " + door.ColorTextS("BRI RED ON BLA") + "Apollo" + door.ColorTextS("BRI BLA ON BLA") + "@" + door.ColorTextS("BRI GRE ON BLA") + "21:1/236" + door.Reset + door.CRNL)
  133. LOGIN:
  134. for {
  135. d.WriteS(door.GotoS(1, 3) + door.Reset + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 4) + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 5) + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 6) + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 7) + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 8) + strings.Repeat(" ", door.Width-1) + door.GotoS(1, 9) + strings.Repeat(" ", door.Width-1))
  136. d.WriteS(door.GotoS(1, 3) + door.ColorTextS("BRI YEL ON BLA") + "Login: " + door.ColorTextS("BRI WHI ON BLU"))
  137. name := d.Input(30)
  138. if len(name) == 0 {
  139. d.WriteS(door.Reset + door.CRNL + "Goodbye!")
  140. return
  141. }
  142. u = udb.FindUserByName(name)
  143. if u == nil {
  144. u = &User{Name: name}
  145. // New User, So get their password and their class of choice
  146. d.WriteS(door.GotoS(1, 4) + door.ColorTextS("BRI YEL ON BLA") + "Password: " + door.ColorTextS("BLU ON BLU"))
  147. pwd := d.Input(30)
  148. if len(pwd) == 0 {
  149. d.WriteS(door.Reset + door.CRNL + "Goodbye!")
  150. return
  151. }
  152. err = u.SetPassword(pwd)
  153. if err != nil {
  154. d.WriteS(door.Reset + door.CRNL + "Err: " + err.Error() + door.CRNL)
  155. _, _, err = d.WaitKey(door.Inactivity)
  156. if err != nil {
  157. if errors.Is(err, door.ErrDisconnected) {
  158. return
  159. }
  160. }
  161. continue LOGIN
  162. }
  163. d.WriteS(door.Reset + door.CRNL)
  164. bb := door.ColorTextS("BRI BLA ON BLA")
  165. d.WriteS(bb + "[" + door.ColorTextS(C_KNIGHT.ColorText()) + "K" + bb + "] " + door.ColorTextS(C_KNIGHT.ColorText()) + C_KNIGHT.Name() + door.Reset + door.CRNL)
  166. d.WriteS(bb + "[" + door.ColorTextS(C_THIEF.ColorText()) + "T" + bb + "] " + door.ColorTextS(C_THIEF.ColorText()) + C_THIEF.Name() + door.Reset + door.CRNL)
  167. d.WriteS(bb + "[" + door.ColorTextS(C_CLERIC.ColorText()) + "C" + bb + "] " + door.ColorTextS(C_CLERIC.ColorText()) + C_CLERIC.Name() + door.Reset + door.CRNL)
  168. d.WriteS(bb + "[" + door.ColorTextS(C_WIZARD.ColorText()) + "W" + bb + "] " + door.ColorTextS(C_WIZARD.ColorText()) + C_WIZARD.Name() + door.Reset + door.CRNL)
  169. d.WriteS(bb + "[" + door.ColorTextS(C_RANGER.ColorText()) + "R" + bb + "] " + door.ColorTextS(C_RANGER.ColorText()) + C_RANGER.Name() + door.Reset + door.CRNL)
  170. r, _, err := d.WaitKey(door.Inactivity)
  171. if err != nil {
  172. if errors.Is(err, door.ErrDisconnected) {
  173. return
  174. }
  175. continue LOGIN
  176. }
  177. switch r {
  178. case 'k', 'K':
  179. u.Class = C_KNIGHT
  180. u.Health = 30
  181. u.MaxHealth = 30
  182. u.MaxMagic = 0
  183. u.Magic = 0
  184. u.Gold = 200
  185. case 't', 'T':
  186. u.Class = C_THIEF
  187. u.Health = 20
  188. u.MaxHealth = 20
  189. u.MaxMagic = 0
  190. u.Magic = 0
  191. u.Gold = 250 // Thieves get bonus gold (+50)
  192. case 'c', 'C':
  193. u.Class = C_CLERIC
  194. u.Health = 25
  195. u.MaxHealth = 25
  196. u.MaxMagic = 7
  197. u.Magic = 7
  198. u.Gold = 200
  199. case 'w', 'W':
  200. u.Class = C_WIZARD
  201. u.Health = 20
  202. u.MaxHealth = 20
  203. u.MaxMagic = 12
  204. u.Magic = 12
  205. u.Gold = 200
  206. case 'r', 'R':
  207. u.Class = C_RANGER
  208. u.Health = 22
  209. u.MaxHealth = 22
  210. u.MaxMagic = 0
  211. u.Magic = 0
  212. u.Gold = 200
  213. default:
  214. continue LOGIN
  215. }
  216. u.Level = 1
  217. err = udb.SaveUser(u)
  218. if err != nil {
  219. log.Printf("u = %#v", u)
  220. log.Printf("UserDB.SaveUser(u) > %v", err)
  221. d.WriteS(door.Reset + door.CRNL + "Err: " + err.Error() + door.CRNL)
  222. d.WaitKey(door.Inactivity)
  223. return
  224. }
  225. break LOGIN
  226. } else {
  227. // Existing User, So verify their password
  228. d.WriteS(door.GotoS(1, 4) + door.ColorTextS("BRI YEL ON BLA") + "Password: " + door.ColorTextS("BLU ON BLU"))
  229. pwd := d.Input(30)
  230. if len(pwd) == 0 {
  231. d.WriteS(door.Reset + door.CRNL + "Goodbye!")
  232. return
  233. }
  234. if u.VerifyPassword(pwd) != nil {
  235. d.WriteS(door.Reset + door.CRNL + door.ColorTextS("BRI RED ON BLA") + "Invalid Username or Password!" + door.Reset + door.CRNL)
  236. d.WaitKey(time.Duration(10) * time.Second)
  237. u = nil
  238. continue LOGIN
  239. } else {
  240. d.WriteS(door.Reset + door.CRNL)
  241. break LOGIN
  242. }
  243. }
  244. }
  245. SaveTemp()
  246. defer DropTemp()
  247. d.WriteS(door.ColorTextS("BRI CYA ON BLA") + "Welcome " + door.ColorTextS("BRI WHI ON BLA") + u.Name + door.ColorTextS("BRI CYA ON BLA") + " the ")
  248. d.WriteS(door.ColorTextS(u.Class.ColorText()) + u.Class.Name())
  249. d.WriteS(door.Reset + door.CRNL)
  250. go renderStatusBar("Hello "+u.Name, time.Now().Format("Jan 02 2006 @ 03:04:05PM"))
  251. d.WriteS(fmt.Sprintf("Weapon: %s with %s enchantment", u.Weapon.Name(), u.WeaponEnchant.Name()) + door.CRNL)
  252. d.WriteS(fmt.Sprintf("Armor: %s with %s enchantment", u.Armor.Name(), u.ArmorEnchant.Name()) + door.CRNL)
  253. d.WriteS(fmt.Sprintf("Ranged: %s with %s enchantment", u.RangedWeapon.Name(), u.RangedWeaponEnchant.Name()) + door.CRNL)
  254. d.WriteS(fmt.Sprintf("Shield: %s", u.Shield.Name()) + door.CRNL)
  255. d.WriteS(fmt.Sprintf("Ring: %s", u.Ring.Name()) + door.CRNL)
  256. d.WriteS(fmt.Sprintf("Amulet: %s", u.Amulet.Name()) + door.CRNL)
  257. d.WaitKey(door.Inactivity)
  258. }
  259. func renderStatusBar(msg ...string) {
  260. if d.Disconnected || u == nil {
  261. return
  262. }
  263. d.WriteS(door.SavePos + door.GotoS(1, door.Height-1) + door.Reset + strings.Repeat(" ", door.Width-1) + door.RestorePos)
  264. d.WriteS(door.SavePos + door.GotoS(1, door.Height) + door.Reset + strings.Repeat(" ", door.Width-1) + door.RestorePos)
  265. bb := door.ColorTextS("BRI BLA ON BLA")
  266. bar_width := ((door.Width - 3) / 2) - 1
  267. hp := int(float64(bar_width) * (float64(u.Health) / float64(u.MaxHealth)))
  268. var pos_txt string
  269. if len(msg) >= 1 {
  270. pos_txt += msg[0] + " - "
  271. }
  272. if u.MaxMagic != 0 {
  273. pos_txt += fmt.Sprintf("%-3d%% %s %-3d%%", int((float64(u.Health)/float64(u.MaxHealth))*100.0), u.Pos.String(), int((float64(u.Magic)/float64(u.MaxMagic))*100.0))
  274. } else {
  275. pos_txt += fmt.Sprintf("%-3d%% %s", int((float64(u.Health)/float64(u.MaxHealth))*100.0), u.Pos.String())
  276. }
  277. if len(msg) >= 2 {
  278. pos_txt += " - " + msg[1]
  279. }
  280. d.WriteS(door.SavePos + door.GotoS((door.Width/2)-(len(pos_txt)/2), door.Height-1) + door.ColorTextS("BRI CYA ON BLA") + pos_txt + door.RestorePos)
  281. if u.MaxMagic != 0 {
  282. mp := int(float64(bar_width) * (float64(u.Magic) / float64(u.MaxMagic)))
  283. log.Printf("HP=%d/%d %d%% (%d) MP=%d/%d %d%% (%d) bar_width=%d", u.Health, u.MaxHealth, int((float64(u.Health)/float64(u.MaxHealth))*100.0), hp, u.Magic, u.MaxMagic, int((float64(u.Magic)/float64(u.MaxMagic))*100.0), mp, bar_width)
  284. d.WriteS(door.SavePos + door.GotoS(1, door.Height) + bb + "[" + door.ColorTextS("BRI RED ON BLA") + strings.Repeat(door.BARS.Solid, hp) + strings.Repeat(" ", bar_width-hp) + bb + "] [" + door.ColorTextS("BRI MAG ON BLA") + strings.Repeat(door.BARS.Solid, mp) + strings.Repeat(" ", bar_width-mp) + bb + "]" + door.RestorePos)
  285. } else {
  286. log.Printf("HP=%d/%d %d%% (%d) bar_width=%d", u.Health, u.MaxHealth, int((float64(u.Health)/float64(u.MaxHealth))*100.0), hp, bar_width)
  287. d.WriteS(door.SavePos + door.GotoS(1, door.Height) + bb + "[" + door.ColorTextS("BRI RED ON BLA") + strings.Repeat(door.BARS.Solid, hp) + strings.Repeat(" ", bar_width-hp) + bb + "]" + door.RestorePos)
  288. }
  289. }