albibong 1.0.4__py3-none-any.whl → 1.0.6__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 (29) hide show
  1. albibong/classes/character.py +35 -7
  2. albibong/classes/event_handler/__init__.py +116 -0
  3. albibong/classes/event_handler/handle_event_character_equipment_changed.py +24 -0
  4. albibong/classes/event_handler/handle_event_health.py +35 -0
  5. albibong/classes/event_handler/handle_event_in_combat_state_update.py +17 -0
  6. albibong/classes/event_handler/handle_event_new_character.py +44 -0
  7. albibong/classes/event_handler/handle_event_other_grabbed_loot.py +14 -0
  8. albibong/classes/event_handler/handle_event_party.py +38 -0
  9. albibong/classes/event_handler/handle_event_update_fame.py +7 -0
  10. albibong/classes/event_handler/handle_event_update_re_spec_points.py +11 -0
  11. albibong/classes/event_handler/handle_operation_change_cluster.py +43 -0
  12. albibong/classes/event_handler/handle_operation_join.py +78 -0
  13. albibong/classes/event_handler/handle_operation_move.py +8 -0
  14. albibong/classes/event_handler/world_data_utils.py +102 -0
  15. albibong/classes/item.py +1 -1
  16. albibong/classes/packet_handler.py +6 -4
  17. albibong/classes/world_data.py +14 -318
  18. albibong/gui_dist/assets/{index-BFSx0nua.css → index-DZvgNqlG.css} +1 -1
  19. albibong/gui_dist/assets/index-Dt6hyZiS.css +1 -0
  20. albibong/gui_dist/assets/{index-DAndaN_4.js → index-E7pha23k.js} +20 -20
  21. albibong/gui_dist/assets/index-WIuC9Mnh.js +161 -0
  22. albibong/gui_dist/index.html +2 -2
  23. albibong/requirements.txt +0 -1
  24. albibong/threads/websocket_server.py +30 -0
  25. {albibong-1.0.4.dist-info → albibong-1.0.6.dist-info}/METADATA +2 -3
  26. {albibong-1.0.4.dist-info → albibong-1.0.6.dist-info}/RECORD +29 -14
  27. {albibong-1.0.4.dist-info → albibong-1.0.6.dist-info}/WHEEL +1 -1
  28. {albibong-1.0.4.dist-info → albibong-1.0.6.dist-info}/entry_points.txt +0 -0
  29. {albibong-1.0.4.dist-info → albibong-1.0.6.dist-info}/licenses/LICENSE +0 -0
@@ -1,22 +1,10 @@
1
- import json
2
- import os
3
- from collections import deque
4
- import threading
5
1
  from uuid import UUID
6
- from playsound import playsound
7
2
 
8
3
  from albibong.classes.character import Character
9
4
  from albibong.classes.coords import Coords
10
5
  from albibong.classes.dungeon import Dungeon
11
6
  from albibong.classes.item import Item
12
7
  from albibong.classes.location import Location
13
- from albibong.classes.utils import Utils
14
- from albibong.resources.EventCode import EventCode
15
- from albibong.resources.OperationCode import OperationCode
16
- from albibong.threads.websocket_server import send_event
17
-
18
- FILENAME = os.path.join(os.path.expanduser("~"), "Albibong/list_dungeon.json")
19
- os.makedirs(os.path.dirname(FILENAME), exist_ok=True)
20
8
 
21
9
 
22
10
  class WorldData:
@@ -39,310 +27,6 @@ class WorldData:
39
27
  self.party_members: set[str] = set()
40
28
  self.is_dps_meter_running: bool = True
41
29
 
42
- def handle_response(self, parameters):
43
- if 253 in parameters:
44
- if parameters[253] == OperationCode.JOIN.value:
45
- self.handle_join_response(parameters)
46
- elif parameters[253] == OperationCode.CHANGE_CLUSTER.value:
47
- self.set_location(parameters)
48
-
49
- def handle_event(self, parameters):
50
- if 252 in parameters:
51
- if parameters[252] == EventCode.OTHER_GRABBED_LOOT.value:
52
- if 2 in parameters and parameters[2] in self.characters:
53
- char: Character = self.characters[parameters[2]]
54
- char.update_loot(parameters)
55
- if self.current_dungeon and parameters[2] == self.me.username:
56
- self.current_dungeon.update_loot(parameters)
57
- elif parameters[252] == EventCode.UPDATE_FAME.value:
58
- self.me.update_fame(parameters)
59
- if self.current_dungeon:
60
- self.current_dungeon.update_fame(parameters)
61
- elif parameters[252] == EventCode.UPDATE_RE_SPEC_POINTS.value:
62
- self.me.update_re_spec(parameters)
63
- if self.current_dungeon:
64
- self.current_dungeon.update_re_spec(parameters)
65
- elif parameters[252] == EventCode.CHARACTER_EQUIPMENT_CHANGED.value:
66
- self.change_character_equipment(parameters)
67
- elif (
68
- parameters[252] == EventCode.HEALTH_UPDATE.value
69
- and self.is_dps_meter_running
70
- ):
71
- self.handle_health_update(parameters)
72
- elif (
73
- parameters[252] == EventCode.HEALTH_UPDATES.value
74
- and self.is_dps_meter_running
75
- ):
76
- self.handle_health_updates(parameters)
77
- elif (
78
- parameters[252] == EventCode.PARTY_JOINED.value
79
- or parameters[252] == EventCode.PARTY_PLAYER_JOINED.value
80
- or parameters[252] == EventCode.PARTY_PLAYER_LEFT.value
81
- or parameters[252] == EventCode.PARTY_DISBANDED.value
82
- ):
83
- self.update_party_member(parameters)
84
- elif parameters[252] == EventCode.NEW_CHARACTER.value:
85
- self.create_character(
86
- id=parameters[0],
87
- uuid=parameters[7],
88
- username=parameters[1],
89
- guild=parameters[8] if 8 in parameters else "",
90
- alliance=parameters[49] if 49 in parameters else "",
91
- coords=(
92
- Coords(parameters[15][0], parameters[15][1])
93
- if 15 in parameters
94
- else Coords(0, 0)
95
- ),
96
- equipments=parameters[38] if 38 in parameters else [],
97
- )
98
- ...
99
-
100
- def handle_request(self, parameters):
101
- if 253 in parameters:
102
- if parameters[253] == OperationCode.MOVE.value and self.me:
103
- self.me.update_coords(parameters)
104
- ...
105
-
106
- def end_current_dungeon(self):
107
- if self.current_dungeon:
108
- list_dungeon = deque()
109
-
110
- try:
111
- with open(FILENAME) as json_file:
112
- list_dungeon = deque(json.load(json_file))
113
- except:
114
- pass
115
-
116
- self.current_dungeon.get_elapsed_time()
117
- list_dungeon.appendleft(Dungeon.serialize(self.current_dungeon))
118
-
119
- with open(FILENAME, "w") as json_file:
120
- json.dump(list(list_dungeon), json_file)
121
-
122
- event = {
123
- "type": "update_dungeon",
124
- "payload": {"list_dungeon": list(list_dungeon)},
125
- }
126
- send_event(event)
127
- self.current_dungeon = None
128
-
129
- def start_current_dungeon(self, type, name):
130
- if self.current_dungeon == None:
131
- new_dungeon = Dungeon(type, name)
132
- self.current_dungeon = new_dungeon
133
-
134
- def set_dungeon_status(self, check_map, map_type_splitted):
135
- if "EXPEDITION" in map_type_splitted or "DUNGEON" in map_type_splitted:
136
- self.start_current_dungeon(type=check_map.type, name=check_map.name)
137
- elif (
138
- "EXPEDITION" not in map_type_splitted or "DUNGEON" not in map_type_splitted
139
- ):
140
- self.end_current_dungeon()
141
- return False
142
-
143
- def set_location(self, parameters):
144
- self.change_equipment_log = {}
145
-
146
- if 1 in parameters:
147
- check_map = Location.get_location_from_code(parameters[1])
148
- map_type_splitted = set(check_map.type.split("_"))
149
- self.set_dungeon_status(check_map, map_type_splitted)
150
-
151
- if "ISLAND" in map_type_splitted or "HIDEOUT" in map_type_splitted:
152
- check_map.name = f"{parameters[2]}'s {check_map.name}"
153
- self.current_map = check_map
154
-
155
- elif 0 in parameters:
156
- check_map = Location.get_location_from_code(parameters[0])
157
- map_type_splitted = set(check_map.type.split("_"))
158
- is_dungeon = self.set_dungeon_status(check_map, map_type_splitted)
159
- if is_dungeon == False:
160
- self.current_map = Location.get_location_from_code(parameters[0])
161
-
162
- event = {
163
- "type": "update_location",
164
- "payload": {
165
- "map": self.current_map.name if self.current_map else "None",
166
- "dungeon": (
167
- self.current_dungeon.name if self.current_dungeon else "None"
168
- ),
169
- },
170
- }
171
- send_event(event)
172
-
173
- def update_party_member(self, parameters):
174
- if parameters[252] == EventCode.PARTY_JOINED.value:
175
- self.party_members = set(parameters[5])
176
- elif parameters[252] == EventCode.PARTY_DISBANDED.value:
177
- self.party_members = {self.me.username}
178
- elif parameters[252] == EventCode.PARTY_PLAYER_JOINED.value:
179
- self.party_members.add(parameters[2])
180
- elif parameters[252] == EventCode.PARTY_PLAYER_LEFT.value:
181
- uuid = UUID(bytes=bytes(parameters[1]))
182
- if uuid in self.char_uuid_to_username:
183
- name = self.char_uuid_to_username[uuid]
184
- if name == self.me.username:
185
- self.party_members = {self.me.username}
186
- event = {
187
- "type": "update_dps",
188
- "payload": {"party_members": self.serialize_party_members()},
189
- }
190
- send_event(event)
191
-
192
- def handle_health_update(self, parameters):
193
-
194
- nominal = parameters[2] if 2 in parameters else 0
195
- target = parameters[0]
196
- inflictor = parameters[6]
197
-
198
- self.update_damage_or_heal(target, inflictor, nominal)
199
-
200
- def update_damage_or_heal(self, target, inflictor, nominal):
201
-
202
- if inflictor not in self.char_id_to_username:
203
- # character not initialized yet
204
- return
205
-
206
- username = self.char_id_to_username[inflictor]
207
-
208
- if username == "not initialized":
209
- # self not initialized
210
- return
211
-
212
- char: Character = self.characters[username]
213
-
214
- if nominal < 0:
215
- if target == inflictor:
216
- # suicide
217
- return
218
- char.update_damage_dealt(abs(nominal))
219
- else:
220
- char.update_heal_dealt(nominal)
221
-
222
- event = {
223
- "type": "update_dps",
224
- "payload": {"party_members": self.serialize_party_members()},
225
- }
226
- send_event(event)
227
-
228
- def handle_health_updates(self, parameters):
229
-
230
- for i in range(len(parameters[2])):
231
- nominal = parameters[2][i]
232
- target = parameters[0]
233
- inflictor = parameters[6][i]
234
-
235
- self.update_damage_or_heal(target, inflictor, nominal)
236
-
237
- def change_character_equipment(self, parameters):
238
- if 2 in parameters:
239
- if parameters[0] in self.char_id_to_username:
240
- if self.char_id_to_username[parameters[0]] != "not initialized":
241
- char = self.characters[self.char_id_to_username[parameters[0]]]
242
- if char.username in self.party_members:
243
- char.update_equipment(parameters[2])
244
- event = {
245
- "type": "update_dps",
246
- "payload": {
247
- "party_members": self.serialize_party_members()
248
- },
249
- }
250
- send_event(event)
251
- else:
252
- self.change_equipment_log[parameters[0]] = parameters[2]
253
-
254
- def handle_join_response(self, parameters):
255
- # set my character
256
- self.convert_id_to_name(old_id=self.me.id, new_id=parameters[0], char=self.me)
257
- self.me.uuid = Utils.convert_int_arr_to_uuid(parameters[1])
258
- self.me.username = parameters[2]
259
- self.me.guild = parameters[57] if 57 in parameters else ""
260
- self.me.alliance = parameters[77] if 77 in parameters else ""
261
- if self.me.id in self.change_equipment_log:
262
- self.me.update_equipment(self.change_equipment_log[self.me.id])
263
-
264
- # put self in characters list
265
- self.characters[self.me.username] = self.me
266
- self.char_uuid_to_username[self.me.uuid] = self.me.username
267
-
268
- # put self in party
269
- self.party_members.add(self.me.username)
270
-
271
- # set map my character is currently in
272
- if parameters[8][0] == "@":
273
- area = parameters[8].split("@")
274
- if area[1] == "RANDOMDUNGEON":
275
- check_map = Location.get_location_from_code(area[1])
276
- self.start_current_dungeon(type=check_map.type, name=check_map.name)
277
-
278
- event_char = {
279
- "type": "init_character",
280
- "payload": {
281
- "username": self.me.username,
282
- "fame": self.me.fame_gained,
283
- "re_spec": self.me.re_spec_gained,
284
- "silver": self.me.silver_gained,
285
- "weapon": self.me.equipment[0].image,
286
- },
287
- }
288
- event_map = {
289
- "type": "update_location",
290
- "payload": {
291
- "map": self.current_map.name if self.current_map else "None",
292
- "dungeon": (
293
- Dungeon.serialize(self.current_dungeon)
294
- if self.current_dungeon
295
- else None
296
- ),
297
- },
298
- }
299
- event_party = {
300
- "type": "update_dps",
301
- "payload": {"party_members": self.serialize_party_members()},
302
- }
303
- send_event(event_map)
304
- send_event(event_char)
305
- send_event(event_party)
306
-
307
- def convert_id_to_name(self, old_id, new_id, char: Character):
308
- if old_id in self.char_id_to_username:
309
- self.char_id_to_username.pop(old_id) # delete old relative id
310
- char.id = new_id
311
- self.char_id_to_username[char.id] = char.username # add new relative id
312
-
313
- def create_character(
314
- self,
315
- id: int,
316
- uuid: list[int],
317
- username: str,
318
- guild: str,
319
- alliance: str,
320
- equipments: list[str] = [],
321
- coords: Coords = Coords(0, 0),
322
- ):
323
-
324
- # initiate character
325
- if username not in self.characters:
326
- char: Character = Character(
327
- id=id,
328
- uuid=Utils.convert_int_arr_to_uuid(uuid),
329
- username=username,
330
- guild=guild,
331
- alliance=alliance,
332
- coords=coords,
333
- )
334
- char.update_equipment(equipments)
335
- self.characters[char.username] = char
336
- self.char_id_to_username[char.id] = char.username
337
- self.char_uuid_to_username[char.uuid] = char.username
338
-
339
- # change map
340
- else:
341
- char: Character = self.characters[username]
342
- char.update_equipment(equipments)
343
- char.coords = coords
344
- self.convert_id_to_name(old_id=char.id, new_id=id, char=char)
345
-
346
30
  def serialize_party_members(self):
347
31
  serialized = []
348
32
 
@@ -372,10 +56,18 @@ class WorldData:
372
56
  if total_heal > 0
373
57
  else 0
374
58
  )
59
+ duration = char.total_combat_duration
60
+
61
+ combat_duration = str(duration).split(".")[0]
62
+ dps = (
63
+ damage_dealt // duration.total_seconds()
64
+ if duration.total_seconds() != 0
65
+ else 0
66
+ )
375
67
  weapon = (
376
68
  Item.serialize(char.equipment[0])["image"]
377
69
  if char.equipment != []
378
- else "../public/No Equipment.png"
70
+ else "/No Equipment.png"
379
71
  )
380
72
 
381
73
  # member character not initialized
@@ -385,7 +77,9 @@ class WorldData:
385
77
  damage_percent = 0
386
78
  healing_dealt = 0
387
79
  heal_percent = 0
388
- weapon = "../public/No Equipment.png"
80
+ combat_duration = 0
81
+ dps = 0
82
+ weapon = "/No Equipment.png"
389
83
 
390
84
  data = {
391
85
  "username": username,
@@ -393,6 +87,8 @@ class WorldData:
393
87
  "damage_percent": damage_percent,
394
88
  "healing_dealt": healing_dealt,
395
89
  "heal_percent": heal_percent,
90
+ "combat_duration": combat_duration,
91
+ "dps": dps,
396
92
  "weapon": weapon,
397
93
  }
398
94
  serialized.append(data)
@@ -1 +1 @@
1
- *{box-sizing:border-box}:root{font-family:Inter,system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color-scheme:light dark;color:#ffffffde;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}p{margin:0}a{font-weight:500;color:#646cff;text-decoration:inherit}a:hover{color:#535bf2}#root,body{margin:auto;display:flex;flex-direction:column;justify-content:start;align-items:center;min-width:320px;min-height:100vh;color:#fff;width:100%}h1{font-size:2em;line-height:1}button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:500;font-family:inherit;background-color:#1a1a1a;cursor:pointer;transition:border-color .25s}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}@media (prefers-color-scheme: light){:root{color:#213547;background-color:#fff}a:hover{color:#747bff}button{background-color:#f9f9f9}}._dmgBar_zdqdf_1{background:linear-gradient(135deg,#ff6486,#6486ff);height:6px;border-radius:8px;margin-bottom:2px}._healBar_zdqdf_8{background:linear-gradient(135deg,#64ffde,#64ff90);height:2px;border-radius:4px}._dpsContainer_zdqdf_14{display:flex;flex-direction:column;justify-content:flex-start;width:100%;gap:4px;box-sizing:content-box;padding:16px}._dpsRow_zdqdf_24{display:flex;flex-direction:row;justify-content:space-between;align-items:center}._dpsNumber_zdqdf_31{width:128px;text-align:right}._hidden_zdqdf_36{display:none}._player_zdqdf_40{flex-grow:1}._checkboxColor_zdqdf_44{accent-color:#64d3ff}._container_pkz1i_1{display:flex;flex-direction:column;align-items:center;gap:8px;width:100%;gap:1.5rem}._snackbar_pkz1i_10{position:fixed;right:64px}._stats_pkz1i_15{display:flex;flex-direction:row;align-items:center;gap:.5rem}._options_pkz1i_22{display:flex;flex-direction:row;align-items:center;gap:2rem}._row_pkz1i_29{display:flex;width:100%;justify-content:space-between}._hidden_pkz1i_35{display:none}._dungeonContainer_mlu2u_1{border-radius:1rem;width:100%;padding:2rem;display:flex;flex-direction:column;gap:1rem}._tag_mlu2u_12{background-color:#64d3ff;padding:0 1rem;border-radius:1rem;color:#0f3c4e;font-weight:700}
1
+ *{box-sizing:border-box}:root{font-family:Inter,system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color-scheme:light dark;color:#ffffffde;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}p{margin:0}a{font-weight:500;color:#646cff;text-decoration:inherit}a:hover{color:#535bf2}#root,body{margin:auto;display:flex;flex-direction:column;justify-content:start;align-items:center;min-width:320px;min-height:100vh;color:#fff;width:100%}h1{font-size:2em;line-height:1}button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:500;font-family:inherit;background-color:#1a1a1a;cursor:pointer;transition:border-color .25s}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}@media (prefers-color-scheme: light){:root{color:#213547;background-color:#fff}a:hover{color:#747bff}button{background-color:#f9f9f9}}._dmgBar_zdqdf_1{background:linear-gradient(135deg,#ff6486,#6486ff);height:6px;border-radius:8px;margin-bottom:2px}._healBar_zdqdf_8{background:linear-gradient(135deg,#64ffde,#64ff90);height:2px;border-radius:4px}._dpsContainer_zdqdf_14{display:flex;flex-direction:column;justify-content:flex-start;width:100%;gap:4px;box-sizing:content-box;padding:16px}._dpsRow_zdqdf_24{display:flex;flex-direction:row;justify-content:space-between;align-items:center}._dpsNumber_zdqdf_31{width:128px;text-align:right}._hidden_zdqdf_36{display:none}._player_zdqdf_40{flex-grow:1}._checkboxColor_zdqdf_44{accent-color:#64d3ff}._dungeonContainer_3nxyx_1{border-radius:1rem;width:100%;padding:2rem;display:flex;flex-direction:column;gap:1rem}._tag_3nxyx_12{background-color:#64d3ff;padding:0 1rem;border-radius:1rem;color:#0f3c4e;font-weight:700}._stickToTop_3nxyx_20{z-index:10;position:sticky;top:64px;left:0;width:100%;padding:24px 0}._container_pkz1i_1{display:flex;flex-direction:column;align-items:center;gap:8px;width:100%;gap:1.5rem}._snackbar_pkz1i_10{position:fixed;right:64px}._stats_pkz1i_15{display:flex;flex-direction:row;align-items:center;gap:.5rem}._options_pkz1i_22{display:flex;flex-direction:row;align-items:center;gap:2rem}._row_pkz1i_29{display:flex;width:100%;justify-content:space-between}._hidden_pkz1i_35{display:none}
@@ -0,0 +1 @@
1
+ *{box-sizing:border-box}:root{font-family:Inter,system-ui,Avenir,Helvetica,Arial,sans-serif;line-height:1.5;font-weight:400;color-scheme:light dark;color:#ffffffde;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}p{margin:0}a{font-weight:500;color:#646cff;text-decoration:inherit}a:hover{color:#535bf2}#root,body{margin:auto;display:flex;flex-direction:column;justify-content:start;align-items:center;min-width:320px;min-height:100vh;color:#fff;width:100%}h1{font-size:2em;line-height:1}button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:500;font-family:inherit;background-color:#1a1a1a;cursor:pointer;transition:border-color .25s}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}@media (prefers-color-scheme: light){:root{color:#213547;background-color:#fff}a:hover{color:#747bff}button{background-color:#f9f9f9}}._dmgBar_uvx94_1{background:linear-gradient(135deg,#ff6486,#6486ff);height:6px;border-radius:8px;margin-bottom:2px}._healBar_uvx94_8{background:linear-gradient(135deg,#64ffde,#64ff90);height:2px;border-radius:4px}._dpsContainer_uvx94_14{display:flex;flex-direction:column;justify-content:flex-start;width:100%;gap:4px;box-sizing:content-box;padding:16px}._dpsRow_uvx94_24{display:flex;flex-direction:row;justify-content:space-between;align-items:center}._dpsNumber_uvx94_31{width:128px;text-align:right}._dpsButton_uvx94_36{display:flex;flex-grow:1;gap:1rem}._hidden_uvx94_42{display:none}._player_uvx94_46{flex-grow:1}._checkboxColor_uvx94_50{accent-color:#64d3ff}._dungeonContainer_3nxyx_1{border-radius:1rem;width:100%;padding:2rem;display:flex;flex-direction:column;gap:1rem}._tag_3nxyx_12{background-color:#64d3ff;padding:0 1rem;border-radius:1rem;color:#0f3c4e;font-weight:700}._stickToTop_3nxyx_20{z-index:10;position:sticky;top:64px;left:0;width:100%;padding:24px 0}._container_pkz1i_1{display:flex;flex-direction:column;align-items:center;gap:8px;width:100%;gap:1.5rem}._snackbar_pkz1i_10{position:fixed;right:64px}._stats_pkz1i_15{display:flex;flex-direction:row;align-items:center;gap:.5rem}._options_pkz1i_22{display:flex;flex-direction:row;align-items:center;gap:2rem}._row_pkz1i_29{display:flex;width:100%;justify-content:space-between}._hidden_pkz1i_35{display:none}