99import threading
1010
1111import globals as G
12+ from custom_types import fVector , iVector
1213from savingsystem import save_sector_to_bytes , save_blocks , save_world , load_player , save_player
1314from world_server import WorldServer
1415import blocks
1819
1920#This class is effectively a serverside "Player" object
2021class ServerPlayer (socketserver .BaseRequestHandler ):
22+ id : int
23+ position : fVector
24+ momentum : fVector
25+ username : str
2126 inventory = b"\0 " * (4 * 40 ) # Currently, is serialized to be 4 bytes * (27 inv + 9 quickbar + 4 armor) = 160 bytes
2227 command_parser = CommandParser ()
28+ server : 'Server'
2329
2430 operator = False
2531
2632 def sendpacket (self , size : int , packet : bytes ):
2733 self .request .sendall (struct .pack ("i" , 5 + size ) + packet )
2834
35+ def send_sector (self , world : WorldServer , sector : iVector ):
36+ if sector not in world .sectors :
37+ with world .server_lock :
38+ world .open_sector (sector )
39+
40+ if not world .sectors [sector ]:
41+ # Empty sector, send packet 2
42+ self .sendpacket (12 , b"\2 " + struct .pack ("iii" , * sector ))
43+ else :
44+ packet = struct .pack ("iii" , * sector ) \
45+ + save_sector_to_bytes (world , sector ) \
46+ + world .get_exposed_sector (sector )
47+ self .sendpacket (len (packet ), b"\1 " + packet )
48+
2949 def sendchat (self , txt : str , color = (255 ,255 ,255 ,255 )):
3050 txt_bytes = txt .encode ('utf-8' )
3151 self .sendpacket (len (txt_bytes ) + 4 , b"\5 " + txt_bytes + struct .pack ("BBBB" , * color ))
@@ -70,17 +90,7 @@ def loop(self):
7090 packettype = struct .unpack ("B" , byte )[0 ] # Client Packet Type
7191 if packettype == 1 : # Sector request
7292 sector = struct .unpack ("iii" , self .request .recv (4 * 3 ))
73-
74- if sector not in world .sectors :
75- with world .server_lock :
76- world .open_sector (sector )
77-
78- if not world .sectors [sector ]:
79- #Empty sector, send packet 2
80- self .sendpacket (12 , b"\2 " + struct .pack ("iii" ,* sector ))
81- else :
82- msg = struct .pack ("iii" ,* sector ) + save_sector_to_bytes (world , sector ) + world .get_exposed_sector (sector )
83- self .sendpacket (len (msg ), b"\1 " + msg )
93+ self .send_sector (world , sector )
8494 elif packettype == 3 : # Add block
8595 positionbytes = self .request .recv (4 * 3 )
8696 blockbytes = self .request .recv (2 )
@@ -141,15 +151,18 @@ def loop(self):
141151 elif packettype == 255 : # Initial Login
142152 txtlen = struct .unpack ("i" , self .request .recv (4 ))[0 ]
143153 self .username = self .request .recv (txtlen ).decode ('utf-8' )
144- self .position = None
145154 load_player (self , "world" )
146155
147156 for player in self .server .players .values ():
148157 player .sendchat ("$$y%s has connected." % self .username )
149158 print ("%s's username is %s" % (self .client_address , self .username ))
150159
151- position = (0 ,self .server .world .terraingen .get_height (0 ,0 )+ 2 ,0 )
152- if self .position is None : self .position = position # New player, set initial position
160+ if self .position is None :
161+ # New player, set initial position
162+ self .position = (0.0 , world .terraingen .get_height (0 , 0 ) + 2.0 , 0.0 )
163+ elif self .position [1 ] < 0 :
164+ # Somehow fell below the world, reset their height
165+ self .position = (self .position [0 ], world .terraingen .get_height (0 , 0 ) + 2.0 , self .position [2 ])
153166
154167 # Send list of current players to the newcomer
155168 for player in self .server .players .values ():
@@ -163,16 +176,15 @@ def loop(self):
163176 player .sendpacket (2 + len (name ), b'\7 ' + struct .pack ("H" , self .id ) + name )
164177
165178 #Send them the sector under their feet first so they don't fall
166- sector = sectorize (position )
167- if sector not in world .sectors :
168- with world .server_lock :
169- world .open_sector (sector )
170- msg = struct .pack ("iii" ,* sector ) + save_sector_to_bytes (world , sector ) + world .get_exposed_sector (sector )
171- self .sendpacket (len (msg ), b"\1 " + msg )
179+ sector = sectorize (self .position )
180+ self .send_sector (world , sector )
181+ if sector [1 ] > 0 :
182+ sector_below = (sector [0 ], sector [1 ] - 1 , sector [2 ])
183+ self .send_sector (world , sector_below )
172184
173185 #Send them their spawn position and world seed(for client side biome generator)
174186 seed_packet = make_string_packet (G .SEED )
175- self .sendpacket (12 + len (seed_packet ), struct .pack ("B" ,255 ) + struct .pack ("iii " , * position ) + seed_packet )
187+ self .sendpacket (12 + len (seed_packet ), struct .pack ("B" ,255 ) + struct .pack ("fff " , * self . position ) + seed_packet )
176188 self .sendpacket (4 * 40 , b"\6 " + self .inventory )
177189 else :
178190 print ("Received unknown packettype" , packettype )
0 commit comments