Skip to content

Commit 6b0d00e

Browse files
committed
Auto sub chunk request: Try to send fewer sub chunk request packets
1 parent dc876a8 commit 6b0d00e

4 files changed

Lines changed: 156 additions & 6 deletions

File tree

前置_主动区块请求/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
class AutoSubChunkRequest(Plugin):
1616
name = "NieR: Automata"
1717
author = "2B"
18-
version = (0, 2, 5)
18+
version = (0, 3, 0)
1919

2020
base: AutoSubChunkRequestBase
2121
api: AutoSubChunkRequestAPI

前置_主动区块请求/datas.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"author": "2B",
3-
"version": "0.2.5",
3+
"version": "0.3.0",
44
"plugin-type": "classic",
55
"description": "自动请求区块数据,并将二进制化的数据分发给任何需要的插件",
66
"pre-plugins": {

前置_主动区块请求/requet_queue.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import threading
22
import time
3+
from .sub_chunk_classifier import sub_chunk_classifier
34
from tooldelta import InternalBroadcast
45
from tooldelta.constants.packets import PacketIDS
56
from tooldelta.mc_bytes_packet import sub_chunk_request
@@ -43,6 +44,7 @@ def send_request_queue(self):
4344
self.base().mu.acquire()
4445

4546
count = len(self.base().multiple_pos) * self.base().request_chunk_per_second
47+
multiple_sub_chunks: list[tuple[int, tuple[int, int, int]]] = []
4648
key_to_delete: list[ChunkPosWithDimension] = []
4749

4850
if self.base().should_close:
@@ -57,13 +59,29 @@ def send_request_queue(self):
5759
for key, value in self.base().requet_queue.items():
5860
if count <= 0:
5961
break
60-
try:
61-
self.base().game_ctrl.sendPacket(PacketIDS.IDSubChunkRequest, value)
62-
except Exception:
63-
pass
62+
for i in value.Offsets:
63+
multiple_sub_chunks.append(
64+
(
65+
value.Dimension,
66+
(
67+
value.SubChunkPosX + i[0],
68+
value.SubChunkPosY + i[1],
69+
value.SubChunkPosZ + i[2],
70+
),
71+
)
72+
)
6473
key_to_delete.append(key)
6574
count -= 1
6675

76+
if len(multiple_sub_chunks) > 0:
77+
for packet in sub_chunk_classifier(multiple_sub_chunks):
78+
try:
79+
self.base().game_ctrl.sendPacket(
80+
PacketIDS.IDSubChunkRequest, packet
81+
)
82+
except Exception:
83+
pass
84+
6785
for i in key_to_delete:
6886
del self.base().requet_queue[i]
6987

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import bisect
2+
from tooldelta.mc_bytes_packet import sub_chunk_request
3+
4+
5+
def single_dimension_classifier(
6+
sub_chunks: list[tuple[int, int, int]],
7+
) -> list[tuple[tuple[int, int], list[tuple[int, int, int]]]]:
8+
result: list[tuple[tuple[int, int], list[tuple[int, int, int]]]] = []
9+
usc_sort_x: dict[tuple[int, int, int], bool] = {}
10+
11+
for sub_chunk in sorted(sub_chunks, key=lambda i: i[0]):
12+
usc_sort_x[sub_chunk] = True
13+
14+
for sub_chunk in sorted(sub_chunks, key=lambda i: i[2]):
15+
if sub_chunk not in usc_sort_x:
16+
continue
17+
18+
x, z = sub_chunk[0], sub_chunk[2]
19+
z_start, z_end = z, z + 255
20+
last_hit_sub_chunks = 0
21+
matrix: list[tuple[int, list[tuple[int, int]]]] = []
22+
23+
best_x_start, best_hit_sub_chunks = 0, 0
24+
best_one: list[tuple[int, list[tuple[int, int]]]] = []
25+
best_center: tuple[int, int] = (0, 0)
26+
27+
last_x = 0
28+
temp: list[tuple[int, int]] = []
29+
30+
for i in usc_sort_x:
31+
if i[0] != last_x:
32+
if len(temp) > 0:
33+
temp.sort(key=lambda i: i[1])
34+
matrix.append((last_x, temp))
35+
temp = []
36+
last_x = i[0]
37+
temp.append((i[1], i[2]))
38+
if len(temp) > 0:
39+
temp.sort(key=lambda i: i[1])
40+
matrix.append((last_x, temp))
41+
temp = []
42+
43+
x_start, x_end, best_x_start = x - 127, x + 128, x - 127
44+
left = bisect.bisect_left(matrix, x_start, key=lambda i: i[0])
45+
right = bisect.bisect_right(matrix, x_end, key=lambda i: i[0])
46+
for i in matrix[left:right]:
47+
left = bisect.bisect_left(i[1], z_start, key=lambda i: i[1])
48+
right = bisect.bisect_right(i[1], z_end, key=lambda i: i[1])
49+
best_hit_sub_chunks += right - left
50+
last_hit_sub_chunks = best_hit_sub_chunks
51+
52+
for x_start in range(x - 126, x + 1):
53+
hit_sub_chunks, x_end = last_hit_sub_chunks, x_start + 255
54+
55+
ptr = bisect.bisect_left(matrix, x_start - 1, key=lambda i: i[0])
56+
sub_matrix = matrix[ptr : ptr + 1][0]
57+
if sub_matrix[0] == x_start - 1:
58+
left = bisect.bisect_left(sub_matrix[1], z_start, key=lambda i: i[1])
59+
right = bisect.bisect_right(sub_matrix[1], z_end, key=lambda i: i[1])
60+
hit_sub_chunks -= right - left
61+
62+
ptr = bisect.bisect_right(matrix, x_end, key=lambda i: i[0])
63+
sub_matrix = matrix[ptr - 1 : ptr][0]
64+
if sub_matrix[0] == x_end:
65+
left = bisect.bisect_left(sub_matrix[1], z_start, key=lambda i: i[1])
66+
right = bisect.bisect_right(sub_matrix[1], z_end, key=lambda i: i[1])
67+
hit_sub_chunks += right - left
68+
69+
if hit_sub_chunks > best_hit_sub_chunks:
70+
best_x_start = x_start
71+
best_hit_sub_chunks = hit_sub_chunks
72+
last_hit_sub_chunks = hit_sub_chunks
73+
74+
x_start, x_end = best_x_start, best_x_start + 255
75+
left = bisect.bisect_left(matrix, x_start, key=lambda i: i[0])
76+
right = bisect.bisect_right(matrix, x_end, key=lambda i: i[0])
77+
for i in matrix[left:right]:
78+
left = bisect.bisect_left(i[1], z_start, key=lambda i: i[1])
79+
right = bisect.bisect_right(i[1], z_end, key=lambda i: i[1])
80+
best_one.append((i[0], i[1][left:right]))
81+
best_center = (
82+
(x_start + x_end) // 2 + 1,
83+
(z_start + z_end) // 2 + 1,
84+
)
85+
86+
current_result: list[tuple[int, int, int]] = []
87+
88+
for i in best_one:
89+
for j in i[1]:
90+
sub_chunk_pos = (i[0], j[0], j[1])
91+
current_result.append(sub_chunk_pos)
92+
del usc_sort_x[sub_chunk_pos]
93+
94+
result.append((best_center, current_result))
95+
96+
return result
97+
98+
99+
def sub_chunk_classifier(
100+
sub_chunks: list[tuple[int, tuple[int, int, int]]],
101+
) -> list[sub_chunk_request.SubChunkRequest]:
102+
result: list[sub_chunk_request.SubChunkRequest] = []
103+
104+
sub_chunks_mapping: dict[int, list[tuple[int, int, int]]] = {}
105+
for i in sub_chunks:
106+
if i[0] not in sub_chunks_mapping:
107+
sub_chunks_mapping[i[0]] = []
108+
sub_chunks_mapping[i[0]].append(i[1])
109+
110+
for dim_id, value in sub_chunks_mapping.items():
111+
for i in single_dimension_classifier(value):
112+
packet = sub_chunk_request.SubChunkRequest()
113+
114+
packet.Dimension = dim_id
115+
packet.SubChunkPosX = i[0][0]
116+
packet.SubChunkPosY = 0
117+
packet.SubChunkPosZ = i[0][1]
118+
119+
for j in i[1]:
120+
offset = (
121+
j[0] - packet.SubChunkPosX,
122+
j[1],
123+
j[2] - packet.SubChunkPosZ,
124+
)
125+
for k in offset:
126+
if k > 127 or k < -128:
127+
raise Exception("sub_chunk_classifier: Should nerver happened")
128+
packet.Offsets.append(offset)
129+
130+
result.append(packet)
131+
132+
return result

0 commit comments

Comments
 (0)