albibong 1.0.4__tar.gz → 1.0.6__tar.gz

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 (66) hide show
  1. {albibong-1.0.4 → albibong-1.0.6}/PKG-INFO +2 -3
  2. {albibong-1.0.4 → albibong-1.0.6}/pyproject.toml +2 -3
  3. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/classes/character.py +35 -7
  4. albibong-1.0.6/src/albibong/classes/event_handler/__init__.py +116 -0
  5. albibong-1.0.6/src/albibong/classes/event_handler/handle_event_character_equipment_changed.py +24 -0
  6. albibong-1.0.6/src/albibong/classes/event_handler/handle_event_health.py +35 -0
  7. albibong-1.0.6/src/albibong/classes/event_handler/handle_event_in_combat_state_update.py +17 -0
  8. albibong-1.0.6/src/albibong/classes/event_handler/handle_event_new_character.py +44 -0
  9. albibong-1.0.6/src/albibong/classes/event_handler/handle_event_other_grabbed_loot.py +14 -0
  10. albibong-1.0.6/src/albibong/classes/event_handler/handle_event_party.py +38 -0
  11. albibong-1.0.6/src/albibong/classes/event_handler/handle_event_update_fame.py +7 -0
  12. albibong-1.0.6/src/albibong/classes/event_handler/handle_event_update_re_spec_points.py +11 -0
  13. albibong-1.0.6/src/albibong/classes/event_handler/handle_operation_change_cluster.py +43 -0
  14. albibong-1.0.6/src/albibong/classes/event_handler/handle_operation_join.py +78 -0
  15. albibong-1.0.6/src/albibong/classes/event_handler/handle_operation_move.py +8 -0
  16. albibong-1.0.6/src/albibong/classes/event_handler/world_data_utils.py +102 -0
  17. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/classes/item.py +1 -1
  18. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/classes/packet_handler.py +6 -4
  19. albibong-1.0.6/src/albibong/classes/world_data.py +103 -0
  20. albibong-1.0.4/src/albibong/gui_dist/assets/index-BFSx0nua.css → albibong-1.0.6/src/albibong/gui_dist/assets/index-DZvgNqlG.css +1 -1
  21. albibong-1.0.6/src/albibong/gui_dist/assets/index-Dt6hyZiS.css +1 -0
  22. albibong-1.0.4/src/albibong/gui_dist/assets/index-DAndaN_4.js → albibong-1.0.6/src/albibong/gui_dist/assets/index-E7pha23k.js +20 -20
  23. albibong-1.0.6/src/albibong/gui_dist/assets/index-WIuC9Mnh.js +161 -0
  24. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/gui_dist/index.html +2 -2
  25. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/requirements.txt +0 -1
  26. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/threads/websocket_server.py +30 -0
  27. albibong-1.0.4/src/albibong/classes/world_data.py +0 -407
  28. {albibong-1.0.4 → albibong-1.0.6}/.gitignore +0 -0
  29. {albibong-1.0.4 → albibong-1.0.6}/LICENSE +0 -0
  30. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/__init__.py +0 -0
  31. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/__main__.py +0 -0
  32. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/assets/boom_small.mp3 +0 -0
  33. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/classes/__init__.py +0 -0
  34. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/classes/coords.py +0 -0
  35. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/classes/dungeon.py +0 -0
  36. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/classes/location.py +0 -0
  37. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/classes/logger.py +0 -0
  38. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/classes/utils.py +0 -0
  39. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/gui_dist/Albibong.png +0 -0
  40. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/gui_dist/No Equipment.png +0 -0
  41. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/gui_dist/fame.png +0 -0
  42. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/gui_dist/re_spec.png +0 -0
  43. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/gui_dist/silver.png +0 -0
  44. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/gui_dist/vite.svg +0 -0
  45. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/__init__.py +0 -0
  46. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/command_type.py +0 -0
  47. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/crc_calculator.py +0 -0
  48. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/event_data.py +0 -0
  49. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/message_type.py +0 -0
  50. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/number_serializer.py +0 -0
  51. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/operation_request.py +0 -0
  52. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/operation_response.py +0 -0
  53. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/photon_packet_parser.py +0 -0
  54. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/protocol16_deserializer.py +0 -0
  55. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/protocol16_type.py +0 -0
  56. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/photon_packet_parser/segmented_packet.py +0 -0
  57. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/resources/EventCode.py +0 -0
  58. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/resources/OperationCode.py +0 -0
  59. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/resources/event_code.json +0 -0
  60. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/resources/items.json +0 -0
  61. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/resources/maps.json +0 -0
  62. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/resources/operation_code.json +0 -0
  63. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/threads/__init__.py +0 -0
  64. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/threads/http_server.py +0 -0
  65. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/threads/packet_handler_thread.py +0 -0
  66. {albibong-1.0.4 → albibong-1.0.6}/src/albibong/threads/sniffer_thread.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: albibong
3
- Version: 1.0.4
3
+ Version: 1.0.6
4
4
  Summary: A cross-platform Albion Online damage, fame, and dungeon tracker
5
5
  Project-URL: Homepage, https://github.com/imjangkar/albibong
6
6
  Project-URL: Issues, https://github.com/imjangkar/albibong/issues
@@ -9,8 +9,7 @@ License-File: LICENSE
9
9
  Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python :: 3
12
- Requires-Python: >=3.8
13
- Requires-Dist: playsound==1.3.0
12
+ Requires-Python: >=3.10
14
13
  Requires-Dist: pywebview==5.1
15
14
  Requires-Dist: scapy==2.5.0
16
15
  Requires-Dist: websockets==12.0
@@ -19,12 +19,12 @@ albibong = "albibong:main"
19
19
 
20
20
  [project]
21
21
  name = "albibong"
22
- version = "1.0.4"
22
+ version = "1.0.6"
23
23
  authors = [
24
24
  { name="imjangkar", email="imjangkar@gmail.com" },
25
25
  ]
26
26
  description = "A cross-platform Albion Online damage, fame, and dungeon tracker"
27
- requires-python = ">=3.8"
27
+ requires-python = ">=3.10"
28
28
  classifiers = [
29
29
  "Programming Language :: Python :: 3",
30
30
  "License :: OSI Approved :: MIT License",
@@ -34,7 +34,6 @@ dependencies = [
34
34
  "scapy==2.5.0",
35
35
  "websockets==12.0",
36
36
  "pywebview==5.1",
37
- "playsound==1.3.0"
38
37
  ]
39
38
 
40
39
  [project.urls]
@@ -1,3 +1,4 @@
1
+ from datetime import datetime, timedelta
1
2
  import json
2
3
  from uuid import UUID
3
4
 
@@ -20,25 +21,46 @@ class Character:
20
21
  coords: Coords,
21
22
  equipment: list[Item] = [Item.get_item_from_code("0")] * 10,
22
23
  ):
24
+ # Profile
23
25
  self.id = id
24
26
  self.uuid = uuid
25
27
  self.username = username
26
28
  self.guild = guild
27
29
  self.alliance = alliance
28
30
  self.coords = coords
31
+ self.equipment = equipment
32
+
33
+ # Stats
29
34
  self.fame_gained: int = 0
30
35
  self.re_spec_gained: int = 0
31
36
  self.silver_gained: int = 0
37
+ self.loot: list[str] = []
38
+
39
+ # Combat
32
40
  self.damage_dealt: int = 0
33
41
  self.healing_dealt: int = 0
34
- self.loot: list[str] = []
35
- self.equipment = equipment
42
+ self.is_already_in_combat: bool = False
43
+ self.start_combat_time: timedelta = timedelta(0, 0)
44
+ self.total_combat_duration: timedelta = timedelta(0, 0)
45
+
46
+ def update_combat_duration(self, is_starting_combat):
47
+ if self.is_already_in_combat == False:
48
+ if is_starting_combat == True:
49
+ self.is_already_in_combat = True
50
+ self.start_combat_time = datetime.now()
51
+ else:
52
+ if is_starting_combat == False:
53
+ self.is_already_in_combat = False
54
+ current_combat_duration = datetime.now() - self.start_combat_time
55
+ self.total_combat_duration += current_combat_duration
36
56
 
37
57
  def update_damage_dealt(self, nominal):
38
- self.damage_dealt += nominal
58
+ if self.is_already_in_combat:
59
+ self.damage_dealt += nominal
39
60
 
40
61
  def update_heal_dealt(self, nominal):
41
- self.healing_dealt += nominal
62
+ if self.is_already_in_combat:
63
+ self.healing_dealt += nominal
42
64
 
43
65
  def update_coords(self, parameters):
44
66
  if 3 in parameters:
@@ -49,7 +71,7 @@ class Character:
49
71
  self.fame_gained += fame
50
72
  event = {
51
73
  "type": "update_fame",
52
- "payload": {"username": self.username, "fame_gained": fame},
74
+ "payload": {"username": self.username, "fame_gained": self.fame_gained},
53
75
  }
54
76
  send_event(event)
55
77
 
@@ -58,7 +80,10 @@ class Character:
58
80
  self.re_spec_gained += re_spec
59
81
  event = {
60
82
  "type": "update_re_spec",
61
- "payload": {"username": self.username, "re_spec_gained": re_spec},
83
+ "payload": {
84
+ "username": self.username,
85
+ "re_spec_gained": self.re_spec_gained,
86
+ },
62
87
  }
63
88
  send_event(event)
64
89
 
@@ -69,7 +94,10 @@ class Character:
69
94
  self.silver_gained += silver
70
95
  event = {
71
96
  "type": "update_silver",
72
- "payload": {"username": self.username, "silver_gained": silver},
97
+ "payload": {
98
+ "username": self.username,
99
+ "silver_gained": self.silver_gained,
100
+ },
73
101
  }
74
102
  send_event(event)
75
103
  else:
@@ -0,0 +1,116 @@
1
+ from albibong.classes.event_handler.handle_event_character_equipment_changed import (
2
+ handle_event_character_equipment_changed,
3
+ )
4
+ from albibong.classes.event_handler.handle_event_health import (
5
+ handle_event_health_update,
6
+ handle_event_health_updates,
7
+ )
8
+ from albibong.classes.event_handler.handle_event_in_combat_state_update import (
9
+ handle_event_in_combat_state_update,
10
+ )
11
+ from albibong.classes.event_handler.handle_event_new_character import (
12
+ handle_event_new_character,
13
+ )
14
+ from albibong.classes.event_handler.handle_event_other_grabbed_loot import (
15
+ handle_event_other_grabbed_loot,
16
+ )
17
+ from albibong.classes.event_handler.handle_event_party import (
18
+ handle_event_party_disbanded,
19
+ handle_event_party_joined,
20
+ handle_event_party_player_joined,
21
+ handle_event_party_player_left,
22
+ )
23
+ from albibong.classes.event_handler.handle_event_update_fame import (
24
+ handle_event_update_fame,
25
+ )
26
+ from albibong.classes.event_handler.handle_event_update_re_spec_points import (
27
+ handle_event_update_re_spec_points,
28
+ )
29
+ from albibong.classes.event_handler.handle_operation_change_cluster import (
30
+ handle_operation_change_cluster,
31
+ )
32
+ from albibong.classes.event_handler.handle_operation_join import handle_operation_join
33
+ from albibong.classes.event_handler.handle_operation_move import handle_operation_move
34
+ from albibong.classes.world_data import WorldData
35
+ from albibong.resources.EventCode import EventCode
36
+ from albibong.resources.OperationCode import OperationCode
37
+
38
+
39
+ EVENT_TYPE_PARAMETER = 252
40
+ REQUEST_TYPE_PARAMETER = 253
41
+ RESPONSE_TYPE_PARAMETER = 253
42
+
43
+
44
+ class EventHandler:
45
+ def __init__(self):
46
+ self.request_handler = {}
47
+ self.response_handler = {}
48
+ self.event_handler = {}
49
+
50
+ # Event Handler
51
+ self.event_handler[EventCode.NEW_CHARACTER.value] = handle_event_new_character
52
+ self.event_handler[EventCode.HEALTH_UPDATE.value] = handle_event_health_update
53
+ self.event_handler[EventCode.HEALTH_UPDATES.value] = handle_event_health_updates
54
+ self.event_handler[EventCode.IN_COMBAT_STATE_UPDATE.value] = (
55
+ handle_event_in_combat_state_update
56
+ )
57
+
58
+ self.event_handler[EventCode.UPDATE_FAME.value] = handle_event_update_fame
59
+ self.event_handler[EventCode.UPDATE_RE_SPEC_POINTS.value] = (
60
+ handle_event_update_re_spec_points
61
+ )
62
+ self.event_handler[EventCode.OTHER_GRABBED_LOOT.value] = (
63
+ handle_event_other_grabbed_loot
64
+ )
65
+ self.event_handler[EventCode.PARTY_JOINED.value] = handle_event_party_joined
66
+ self.event_handler[EventCode.PARTY_DISBANDED.value] = (
67
+ handle_event_party_disbanded
68
+ )
69
+ self.event_handler[EventCode.PARTY_PLAYER_JOINED.value] = (
70
+ handle_event_party_player_joined
71
+ )
72
+ self.event_handler[EventCode.PARTY_PLAYER_LEFT.value] = (
73
+ handle_event_party_player_left
74
+ )
75
+ self.event_handler[EventCode.CHARACTER_EQUIPMENT_CHANGED.value] = (
76
+ handle_event_character_equipment_changed
77
+ )
78
+
79
+ # Request Handler
80
+ self.request_handler[OperationCode.MOVE.value] = handle_operation_move
81
+
82
+ # Response Handler
83
+ self.response_handler[OperationCode.JOIN.value] = handle_operation_join
84
+ self.response_handler[OperationCode.CHANGE_CLUSTER.value] = (
85
+ handle_operation_change_cluster
86
+ )
87
+
88
+ def on_request(self, world_data: WorldData, parameters):
89
+ if REQUEST_TYPE_PARAMETER not in parameters:
90
+ return None
91
+
92
+ if parameters[REQUEST_TYPE_PARAMETER] not in self.request_handler:
93
+ return None
94
+
95
+ handler = self.request_handler[parameters[REQUEST_TYPE_PARAMETER]]
96
+ return handler(world_data, parameters)
97
+
98
+ def on_response(self, world_data: WorldData, parameters):
99
+ if RESPONSE_TYPE_PARAMETER not in parameters:
100
+ return None
101
+
102
+ if parameters[RESPONSE_TYPE_PARAMETER] not in self.response_handler:
103
+ return None
104
+
105
+ handler = self.response_handler[parameters[RESPONSE_TYPE_PARAMETER]]
106
+ return handler(world_data, parameters)
107
+
108
+ def on_event(self, world_data: WorldData, parameters):
109
+ if EVENT_TYPE_PARAMETER not in parameters:
110
+ return None
111
+
112
+ if parameters[EVENT_TYPE_PARAMETER] not in self.event_handler:
113
+ return None
114
+
115
+ handler = self.event_handler[parameters[EVENT_TYPE_PARAMETER]]
116
+ return handler(world_data, parameters)
@@ -0,0 +1,24 @@
1
+ from albibong.classes.world_data import WorldData
2
+ from albibong.threads.websocket_server import send_event
3
+
4
+
5
+ def handle_event_character_equipment_changed(world_data: WorldData, parameters):
6
+ if 2 in parameters:
7
+ if parameters[0] in world_data.char_id_to_username:
8
+ if world_data.char_id_to_username[parameters[0]] != "not initialized":
9
+ char = world_data.characters[
10
+ world_data.char_id_to_username[parameters[0]]
11
+ ]
12
+ if char.username in world_data.party_members:
13
+ char.update_equipment(parameters[2])
14
+ ws_update_character_equipment(world_data)
15
+ else:
16
+ world_data.change_equipment_log[parameters[0]] = parameters[2]
17
+
18
+
19
+ def ws_update_character_equipment(world_data: WorldData):
20
+ event = {
21
+ "type": "update_dps",
22
+ "payload": {"party_members": world_data.serialize_party_members()},
23
+ }
24
+ send_event(event)
@@ -0,0 +1,35 @@
1
+ from albibong.classes.character import Character
2
+ from albibong.classes.event_handler.world_data_utils import WorldDataUtils
3
+ from albibong.classes.world_data import WorldData
4
+ from albibong.threads.websocket_server import send_event
5
+
6
+
7
+ def handle_event_health_update(world_data: WorldData, parameters):
8
+
9
+ if world_data.is_dps_meter_running == False:
10
+ return
11
+
12
+ if 0 not in parameters or 6 not in parameters or 2 not in parameters:
13
+ return
14
+
15
+ nominal = parameters[2]
16
+ target = parameters[0]
17
+ inflictor = parameters[6]
18
+
19
+ WorldDataUtils.update_damage_or_heal(world_data, target, inflictor, nominal)
20
+
21
+
22
+ def handle_event_health_updates(world_data: WorldData, parameters):
23
+
24
+ if world_data.is_dps_meter_running == False:
25
+ return
26
+
27
+ if 0 not in parameters or 6 not in parameters or 2 not in parameters:
28
+ return
29
+
30
+ for i in range(len(parameters[2])):
31
+ nominal = parameters[2][i]
32
+ target = parameters[0]
33
+ inflictor = parameters[6][i]
34
+
35
+ WorldDataUtils.update_damage_or_heal(world_data, target, inflictor, nominal)
@@ -0,0 +1,17 @@
1
+ from albibong.classes.character import Character
2
+ from albibong.classes.world_data import WorldData
3
+
4
+
5
+ def handle_event_in_combat_state_update(world_data: WorldData, parameters):
6
+
7
+ if parameters[0] not in world_data.char_id_to_username:
8
+ # character not initialized
9
+ return
10
+
11
+ name = world_data.char_id_to_username[parameters[0]]
12
+ char: Character = world_data.characters[name]
13
+
14
+ if 1 in parameters:
15
+ char.update_combat_duration(True)
16
+ else:
17
+ char.update_combat_duration(False)
@@ -0,0 +1,44 @@
1
+ from albibong.classes.character import Character
2
+ from albibong.classes.coords import Coords
3
+ from albibong.classes.event_handler.world_data_utils import WorldDataUtils
4
+ from albibong.classes.utils import Utils
5
+ from albibong.classes.world_data import WorldData
6
+
7
+
8
+ def handle_event_new_character(world_data: WorldData, parameters):
9
+
10
+ id = parameters[0]
11
+ uuid = parameters[7]
12
+ username = parameters[1]
13
+ guild = parameters[8] if 8 in parameters else ""
14
+ alliance = parameters[49] if 49 in parameters else ""
15
+ coords = (
16
+ Coords(parameters[15][0], parameters[15][1])
17
+ if 15 in parameters
18
+ else Coords(0, 0)
19
+ )
20
+ equipments = parameters[38] if 38 in parameters else []
21
+
22
+ # initiate character
23
+ if username not in world_data.characters:
24
+ char: Character = Character(
25
+ id=id,
26
+ uuid=Utils.convert_int_arr_to_uuid(uuid),
27
+ username=username,
28
+ guild=guild,
29
+ alliance=alliance,
30
+ coords=coords,
31
+ )
32
+ char.update_equipment(equipments)
33
+ world_data.characters[char.username] = char
34
+ world_data.char_id_to_username[char.id] = char.username
35
+ world_data.char_uuid_to_username[char.uuid] = char.username
36
+
37
+ # change map
38
+ else:
39
+ char: Character = world_data.characters[username]
40
+ char.update_equipment(equipments)
41
+ char.coords = coords
42
+ WorldDataUtils.convert_id_to_name(
43
+ world_data, old_id=char.id, new_id=id, char=char
44
+ )
@@ -0,0 +1,14 @@
1
+ from albibong.classes.character import Character
2
+ from albibong.classes.world_data import WorldData
3
+
4
+
5
+ def handle_event_other_grabbed_loot(world_data: WorldData, parameters):
6
+
7
+ # update char data
8
+ if 2 in parameters and parameters[2] in world_data.characters:
9
+ char: Character = world_data.characters[parameters[2]]
10
+ char.update_loot(parameters)
11
+
12
+ # update dungeon data
13
+ if world_data.current_dungeon and parameters[2] == world_data.me.username:
14
+ world_data.current_dungeon.update_loot(parameters)
@@ -0,0 +1,38 @@
1
+ from uuid import UUID
2
+ from albibong.classes.world_data import WorldData
3
+ from albibong.threads.websocket_server import send_event
4
+
5
+
6
+ def handle_event_party_joined(world_data: WorldData, parameters):
7
+ world_data.party_members = set(parameters[5])
8
+ ws_update_party_member(world_data)
9
+
10
+
11
+ def handle_event_party_disbanded(world_data: WorldData, parameters):
12
+ world_data.party_members = {world_data.me.username}
13
+ ws_update_party_member(world_data)
14
+
15
+
16
+ def handle_event_party_player_joined(world_data: WorldData, parameters):
17
+ world_data.party_members.add(parameters[2])
18
+ ws_update_party_member(world_data)
19
+
20
+
21
+ def handle_event_party_player_left(world_data: WorldData, parameters):
22
+ uuid = UUID(bytes=bytes(parameters[1]))
23
+
24
+ if uuid in world_data.char_uuid_to_username:
25
+ name = world_data.char_uuid_to_username[uuid]
26
+
27
+ # self out party
28
+ if name == world_data.me.username:
29
+ world_data.party_members = {world_data.me.username}
30
+ ws_update_party_member(world_data)
31
+
32
+
33
+ def ws_update_party_member(world_data: WorldData):
34
+ event = {
35
+ "type": "update_dps",
36
+ "payload": {"party_members": world_data.serialize_party_members()},
37
+ }
38
+ send_event(event)
@@ -0,0 +1,7 @@
1
+ from albibong.classes.world_data import WorldData
2
+
3
+
4
+ def handle_event_update_fame(world_data: WorldData, parameters):
5
+ world_data.me.update_fame(parameters)
6
+ if world_data.current_dungeon:
7
+ world_data.current_dungeon.update_fame(parameters)
@@ -0,0 +1,11 @@
1
+ from albibong.classes.world_data import WorldData
2
+
3
+
4
+ def handle_event_update_re_spec_points(world_data: WorldData, parameters):
5
+
6
+ # update char data
7
+ world_data.me.update_re_spec(parameters)
8
+
9
+ # update dungeon data
10
+ if world_data.current_dungeon:
11
+ world_data.current_dungeon.update_re_spec(parameters)
@@ -0,0 +1,43 @@
1
+ from albibong.classes.event_handler.world_data_utils import WorldDataUtils
2
+ from albibong.classes.location import Location
3
+ from albibong.classes.world_data import WorldData
4
+ from albibong.threads.websocket_server import send_event
5
+
6
+
7
+ def handle_operation_change_cluster(world_data: WorldData, parameters):
8
+ world_data.change_equipment_log = {}
9
+
10
+ if 1 in parameters:
11
+ check_map = Location.get_location_from_code(parameters[1])
12
+ map_type_splitted = set(check_map.type.split("_"))
13
+ WorldDataUtils.set_dungeon_status(world_data, check_map, map_type_splitted)
14
+
15
+ if "ISLAND" in map_type_splitted or "HIDEOUT" in map_type_splitted:
16
+ check_map.name = f"{parameters[2]}'s {check_map.name}"
17
+ world_data.current_map = check_map
18
+
19
+ elif 0 in parameters:
20
+ check_map = Location.get_location_from_code(parameters[0])
21
+ map_type_splitted = set(check_map.type.split("_"))
22
+ is_dungeon = WorldDataUtils.set_dungeon_status(
23
+ world_data, check_map, map_type_splitted
24
+ )
25
+ if is_dungeon == False:
26
+ world_data.current_map = Location.get_location_from_code(parameters[0])
27
+
28
+ ws_update_location(world_data)
29
+
30
+
31
+ def ws_update_location(world_data: WorldData):
32
+ event = {
33
+ "type": "update_location",
34
+ "payload": {
35
+ "map": world_data.current_map.name if world_data.current_map else "None",
36
+ "dungeon": (
37
+ world_data.current_dungeon.name
38
+ if world_data.current_dungeon
39
+ else "None"
40
+ ),
41
+ },
42
+ }
43
+ send_event(event)
@@ -0,0 +1,78 @@
1
+ from albibong.classes.dungeon import Dungeon
2
+ from albibong.classes.event_handler.world_data_utils import WorldDataUtils
3
+ from albibong.classes.location import Location
4
+ from albibong.classes.utils import Utils
5
+ from albibong.classes.world_data import WorldData
6
+ from albibong.threads.websocket_server import send_event
7
+
8
+
9
+ def handle_operation_join(world_data: WorldData, parameters):
10
+ # set my character
11
+ WorldDataUtils.convert_id_to_name(
12
+ world_data, old_id=world_data.me.id, new_id=parameters[0], char=world_data.me
13
+ )
14
+ world_data.me.uuid = Utils.convert_int_arr_to_uuid(parameters[1])
15
+ world_data.me.username = parameters[2]
16
+ world_data.me.guild = parameters[57] if 57 in parameters else ""
17
+ world_data.me.alliance = parameters[77] if 77 in parameters else ""
18
+ if world_data.me.id in world_data.change_equipment_log:
19
+ world_data.me.update_equipment(
20
+ world_data.change_equipment_log[world_data.me.id]
21
+ )
22
+
23
+ # put self in characters list
24
+ world_data.characters[world_data.me.username] = world_data.me
25
+ world_data.char_uuid_to_username[world_data.me.uuid] = world_data.me.username
26
+
27
+ # put self in party
28
+ world_data.party_members.add(world_data.me.username)
29
+
30
+ # set map my character is currently in
31
+ if parameters[8][0] == "@":
32
+ area = parameters[8].split("@")
33
+ if area[1] == "RANDOMDUNGEON":
34
+ check_map = Location.get_location_from_code(area[1])
35
+ WorldDataUtils.start_current_dungeon(
36
+ world_data, type=check_map.type, name=check_map.name
37
+ )
38
+
39
+ ws_init_character(world_data)
40
+ ws_update_location(world_data)
41
+ ws_update_dps(world_data)
42
+
43
+
44
+ def ws_init_character(world_data: WorldData):
45
+ event = {
46
+ "type": "init_character",
47
+ "payload": {
48
+ "username": world_data.me.username,
49
+ "fame": world_data.me.fame_gained,
50
+ "re_spec": world_data.me.re_spec_gained,
51
+ "silver": world_data.me.silver_gained,
52
+ "weapon": world_data.me.equipment[0].image,
53
+ },
54
+ }
55
+ send_event(event)
56
+
57
+
58
+ def ws_update_location(world_data: WorldData):
59
+ event = {
60
+ "type": "update_location",
61
+ "payload": {
62
+ "map": world_data.current_map.name if world_data.current_map else "None",
63
+ "dungeon": (
64
+ Dungeon.serialize(world_data.current_dungeon)
65
+ if world_data.current_dungeon
66
+ else None
67
+ ),
68
+ },
69
+ }
70
+ send_event(event)
71
+
72
+
73
+ def ws_update_dps(world_data: WorldData):
74
+ event = {
75
+ "type": "update_dps",
76
+ "payload": {"party_members": world_data.serialize_party_members()},
77
+ }
78
+ send_event(event)
@@ -0,0 +1,8 @@
1
+ from albibong.classes.world_data import WorldData
2
+
3
+
4
+ def handle_operation_move(world_data: WorldData, parameters):
5
+ if not world_data.me:
6
+ return
7
+
8
+ world_data.me.update_coords(parameters)
@@ -0,0 +1,102 @@
1
+ from collections import deque
2
+ import json
3
+ import os
4
+
5
+ from albibong.classes.character import Character
6
+ from albibong.classes.dungeon import Dungeon
7
+ from albibong.classes.location import Location
8
+ from albibong.classes.utils import Utils
9
+ from albibong.classes.world_data import WorldData
10
+ from albibong.threads.websocket_server import send_event
11
+
12
+ FILENAME = os.path.join(os.path.expanduser("~"), "Albibong/list_dungeon.json")
13
+ os.makedirs(os.path.dirname(FILENAME), exist_ok=True)
14
+
15
+
16
+ class WorldDataUtils:
17
+
18
+ def end_current_dungeon(world_data: WorldData):
19
+ if world_data.current_dungeon:
20
+ list_dungeon = deque()
21
+
22
+ try:
23
+ with open(FILENAME) as json_file:
24
+ list_dungeon = deque(json.load(json_file))
25
+ except:
26
+ pass
27
+
28
+ world_data.current_dungeon.get_elapsed_time()
29
+ list_dungeon.appendleft(Dungeon.serialize(world_data.current_dungeon))
30
+
31
+ with open(FILENAME, "w") as json_file:
32
+ json.dump(list(list_dungeon), json_file)
33
+
34
+ WorldDataUtils.ws_update_dungeon(list(list_dungeon))
35
+
36
+ world_data.current_dungeon = None
37
+
38
+ def ws_update_dungeon(list_dungeon: list):
39
+ event = {
40
+ "type": "update_dungeon",
41
+ "payload": {"list_dungeon": list_dungeon},
42
+ }
43
+ send_event(event)
44
+
45
+ @staticmethod
46
+ def start_current_dungeon(world_data: WorldData, type: str, name: str):
47
+ if world_data.current_dungeon == None:
48
+ new_dungeon = Dungeon(type, name)
49
+ world_data.current_dungeon = new_dungeon
50
+
51
+ @staticmethod
52
+ def set_dungeon_status(
53
+ world_data: WorldData, check_map: Location, map_type_splitted: set
54
+ ):
55
+ if "EXPEDITION" in map_type_splitted or "DUNGEON" in map_type_splitted:
56
+ WorldDataUtils.start_current_dungeon(
57
+ world_data, type=check_map.type, name=check_map.name
58
+ )
59
+ elif (
60
+ "EXPEDITION" not in map_type_splitted or "DUNGEON" not in map_type_splitted
61
+ ):
62
+ WorldDataUtils.end_current_dungeon(world_data)
63
+ return False
64
+
65
+ @staticmethod
66
+ def convert_id_to_name(world_data: WorldData, old_id, new_id, char: Character):
67
+ if old_id in world_data.char_id_to_username:
68
+ world_data.char_id_to_username.pop(old_id) # delete old relative id
69
+ char.id = new_id
70
+ world_data.char_id_to_username[char.id] = char.username # add new relative id
71
+
72
+ @staticmethod
73
+ def update_damage_or_heal(world_data: WorldData, target, inflictor, nominal):
74
+
75
+ if inflictor not in world_data.char_id_to_username:
76
+ # character not initialized yet
77
+ return
78
+
79
+ username = world_data.char_id_to_username[inflictor]
80
+
81
+ if username == "not initialized":
82
+ # self not initialized
83
+ return
84
+
85
+ char: Character = world_data.characters[username]
86
+
87
+ if nominal < 0:
88
+ if target == inflictor:
89
+ # suicide
90
+ return
91
+ char.update_damage_dealt(abs(nominal))
92
+ else:
93
+ char.update_heal_dealt(nominal)
94
+
95
+ WorldDataUtils.ws_update_damage_heal(world_data)
96
+
97
+ def ws_update_damage_heal(world_data: WorldData):
98
+ event = {
99
+ "type": "update_dps",
100
+ "payload": {"party_members": world_data.serialize_party_members()},
101
+ }
102
+ send_event(event)