albibong 1.0.6__tar.gz → 1.1.0__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.
- {albibong-1.0.6 → albibong-1.1.0}/.gitignore +2 -0
- {albibong-1.0.6 → albibong-1.1.0}/PKG-INFO +2 -1
- {albibong-1.0.6 → albibong-1.1.0}/pyproject.toml +4 -2
- albibong-1.1.0/src/albibong/__init__.py +147 -0
- albibong-1.1.0/src/albibong/classes/dungeon.py +66 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/__init__.py +10 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/handle_event_character_equipment_changed.py +2 -10
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/handle_event_party.py +6 -13
- albibong-1.1.0/src/albibong/classes/event_handler/handle_operation_change_cluster.py +38 -0
- albibong-1.1.0/src/albibong/classes/event_handler/handle_operation_farmable_harvest.py +17 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/handle_operation_join.py +12 -29
- albibong-1.1.0/src/albibong/classes/event_handler/world_data_utils.py +155 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/item.py +19 -4
- albibong-1.1.0/src/albibong/classes/location.py +151 -0
- albibong-1.1.0/src/albibong/gui_dist/assets/index-C4r00CBk.js +168 -0
- albibong-1.1.0/src/albibong/gui_dist/assets/index-DKbORdbN.css +1 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/gui_dist/index.html +2 -2
- albibong-1.1.0/src/albibong/models/models.py +12 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/requirements.txt +1 -0
- albibong-1.1.0/src/albibong/resources/EventCode.py +593 -0
- albibong-1.1.0/src/albibong/resources/OperationCode.py +502 -0
- albibong-1.1.0/src/albibong/resources/event_code.json +591 -0
- albibong-1.0.6/src/albibong/resources/items.json → albibong-1.1.0/src/albibong/resources/items_by_id.json +21767 -21108
- albibong-1.1.0/src/albibong/resources/items_by_unique_name.json +55282 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/resources/maps.json +755 -514
- albibong-1.1.0/src/albibong/resources/operation_code.json +500 -0
- albibong-1.1.0/src/albibong/threads/__init__.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/threads/websocket_server.py +64 -41
- albibong-1.0.6/src/albibong/__init__.py +0 -89
- albibong-1.0.6/src/albibong/classes/dungeon.py +0 -59
- albibong-1.0.6/src/albibong/classes/event_handler/handle_operation_change_cluster.py +0 -43
- albibong-1.0.6/src/albibong/classes/event_handler/world_data_utils.py +0 -102
- albibong-1.0.6/src/albibong/classes/location.py +0 -48
- albibong-1.0.6/src/albibong/gui_dist/assets/index-DZvgNqlG.css +0 -1
- albibong-1.0.6/src/albibong/gui_dist/assets/index-Dt6hyZiS.css +0 -1
- albibong-1.0.6/src/albibong/gui_dist/assets/index-E7pha23k.js +0 -161
- albibong-1.0.6/src/albibong/gui_dist/assets/index-WIuC9Mnh.js +0 -161
- albibong-1.0.6/src/albibong/resources/EventCode.py +0 -588
- albibong-1.0.6/src/albibong/resources/OperationCode.py +0 -499
- albibong-1.0.6/src/albibong/resources/event_code.json +0 -586
- albibong-1.0.6/src/albibong/resources/operation_code.json +0 -497
- {albibong-1.0.6 → albibong-1.1.0}/LICENSE +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/__main__.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/assets/boom_small.mp3 +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/__init__.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/character.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/coords.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/handle_event_health.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/handle_event_in_combat_state_update.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/handle_event_new_character.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/handle_event_other_grabbed_loot.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/handle_event_update_fame.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/handle_event_update_re_spec_points.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/handle_operation_move.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/logger.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/packet_handler.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/utils.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/world_data.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/gui_dist/Albibong.png +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/gui_dist/No Equipment.png +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/gui_dist/fame.png +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/gui_dist/re_spec.png +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/gui_dist/silver.png +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/gui_dist/vite.svg +0 -0
- {albibong-1.0.6/src/albibong/threads → albibong-1.1.0/src/albibong/models}/__init__.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/__init__.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/command_type.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/crc_calculator.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/event_data.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/message_type.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/number_serializer.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/operation_request.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/operation_response.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/photon_packet_parser.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/protocol16_deserializer.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/protocol16_type.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/photon_packet_parser/segmented_packet.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/threads/http_server.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/src/albibong/threads/packet_handler_thread.py +0 -0
- {albibong-1.0.6 → albibong-1.1.0}/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
|
|
3
|
+
Version: 1.1.0
|
|
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.10
|
|
13
|
+
Requires-Dist: peewee==3.17.6
|
|
13
14
|
Requires-Dist: pywebview==5.1
|
|
14
15
|
Requires-Dist: scapy==2.5.0
|
|
15
16
|
Requires-Dist: websockets==12.0
|
|
@@ -11,7 +11,8 @@ exclude = [
|
|
|
11
11
|
"/tests",
|
|
12
12
|
"/gui",
|
|
13
13
|
"/readme_screenshots",
|
|
14
|
-
"/README.md"
|
|
14
|
+
"/README.md",
|
|
15
|
+
"/*.db"
|
|
15
16
|
]
|
|
16
17
|
|
|
17
18
|
[project.scripts]
|
|
@@ -19,7 +20,7 @@ albibong = "albibong:main"
|
|
|
19
20
|
|
|
20
21
|
[project]
|
|
21
22
|
name = "albibong"
|
|
22
|
-
version = "1.0
|
|
23
|
+
version = "1.1.0"
|
|
23
24
|
authors = [
|
|
24
25
|
{ name="imjangkar", email="imjangkar@gmail.com" },
|
|
25
26
|
]
|
|
@@ -34,6 +35,7 @@ dependencies = [
|
|
|
34
35
|
"scapy==2.5.0",
|
|
35
36
|
"websockets==12.0",
|
|
36
37
|
"pywebview==5.1",
|
|
38
|
+
"peewee==3.17.6",
|
|
37
39
|
]
|
|
38
40
|
|
|
39
41
|
[project.urls]
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import queue
|
|
4
|
+
import random
|
|
5
|
+
import socket
|
|
6
|
+
import sys
|
|
7
|
+
import uuid
|
|
8
|
+
from datetime import datetime, timedelta
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from time import sleep
|
|
11
|
+
|
|
12
|
+
import webview
|
|
13
|
+
from scapy.all import rdpcap
|
|
14
|
+
|
|
15
|
+
from albibong.classes.dungeon import Dungeon
|
|
16
|
+
from albibong.classes.location import Island
|
|
17
|
+
from albibong.classes.logger import Logger
|
|
18
|
+
from albibong.classes.packet_handler import PacketHandler
|
|
19
|
+
from albibong.models.models import db
|
|
20
|
+
from albibong.threads.http_server import HttpServerThread
|
|
21
|
+
from albibong.threads.packet_handler_thread import PacketHandlerThread
|
|
22
|
+
from albibong.threads.sniffer_thread import SnifferThread
|
|
23
|
+
from albibong.threads.websocket_server import get_ws_server
|
|
24
|
+
|
|
25
|
+
logger = Logger(__name__, stdout=True, log_to_file=False)
|
|
26
|
+
PORT = random.randrange(8500, 8999)
|
|
27
|
+
|
|
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"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def read_pcap(path):
|
|
34
|
+
packet_handler = PacketHandler()
|
|
35
|
+
scapy_cap = rdpcap(path)
|
|
36
|
+
for packet in scapy_cap:
|
|
37
|
+
packet_handler.handle(packet)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def sniff(useWebview):
|
|
41
|
+
_sentinel = object()
|
|
42
|
+
packet_queue = queue.Queue()
|
|
43
|
+
|
|
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
|
+
|
|
52
|
+
p.start()
|
|
53
|
+
c.start()
|
|
54
|
+
|
|
55
|
+
ws_server = get_ws_server()
|
|
56
|
+
ws_server.start()
|
|
57
|
+
|
|
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
|
|
62
|
+
|
|
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
|
+
# convert json db to sqlite db
|
|
68
|
+
json_data = json.load(open(DUNGEON_DB))
|
|
69
|
+
|
|
70
|
+
for dungeon in json_data:
|
|
71
|
+
start_time = datetime.strptime(
|
|
72
|
+
dungeon["date_time"], "%a %d %b %Y, %I:%M%p"
|
|
73
|
+
)
|
|
74
|
+
type_splitted = set(dungeon["type"].split("_"))
|
|
75
|
+
|
|
76
|
+
if "CORRUPTED" in type_splitted:
|
|
77
|
+
converted_type = "CORRUPTED DUNGEON"
|
|
78
|
+
elif "HARDCORE" in type_splitted:
|
|
79
|
+
converted_type = "HARDCORE EXPEDITION"
|
|
80
|
+
elif "10V10" in type_splitted:
|
|
81
|
+
converted_type = "HELLGATE 10V10"
|
|
82
|
+
elif "5V5" in type_splitted:
|
|
83
|
+
converted_type = "HELLGATE 5V5"
|
|
84
|
+
elif "2V2" in type_splitted:
|
|
85
|
+
converted_type = "HELLGATE 2V2"
|
|
86
|
+
elif "DUNGEON" in type_splitted:
|
|
87
|
+
converted_type = "STATIC DUNGEON"
|
|
88
|
+
elif "RANDOMDUNGEON" in type_splitted:
|
|
89
|
+
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
|
+
|
|
101
|
+
db.connect(reuse_if_open=True)
|
|
102
|
+
|
|
103
|
+
if useWebview:
|
|
104
|
+
|
|
105
|
+
sock = socket.socket()
|
|
106
|
+
sock.bind(("", 0))
|
|
107
|
+
port = sock.getsockname()[1]
|
|
108
|
+
sock.close()
|
|
109
|
+
|
|
110
|
+
http_server = HttpServerThread(name="http_server", port=port)
|
|
111
|
+
http_server.start()
|
|
112
|
+
|
|
113
|
+
window = webview.create_window(
|
|
114
|
+
"Albibong",
|
|
115
|
+
url=f"http://localhost:{port}/",
|
|
116
|
+
width=1280,
|
|
117
|
+
height=720,
|
|
118
|
+
zoomable=True,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
def on_closing():
|
|
122
|
+
c.stop()
|
|
123
|
+
p.stop()
|
|
124
|
+
ws_server.stop()
|
|
125
|
+
http_server.stop()
|
|
126
|
+
db.close()
|
|
127
|
+
|
|
128
|
+
window.events.closing += on_closing
|
|
129
|
+
|
|
130
|
+
webview.start()
|
|
131
|
+
else:
|
|
132
|
+
try:
|
|
133
|
+
while True:
|
|
134
|
+
sleep(100)
|
|
135
|
+
except KeyboardInterrupt as e:
|
|
136
|
+
p.stop()
|
|
137
|
+
ws_server.stop()
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def main(useWebview=True):
|
|
141
|
+
if len(sys.argv) > 1:
|
|
142
|
+
ws_server = get_ws_server()
|
|
143
|
+
ws_server.start()
|
|
144
|
+
|
|
145
|
+
read_pcap(sys.argv[1])
|
|
146
|
+
else:
|
|
147
|
+
sniff(useWebview)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
|
|
4
|
+
from peewee import *
|
|
5
|
+
from playhouse.sqlite_ext import JSONField
|
|
6
|
+
|
|
7
|
+
from albibong.models.models import BaseModel
|
|
8
|
+
|
|
9
|
+
DIVISOR = 10000
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Dungeon(BaseModel):
|
|
13
|
+
|
|
14
|
+
id = UUIDField(unique=True, default=uuid.uuid4)
|
|
15
|
+
type = CharField()
|
|
16
|
+
name = CharField()
|
|
17
|
+
tier = IntegerField(default=0)
|
|
18
|
+
fame = FloatField(default=0)
|
|
19
|
+
silver = FloatField(default=0)
|
|
20
|
+
re_spec = FloatField(default=0)
|
|
21
|
+
start_time = DateTimeField(default=datetime.now)
|
|
22
|
+
end_time = DateTimeField(null=True, default=None)
|
|
23
|
+
meter = JSONField(default=dict)
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def serialize(dungeon):
|
|
27
|
+
return {
|
|
28
|
+
"id": str(dungeon.id),
|
|
29
|
+
"type": dungeon.type,
|
|
30
|
+
"name": dungeon.name,
|
|
31
|
+
"tier": dungeon.tier,
|
|
32
|
+
"fame": dungeon.fame,
|
|
33
|
+
"silver": dungeon.silver,
|
|
34
|
+
"re_spec": dungeon.re_spec,
|
|
35
|
+
"date_time": dungeon.start_time.strftime("%a %d %b %Y, %I:%M%p"),
|
|
36
|
+
"time_elapsed": (
|
|
37
|
+
str(dungeon.end_time - dungeon.start_time).split(".")[0]
|
|
38
|
+
if dungeon.end_time
|
|
39
|
+
else ""
|
|
40
|
+
),
|
|
41
|
+
"meter": dungeon.meter,
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
def set_end_time(self):
|
|
45
|
+
self.end_time = datetime.now()
|
|
46
|
+
|
|
47
|
+
def update_fame(self, parameters):
|
|
48
|
+
fame = parameters[2] / DIVISOR
|
|
49
|
+
self.fame += fame
|
|
50
|
+
|
|
51
|
+
def update_re_spec(self, parameters):
|
|
52
|
+
re_spec = parameters[2] / DIVISOR
|
|
53
|
+
self.re_spec += re_spec
|
|
54
|
+
|
|
55
|
+
def update_loot(self, parameters):
|
|
56
|
+
if 3 in parameters and parameters[3] == True:
|
|
57
|
+
silver = parameters[5] / DIVISOR
|
|
58
|
+
self.silver += silver
|
|
59
|
+
|
|
60
|
+
def update_meter(self, party):
|
|
61
|
+
self.meter = party
|
|
62
|
+
|
|
63
|
+
@staticmethod
|
|
64
|
+
def get_all_dungeon():
|
|
65
|
+
query = Dungeon.select().order_by(Dungeon.start_time.desc())
|
|
66
|
+
return [Dungeon.serialize(dungeon) for dungeon in query]
|
|
@@ -30,6 +30,10 @@ from albibong.classes.event_handler.handle_operation_change_cluster import (
|
|
|
30
30
|
handle_operation_change_cluster,
|
|
31
31
|
)
|
|
32
32
|
from albibong.classes.event_handler.handle_operation_join import handle_operation_join
|
|
33
|
+
from albibong.classes.event_handler.handle_operation_farmable_harvest import (
|
|
34
|
+
handle_operation_farmable_harvest,
|
|
35
|
+
handle_operation_farmable_finish_grown_item,
|
|
36
|
+
)
|
|
33
37
|
from albibong.classes.event_handler.handle_operation_move import handle_operation_move
|
|
34
38
|
from albibong.classes.world_data import WorldData
|
|
35
39
|
from albibong.resources.EventCode import EventCode
|
|
@@ -84,6 +88,12 @@ class EventHandler:
|
|
|
84
88
|
self.response_handler[OperationCode.CHANGE_CLUSTER.value] = (
|
|
85
89
|
handle_operation_change_cluster
|
|
86
90
|
)
|
|
91
|
+
self.response_handler[OperationCode.FARMABLE_FINISH_GROWN_ITEM.value] = (
|
|
92
|
+
handle_operation_farmable_finish_grown_item
|
|
93
|
+
)
|
|
94
|
+
self.response_handler[OperationCode.FARMABLE_HARVEST.value] = (
|
|
95
|
+
handle_operation_farmable_harvest
|
|
96
|
+
)
|
|
87
97
|
|
|
88
98
|
def on_request(self, world_data: WorldData, parameters):
|
|
89
99
|
if REQUEST_TYPE_PARAMETER not in parameters:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
from albibong.classes.event_handler.world_data_utils import WorldDataUtils
|
|
1
2
|
from albibong.classes.world_data import WorldData
|
|
2
|
-
from albibong.threads.websocket_server import send_event
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def handle_event_character_equipment_changed(world_data: WorldData, parameters):
|
|
@@ -11,14 +11,6 @@ def handle_event_character_equipment_changed(world_data: WorldData, parameters):
|
|
|
11
11
|
]
|
|
12
12
|
if char.username in world_data.party_members:
|
|
13
13
|
char.update_equipment(parameters[2])
|
|
14
|
-
|
|
14
|
+
WorldDataUtils.ws_update_damage_meter(world_data)
|
|
15
15
|
else:
|
|
16
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)
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
from uuid import UUID
|
|
2
|
+
|
|
3
|
+
from albibong.classes.event_handler.world_data_utils import WorldDataUtils
|
|
2
4
|
from albibong.classes.world_data import WorldData
|
|
3
|
-
from albibong.threads.websocket_server import send_event
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def handle_event_party_joined(world_data: WorldData, parameters):
|
|
7
8
|
world_data.party_members = set(parameters[5])
|
|
8
|
-
|
|
9
|
+
WorldDataUtils.ws_update_damage_meter(world_data)
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
def handle_event_party_disbanded(world_data: WorldData, parameters):
|
|
12
13
|
world_data.party_members = {world_data.me.username}
|
|
13
|
-
|
|
14
|
+
WorldDataUtils.ws_update_damage_meter(world_data)
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
def handle_event_party_player_joined(world_data: WorldData, parameters):
|
|
17
18
|
world_data.party_members.add(parameters[2])
|
|
18
|
-
|
|
19
|
+
WorldDataUtils.ws_update_damage_meter(world_data)
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
def handle_event_party_player_left(world_data: WorldData, parameters):
|
|
@@ -27,12 +28,4 @@ def handle_event_party_player_left(world_data: WorldData, parameters):
|
|
|
27
28
|
# self out party
|
|
28
29
|
if name == world_data.me.username:
|
|
29
30
|
world_data.party_members = {world_data.me.username}
|
|
30
|
-
|
|
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)
|
|
31
|
+
WorldDataUtils.ws_update_damage_meter(world_data)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from albibong.classes.event_handler.world_data_utils import WorldDataUtils
|
|
2
|
+
from albibong.classes.location import Island, 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 type(world_data.current_map).__name__ == "Island":
|
|
11
|
+
WorldDataUtils.set_island_status(
|
|
12
|
+
current_island=world_data.current_map, parameters=parameters
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
if 1 in parameters:
|
|
16
|
+
check_map = Location.get_location_from_code(parameters[1])
|
|
17
|
+
map_type_splitted = set(check_map.type.split(" "))
|
|
18
|
+
WorldDataUtils.set_dungeon_status(world_data, check_map, map_type_splitted)
|
|
19
|
+
|
|
20
|
+
if "ISLAND" in map_type_splitted:
|
|
21
|
+
island = Island.get_island_from_code(parameters[1])
|
|
22
|
+
island.name = f"{parameters[2]}'s {island.name}"
|
|
23
|
+
world_data.current_map = island
|
|
24
|
+
elif "HIDEOUT" in map_type_splitted:
|
|
25
|
+
hideout = Location.get_location_from_code(parameters[1])
|
|
26
|
+
hideout.name = f"{parameters[2]}'s {hideout.name}"
|
|
27
|
+
world_data.current_map = hideout
|
|
28
|
+
|
|
29
|
+
elif 0 in parameters:
|
|
30
|
+
check_map = Location.get_location_from_code(parameters[0])
|
|
31
|
+
map_type_splitted = set(check_map.type.split(" "))
|
|
32
|
+
is_dungeon = WorldDataUtils.set_dungeon_status(
|
|
33
|
+
world_data, check_map, map_type_splitted
|
|
34
|
+
)
|
|
35
|
+
if is_dungeon == False:
|
|
36
|
+
world_data.current_map = Location.get_location_from_code(parameters[0])
|
|
37
|
+
|
|
38
|
+
WorldDataUtils.ws_update_location(world_data)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from albibong.classes.world_data import WorldData
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def handle_operation_farmable_harvest(world_data: WorldData, parameters):
|
|
5
|
+
if type(world_data.current_map).__name__ == "Island":
|
|
6
|
+
for i in range(len(parameters[0])):
|
|
7
|
+
world_data.current_map.add_crop(
|
|
8
|
+
unique_name=parameters[0][i], quantity=parameters[1][i]
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def handle_operation_farmable_finish_grown_item(world_data: WorldData, parameters):
|
|
13
|
+
if type(world_data.current_map).__name__ == "Island":
|
|
14
|
+
for i in range(len(parameters[0])):
|
|
15
|
+
world_data.current_map.add_animal(
|
|
16
|
+
unique_name=parameters[0][i], quantity=parameters[1][i]
|
|
17
|
+
)
|
{albibong-1.0.6 → albibong-1.1.0}/src/albibong/classes/event_handler/handle_operation_join.py
RENAMED
|
@@ -7,10 +7,16 @@ from albibong.threads.websocket_server import send_event
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
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
|
+
|
|
10
19
|
# 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
20
|
world_data.me.uuid = Utils.convert_int_arr_to_uuid(parameters[1])
|
|
15
21
|
world_data.me.username = parameters[2]
|
|
16
22
|
world_data.me.guild = parameters[57] if 57 in parameters else ""
|
|
@@ -30,15 +36,15 @@ def handle_operation_join(world_data: WorldData, parameters):
|
|
|
30
36
|
# set map my character is currently in
|
|
31
37
|
if parameters[8][0] == "@":
|
|
32
38
|
area = parameters[8].split("@")
|
|
33
|
-
if area[1] == "RANDOMDUNGEON":
|
|
39
|
+
if area[1] == "RANDOMDUNGEON" or area[1] == "MISTS":
|
|
34
40
|
check_map = Location.get_location_from_code(area[1])
|
|
35
41
|
WorldDataUtils.start_current_dungeon(
|
|
36
42
|
world_data, type=check_map.type, name=check_map.name
|
|
37
43
|
)
|
|
38
44
|
|
|
39
45
|
ws_init_character(world_data)
|
|
40
|
-
ws_update_location(world_data)
|
|
41
|
-
|
|
46
|
+
WorldDataUtils.ws_update_location(world_data)
|
|
47
|
+
WorldDataUtils.ws_update_damage_meter(world_data)
|
|
42
48
|
|
|
43
49
|
|
|
44
50
|
def ws_init_character(world_data: WorldData):
|
|
@@ -53,26 +59,3 @@ def ws_init_character(world_data: WorldData):
|
|
|
53
59
|
},
|
|
54
60
|
}
|
|
55
61
|
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,155 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
from collections import deque
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
|
|
6
|
+
from albibong.classes.character import Character
|
|
7
|
+
from albibong.classes.dungeon import Dungeon
|
|
8
|
+
from albibong.classes.location import Island, Location
|
|
9
|
+
from albibong.classes.utils import Utils
|
|
10
|
+
from albibong.classes.world_data import WorldData
|
|
11
|
+
from albibong.threads.websocket_server import send_event
|
|
12
|
+
|
|
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
|
+
|
|
19
|
+
class WorldDataUtils:
|
|
20
|
+
|
|
21
|
+
def save_current_island(current_map: Island):
|
|
22
|
+
current_map.save(force_insert=True)
|
|
23
|
+
WorldDataUtils.ws_update_total_harvest_by_date(
|
|
24
|
+
Island.get_total_harvest_by_date()
|
|
25
|
+
)
|
|
26
|
+
WorldDataUtils.ws_update_island(Island.get_all_island())
|
|
27
|
+
|
|
28
|
+
def set_island_status(current_island: Island, parameters):
|
|
29
|
+
check_map = (
|
|
30
|
+
Location.get_location_from_code(parameters[1])
|
|
31
|
+
if 1 in parameters
|
|
32
|
+
else Location.get_location_from_code(parameters[0])
|
|
33
|
+
)
|
|
34
|
+
check_map_name = (
|
|
35
|
+
f"{parameters[2]}'s {check_map.name}" if 2 in parameters else check_map.name
|
|
36
|
+
)
|
|
37
|
+
if current_island.name != check_map_name:
|
|
38
|
+
if current_island.crops != {} or current_island.animals != {}:
|
|
39
|
+
WorldDataUtils.save_current_island(current_island)
|
|
40
|
+
|
|
41
|
+
def ws_update_total_harvest_by_date(payload):
|
|
42
|
+
event = {
|
|
43
|
+
"type": "update_total_harvest_by_date",
|
|
44
|
+
"payload": payload,
|
|
45
|
+
}
|
|
46
|
+
send_event(event)
|
|
47
|
+
|
|
48
|
+
def ws_update_island(list_island: list):
|
|
49
|
+
event = {
|
|
50
|
+
"type": "update_island",
|
|
51
|
+
"payload": {"list_island": list_island},
|
|
52
|
+
}
|
|
53
|
+
send_event(event)
|
|
54
|
+
|
|
55
|
+
def end_current_dungeon(world_data: WorldData):
|
|
56
|
+
if world_data.current_dungeon:
|
|
57
|
+
world_data.current_dungeon.set_end_time()
|
|
58
|
+
world_data.current_dungeon.update_meter(
|
|
59
|
+
world_data.serialize_party_members()
|
|
60
|
+
)
|
|
61
|
+
world_data.current_dungeon.save(force_insert=True)
|
|
62
|
+
WorldDataUtils.ws_update_dungeon(Dungeon.get_all_dungeon())
|
|
63
|
+
world_data.current_dungeon = None
|
|
64
|
+
|
|
65
|
+
def ws_update_dungeon(list_dungeon: list):
|
|
66
|
+
event = {
|
|
67
|
+
"type": "update_dungeon",
|
|
68
|
+
"payload": {"list_dungeon": list_dungeon},
|
|
69
|
+
}
|
|
70
|
+
send_event(event)
|
|
71
|
+
|
|
72
|
+
@staticmethod
|
|
73
|
+
def start_current_dungeon(world_data: WorldData, type: str, name: str):
|
|
74
|
+
if world_data.current_dungeon == None:
|
|
75
|
+
new_dungeon = Dungeon(type=type, name=name)
|
|
76
|
+
world_data.current_dungeon = new_dungeon
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def set_dungeon_status(
|
|
80
|
+
world_data: WorldData, check_map: Location, map_type_splitted: set
|
|
81
|
+
):
|
|
82
|
+
if "EXPEDITION" in map_type_splitted or "HELLGATE" in map_type_splitted:
|
|
83
|
+
WorldDataUtils.start_current_dungeon(
|
|
84
|
+
world_data, type=check_map.type, name=check_map.name
|
|
85
|
+
)
|
|
86
|
+
elif "DUNGEON" in map_type_splitted:
|
|
87
|
+
WorldDataUtils.start_current_dungeon(
|
|
88
|
+
world_data,
|
|
89
|
+
type=check_map.type,
|
|
90
|
+
name=(
|
|
91
|
+
f"{check_map.name} at {world_data.current_map.name}"
|
|
92
|
+
if world_data.current_map
|
|
93
|
+
else check_map.name
|
|
94
|
+
),
|
|
95
|
+
)
|
|
96
|
+
elif (
|
|
97
|
+
"EXPEDITION" not in map_type_splitted or "DUNGEON" not in map_type_splitted
|
|
98
|
+
):
|
|
99
|
+
WorldDataUtils.end_current_dungeon(world_data)
|
|
100
|
+
return False
|
|
101
|
+
|
|
102
|
+
@staticmethod
|
|
103
|
+
def convert_id_to_name(world_data: WorldData, old_id, new_id, char: Character):
|
|
104
|
+
if old_id in world_data.char_id_to_username:
|
|
105
|
+
world_data.char_id_to_username.pop(old_id) # delete old relative id
|
|
106
|
+
char.id = new_id
|
|
107
|
+
world_data.char_id_to_username[char.id] = char.username # add new relative id
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def update_damage_or_heal(world_data: WorldData, target, inflictor, nominal):
|
|
111
|
+
|
|
112
|
+
if inflictor not in world_data.char_id_to_username:
|
|
113
|
+
# character not initialized yet
|
|
114
|
+
return
|
|
115
|
+
|
|
116
|
+
username = world_data.char_id_to_username[inflictor]
|
|
117
|
+
|
|
118
|
+
if username == "not initialized":
|
|
119
|
+
# self not initialized
|
|
120
|
+
return
|
|
121
|
+
|
|
122
|
+
char: Character = world_data.characters[username]
|
|
123
|
+
|
|
124
|
+
if nominal < 0:
|
|
125
|
+
if target == inflictor:
|
|
126
|
+
# suicide
|
|
127
|
+
return
|
|
128
|
+
char.update_damage_dealt(abs(nominal))
|
|
129
|
+
else:
|
|
130
|
+
char.update_heal_dealt(nominal)
|
|
131
|
+
|
|
132
|
+
WorldDataUtils.ws_update_damage_meter(world_data)
|
|
133
|
+
|
|
134
|
+
def ws_update_damage_meter(world_data: WorldData):
|
|
135
|
+
event = {
|
|
136
|
+
"type": "update_damage_meter",
|
|
137
|
+
"payload": {"party_members": world_data.serialize_party_members()},
|
|
138
|
+
}
|
|
139
|
+
send_event(event)
|
|
140
|
+
|
|
141
|
+
def ws_update_location(world_data: WorldData):
|
|
142
|
+
event = {
|
|
143
|
+
"type": "update_location",
|
|
144
|
+
"payload": {
|
|
145
|
+
"map": (
|
|
146
|
+
world_data.current_map.name if world_data.current_map else "None"
|
|
147
|
+
),
|
|
148
|
+
"dungeon": (
|
|
149
|
+
world_data.current_dungeon.name
|
|
150
|
+
if world_data.current_dungeon
|
|
151
|
+
else "None"
|
|
152
|
+
),
|
|
153
|
+
},
|
|
154
|
+
}
|
|
155
|
+
send_event(event)
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
itemsByIdJsonPath = os.path.join(
|
|
5
|
+
os.path.dirname(__file__), "../resources/items_by_id.json"
|
|
6
|
+
)
|
|
7
|
+
itemsByUniqueNameJsonPath = os.path.join(
|
|
8
|
+
os.path.dirname(__file__), "../resources/items_by_unique_name.json"
|
|
9
|
+
)
|
|
10
|
+
with open(itemsByIdJsonPath) as json_file:
|
|
11
|
+
items_by_id = json.load(json_file)
|
|
12
|
+
with open(itemsByUniqueNameJsonPath) as json_file:
|
|
13
|
+
items_by_unique_name = json.load(json_file)
|
|
7
14
|
|
|
8
15
|
|
|
9
16
|
class Item:
|
|
@@ -17,6 +24,7 @@ class Item:
|
|
|
17
24
|
if self.unique_name != "None"
|
|
18
25
|
else "/No Equipment.png"
|
|
19
26
|
)
|
|
27
|
+
self.quantity = 0
|
|
20
28
|
|
|
21
29
|
@staticmethod
|
|
22
30
|
def serialize(item):
|
|
@@ -25,6 +33,7 @@ class Item:
|
|
|
25
33
|
"name": item.name,
|
|
26
34
|
"unique_name": item.unique_name,
|
|
27
35
|
"image": item.image,
|
|
36
|
+
"quantity": item.quantity,
|
|
28
37
|
}
|
|
29
38
|
|
|
30
39
|
@staticmethod
|
|
@@ -36,6 +45,12 @@ class Item:
|
|
|
36
45
|
|
|
37
46
|
@classmethod
|
|
38
47
|
def get_item_from_code(cls, code: str):
|
|
39
|
-
item =
|
|
48
|
+
item = items_by_id[code]
|
|
49
|
+
|
|
50
|
+
return cls(id=item["id"], name=item["name"], unique_name=item["unique_name"])
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def get_item_from_unique_name(cls, unique_name: str):
|
|
54
|
+
item = items_by_unique_name[unique_name]
|
|
40
55
|
|
|
41
56
|
return cls(id=item["id"], name=item["name"], unique_name=item["unique_name"])
|