aboutsummaryrefslogtreecommitdiff
path: root/internal/game/core_login_char.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/core_login_char.go')
-rw-r--r--internal/game/core_login_char.go37
1 files changed, 36 insertions, 1 deletions
diff --git a/internal/game/core_login_char.go b/internal/game/core_login_char.go
index 0f57d3c..3a2e324 100644
--- a/internal/game/core_login_char.go
+++ b/internal/game/core_login_char.go
@@ -9,6 +9,10 @@ import (
)
func (g *Game) handleNewCharName(sess *net.Session, input string) {
+ if sess.Account == nil {
+ g.resetToAccountName(sess)
+ return
+ }
name := strings.TrimSpace(input)
if sess.PendingChar == "connect" && len(sess.Account.Characters) > 0 {
@@ -62,6 +66,10 @@ func (g *Game) handleNewCharName(sess *net.Session, input string) {
}
func (g *Game) connectCharacter(sess *net.Session, name string) {
+ if sess.Account == nil {
+ g.resetToAccountName(sess)
+ return
+ }
// This whole function runs as one owner step (invoked from session
// input): membership validation, the online check, registry
// publication, and room entry are serialized against every other
@@ -139,6 +147,10 @@ func (g *Game) connectCharacter(sess *net.Session, name string) {
}
func (g *Game) handleRenameChar(sess *net.Session, input string) {
+ if sess.Account == nil {
+ g.resetToAccountName(sess)
+ return
+ }
name := strings.TrimSpace(input)
if idx, err := parseChoiceIndex(name); err == nil && idx > 0 && idx <= len(sess.Account.Characters) {
sess.PendingChar = sess.Account.Characters[idx-1]
@@ -168,13 +180,32 @@ func (g *Game) handleRenameChar(sess *net.Session, input string) {
// through a live session. Menu operations that rename or delete character
// files must refuse while the character is online, otherwise the in-memory
// player later overwrites or resurrects the moved/removed file.
+//
+// The lookup is case-insensitive: loggedInChars is keyed by the canonical
+// on-disk character name, but callers pass names taken from hand-editable
+// account files and admin file paths ("ALICE"), and character names keep the
+// case their owner chose. Character identity in this game is otherwise
+// case-insensitive (see isMemberOf), so liveness must be too - an exact-match
+// lookup lets an online character's file be edited or deleted.
func (g *Game) characterOnline(name string) bool {
g.charsMu.Lock()
defer g.charsMu.Unlock()
- return g.loggedInChars[name] != nil
+ if g.loggedInChars[name] != nil {
+ return true
+ }
+ for logged, sess := range g.loggedInChars {
+ if sess != nil && strings.EqualFold(logged, name) {
+ return true
+ }
+ }
+ return false
}
func (g *Game) handleRenameCharName(sess *net.Session, input string) {
+ if sess.Account == nil {
+ g.resetToAccountName(sess)
+ return
+ }
newName := strings.TrimSpace(input)
oldName := sess.PendingChar
if newName == "" {
@@ -239,6 +270,10 @@ func (g *Game) showDeleteConfirm(sess *net.Session) {
}
func (g *Game) handleDeleteChar(sess *net.Session, input string) {
+ if sess.Account == nil {
+ g.resetToAccountName(sess)
+ return
+ }
if sess.PendingChar == "" {
name := strings.TrimSpace(input)
if idx, err := parseChoiceIndex(name); err == nil && idx > 0 && idx <= len(sess.Account.Characters) {