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
|
||||
|
||||
|
||||
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):
|
||||
|
||||
def player_joined(self):
|
||||
|
@ -89,6 +205,17 @@ class YTDServerProtocol(ServerProtocol):
|
|||
# in-game, and does some logging.
|
||||
ServerProtocol.player_joined(self)
|
||||
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
|
||||
self.send_join_game()
|
||||
|
@ -97,17 +224,18 @@ class YTDServerProtocol(ServerProtocol):
|
|||
self.send_packet(
|
||||
"player_position_and_look",
|
||||
self.buff_type.pack("dddff?",
|
||||
0, # x
|
||||
325, # y Must be >= build height to pass the "Loading Terrain" screen on 1.18.2
|
||||
0, # z
|
||||
0, # yaw
|
||||
0, # pitch
|
||||
0b00000), # flags
|
||||
self.buff_type.pack_varint(0), # teleport id
|
||||
self.buff_type.pack("?", True)) # Leave vehicle
|
||||
self.player.x,
|
||||
self.player.y,
|
||||
self.player.z,
|
||||
self.player.yaw,
|
||||
self.player.pitch,
|
||||
0b00000),
|
||||
self.buff_type.pack_varint(0),
|
||||
self.buff_type.pack("?", True))
|
||||
|
||||
# Start sending "Keep Alive" packets
|
||||
self.ticker.add_loop(20, self.update_keep_alive)
|
||||
self.ticker.add_loop(1, self.manage_queue)
|
||||
|
||||
# Announce player join to other players
|
||||
self.factory.broadcast_player_join(self)
|
||||
|
@ -116,10 +244,14 @@ class YTDServerProtocol(ServerProtocol):
|
|||
self.factory.send_player_list_add(self, self.factory.players)
|
||||
|
||||
self.send_update_view_position(0,0)
|
||||
self.send_chunk(0,0)
|
||||
self.send_chunk(-1,0)
|
||||
self.send_chunk(0,-1)
|
||||
self.send_chunk(-1,-1)
|
||||
self.player.load_chunk(0,0)
|
||||
self.player.load_chunk(-1,0)
|
||||
self.player.load_chunk(0,-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(0,1)
|
||||
# self.send_chunk(1,1)
|
||||
|
@ -130,7 +262,7 @@ class YTDServerProtocol(ServerProtocol):
|
|||
entity_id = 0
|
||||
max_players = 0
|
||||
hashed_seed = 42
|
||||
view_distance = 2
|
||||
view_distance = self.view_distance
|
||||
simulation_distance = 2
|
||||
game_mode = 3
|
||||
prev_game_mode = 3
|
||||
|
@ -167,6 +299,22 @@ class YTDServerProtocol(ServerProtocol):
|
|||
# Send "Join Game" packet
|
||||
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):
|
||||
ServerProtocol.player_left(self)
|
||||
|
||||
|
@ -194,14 +342,22 @@ class YTDServerProtocol(ServerProtocol):
|
|||
self.buff_type.pack_varint(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)
|
||||
def packet_player_position(self, buff: Buffer_1_18_2):
|
||||
self.player.update_pos(*buff.unpack('ddd'))
|
||||
|
||||
buff.discard()
|
||||
|
||||
def send_unload_chunk(self, x, z):
|
||||
self.send_packet(
|
||||
'unload_chunk',
|
||||
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(
|
||||
'chunk_data',
|
||||
self.buff_type.pack('ii', x, z),
|
||||
|
|
Loading…
Reference in New Issue