Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send returning players their saved position on connect, rather than 0,0 #97

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion client.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def dequeue_packet(self):
elif packetid == 10: # Update Tile Entity
self.world[struct.unpack("iii", packet[:12])].update_tile_entity(packet[12:])
elif packetid == 255: # Spawn Position
self.controller.player.position = struct.unpack("iii", packet[:12])
self.controller.player.position = struct.unpack("fff", packet[:12])
packet = packet[12:]
packet, seed = extract_string_packet(packet)
self.world.biome_generator = BiomeGenerator(seed)
Expand Down
4 changes: 2 additions & 2 deletions savingsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def save_blocks(blocks: custom_types.WorldServer, world: str):
#blocks and sectors (window.world and window.world.sectors)
#Saves individual sectors in region files (4x4x4 sectors)

for secpos in blocks.sectors: #TODO: only save dirty sectors
for secpos in blocks.sectors.keys(): #TODO: only save dirty sectors
if not blocks.sectors[secpos]:
continue #Skip writing empty sectors
file = os.path.join(G.game_dir, world, sector_to_filename(secpos))
Expand Down Expand Up @@ -182,7 +182,7 @@ def load_region(world: custom_types.WorldServer, world_name: str = "world", regi
print("load_region: Invalid Block", e)
sectors[(x//SECTOR_SIZE, y//SECTOR_SIZE, z//SECTOR_SIZE)].append(position)

def load_player(player, world: str):
def load_player(player: custom_types.ServerPlayer, world: str):
db = connect_db(world)
cur = db.cursor()
cur.execute("select * from players where name='%s'" % player.username)
Expand Down
54 changes: 33 additions & 21 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import threading

import globals as G
from custom_types import fVector, iVector
from savingsystem import save_sector_to_bytes, save_blocks, save_world, load_player, save_player
from world_server import WorldServer
import blocks
Expand All @@ -18,14 +19,33 @@

#This class is effectively a serverside "Player" object
class ServerPlayer(socketserver.BaseRequestHandler):
id: int
position: fVector
momentum: fVector
username: str
inventory = b"\0"*(4*40) # Currently, is serialized to be 4 bytes * (27 inv + 9 quickbar + 4 armor) = 160 bytes
command_parser = CommandParser()
server: 'Server'

operator = False

def sendpacket(self, size: int, packet: bytes):
self.request.sendall(struct.pack("i", 5 + size) + packet)

def send_sector(self, world: WorldServer, sector: iVector):
if sector not in world.sectors:
with world.server_lock:
world.open_sector(sector)

if not world.sectors[sector]:
# Empty sector, send packet 2
self.sendpacket(12, b"\2" + struct.pack("iii", *sector))
else:
packet = struct.pack("iii", *sector) \
+ save_sector_to_bytes(world, sector) \
+ world.get_exposed_sector(sector)
self.sendpacket(len(packet), b"\1" + packet)

def sendchat(self, txt: str, color=(255,255,255,255)):
txt_bytes = txt.encode('utf-8')
self.sendpacket(len(txt_bytes) + 4, b"\5" + txt_bytes + struct.pack("BBBB", *color))
Expand Down Expand Up @@ -70,17 +90,7 @@ def loop(self):
packettype = struct.unpack("B", byte)[0] # Client Packet Type
if packettype == 1: # Sector request
sector = struct.unpack("iii", self.request.recv(4*3))

if sector not in world.sectors:
with world.server_lock:
world.open_sector(sector)

if not world.sectors[sector]:
#Empty sector, send packet 2
self.sendpacket(12, b"\2" + struct.pack("iii",*sector))
else:
msg = struct.pack("iii",*sector) + save_sector_to_bytes(world, sector) + world.get_exposed_sector(sector)
self.sendpacket(len(msg), b"\1" + msg)
self.send_sector(world, sector)
elif packettype == 3: # Add block
positionbytes = self.request.recv(4*3)
blockbytes = self.request.recv(2)
Expand Down Expand Up @@ -141,15 +151,18 @@ def loop(self):
elif packettype == 255: # Initial Login
txtlen = struct.unpack("i", self.request.recv(4))[0]
self.username = self.request.recv(txtlen).decode('utf-8')
self.position = None
load_player(self, "world")

for player in self.server.players.values():
player.sendchat("$$y%s has connected." % self.username)
print("%s's username is %s" % (self.client_address, self.username))

position = (0,self.server.world.terraingen.get_height(0,0)+2,0)
if self.position is None: self.position = position # New player, set initial position
if self.position is None:
# New player, set initial position
self.position = (0.0, world.terraingen.get_height(0, 0) + 2.0, 0.0)
elif self.position[1] < 0:
# Somehow fell below the world, reset their height
self.position = (self.position[0], world.terraingen.get_height(0, 0) + 2.0, self.position[2])

# Send list of current players to the newcomer
for player in self.server.players.values():
Expand All @@ -163,16 +176,15 @@ def loop(self):
player.sendpacket(2 + len(name), b'\7' + struct.pack("H", self.id) + name)

#Send them the sector under their feet first so they don't fall
sector = sectorize(position)
if sector not in world.sectors:
with world.server_lock:
world.open_sector(sector)
msg = struct.pack("iii",*sector) + save_sector_to_bytes(world, sector) + world.get_exposed_sector(sector)
self.sendpacket(len(msg), b"\1" + msg)
sector = sectorize(self.position)
self.send_sector(world, sector)
if sector[1] > 0:
sector_below = (sector[0], sector[1] - 1, sector[2])
self.send_sector(world, sector_below)

#Send them their spawn position and world seed(for client side biome generator)
seed_packet = make_string_packet(G.SEED)
self.sendpacket(12 + len(seed_packet), struct.pack("B",255) + struct.pack("iii", *position) + seed_packet)
self.sendpacket(12 + len(seed_packet), struct.pack("B",255) + struct.pack("fff", *self.position) + seed_packet)
self.sendpacket(4*40, b"\6" + self.inventory)
else:
print("Received unknown packettype", packettype)
Expand Down
12 changes: 5 additions & 7 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Python packages
import os
import struct
from typing import Tuple, List
from typing import Tuple, List, Union
from ctypes import byref

# Third-party packages
Expand Down Expand Up @@ -204,12 +204,10 @@ def normalize(position: fVector) -> fVector:
return normalize_float(x), normalize_float(y), normalize_float(z)


def sectorize(position: iVector) -> iVector:
x, y, z = normalize(position)
x, y, z = (x // G.SECTOR_SIZE,
y // G.SECTOR_SIZE,
z // G.SECTOR_SIZE)
return x, y, z
def sectorize(position: Union[iVector, fVector]) -> iVector:
return (normalize_float(float(position[0])) // G.SECTOR_SIZE,
normalize_float(float(position[1])) // G.SECTOR_SIZE,
normalize_float(float(position[2])) // G.SECTOR_SIZE)


class TextureGroup(pyglet.graphics.Group):
Expand Down