rom24-quickmud-python 1.2.2__py3-none-any.whl → 2.0.4__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 (155) hide show
  1. mud/__main__.py +19 -1
  2. mud/account/__init__.py +42 -2
  3. mud/account/account_manager.py +44 -14
  4. mud/account/account_service.py +961 -32
  5. mud/admin_logging/admin.py +167 -0
  6. mud/{logging → admin_logging}/agent_trace.py +3 -3
  7. mud/advancement.py +151 -11
  8. mud/affects/engine.py +32 -0
  9. mud/affects/saves.py +46 -5
  10. mud/agent/agent_protocol.py +3 -4
  11. mud/agent/character_agent.py +16 -9
  12. mud/ai/__init__.py +374 -0
  13. mud/ai/aggressive.py +119 -0
  14. mud/characters/__init__.py +56 -0
  15. mud/characters/conditions.py +58 -0
  16. mud/characters/follow.py +70 -0
  17. mud/combat/__init__.py +5 -2
  18. mud/combat/death.py +593 -0
  19. mud/combat/engine.py +1349 -49
  20. mud/combat/kill_table.py +48 -0
  21. mud/combat/messages.py +182 -0
  22. mud/commands/admin_commands.py +446 -26
  23. mud/commands/advancement.py +188 -8
  24. mud/commands/alias_cmds.py +23 -3
  25. mud/commands/build.py +1112 -13
  26. mud/commands/combat.py +536 -8
  27. mud/commands/communication.py +477 -19
  28. mud/commands/decorators.py +2 -0
  29. mud/commands/dispatcher.py +372 -82
  30. mud/commands/healer.py +1 -4
  31. mud/commands/help.py +327 -8
  32. mud/commands/imc.py +382 -4
  33. mud/commands/info.py +75 -0
  34. mud/commands/inspection.py +6 -3
  35. mud/commands/inventory.py +90 -0
  36. mud/commands/mobprog_tools.py +124 -0
  37. mud/commands/movement.py +37 -21
  38. mud/commands/notes.py +447 -22
  39. mud/commands/shop.py +897 -45
  40. mud/commands/socials.py +1 -1
  41. mud/config.py +164 -0
  42. mud/db/init.py +8 -7
  43. mud/db/migrate_from_files.py +4 -3
  44. mud/db/migrations.py +23 -1
  45. mud/db/models.py +106 -65
  46. mud/db/seed.py +1 -1
  47. mud/db/session.py +1 -0
  48. mud/devtools/agent_demo.py +2 -2
  49. mud/game_loop.py +933 -41
  50. mud/game_tick_scheduler.py +51 -0
  51. mud/groups/__init__.py +5 -0
  52. mud/groups/xp.py +258 -0
  53. mud/imc/__init__.py +1148 -4
  54. mud/imc/commands.py +149 -0
  55. mud/imc/network.py +98 -0
  56. mud/imc/protocol.py +3 -2
  57. mud/loaders/__init__.py +9 -6
  58. mud/loaders/area_loader.py +138 -26
  59. mud/loaders/base_loader.py +6 -5
  60. mud/loaders/help_loader.py +60 -3
  61. mud/loaders/json_area_loader.py +136 -95
  62. mud/loaders/json_loader.py +419 -167
  63. mud/loaders/mob_loader.py +127 -44
  64. mud/loaders/mobprog_loader.py +26 -0
  65. mud/loaders/obj_loader.py +443 -40
  66. mud/loaders/reset_loader.py +141 -13
  67. mud/loaders/room_loader.py +71 -14
  68. mud/loaders/shop_loader.py +4 -2
  69. mud/loaders/social_loader.py +1 -1
  70. mud/loaders/specials_loader.py +22 -11
  71. mud/logging.py +20 -0
  72. mud/magic/__init__.py +19 -0
  73. mud/magic/effects.py +86 -0
  74. mud/math/c_compat.py +1 -1
  75. mud/mob_cmds.py +1101 -0
  76. mud/mobprog.py +1509 -27
  77. mud/models/__init__.py +43 -34
  78. mud/models/area.py +10 -8
  79. mud/models/area_json.py +8 -7
  80. mud/models/board.py +114 -7
  81. mud/models/board_json.py +6 -2
  82. mud/models/character.py +829 -42
  83. mud/models/character_json.py +9 -7
  84. mud/models/clans.py +83 -0
  85. mud/models/classes.py +112 -0
  86. mud/models/constants.py +605 -31
  87. mud/models/conversion.py +5 -6
  88. mud/models/help.py +21 -5
  89. mud/models/json_io.py +4 -4
  90. mud/models/mob.py +70 -42
  91. mud/models/note.py +3 -1
  92. mud/models/note_json.py +1 -0
  93. mud/models/obj.py +44 -32
  94. mud/models/object.py +39 -8
  95. mud/models/object_json.py +9 -7
  96. mud/models/player_json.py +27 -4
  97. mud/models/races.py +534 -0
  98. mud/models/room.py +50 -30
  99. mud/models/room_json.py +15 -12
  100. mud/models/shop.py +1 -1
  101. mud/models/skill.py +34 -5
  102. mud/models/skill_json.py +7 -1
  103. mud/models/social.py +26 -5
  104. mud/music/__init__.py +161 -0
  105. mud/net/__init__.py +2 -2
  106. mud/net/ansi.py +13 -0
  107. mud/net/connection.py +1772 -100
  108. mud/net/protocol.py +39 -5
  109. mud/net/session.py +148 -4
  110. mud/net/ssh_server.py +327 -0
  111. mud/net/telnet_server.py +24 -10
  112. mud/network/websocket_server.py +20 -14
  113. mud/network/websocket_session.py +6 -3
  114. mud/notes.py +64 -12
  115. mud/persistence.py +666 -39
  116. mud/registry.py +12 -5
  117. mud/scripts/convert_are_to_json.py +103 -48
  118. mud/scripts/convert_help_are_to_json.py +7 -6
  119. mud/scripts/convert_player_to_json.py +165 -19
  120. mud/scripts/convert_shops_to_json.py +3 -5
  121. mud/scripts/convert_skills_to_json.py +44 -53
  122. mud/scripts/convert_social_are_to_json.py +6 -7
  123. mud/scripts/load_test_data.py +1 -2
  124. mud/security/bans.py +245 -48
  125. mud/server.py +3 -2
  126. mud/skills/__init__.py +14 -2
  127. mud/skills/groups.py +337 -0
  128. mud/skills/handlers.py +6574 -512
  129. mud/skills/metadata.py +160 -0
  130. mud/skills/registry.py +313 -29
  131. mud/spawning/mob_spawner.py +2 -2
  132. mud/spawning/obj_spawner.py +59 -4
  133. mud/spawning/reset_handler.py +744 -144
  134. mud/spawning/templates.py +419 -20
  135. mud/spec_funs.py +1409 -15
  136. mud/time.py +5 -3
  137. mud/utils/act.py +168 -0
  138. mud/utils/rng_mm.py +30 -13
  139. mud/utils/text.py +115 -0
  140. mud/wiznet.py +212 -19
  141. mud/world/__init__.py +2 -2
  142. mud/world/linking.py +3 -1
  143. mud/world/look.py +15 -5
  144. mud/world/movement.py +512 -67
  145. mud/world/vision.py +332 -0
  146. mud/world/world_state.py +92 -27
  147. {rom24_quickmud_python-1.2.2.dist-info → rom24_quickmud_python-2.0.4.dist-info}/METADATA +114 -7
  148. rom24_quickmud_python-2.0.4.dist-info/RECORD +166 -0
  149. mud/logging/admin.py +0 -40
  150. rom24_quickmud_python-1.2.2.dist-info/RECORD +0 -135
  151. /mud/{logging → admin_logging}/__init__.py +0 -0
  152. {rom24_quickmud_python-1.2.2.dist-info → rom24_quickmud_python-2.0.4.dist-info}/WHEEL +0 -0
  153. {rom24_quickmud_python-1.2.2.dist-info → rom24_quickmud_python-2.0.4.dist-info}/entry_points.txt +0 -0
  154. {rom24_quickmud_python-1.2.2.dist-info → rom24_quickmud_python-2.0.4.dist-info}/licenses/LICENSE +0 -0
  155. {rom24_quickmud_python-1.2.2.dist-info → rom24_quickmud_python-2.0.4.dist-info}/top_level.txt +0 -0
mud/__main__.py CHANGED
@@ -1,12 +1,15 @@
1
1
  import asyncio
2
+
2
3
  import typer
3
- from mud.server import run_game_loop
4
+
4
5
  from mud.db.migrations import run_migrations
5
6
  from mud.net.telnet_server import start_server as start_telnet
6
7
  from mud.network.websocket_server import run as start_websocket
8
+ from mud.server import run_game_loop
7
9
 
8
10
  cli = typer.Typer()
9
11
 
12
+
10
13
  @cli.command()
11
14
  def runserver():
12
15
  """Start the main game server."""
@@ -23,6 +26,7 @@ def migrate():
23
26
  def loadtestuser():
24
27
  """Load a default test account and character."""
25
28
  from mud.scripts.load_test_data import load_test_user
29
+
26
30
  load_test_user()
27
31
 
28
32
 
@@ -31,10 +35,24 @@ def socketserver(host: str = "0.0.0.0", port: int = 5000):
31
35
  """Start the telnet server."""
32
36
  asyncio.run(start_telnet(host=host, port=port))
33
37
 
38
+
34
39
  @cli.command()
35
40
  def websocketserver(host: str = "0.0.0.0", port: int = 8000):
36
41
  """Start the websocket server."""
37
42
  start_websocket(host=host, port=port)
38
43
 
44
+
45
+ @cli.command()
46
+ def sshserver(host: str = "0.0.0.0", port: int = 2222):
47
+ """Start the SSH server.
48
+
49
+ Players can connect with: ssh -p 2222 player@hostname
50
+ SSH credentials are ignored; authentication happens via MUD account login.
51
+ """
52
+ from mud.net.ssh_server import start_server as start_ssh
53
+
54
+ asyncio.run(start_ssh(host=host, port=port))
55
+
56
+
39
57
  if __name__ == "__main__":
40
58
  cli()
mud/account/__init__.py CHANGED
@@ -2,19 +2,59 @@
2
2
 
3
3
  from .account_manager import load_character, save_character
4
4
  from .account_service import (
5
+ CreationSelection,
6
+ account_exists,
5
7
  create_account,
8
+ create_character,
9
+ clear_active_accounts,
10
+ get_creation_classes,
11
+ get_creation_races,
12
+ get_hometown_choices,
13
+ get_weapon_choices,
14
+ get_race_archetype,
15
+ is_account_active,
16
+ is_valid_account_name,
17
+ lookup_creation_class,
18
+ lookup_creation_race,
19
+ lookup_hometown,
20
+ lookup_weapon_choice,
21
+ LoginFailureReason,
22
+ LoginResult,
23
+ list_characters,
6
24
  login,
7
25
  login_with_host,
8
- list_characters,
9
- create_character,
26
+ roll_creation_stats,
27
+ finalize_creation_stats,
28
+ sanitize_account_name,
29
+ release_account,
10
30
  )
11
31
 
12
32
  __all__ = [
13
33
  "load_character",
14
34
  "save_character",
35
+ "account_exists",
15
36
  "create_account",
16
37
  "login",
17
38
  "login_with_host",
18
39
  "list_characters",
19
40
  "create_character",
41
+ "CreationSelection",
42
+ "get_creation_races",
43
+ "lookup_creation_race",
44
+ "get_race_archetype",
45
+ "get_creation_classes",
46
+ "lookup_creation_class",
47
+ "get_hometown_choices",
48
+ "lookup_hometown",
49
+ "get_weapon_choices",
50
+ "lookup_weapon_choice",
51
+ "roll_creation_stats",
52
+ "finalize_creation_stats",
53
+ "is_valid_account_name",
54
+ "sanitize_account_name",
55
+ "clear_active_accounts",
56
+ "is_account_active",
57
+ "release_account",
58
+ "LoginFailureReason",
59
+ "LoginResult",
20
60
  ]
@@ -1,17 +1,19 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Optional
3
+ import json
4
4
 
5
+ from mud.db.models import Character as DBCharacter
6
+ from mud.db.models import PlayerAccount
5
7
  from mud.db.session import SessionLocal
6
- from mud.db.models import Character as DBCharacter, PlayerAccount
7
8
  from mud.models.character import Character, from_orm
9
+ from mud.models.constants import ROOM_VNUM_LIMBO, ROOM_VNUM_TEMPLE
8
10
  from mud.models.conversion import (
9
11
  load_objects_for_character,
10
12
  save_objects_for_character,
11
13
  )
12
14
 
13
15
 
14
- def load_character(username: str, char_name: str) -> Optional[Character]:
16
+ def load_character(username: str, char_name: str) -> Character | None:
15
17
  session = None
16
18
  try:
17
19
  session = SessionLocal()
@@ -26,10 +28,8 @@ def load_character(username: str, char_name: str) -> Optional[Character]:
26
28
  )
27
29
  char = from_orm(db_char) if db_char else None
28
30
  if char and db_char:
29
- db_char.player # load relationship
30
- char.inventory, char.equipment = load_objects_for_character(
31
- db_char
32
- )
31
+ _ = db_char.player # load relationship
32
+ char.inventory, char.equipment = load_objects_for_character(db_char)
33
33
  return char
34
34
  except Exception as e:
35
35
  print(f"[ERROR] Failed to load character {char_name}: {e}")
@@ -43,16 +43,46 @@ def save_character(character: Character) -> None:
43
43
  session = None
44
44
  try:
45
45
  session = SessionLocal()
46
- db_char = (
47
- session.query(DBCharacter)
48
- .filter_by(name=character.name)
49
- .first()
50
- )
46
+ db_char = session.query(DBCharacter).filter_by(name=character.name).first()
51
47
  if db_char:
52
48
  db_char.level = character.level
53
49
  db_char.hp = character.hit
54
- if getattr(character, "room", None):
55
- db_char.room_vnum = character.room.vnum
50
+ db_char.race = int(character.race or 0)
51
+ db_char.ch_class = int(character.ch_class or 0)
52
+ pcdata = getattr(character, "pcdata", None)
53
+ true_sex_value = int(
54
+ getattr(pcdata, "true_sex", getattr(character, "sex", 0)) or 0
55
+ )
56
+ db_char.true_sex = true_sex_value
57
+ db_char.sex = int(character.sex or true_sex_value or 0)
58
+ db_char.alignment = int(character.alignment or 0)
59
+ db_char.act = int(getattr(character, "act", 0) or 0)
60
+ db_char.hometown_vnum = int(character.hometown_vnum or 0)
61
+ db_char.perm_stats = json.dumps([int(val) for val in character.perm_stat])
62
+ db_char.size = int(character.size or 0)
63
+ db_char.form = int(character.form or 0)
64
+ db_char.parts = int(character.parts or 0)
65
+ db_char.imm_flags = int(character.imm_flags or 0)
66
+ db_char.res_flags = int(character.res_flags or 0)
67
+ db_char.vuln_flags = int(character.vuln_flags or 0)
68
+ db_char.practice = int(character.practice or 0)
69
+ db_char.train = int(character.train or 0)
70
+ db_char.default_weapon_vnum = int(character.default_weapon_vnum or 0)
71
+ db_char.creation_points = int(getattr(character, "creation_points", 0) or 0)
72
+ db_char.creation_groups = json.dumps(list(getattr(character, "creation_groups", ())))
73
+ db_char.newbie_help_seen = bool(getattr(character, "newbie_help_seen", False))
74
+ room = getattr(character, "room", None)
75
+ was_in_room = getattr(character, "was_in_room", None)
76
+ room_vnum = 0
77
+ if room is not None:
78
+ room_vnum = int(getattr(room, "vnum", 0) or 0)
79
+ if room_vnum == int(ROOM_VNUM_LIMBO) and was_in_room is not None:
80
+ room_vnum = int(getattr(was_in_room, "vnum", 0) or 0)
81
+ elif was_in_room is not None:
82
+ room_vnum = int(getattr(was_in_room, "vnum", 0) or 0)
83
+ if room_vnum <= 0:
84
+ room_vnum = int(ROOM_VNUM_TEMPLE)
85
+ db_char.room_vnum = room_vnum
56
86
  save_objects_for_character(session, character, db_char)
57
87
  session.commit()
58
88
  except Exception as e: