rom24-quickmud-python 2.5.3__py3-none-any.whl → 2.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. mud/__init__.py +1 -0
  2. mud/__main__.py +1 -1
  3. mud/account/__init__.py +16 -2
  4. mud/account/account_manager.py +16 -43
  5. mud/account/account_service.py +273 -151
  6. mud/admin_logging/__init__.py +1 -0
  7. mud/advancement.py +32 -6
  8. mud/agent/__init__.py +1 -0
  9. mud/ai/__init__.py +2 -1
  10. mud/combat/assist.py +10 -4
  11. mud/combat/engine.py +93 -79
  12. mud/commands/admin_commands.py +82 -90
  13. mud/commands/advancement.py +188 -17
  14. mud/commands/affects.py +34 -1
  15. mud/commands/alias_cmds.py +102 -26
  16. mud/commands/auto_settings.py +143 -18
  17. mud/commands/build.py +870 -96
  18. mud/commands/character.py +39 -27
  19. mud/commands/combat.py +1 -1
  20. mud/commands/communication.py +62 -24
  21. mud/commands/consumption.py +261 -165
  22. mud/commands/dispatcher.py +383 -186
  23. mud/commands/doors.py +227 -130
  24. mud/commands/equipment.py +281 -165
  25. mud/commands/give.py +217 -168
  26. mud/commands/group_commands.py +255 -150
  27. mud/commands/healer.py +222 -53
  28. mud/commands/imm_admin.py +162 -122
  29. mud/commands/imm_commands.py +94 -68
  30. mud/commands/imm_display.py +198 -151
  31. mud/commands/imm_emote.py +167 -102
  32. mud/commands/imm_load.py +133 -113
  33. mud/commands/imm_olc.py +418 -111
  34. mud/commands/imm_punish.py +154 -151
  35. mud/commands/imm_search.py +850 -306
  36. mud/commands/imm_server.py +122 -106
  37. mud/commands/imm_set.py +490 -397
  38. mud/commands/info.py +4 -2
  39. mud/commands/info_extended.py +1 -76
  40. mud/commands/inspection.py +13 -5
  41. mud/commands/inventory.py +563 -36
  42. mud/commands/liquids.py +138 -63
  43. mud/commands/magic_items.py +296 -384
  44. mud/commands/misc_player.py +3 -3
  45. mud/commands/movement.py +34 -23
  46. mud/commands/notes.py +39 -28
  47. mud/commands/obj_manipulation.py +225 -67
  48. mud/commands/player_info.py +105 -65
  49. mud/commands/position.py +421 -40
  50. mud/commands/remaining_rom.py +233 -240
  51. mud/commands/session.py +89 -88
  52. mud/commands/shop.py +131 -32
  53. mud/commands/socials.py +57 -6
  54. mud/commands/thief_skills.py +324 -234
  55. mud/commands/typo_guards.py +10 -34
  56. mud/config.py +1 -1
  57. mud/db/__init__.py +1 -0
  58. mud/db/migrations.py +12 -0
  59. mud/db/models.py +10 -20
  60. mud/db/seed.py +11 -12
  61. mud/devtools/__init__.py +1 -0
  62. mud/game_loop.py +19 -10
  63. mud/handler.py +278 -17
  64. mud/loaders/json_loader.py +307 -29
  65. mud/loaders/mob_loader.py +75 -7
  66. mud/magic/effects.py +20 -13
  67. mud/math/stat_apps.py +294 -0
  68. mud/mob_cmds.py +298 -52
  69. mud/mobprog.py +121 -40
  70. mud/models/board.py +25 -2
  71. mud/models/character.py +8 -4
  72. mud/models/clans.py +3 -1
  73. mud/models/constants.py +123 -69
  74. mud/models/object.py +30 -2
  75. mud/models/races.py +17 -0
  76. mud/models/room.py +14 -1
  77. mud/models/social.py +21 -0
  78. mud/music/__init__.py +104 -1
  79. mud/net/ansi.py +54 -8
  80. mud/net/connection.py +299 -117
  81. mud/net/session.py +8 -0
  82. mud/network/__init__.py +1 -0
  83. mud/network/websocket_server.py +17 -55
  84. mud/network/websocket_stream.py +162 -0
  85. mud/notes.py +253 -2
  86. mud/olc/editor_state.py +79 -0
  87. mud/olc/save.py +246 -5
  88. mud/persistence.py +92 -0
  89. mud/rom_api.py +1 -1
  90. mud/scripts/convert_are_to_json.py +24 -7
  91. mud/scripts/load_test_data.py +6 -13
  92. mud/security/__init__.py +1 -0
  93. mud/security/bans.py +3 -1
  94. mud/skills/handlers.py +43 -3
  95. mud/skills/registry.py +15 -0
  96. mud/spawning/mob_spawner.py +7 -0
  97. mud/spawning/reset_handler.py +11 -12
  98. mud/spawning/templates.py +23 -2
  99. mud/spec_funs.py +142 -64
  100. mud/utils/bit.py +122 -0
  101. mud/utils/fix_sex.py +24 -0
  102. mud/utils/olc_tables.py +127 -0
  103. mud/utils/poses.py +187 -0
  104. mud/utils/prefix_lookup.py +217 -0
  105. mud/utils/prompt.py +169 -0
  106. mud/utils/string_editor.py +581 -0
  107. mud/wiznet.py +105 -49
  108. mud/world/char_find.py +2 -2
  109. mud/world/look.py +20 -6
  110. mud/world/movement.py +138 -50
  111. mud/world/obj_find.py +3 -3
  112. mud/world/world_state.py +8 -0
  113. {rom24_quickmud_python-2.5.3.dist-info → rom24_quickmud_python-2.7.0.dist-info}/METADATA +100 -20
  114. rom24_quickmud_python-2.7.0.dist-info/RECORD +221 -0
  115. {rom24_quickmud_python-2.5.3.dist-info → rom24_quickmud_python-2.7.0.dist-info}/WHEEL +1 -1
  116. rom24_quickmud_python-2.5.3.dist-info/RECORD +0 -211
  117. {rom24_quickmud_python-2.5.3.dist-info → rom24_quickmud_python-2.7.0.dist-info}/entry_points.txt +0 -0
  118. {rom24_quickmud_python-2.5.3.dist-info → rom24_quickmud_python-2.7.0.dist-info}/licenses/LICENSE +0 -0
  119. {rom24_quickmud_python-2.5.3.dist-info → rom24_quickmud_python-2.7.0.dist-info}/top_level.txt +0 -0
mud/__init__.py CHANGED
@@ -0,0 +1 @@
1
+ """Package marker for mud."""
mud/__main__.py CHANGED
@@ -31,7 +31,7 @@ def loadtestuser():
31
31
 
32
32
 
33
33
  @cli.command()
34
- def socketserver(host: str = "0.0.0.0", port: int = 5000):
34
+ def socketserver(host: str = "0.0.0.0", port: int = 5001):
35
35
  """Start the telnet server."""
36
36
  asyncio.run(start_telnet(host=host, port=port))
37
37
 
mud/account/__init__.py CHANGED
@@ -1,11 +1,17 @@
1
- """Account management utilities."""
1
+ """Account management utilities.
2
+
3
+ The Python-only PlayerAccount layer has been removed. Characters now own
4
+ their passwords directly, mirroring ROM src/merc.h PCData.pwd.
5
+ """
2
6
 
3
7
  from .account_manager import load_character, save_character
4
8
  from .account_service import (
5
9
  CreationSelection,
6
10
  account_exists,
11
+ character_exists,
7
12
  create_account,
8
13
  create_character,
14
+ create_character_record,
9
15
  clear_active_accounts,
10
16
  get_creation_classes,
11
17
  get_creation_races,
@@ -14,6 +20,8 @@ from .account_service import (
14
20
  get_race_archetype,
15
21
  is_account_active,
16
22
  is_valid_account_name,
23
+ is_valid_character_name,
24
+ login_character,
17
25
  lookup_creation_class,
18
26
  lookup_creation_race,
19
27
  lookup_hometown,
@@ -27,17 +35,21 @@ from .account_service import (
27
35
  finalize_creation_stats,
28
36
  sanitize_account_name,
29
37
  release_account,
38
+ release_character,
30
39
  )
31
40
 
32
41
  __all__ = [
33
42
  "load_character",
34
43
  "save_character",
35
44
  "account_exists",
45
+ "character_exists",
36
46
  "create_account",
47
+ "create_character",
48
+ "create_character_record",
37
49
  "login",
50
+ "login_character",
38
51
  "login_with_host",
39
52
  "list_characters",
40
- "create_character",
41
53
  "CreationSelection",
42
54
  "get_creation_races",
43
55
  "lookup_creation_race",
@@ -51,10 +63,12 @@ __all__ = [
51
63
  "roll_creation_stats",
52
64
  "finalize_creation_stats",
53
65
  "is_valid_account_name",
66
+ "is_valid_character_name",
54
67
  "sanitize_account_name",
55
68
  "clear_active_accounts",
56
69
  "is_account_active",
57
70
  "release_account",
71
+ "release_character",
58
72
  "LoginFailureReason",
59
73
  "LoginResult",
60
74
  ]
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  import json
4
4
 
5
5
  from mud.db.models import Character as DBCharacter
6
- from mud.db.models import PlayerAccount
7
6
  from mud.db.session import SessionLocal
8
7
  from mud.models.character import Character, from_orm
9
8
  from mud.models.constants import ROOM_VNUM_LIMBO, ROOM_VNUM_TEMPLE
@@ -13,22 +12,19 @@ from mud.models.conversion import (
13
12
  )
14
13
 
15
14
 
16
- def load_character(username: str, char_name: str) -> Character | None:
15
+ def load_character(char_name: str, _ignored: str | None = None) -> Character | None:
16
+ """Load a character by name from the database.
17
+
18
+ The second argument is accepted but ignored for backward compatibility;
19
+ previously it was a username (account name). Characters are now
20
+ standalone identities — mirroring ROM src/save.c:fread_char.
21
+ """
17
22
  session = None
18
23
  try:
19
24
  session = SessionLocal()
20
- db_char = (
21
- session.query(DBCharacter)
22
- .join(PlayerAccount)
23
- .filter(
24
- DBCharacter.name == char_name,
25
- PlayerAccount.username == username,
26
- )
27
- .first()
28
- )
25
+ db_char = session.query(DBCharacter).filter(DBCharacter.name == char_name).first()
29
26
  char = from_orm(db_char) if db_char else None
30
27
  if char and db_char:
31
- _ = db_char.player # load relationship
32
28
  char.inventory, char.equipment = load_objects_for_character(db_char)
33
29
  return char
34
30
  except Exception as e:
@@ -45,39 +41,11 @@ def save_character(character: Character) -> None:
45
41
  session = SessionLocal()
46
42
  db_char = session.query(DBCharacter).filter_by(name=character.name).first()
47
43
  if not db_char:
48
- # Character doesn't exist in database - create it
49
- # This handles cases where character was created via JSON or other means
50
44
  print(f"[WARN] Character '{character.name}' not found in database, creating new record")
51
-
52
- # CRITICAL: Try to find and link the player account
53
- player_id = None
54
- pcdata = getattr(character, "pcdata", None)
55
- if pcdata:
56
- account_name = getattr(pcdata, "account_name", None)
57
- if account_name:
58
- player_account = session.query(PlayerAccount).filter_by(username=account_name).first()
59
- if player_account:
60
- player_id = player_account.id
61
- print(f"[INFO] Linked character '{character.name}' to account '{account_name}' (id={player_id})")
62
- else:
63
- print(f"[WARN] Could not find player account '{account_name}' for character '{character.name}'")
64
-
65
- db_char = DBCharacter(name=character.name, player_id=player_id)
45
+ db_char = DBCharacter(name=character.name)
66
46
  session.add(db_char)
67
-
68
- # Update all fields
47
+
69
48
  if db_char:
70
- # Ensure player_id is set if we have account information
71
- if not db_char.player_id:
72
- pcdata = getattr(character, "pcdata", None)
73
- if pcdata:
74
- account_name = getattr(pcdata, "account_name", None)
75
- if account_name:
76
- player_account = session.query(PlayerAccount).filter_by(username=account_name).first()
77
- if player_account:
78
- db_char.player_id = player_account.id
79
- print(f"[INFO] Fixed missing player_id for character '{character.name}' -> account '{account_name}'")
80
-
81
49
  db_char.level = character.level
82
50
  db_char.hp = character.hit
83
51
  db_char.race = int(character.race or 0)
@@ -105,11 +73,16 @@ def save_character(character: Character) -> None:
105
73
  db_char.perm_mana = int(getattr(pcdata, "perm_mana", character.max_mana or 100))
106
74
  db_char.perm_move = int(getattr(pcdata, "perm_move", character.max_move or 100))
107
75
  else:
108
- # Fallback if no pcdata
109
76
  db_char.perm_hit = int(character.max_hit or 20)
110
77
  db_char.perm_mana = int(character.max_mana or 100)
111
78
  db_char.perm_move = int(character.max_move or 100)
112
79
 
80
+ # Persist password hash if available on runtime character
81
+ if pcdata:
82
+ pwd = getattr(pcdata, "pwd", None) or ""
83
+ if pwd and not getattr(db_char, "password_hash", ""):
84
+ db_char.password_hash = pwd
85
+
113
86
  db_char.default_weapon_vnum = int(character.default_weapon_vnum or 0)
114
87
  db_char.creation_points = int(getattr(character, "creation_points", 0) or 0)
115
88
  db_char.creation_groups = json.dumps(list(getattr(character, "creation_groups", ())))