albibong 1.0.2__tar.gz → 1.0.4__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 (53) hide show
  1. {albibong-1.0.2 → albibong-1.0.4}/PKG-INFO +2 -1
  2. {albibong-1.0.2 → albibong-1.0.4}/pyproject.toml +3 -2
  3. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/__init__.py +10 -4
  4. albibong-1.0.4/src/albibong/assets/boom_small.mp3 +0 -0
  5. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/classes/character.py +5 -7
  6. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/classes/logger.py +1 -1
  7. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/classes/world_data.py +109 -43
  8. albibong-1.0.4/src/albibong/gui_dist/Albibong.png +0 -0
  9. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/gui_dist/index.html +3 -3
  10. albibong-1.0.4/src/albibong/requirements.txt +4 -0
  11. albibong-1.0.4/src/albibong/resources/EventCode.py +588 -0
  12. albibong-1.0.4/src/albibong/resources/event_code.json +586 -0
  13. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/resources/items.json +16421 -16051
  14. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/threads/http_server.py +2 -2
  15. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/threads/sniffer_thread.py +1 -0
  16. albibong-1.0.2/src/albibong/requirements.txt +0 -3
  17. albibong-1.0.2/src/albibong/resources/EventCode.py +0 -587
  18. albibong-1.0.2/src/albibong/resources/event_code.json +0 -585
  19. {albibong-1.0.2 → albibong-1.0.4}/.gitignore +0 -0
  20. {albibong-1.0.2 → albibong-1.0.4}/LICENSE +0 -0
  21. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/__main__.py +0 -0
  22. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/classes/__init__.py +0 -0
  23. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/classes/coords.py +0 -0
  24. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/classes/dungeon.py +0 -0
  25. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/classes/item.py +0 -0
  26. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/classes/location.py +0 -0
  27. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/classes/packet_handler.py +0 -0
  28. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/classes/utils.py +0 -0
  29. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/gui_dist/No Equipment.png +0 -0
  30. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/gui_dist/assets/index-BFSx0nua.css +0 -0
  31. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/gui_dist/assets/index-DAndaN_4.js +0 -0
  32. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/gui_dist/fame.png +0 -0
  33. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/gui_dist/re_spec.png +0 -0
  34. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/gui_dist/silver.png +0 -0
  35. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/gui_dist/vite.svg +0 -0
  36. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/__init__.py +0 -0
  37. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/command_type.py +0 -0
  38. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/crc_calculator.py +0 -0
  39. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/event_data.py +0 -0
  40. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/message_type.py +0 -0
  41. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/number_serializer.py +0 -0
  42. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/operation_request.py +0 -0
  43. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/operation_response.py +0 -0
  44. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/photon_packet_parser.py +0 -0
  45. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/protocol16_deserializer.py +0 -0
  46. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/protocol16_type.py +0 -0
  47. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/photon_packet_parser/segmented_packet.py +0 -0
  48. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/resources/OperationCode.py +0 -0
  49. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/resources/maps.json +0 -0
  50. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/resources/operation_code.json +0 -0
  51. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/threads/__init__.py +0 -0
  52. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/threads/packet_handler_thread.py +0 -0
  53. {albibong-1.0.2 → albibong-1.0.4}/src/albibong/threads/websocket_server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: albibong
3
- Version: 1.0.2
3
+ Version: 1.0.4
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
@@ -10,6 +10,7 @@ Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.8
13
+ Requires-Dist: playsound==1.3.0
13
14
  Requires-Dist: pywebview==5.1
14
15
  Requires-Dist: scapy==2.5.0
15
16
  Requires-Dist: websockets==12.0
@@ -19,7 +19,7 @@ albibong = "albibong:main"
19
19
 
20
20
  [project]
21
21
  name = "albibong"
22
- version = "1.0.2"
22
+ version = "1.0.4"
23
23
  authors = [
24
24
  { name="imjangkar", email="imjangkar@gmail.com" },
25
25
  ]
@@ -33,7 +33,8 @@ classifiers = [
33
33
  dependencies = [
34
34
  "scapy==2.5.0",
35
35
  "websockets==12.0",
36
- "pywebview==5.1"
36
+ "pywebview==5.1",
37
+ "playsound==1.3.0"
37
38
  ]
38
39
 
39
40
  [project.urls]
@@ -1,5 +1,6 @@
1
1
  import queue
2
2
  import random
3
+ import socket
3
4
  import sys
4
5
  from time import sleep
5
6
 
@@ -14,7 +15,8 @@ from albibong.threads.sniffer_thread import SnifferThread
14
15
  from albibong.threads.websocket_server import get_ws_server
15
16
 
16
17
  logger = Logger(__name__, stdout=True, log_to_file=False)
17
- PORT = random.randrange(8500,8999)
18
+ PORT = random.randrange(8500, 8999)
19
+
18
20
 
19
21
  def read_pcap(path):
20
22
  packet_handler = PacketHandler()
@@ -42,14 +44,18 @@ def sniff(useWebview):
42
44
  ws_server.start()
43
45
 
44
46
  if useWebview:
45
- print("addr",PORT)
46
47
 
47
- http_server = HttpServerThread(name="http_server", port=PORT)
48
+ sock = socket.socket()
49
+ sock.bind(("", 0))
50
+ port = sock.getsockname()[1]
51
+ sock.close()
52
+
53
+ http_server = HttpServerThread(name="http_server", port=port)
48
54
  http_server.start()
49
55
 
50
56
  window = webview.create_window(
51
57
  "Albibong",
52
- url=f"http://localhost:{PORT}/",
58
+ url=f"http://localhost:{port}/",
53
59
  width=1280,
54
60
  height=720,
55
61
  zoomable=True,
@@ -34,13 +34,11 @@ class Character:
34
34
  self.loot: list[str] = []
35
35
  self.equipment = equipment
36
36
 
37
- def handle_health_update(self, parameters):
38
- if 2 in parameters:
39
- if parameters[2] < 0:
40
- if parameters[0] != self.id:
41
- self.damage_dealt += abs(parameters[2])
42
- else:
43
- self.healing_dealt += abs(parameters[2])
37
+ def update_damage_dealt(self, nominal):
38
+ self.damage_dealt += nominal
39
+
40
+ def update_heal_dealt(self, nominal):
41
+ self.healing_dealt += nominal
44
42
 
45
43
  def update_coords(self, parameters):
46
44
  if 3 in parameters:
@@ -40,7 +40,7 @@ class Logger(logging.Logger):
40
40
  log_formatter = logging.Formatter("%(message)s")
41
41
 
42
42
  if log_to_file:
43
- file_handler = logging.FileHandler(log_filepath)
43
+ file_handler = logging.FileHandler(log_filepath, encoding="utf-8")
44
44
  file_handler.setFormatter(log_formatter)
45
45
  file_handler.setLevel(logging.INFO)
46
46
  self.addHandler(file_handler)
@@ -1,7 +1,9 @@
1
1
  import json
2
2
  import os
3
3
  from collections import deque
4
+ import threading
4
5
  from uuid import UUID
6
+ from playsound import playsound
5
7
 
6
8
  from albibong.classes.character import Character
7
9
  from albibong.classes.coords import Coords
@@ -43,8 +45,6 @@ class WorldData:
43
45
  self.handle_join_response(parameters)
44
46
  elif parameters[253] == OperationCode.CHANGE_CLUSTER.value:
45
47
  self.set_location(parameters)
46
- # elif parameters[253] == OperationCode.PARTY_LEAVE.value:
47
- # self.party_members = set(self.me.username)
48
48
 
49
49
  def handle_event(self, parameters):
50
50
  if 252 in parameters:
@@ -68,7 +68,12 @@ class WorldData:
68
68
  parameters[252] == EventCode.HEALTH_UPDATE.value
69
69
  and self.is_dps_meter_running
70
70
  ):
71
- self.update_dps_meter(parameters)
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)
72
77
  elif (
73
78
  parameters[252] == EventCode.PARTY_JOINED.value
74
79
  or parameters[252] == EventCode.PARTY_PLAYER_JOINED.value
@@ -169,7 +174,7 @@ class WorldData:
169
174
  if parameters[252] == EventCode.PARTY_JOINED.value:
170
175
  self.party_members = set(parameters[5])
171
176
  elif parameters[252] == EventCode.PARTY_DISBANDED.value:
172
- self.party_members = set()
177
+ self.party_members = {self.me.username}
173
178
  elif parameters[252] == EventCode.PARTY_PLAYER_JOINED.value:
174
179
  self.party_members.add(parameters[2])
175
180
  elif parameters[252] == EventCode.PARTY_PLAYER_LEFT.value:
@@ -177,26 +182,57 @@ class WorldData:
177
182
  if uuid in self.char_uuid_to_username:
178
183
  name = self.char_uuid_to_username[uuid]
179
184
  if name == self.me.username:
180
- self.party_members = set()
181
- if self.me.id != None:
182
- self.party_members.add(self.me.username)
185
+ self.party_members = {self.me.username}
183
186
  event = {
184
187
  "type": "update_dps",
185
188
  "payload": {"party_members": self.serialize_party_members()},
186
189
  }
187
190
  send_event(event)
188
191
 
189
- def update_dps_meter(self, parameters):
190
- if 6 in parameters and parameters[6] in self.char_id_to_username:
191
- username = self.char_id_to_username[parameters[6]]
192
- if username in self.party_members:
193
- char: Character = self.characters[username]
194
- char.handle_health_update(parameters)
195
- event = {
196
- "type": "update_dps",
197
- "payload": {"party_members": self.serialize_party_members()},
198
- }
199
- send_event(event)
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)
200
236
 
201
237
  def change_character_equipment(self, parameters):
202
238
  if 2 in parameters:
@@ -217,18 +253,21 @@ class WorldData:
217
253
 
218
254
  def handle_join_response(self, parameters):
219
255
  # set my character
220
-
221
256
  self.convert_id_to_name(old_id=self.me.id, new_id=parameters[0], char=self.me)
222
-
223
257
  self.me.uuid = Utils.convert_int_arr_to_uuid(parameters[1])
224
258
  self.me.username = parameters[2]
225
259
  self.me.guild = parameters[57] if 57 in parameters else ""
226
260
  self.me.alliance = parameters[77] if 77 in parameters else ""
227
- self.characters[self.me.username] = self.me
228
- self.char_uuid_to_username[self.me.uuid] = self.me.username
229
261
  if self.me.id in self.change_equipment_log:
230
262
  self.me.update_equipment(self.change_equipment_log[self.me.id])
231
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
+
232
271
  # set map my character is currently in
233
272
  if parameters[8][0] == "@":
234
273
  area = parameters[8].split("@")
@@ -257,8 +296,13 @@ class WorldData:
257
296
  ),
258
297
  },
259
298
  }
299
+ event_party = {
300
+ "type": "update_dps",
301
+ "payload": {"party_members": self.serialize_party_members()},
302
+ }
260
303
  send_event(event_map)
261
304
  send_event(event_char)
305
+ send_event(event_party)
262
306
 
263
307
  def convert_id_to_name(self, old_id, new_id, char: Character):
264
308
  if old_id in self.char_id_to_username:
@@ -304,32 +348,54 @@ class WorldData:
304
348
 
305
349
  total_damage = 0
306
350
  total_heal = 0
351
+
352
+ # get total damage and heal for percentage
307
353
  for key, value in self.characters.items():
308
354
  if key in self.party_members:
309
355
  total_damage += value.damage_dealt
310
356
  total_heal += value.healing_dealt
311
357
 
312
- for key, value in self.characters.items():
313
- if key in self.party_members:
314
- if value.equipment != []:
315
- weapon = Item.serialize(value.equipment[0])["image"]
316
- data = {
317
- "username": value.username,
318
- "damage_dealt": value.damage_dealt,
319
- "damage_percent": (
320
- round(value.damage_dealt / total_damage * 100, 2)
321
- if total_damage > 0
322
- else 0
323
- ),
324
- "healing_dealt": value.healing_dealt,
325
- "heal_percent": (
326
- round(value.healing_dealt / total_heal * 100, 2)
327
- if total_heal > 0
328
- else 0
329
- ),
330
- "weapon": weapon,
331
- }
332
- serialized.append(data)
358
+ for member in self.party_members:
359
+ # member character initialized
360
+ if member in self.characters:
361
+ char = self.characters[member]
362
+ username = char.username
363
+ damage_dealt = char.damage_dealt
364
+ damage_percent = (
365
+ round(char.damage_dealt / total_damage * 100, 2)
366
+ if total_damage > 0
367
+ else 0
368
+ )
369
+ healing_dealt = char.healing_dealt
370
+ heal_percent = (
371
+ round(char.healing_dealt / total_heal * 100, 2)
372
+ if total_heal > 0
373
+ else 0
374
+ )
375
+ weapon = (
376
+ Item.serialize(char.equipment[0])["image"]
377
+ if char.equipment != []
378
+ else "../public/No Equipment.png"
379
+ )
380
+
381
+ # member character not initialized
382
+ else:
383
+ username = member
384
+ damage_dealt = 0
385
+ damage_percent = 0
386
+ healing_dealt = 0
387
+ heal_percent = 0
388
+ weapon = "../public/No Equipment.png"
389
+
390
+ data = {
391
+ "username": username,
392
+ "damage_dealt": damage_dealt,
393
+ "damage_percent": damage_percent,
394
+ "healing_dealt": healing_dealt,
395
+ "heal_percent": heal_percent,
396
+ "weapon": weapon,
397
+ }
398
+ serialized.append(data)
333
399
  serialized.sort(key=lambda x: x["damage_dealt"], reverse=True)
334
400
  return serialized
335
401
 
@@ -1,10 +1,10 @@
1
- <!doctype html>
1
+ <!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
5
+ <link rel="icon" type="image/png" href="/Albibong.png" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Vite + React + TS</title>
7
+ <title>Albibong - Albion Data Tracker</title>
8
8
  <script type="module" crossorigin src="/assets/index-DAndaN_4.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-BFSx0nua.css">
10
10
  </head>
@@ -0,0 +1,4 @@
1
+ scapy==2.5.0
2
+ websockets==12.0
3
+ pywebview==5.1
4
+ playsound==1.3.0