Chunk loading and unloading works moving around
This commit is contained in:
parent
afeac68abc
commit
c1c7fd1b43
190
server/main.py
190
server/main.py
|
@ -82,6 +82,122 @@ class Buffer_1_18_2(Buffer1_14):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
class Player:
|
||||||
|
|
||||||
|
_conn: "YTDServerProtocol"
|
||||||
|
_name: str
|
||||||
|
_x: float
|
||||||
|
_y: float
|
||||||
|
_z: float
|
||||||
|
_yaw: float
|
||||||
|
_pitch: float
|
||||||
|
_chunks: set[tuple[int,int]]
|
||||||
|
_load_queue: list[tuple[int,int]]
|
||||||
|
_unload_queue: list[tuple[int,int]]
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
connection: "YTDServerProtocol",
|
||||||
|
name: str,
|
||||||
|
x: float,
|
||||||
|
y: float,
|
||||||
|
z: float,
|
||||||
|
yaw: float,
|
||||||
|
pitch: float,
|
||||||
|
):
|
||||||
|
self._conn = connection
|
||||||
|
self._name = name
|
||||||
|
self._x = x
|
||||||
|
self._y = y
|
||||||
|
self._z = z
|
||||||
|
self._yaw = yaw
|
||||||
|
self._pitch = pitch
|
||||||
|
|
||||||
|
self._chunks = set()
|
||||||
|
self._load_queue = list()
|
||||||
|
self._unload_queue = list()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def x(self) -> float:
|
||||||
|
return self._x
|
||||||
|
|
||||||
|
@property
|
||||||
|
def y(self) -> float:
|
||||||
|
return self._y
|
||||||
|
|
||||||
|
@property
|
||||||
|
def z(self) -> float:
|
||||||
|
return self._z
|
||||||
|
|
||||||
|
@property
|
||||||
|
def yaw(self) -> float:
|
||||||
|
return self._yaw
|
||||||
|
|
||||||
|
@yaw.setter
|
||||||
|
def yaw(self, value: float):
|
||||||
|
self._yaw = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pitch(self) -> float:
|
||||||
|
return self._pitch
|
||||||
|
|
||||||
|
@pitch.setter
|
||||||
|
def pitch(self, value: float):
|
||||||
|
self._pitch = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cx(self) -> int:
|
||||||
|
return int(self.x // 16)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cy(self) -> int:
|
||||||
|
return int(self.y // 16)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cz(self) -> int:
|
||||||
|
return int(self.z // 16)
|
||||||
|
|
||||||
|
def update_pos(self, x: float, y: float, z: float):
|
||||||
|
chunk_crossed = int(x // 16) != self.cx or int(z // 16) != self.cz
|
||||||
|
self._x = x
|
||||||
|
self._y = y
|
||||||
|
self._z = z
|
||||||
|
if chunk_crossed:
|
||||||
|
self.update_chunks()
|
||||||
|
|
||||||
|
def update_chunks(self):
|
||||||
|
print("Chunk Crossed")
|
||||||
|
vd = self._conn.view_distance
|
||||||
|
chunks: set[tuple[int,int]] = set()
|
||||||
|
for x in range(self.cx-vd, self.cx+vd+1):
|
||||||
|
for z in range(self.cz-vd, self.cz+vd+1):
|
||||||
|
chunks.add((x,z))
|
||||||
|
new_chunks = chunks.difference(self._chunks)
|
||||||
|
old_chunks = self._chunks.difference(chunks)
|
||||||
|
for i in new_chunks:
|
||||||
|
self.load_chunk(*i)
|
||||||
|
for i in old_chunks:
|
||||||
|
self.unload_chunk(*i)
|
||||||
|
self._conn.send_update_view_position(self.cx,self.cz)
|
||||||
|
|
||||||
|
def load_chunk(self, x: int, z: int):
|
||||||
|
print(f"enqueuing loading chunk {x}, {z}")
|
||||||
|
self._chunks.add((x,z))
|
||||||
|
self._load_queue.append((x,z))
|
||||||
|
# self._conn.send_chunk(x,z)
|
||||||
|
|
||||||
|
def unload_chunk(self, x: int, z: int):
|
||||||
|
print(f"enqueuing unloading chunk {x}, {z}")
|
||||||
|
try: self._chunks.remove((x,z))
|
||||||
|
except KeyError: pass
|
||||||
|
self._unload_queue.append((x,z))
|
||||||
|
# self._conn.send_unload_chunk(x,z)
|
||||||
|
|
||||||
|
|
||||||
class YTDServerProtocol(ServerProtocol):
|
class YTDServerProtocol(ServerProtocol):
|
||||||
|
|
||||||
def player_joined(self):
|
def player_joined(self):
|
||||||
|
@ -89,6 +205,17 @@ class YTDServerProtocol(ServerProtocol):
|
||||||
# in-game, and does some logging.
|
# in-game, and does some logging.
|
||||||
ServerProtocol.player_joined(self)
|
ServerProtocol.player_joined(self)
|
||||||
self.buff_type = Buffer_1_18_2
|
self.buff_type = Buffer_1_18_2
|
||||||
|
self.view_distance = 2
|
||||||
|
|
||||||
|
self.player = Player(
|
||||||
|
self,
|
||||||
|
self.display_name, # type: ignore
|
||||||
|
0,
|
||||||
|
325,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
|
||||||
# Send join game packet
|
# Send join game packet
|
||||||
self.send_join_game()
|
self.send_join_game()
|
||||||
|
@ -97,17 +224,18 @@ class YTDServerProtocol(ServerProtocol):
|
||||||
self.send_packet(
|
self.send_packet(
|
||||||
"player_position_and_look",
|
"player_position_and_look",
|
||||||
self.buff_type.pack("dddff?",
|
self.buff_type.pack("dddff?",
|
||||||
0, # x
|
self.player.x,
|
||||||
325, # y Must be >= build height to pass the "Loading Terrain" screen on 1.18.2
|
self.player.y,
|
||||||
0, # z
|
self.player.z,
|
||||||
0, # yaw
|
self.player.yaw,
|
||||||
0, # pitch
|
self.player.pitch,
|
||||||
0b00000), # flags
|
0b00000),
|
||||||
self.buff_type.pack_varint(0), # teleport id
|
self.buff_type.pack_varint(0),
|
||||||
self.buff_type.pack("?", True)) # Leave vehicle
|
self.buff_type.pack("?", True))
|
||||||
|
|
||||||
# Start sending "Keep Alive" packets
|
# Start sending "Keep Alive" packets
|
||||||
self.ticker.add_loop(20, self.update_keep_alive)
|
self.ticker.add_loop(20, self.update_keep_alive)
|
||||||
|
self.ticker.add_loop(1, self.manage_queue)
|
||||||
|
|
||||||
# Announce player join to other players
|
# Announce player join to other players
|
||||||
self.factory.broadcast_player_join(self)
|
self.factory.broadcast_player_join(self)
|
||||||
|
@ -116,10 +244,14 @@ class YTDServerProtocol(ServerProtocol):
|
||||||
self.factory.send_player_list_add(self, self.factory.players)
|
self.factory.send_player_list_add(self, self.factory.players)
|
||||||
|
|
||||||
self.send_update_view_position(0,0)
|
self.send_update_view_position(0,0)
|
||||||
self.send_chunk(0,0)
|
self.player.load_chunk(0,0)
|
||||||
self.send_chunk(-1,0)
|
self.player.load_chunk(-1,0)
|
||||||
self.send_chunk(0,-1)
|
self.player.load_chunk(0,-1)
|
||||||
self.send_chunk(-1,-1)
|
self.player.load_chunk(-1,-1)
|
||||||
|
# self.send_chunk(0,0)
|
||||||
|
# self.send_chunk(-1,0)
|
||||||
|
# self.send_chunk(0,-1)
|
||||||
|
# self.send_chunk(-1,-1)
|
||||||
# self.send_chunk(1,0)
|
# self.send_chunk(1,0)
|
||||||
# self.send_chunk(0,1)
|
# self.send_chunk(0,1)
|
||||||
# self.send_chunk(1,1)
|
# self.send_chunk(1,1)
|
||||||
|
@ -130,7 +262,7 @@ class YTDServerProtocol(ServerProtocol):
|
||||||
entity_id = 0
|
entity_id = 0
|
||||||
max_players = 0
|
max_players = 0
|
||||||
hashed_seed = 42
|
hashed_seed = 42
|
||||||
view_distance = 2
|
view_distance = self.view_distance
|
||||||
simulation_distance = 2
|
simulation_distance = 2
|
||||||
game_mode = 3
|
game_mode = 3
|
||||||
prev_game_mode = 3
|
prev_game_mode = 3
|
||||||
|
@ -167,6 +299,22 @@ class YTDServerProtocol(ServerProtocol):
|
||||||
# Send "Join Game" packet
|
# Send "Join Game" packet
|
||||||
self.send_packet("join_game", *join_game)
|
self.send_packet("join_game", *join_game)
|
||||||
|
|
||||||
|
def manage_queue(self):
|
||||||
|
if self.player._load_queue:
|
||||||
|
x,z = self.player._load_queue.pop(0)
|
||||||
|
while (x,z) in self.player._load_queue:
|
||||||
|
self.player._load_queue.remove((x,z))
|
||||||
|
print(f"dequeuing loading chunk {x}, {z}")
|
||||||
|
self.send_chunk(x,z)
|
||||||
|
elif self.player._unload_queue:
|
||||||
|
x,z = self.player._unload_queue.pop(0)
|
||||||
|
while (x,z) in self.player._unload_queue:
|
||||||
|
self.player._unload_queue.remove((x,z))
|
||||||
|
print(f"dequeuing unloading chunk {x}, {z}")
|
||||||
|
self.send_unload_chunk(x,z)
|
||||||
|
# else:
|
||||||
|
# print("queues empty")
|
||||||
|
|
||||||
def player_left(self):
|
def player_left(self):
|
||||||
ServerProtocol.player_left(self)
|
ServerProtocol.player_left(self)
|
||||||
|
|
||||||
|
@ -194,14 +342,22 @@ class YTDServerProtocol(ServerProtocol):
|
||||||
self.buff_type.pack_varint(z),
|
self.buff_type.pack_varint(z),
|
||||||
)
|
)
|
||||||
|
|
||||||
# def send_chunk(self, x, z, full, heightmap, sections, biomes):
|
def packet_player_position(self, buff: Buffer_1_18_2):
|
||||||
def send_chunk(self, x, z):
|
self.player.update_pos(*buff.unpack('ddd'))
|
||||||
sections, heightmap = self.factory.generate(x,z)
|
|
||||||
sections_data = self.buff_type.pack_chunk(sections)
|
buff.discard()
|
||||||
|
|
||||||
|
def send_unload_chunk(self, x, z):
|
||||||
self.send_packet(
|
self.send_packet(
|
||||||
'unload_chunk',
|
'unload_chunk',
|
||||||
self.buff_type.pack('ii', x, z),
|
self.buff_type.pack('ii', x, z),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# def send_chunk(self, x, z, full, heightmap, sections, biomes):
|
||||||
|
def send_chunk(self, x, z):
|
||||||
|
sections, heightmap = self.factory.generate(x,z)
|
||||||
|
sections_data = self.buff_type.pack_chunk(sections)
|
||||||
|
self.send_unload_chunk(x,z)
|
||||||
self.send_packet(
|
self.send_packet(
|
||||||
'chunk_data',
|
'chunk_data',
|
||||||
self.buff_type.pack('ii', x, z),
|
self.buff_type.pack('ii', x, z),
|
||||||
|
|
Loading…
Reference in New Issue