albibong 1.1.0__py3-none-any.whl → 1.1.2__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 (35) hide show
  1. albibong/__init__.py +70 -44
  2. albibong/__main__.py +6 -0
  3. albibong/classes/character.py +7 -23
  4. albibong/classes/dungeon.py +18 -4
  5. albibong/classes/event_handler/__init__.py +11 -5
  6. albibong/classes/event_handler/handle_event_might_and_favor_received_event.py +18 -0
  7. albibong/classes/event_handler/handle_event_new_character.py +2 -3
  8. albibong/classes/event_handler/handle_event_other_grabbed_loot.py +9 -0
  9. albibong/classes/event_handler/handle_event_update_fame.py +9 -0
  10. albibong/classes/event_handler/handle_event_update_re_spec_points.py +9 -0
  11. albibong/classes/event_handler/handle_operation_farmable_harvest.py +1 -1
  12. albibong/classes/event_handler/handle_operation_join.py +12 -11
  13. albibong/classes/event_handler/world_data_utils.py +0 -11
  14. albibong/classes/utils.py +20 -0
  15. albibong/gui_dist/assets/index-B31tZ4Ku.css +1 -0
  16. albibong/gui_dist/assets/index-BkyL_QUY.js +168 -0
  17. albibong/gui_dist/favor.png +0 -0
  18. albibong/gui_dist/index.html +2 -2
  19. albibong/gui_dist/might.png +0 -0
  20. albibong/migrations/001_init.py +97 -0
  21. albibong/migrations/002_alter_dungeon_table.py +53 -0
  22. albibong/models/models.py +2 -2
  23. albibong/requirements.txt +2 -1
  24. albibong/resources/EventCode.py +2 -0
  25. albibong/resources/event_code.json +2 -1
  26. albibong/threads/http_server.py +4 -0
  27. albibong/threads/sniffer_thread.py +39 -2
  28. albibong/threads/websocket_server.py +17 -3
  29. {albibong-1.1.0.dist-info → albibong-1.1.2.dist-info}/METADATA +2 -1
  30. {albibong-1.1.0.dist-info → albibong-1.1.2.dist-info}/RECORD +33 -28
  31. albibong/gui_dist/assets/index-C4r00CBk.js +0 -168
  32. albibong/gui_dist/assets/index-DKbORdbN.css +0 -1
  33. {albibong-1.1.0.dist-info → albibong-1.1.2.dist-info}/WHEEL +0 -0
  34. {albibong-1.1.0.dist-info → albibong-1.1.2.dist-info}/entry_points.txt +0 -0
  35. {albibong-1.1.0.dist-info → albibong-1.1.2.dist-info}/licenses/LICENSE +0 -0
albibong/__init__.py CHANGED
@@ -10,13 +10,13 @@ from pathlib import Path
10
10
  from time import sleep
11
11
 
12
12
  import webview
13
+ from peewee_migrate import Router
13
14
  from scapy.all import rdpcap
14
15
 
15
- from albibong.classes.dungeon import Dungeon
16
- from albibong.classes.location import Island
17
16
  from albibong.classes.logger import Logger
18
17
  from albibong.classes.packet_handler import PacketHandler
19
- from albibong.models.models import db
18
+ from albibong.classes.utils import Utils
19
+ from albibong.models.models import SQLITE_DB, db
20
20
  from albibong.threads.http_server import HttpServerThread
21
21
  from albibong.threads.packet_handler_thread import PacketHandlerThread
22
22
  from albibong.threads.sniffer_thread import SnifferThread
@@ -26,8 +26,10 @@ logger = Logger(__name__, stdout=True, log_to_file=False)
26
26
  PORT = random.randrange(8500, 8999)
27
27
 
28
28
  home_dir = os.path.expanduser("~")
29
- DUNGEON_DB = f"{home_dir}/Albibong/list_dungeon.json"
30
- SQLITE_DB = f"{home_dir}/Albibong/Albibong.db"
29
+ DUNGEON_JSON = f"{home_dir}/Albibong/list_dungeon.json"
30
+
31
+ current_path = os.path.dirname(__file__)
32
+ MIGRATION_FOLDER = os.path.join(current_path, f"migrations")
31
33
 
32
34
 
33
35
  def read_pcap(path):
@@ -37,35 +39,22 @@ def read_pcap(path):
37
39
  packet_handler.handle(packet)
38
40
 
39
41
 
40
- def sniff(useWebview):
41
- _sentinel = object()
42
- packet_queue = queue.Queue()
42
+ def get_dungeon_end_time(str, start_time):
43
+ timer = str.split(":")
44
+ seconds = int(timer[0]) * 3600 + int(timer[1]) * 60 + int(timer[2])
45
+ return timedelta(seconds=seconds) + start_time
43
46
 
44
- p = SnifferThread(name="sniffer", out_queue=packet_queue, sentinel=_sentinel)
45
-
46
- c = PacketHandlerThread(
47
- name="packet_handler",
48
- in_queue=packet_queue,
49
- sentinel=_sentinel,
50
- )
51
47
 
52
- p.start()
53
- c.start()
48
+ def check_db_validity():
49
+ migrate = Router(db, migrate_dir=MIGRATION_FOLDER)
54
50
 
55
- ws_server = get_ws_server()
56
- ws_server.start()
51
+ if Path(SQLITE_DB).is_file() == False:
52
+ if Path(DUNGEON_JSON).is_file() == True:
57
53
 
58
- def get_end_time(str, start_time):
59
- timer = str.split(":")
60
- seconds = int(timer[0]) * 3600 + int(timer[1]) * 60 + int(timer[2])
61
- return timedelta(seconds=seconds) + start_time
54
+ migrate.run("001_init")
62
55
 
63
- if Path(SQLITE_DB).is_file() == False:
64
- db.connect()
65
- db.create_tables([Dungeon, Island])
66
- if Path(DUNGEON_DB).is_file() == True:
67
56
  # convert json db to sqlite db
68
- json_data = json.load(open(DUNGEON_DB))
57
+ json_data = json.load(open(DUNGEON_JSON))
69
58
 
70
59
  for dungeon in json_data:
71
60
  start_time = datetime.strptime(
@@ -87,21 +76,55 @@ def sniff(useWebview):
87
76
  converted_type = "STATIC DUNGEON"
88
77
  elif "RANDOMDUNGEON" in type_splitted:
89
78
  converted_type = "SPAWN DUNGEON"
90
- Dungeon.create(
91
- type=converted_type,
92
- name=dungeon["name"],
93
- tier=dungeon["tier"],
94
- fame=dungeon["fame"],
95
- silver=dungeon["silver"],
96
- re_spec=dungeon["re_spec"],
97
- start_time=start_time,
98
- end_time=get_end_time(dungeon["time_elapsed"], start_time),
99
- )
100
79
 
101
- db.connect(reuse_if_open=True)
80
+ asd = [
81
+ ("id", str(uuid.uuid4())),
82
+ ("type", f"{converted_type}"),
83
+ ("name", f'{dungeon["name"]}'),
84
+ ("tier", f'{dungeon["tier"]}'),
85
+ ("fame", f'{dungeon["fame"]}'),
86
+ ("silver", f'{dungeon["silver"]}'),
87
+ ("re_spec", f'{dungeon["re_spec"]}'),
88
+ ("start_time", f"{start_time}"),
89
+ (
90
+ "end_time",
91
+ f'{get_dungeon_end_time(dungeon["time_elapsed"], start_time)}',
92
+ ),
93
+ ("meter", ""),
94
+ ]
95
+
96
+ columns = ", ".join([x[0] for x in asd])
97
+ values = ", ".join([f'"{x[1]}"' for x in asd])
98
+ sql_query = f"INSERT INTO dungeon ({columns}) VALUES ({values})"
99
+
100
+ db.execute_sql(sql_query)
101
+
102
+ migrate.run()
102
103
 
103
- if useWebview:
104
104
 
105
+ def sniff(useWebview, is_debug=False):
106
+
107
+ check_db_validity()
108
+
109
+ _sentinel = object()
110
+ packet_queue = queue.Queue()
111
+
112
+ p = SnifferThread(
113
+ name="sniffer", out_queue=packet_queue, sentinel=_sentinel, is_debug=is_debug
114
+ )
115
+ c = PacketHandlerThread(
116
+ name="packet_handler",
117
+ in_queue=packet_queue,
118
+ sentinel=_sentinel,
119
+ )
120
+
121
+ p.start()
122
+ c.start()
123
+
124
+ ws_server = get_ws_server()
125
+ ws_server.start()
126
+
127
+ if useWebview:
105
128
  sock = socket.socket()
106
129
  sock.bind(("", 0))
107
130
  port = sock.getsockname()[1]
@@ -139,9 +162,12 @@ def sniff(useWebview):
139
162
 
140
163
  def main(useWebview=True):
141
164
  if len(sys.argv) > 1:
142
- ws_server = get_ws_server()
143
- ws_server.start()
144
-
145
- read_pcap(sys.argv[1])
165
+ if sys.argv[-1] == "--debug":
166
+ Utils.get_user_specifications("pip")
167
+ sniff(useWebview, is_debug=True)
168
+ else:
169
+ ws_server = get_ws_server()
170
+ ws_server.start()
171
+ read_pcap(sys.argv[1])
146
172
  else:
147
173
  sniff(useWebview)
albibong/__main__.py CHANGED
@@ -1,6 +1,12 @@
1
+ import sys
2
+
1
3
  from albibong import main
2
4
  from albibong.classes.logger import use_logger
5
+ from albibong.classes.utils import Utils
3
6
 
4
7
  if __name__ == "__main__":
5
8
  use_logger(True)
9
+
10
+ if sys.argv[-1] == "--debug":
11
+ Utils.get_user_specifications("source code")
6
12
  main(useWebview=False)
@@ -1,10 +1,9 @@
1
- from datetime import datetime, timedelta
2
1
  import json
2
+ from datetime import datetime, timedelta
3
3
  from uuid import UUID
4
4
 
5
5
  from albibong.classes.coords import Coords
6
6
  from albibong.classes.item import Item
7
- from albibong.threads.websocket_server import send_event
8
7
 
9
8
  DIVISOR = 10000
10
9
 
@@ -35,6 +34,8 @@ class Character:
35
34
  self.re_spec_gained: int = 0
36
35
  self.silver_gained: int = 0
37
36
  self.loot: list[str] = []
37
+ self.might_gained: int = 0
38
+ self.favor_gained: int = 0
38
39
 
39
40
  # Combat
40
41
  self.damage_dealt: int = 0
@@ -69,37 +70,16 @@ class Character:
69
70
  def update_fame(self, parameters):
70
71
  fame = parameters[2] / DIVISOR
71
72
  self.fame_gained += fame
72
- event = {
73
- "type": "update_fame",
74
- "payload": {"username": self.username, "fame_gained": self.fame_gained},
75
- }
76
- send_event(event)
77
73
 
78
74
  def update_re_spec(self, parameters):
79
75
  re_spec = parameters[2] / DIVISOR
80
76
  self.re_spec_gained += re_spec
81
- event = {
82
- "type": "update_re_spec",
83
- "payload": {
84
- "username": self.username,
85
- "re_spec_gained": self.re_spec_gained,
86
- },
87
- }
88
- send_event(event)
89
77
 
90
78
  def update_loot(self, parameters):
91
79
  if 3 in parameters and parameters[3] == True:
92
80
  if 5 in parameters:
93
81
  silver = parameters[5] / DIVISOR
94
82
  self.silver_gained += silver
95
- event = {
96
- "type": "update_silver",
97
- "payload": {
98
- "username": self.username,
99
- "silver_gained": self.silver_gained,
100
- },
101
- }
102
- send_event(event)
103
83
  else:
104
84
  self.loot.append(parameters[4])
105
85
 
@@ -110,3 +90,7 @@ class Character:
110
90
  obj = Item.get_item_from_code(str(eq))
111
91
  new_eq.append(obj)
112
92
  self.equipment = new_eq
93
+
94
+ def update_might_and_favor(self, parameters):
95
+ self.favor_gained += parameters[4] / DIVISOR
96
+ self.might_gained += parameters[1] / DIVISOR
@@ -14,29 +14,39 @@ class Dungeon(BaseModel):
14
14
  id = UUIDField(unique=True, default=uuid.uuid4)
15
15
  type = CharField()
16
16
  name = CharField()
17
- tier = IntegerField(default=0)
17
+ tier = FloatField(default=0)
18
18
  fame = FloatField(default=0)
19
19
  silver = FloatField(default=0)
20
20
  re_spec = FloatField(default=0)
21
+ might = FloatField(default=0)
22
+ favor = FloatField(default=0)
21
23
  start_time = DateTimeField(default=datetime.now)
22
24
  end_time = DateTimeField(null=True, default=None)
23
25
  meter = JSONField(default=dict)
24
26
 
25
27
  @staticmethod
26
28
  def serialize(dungeon):
29
+ time_elapsed = dungeon.end_time - dungeon.start_time
30
+ total_hours = time_elapsed.total_seconds() / 3600
31
+
27
32
  return {
28
33
  "id": str(dungeon.id),
29
34
  "type": dungeon.type,
30
35
  "name": dungeon.name,
31
36
  "tier": dungeon.tier,
32
37
  "fame": dungeon.fame,
38
+ "fame_per_hour": dungeon.fame / total_hours,
33
39
  "silver": dungeon.silver,
40
+ "silver_per_hour": dungeon.silver / total_hours,
34
41
  "re_spec": dungeon.re_spec,
42
+ "re_spec_per_hour": dungeon.re_spec / total_hours,
43
+ "might": dungeon.might,
44
+ "might_per_hour": dungeon.might / total_hours,
45
+ "favor": dungeon.favor,
46
+ "favor_per_hour": dungeon.favor / total_hours,
35
47
  "date_time": dungeon.start_time.strftime("%a %d %b %Y, %I:%M%p"),
36
48
  "time_elapsed": (
37
- str(dungeon.end_time - dungeon.start_time).split(".")[0]
38
- if dungeon.end_time
39
- else ""
49
+ str(time_elapsed).split(".")[0] if dungeon.end_time else ""
40
50
  ),
41
51
  "meter": dungeon.meter,
42
52
  }
@@ -52,6 +62,10 @@ class Dungeon(BaseModel):
52
62
  re_spec = parameters[2] / DIVISOR
53
63
  self.re_spec += re_spec
54
64
 
65
+ def update_might_and_favor(self, parameters):
66
+ self.favor += parameters[4] / DIVISOR
67
+ self.might += parameters[1] / DIVISOR
68
+
55
69
  def update_loot(self, parameters):
56
70
  if 3 in parameters and parameters[3] == True:
57
71
  silver = parameters[5] / DIVISOR
@@ -8,6 +8,9 @@ from albibong.classes.event_handler.handle_event_health import (
8
8
  from albibong.classes.event_handler.handle_event_in_combat_state_update import (
9
9
  handle_event_in_combat_state_update,
10
10
  )
11
+ from albibong.classes.event_handler.handle_event_might_and_favor_received_event import (
12
+ handle_event_might_and_favor_received_event,
13
+ )
11
14
  from albibong.classes.event_handler.handle_event_new_character import (
12
15
  handle_event_new_character,
13
16
  )
@@ -29,17 +32,16 @@ from albibong.classes.event_handler.handle_event_update_re_spec_points import (
29
32
  from albibong.classes.event_handler.handle_operation_change_cluster import (
30
33
  handle_operation_change_cluster,
31
34
  )
32
- from albibong.classes.event_handler.handle_operation_join import handle_operation_join
33
35
  from albibong.classes.event_handler.handle_operation_farmable_harvest import (
36
+ handle_operation_farmable_get_product,
34
37
  handle_operation_farmable_harvest,
35
- handle_operation_farmable_finish_grown_item,
36
38
  )
39
+ from albibong.classes.event_handler.handle_operation_join import handle_operation_join
37
40
  from albibong.classes.event_handler.handle_operation_move import handle_operation_move
38
41
  from albibong.classes.world_data import WorldData
39
42
  from albibong.resources.EventCode import EventCode
40
43
  from albibong.resources.OperationCode import OperationCode
41
44
 
42
-
43
45
  EVENT_TYPE_PARAMETER = 252
44
46
  REQUEST_TYPE_PARAMETER = 253
45
47
  RESPONSE_TYPE_PARAMETER = 253
@@ -63,6 +65,10 @@ class EventHandler:
63
65
  self.event_handler[EventCode.UPDATE_RE_SPEC_POINTS.value] = (
64
66
  handle_event_update_re_spec_points
65
67
  )
68
+ self.event_handler[EventCode.MIGHT_AND_FAVOR_RECEIVED_EVENT.value] = (
69
+ handle_event_might_and_favor_received_event
70
+ )
71
+
66
72
  self.event_handler[EventCode.OTHER_GRABBED_LOOT.value] = (
67
73
  handle_event_other_grabbed_loot
68
74
  )
@@ -88,8 +94,8 @@ class EventHandler:
88
94
  self.response_handler[OperationCode.CHANGE_CLUSTER.value] = (
89
95
  handle_operation_change_cluster
90
96
  )
91
- self.response_handler[OperationCode.FARMABLE_FINISH_GROWN_ITEM.value] = (
92
- handle_operation_farmable_finish_grown_item
97
+ self.response_handler[OperationCode.FARMABLE_GET_PRODUCT.value] = (
98
+ handle_operation_farmable_get_product
93
99
  )
94
100
  self.response_handler[OperationCode.FARMABLE_HARVEST.value] = (
95
101
  handle_operation_farmable_harvest
@@ -0,0 +1,18 @@
1
+ from albibong.classes.world_data import WorldData
2
+ from albibong.threads.websocket_server import send_event
3
+
4
+
5
+ def handle_event_might_and_favor_received_event(world_data: WorldData, parameters):
6
+ world_data.me.update_might_and_favor(parameters)
7
+ event = {
8
+ "type": "update_might_and_favor",
9
+ "payload": {
10
+ "username": world_data.me.username,
11
+ "favor_gained": world_data.me.favor_gained,
12
+ "might_gained": world_data.me.might_gained,
13
+ },
14
+ }
15
+ send_event(event)
16
+
17
+ if world_data.current_dungeon:
18
+ world_data.current_dungeon.update_might_and_favor(parameters)
@@ -6,18 +6,17 @@ from albibong.classes.world_data import WorldData
6
6
 
7
7
 
8
8
  def handle_event_new_character(world_data: WorldData, parameters):
9
-
10
9
  id = parameters[0]
11
10
  uuid = parameters[7]
12
11
  username = parameters[1]
13
12
  guild = parameters[8] if 8 in parameters else ""
14
- alliance = parameters[49] if 49 in parameters else ""
13
+ alliance = parameters[51] if 51 in parameters else ""
15
14
  coords = (
16
15
  Coords(parameters[15][0], parameters[15][1])
17
16
  if 15 in parameters
18
17
  else Coords(0, 0)
19
18
  )
20
- equipments = parameters[38] if 38 in parameters else []
19
+ equipments = parameters[40] if 40 in parameters else []
21
20
 
22
21
  # initiate character
23
22
  if username not in world_data.characters:
@@ -1,5 +1,6 @@
1
1
  from albibong.classes.character import Character
2
2
  from albibong.classes.world_data import WorldData
3
+ from albibong.threads.websocket_server import send_event
3
4
 
4
5
 
5
6
  def handle_event_other_grabbed_loot(world_data: WorldData, parameters):
@@ -8,6 +9,14 @@ def handle_event_other_grabbed_loot(world_data: WorldData, parameters):
8
9
  if 2 in parameters and parameters[2] in world_data.characters:
9
10
  char: Character = world_data.characters[parameters[2]]
10
11
  char.update_loot(parameters)
12
+ event = {
13
+ "type": "update_silver",
14
+ "payload": {
15
+ "username": char.username,
16
+ "silver_gained": char.silver_gained,
17
+ },
18
+ }
19
+ send_event(event)
11
20
 
12
21
  # update dungeon data
13
22
  if world_data.current_dungeon and parameters[2] == world_data.me.username:
@@ -1,7 +1,16 @@
1
1
  from albibong.classes.world_data import WorldData
2
+ from albibong.threads.websocket_server import send_event
2
3
 
3
4
 
4
5
  def handle_event_update_fame(world_data: WorldData, parameters):
5
6
  world_data.me.update_fame(parameters)
7
+ event = {
8
+ "type": "update_fame",
9
+ "payload": {
10
+ "username": world_data.me.username,
11
+ "fame_gained": world_data.me.fame_gained,
12
+ },
13
+ }
14
+ send_event(event)
6
15
  if world_data.current_dungeon:
7
16
  world_data.current_dungeon.update_fame(parameters)
@@ -1,10 +1,19 @@
1
1
  from albibong.classes.world_data import WorldData
2
+ from albibong.threads.websocket_server import send_event
2
3
 
3
4
 
4
5
  def handle_event_update_re_spec_points(world_data: WorldData, parameters):
5
6
 
6
7
  # update char data
7
8
  world_data.me.update_re_spec(parameters)
9
+ event = {
10
+ "type": "update_re_spec",
11
+ "payload": {
12
+ "username": world_data.me.username,
13
+ "re_spec_gained": world_data.me.re_spec_gained,
14
+ },
15
+ }
16
+ send_event(event)
8
17
 
9
18
  # update dungeon data
10
19
  if world_data.current_dungeon:
@@ -9,7 +9,7 @@ def handle_operation_farmable_harvest(world_data: WorldData, parameters):
9
9
  )
10
10
 
11
11
 
12
- def handle_operation_farmable_finish_grown_item(world_data: WorldData, parameters):
12
+ def handle_operation_farmable_get_product(world_data: WorldData, parameters):
13
13
  if type(world_data.current_map).__name__ == "Island":
14
14
  for i in range(len(parameters[0])):
15
15
  world_data.current_map.add_animal(
@@ -1,4 +1,3 @@
1
- from albibong.classes.dungeon import Dungeon
2
1
  from albibong.classes.event_handler.world_data_utils import WorldDataUtils
3
2
  from albibong.classes.location import Location
4
3
  from albibong.classes.utils import Utils
@@ -7,20 +6,20 @@ from albibong.threads.websocket_server import send_event
7
6
 
8
7
 
9
8
  def handle_operation_join(world_data: WorldData, parameters):
10
- # update relative id if character has initialized before
11
- if world_data.me.username != "not initialized":
12
- WorldDataUtils.convert_id_to_name(
13
- world_data,
14
- old_id=world_data.me.id,
15
- new_id=parameters[0],
16
- char=world_data.me,
17
- )
18
-
19
9
  # set my character
20
- world_data.me.uuid = Utils.convert_int_arr_to_uuid(parameters[1])
21
10
  world_data.me.username = parameters[2]
11
+ world_data.me.uuid = Utils.convert_int_arr_to_uuid(parameters[1])
22
12
  world_data.me.guild = parameters[57] if 57 in parameters else ""
23
13
  world_data.me.alliance = parameters[77] if 77 in parameters else ""
14
+
15
+ # update relative id if character has initialized before
16
+ WorldDataUtils.convert_id_to_name(
17
+ world_data,
18
+ old_id=world_data.me.id,
19
+ new_id=parameters[0],
20
+ char=world_data.me,
21
+ )
22
+
24
23
  if world_data.me.id in world_data.change_equipment_log:
25
24
  world_data.me.update_equipment(
26
25
  world_data.change_equipment_log[world_data.me.id]
@@ -55,6 +54,8 @@ def ws_init_character(world_data: WorldData):
55
54
  "fame": world_data.me.fame_gained,
56
55
  "re_spec": world_data.me.re_spec_gained,
57
56
  "silver": world_data.me.silver_gained,
57
+ "might": world_data.me.might_gained,
58
+ "favor": world_data.me.favor_gained,
58
59
  "weapon": world_data.me.equipment[0].image,
59
60
  },
60
61
  }
@@ -1,20 +1,9 @@
1
- import json
2
- import os
3
- from collections import deque
4
- from datetime import datetime
5
-
6
1
  from albibong.classes.character import Character
7
2
  from albibong.classes.dungeon import Dungeon
8
3
  from albibong.classes.location import Island, Location
9
- from albibong.classes.utils import Utils
10
4
  from albibong.classes.world_data import WorldData
11
5
  from albibong.threads.websocket_server import send_event
12
6
 
13
- LIST_DUNGEON = os.path.join(os.path.expanduser("~"), "Albibong/list_dungeon.json")
14
- os.makedirs(os.path.dirname(LIST_DUNGEON), exist_ok=True)
15
- LIST_ISLAND = os.path.join(os.path.expanduser("~"), "Albibong/list_island.json")
16
- os.makedirs(os.path.dirname(LIST_ISLAND), exist_ok=True)
17
-
18
7
 
19
8
  class WorldDataUtils:
20
9
 
albibong/classes/utils.py CHANGED
@@ -1,5 +1,13 @@
1
+ import os
2
+ import platform
3
+ from importlib.metadata import version
1
4
  from uuid import UUID
2
5
 
6
+ from scapy.all import conf, get_if_addr
7
+
8
+ FILENAME = os.path.join(os.path.expanduser("~"), "Albibong/Debug/user_spec.txt")
9
+ os.makedirs(os.path.dirname(FILENAME), exist_ok=True)
10
+
3
11
 
4
12
  class Utils:
5
13
 
@@ -7,3 +15,15 @@ class Utils:
7
15
  def convert_int_arr_to_uuid(arr):
8
16
  b = bytes(arr)
9
17
  return UUID(bytes=b)
18
+
19
+ @staticmethod
20
+ def get_user_specifications(install_source: str):
21
+ os_ver = f"{platform.system()} {platform.release()}"
22
+ python_ver = platform.python_version()
23
+ albibong_ver = version("albibong")
24
+ interfaces = f"{conf.iface} ({get_if_addr(conf.iface)})"
25
+
26
+ text = f"\n===\n\nAlbibong Ver : {albibong_ver}\nPython Ver : {python_ver}\nOS Ver : {os_ver}\nInstallation Source : {install_source}\nInterfaces : {interfaces}\n\n===\n"
27
+ print(text)
28
+ with open(FILENAME, "w+") as file:
29
+ file.write(text)
@@ -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}}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}._passed_ifjrf_1{background-color:green}._failed_ifjrf_4{background-color:red}._healthCheckDiv_ifjrf_7{width:1rem;height:1rem;border-radius:1rem}._toolbar_ifjrf_14{display:flex;justify-content:space-between}._data_ifjrf_19{display:flex;gap:1rem;align-items:center}._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_1kru6_1{border-radius:1rem;width:100%;padding:2rem;display:flex;flex-direction:column;gap:1rem}._tag_1kru6_12{background-color:#64d3ff;padding:0 1rem;border-radius:1rem;color:#0f3c4e;font-weight:700}._stats_1kru6_20{display:flex;flex-direction:row;align-items:start;gap:.5rem}._statRow_1kru6_27{display:flex;flex-direction:row;align-items:start;gap:3rem}._stickToTop_1kru6_34{z-index:10;position:sticky;top:64px;left:0;width:100%;padding:24px 0}@media screen and (max-width: 1000px){._statRow_1kru6_27{width:100%;justify-content:space-between;gap:0}}._container_1ha35_1{display:flex;flex-direction:column;align-items:center;gap:8px;width:100%;gap:1.5rem}._snackbar_1ha35_10{position:fixed;right:64px}._stats_1ha35_15{display:flex;flex-direction:row;align-items:center;gap:.5rem}._options_1ha35_22{display:flex;flex-direction:row;align-items:center;gap:2rem}._row_1ha35_29{display:flex;width:100%;justify-content:space-between;align-items:center}._hidden_1ha35_36{display:none}._column_owxpy_1{width:50%;display:flex;flex-direction:column;gap:16px}._row_owxpy_8{display:flex;gap:40px}._harvest_owxpy_13{display:flex;gap:8px;align-items:center}._statsContainer_owxpy_19{width:100%;display:flex;flex-direction:column;gap:0}