4
4
import socket
5
5
import struct
6
6
import time
7
+ from typing import Any , Tuple , Union
8
+
7
9
import timer
8
10
import socketserver
9
11
import threading
10
12
11
13
import globals as G
14
+ from custom_types import fVector , iVector
12
15
from savingsystem import save_sector_to_bytes , save_blocks , save_world , load_player , save_player
13
16
from world_server import WorldServer
14
17
import blocks
18
21
19
22
#This class is effectively a serverside "Player" object
20
23
class ServerPlayer (socketserver .BaseRequestHandler ):
24
+ id : int
25
+ position : fVector
26
+ momentum : fVector
27
+ username : str
21
28
inventory = b"\0 " * (4 * 40 ) # Currently, is serialized to be 4 bytes * (27 inv + 9 quickbar + 4 armor) = 160 bytes
22
29
command_parser = CommandParser ()
30
+ server : 'Server'
23
31
24
32
operator = False
25
33
26
34
def sendpacket (self , size : int , packet : bytes ):
27
35
self .request .sendall (struct .pack ("i" , 5 + size ) + packet )
28
36
37
+ def send_sector (self , world : WorldServer , sector : iVector ):
38
+ if sector not in world .sectors :
39
+ with world .server_lock :
40
+ world .open_sector (sector )
41
+
42
+ if not world .sectors [sector ]:
43
+ # Empty sector, send packet 2
44
+ self .sendpacket (12 , b"\2 " + struct .pack ("iii" , * sector ))
45
+ else :
46
+ packet = struct .pack ("iii" , * sector ) \
47
+ + save_sector_to_bytes (world , sector ) \
48
+ + world .get_exposed_sector (sector )
49
+ self .sendpacket (len (packet ), b"\1 " + packet )
50
+
29
51
def sendchat (self , txt : str , color = (255 ,255 ,255 ,255 )):
30
52
txt_bytes = txt .encode ('utf-8' )
31
53
self .sendpacket (len (txt_bytes ) + 4 , b"\5 " + txt_bytes + struct .pack ("BBBB" , * color ))
@@ -70,17 +92,7 @@ def loop(self):
70
92
packettype = struct .unpack ("B" , byte )[0 ] # Client Packet Type
71
93
if packettype == 1 : # Sector request
72
94
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 )
95
+ self .send_sector (world , sector )
84
96
elif packettype == 3 : # Add block
85
97
positionbytes = self .request .recv (4 * 3 )
86
98
blockbytes = self .request .recv (2 )
@@ -141,15 +153,18 @@ def loop(self):
141
153
elif packettype == 255 : # Initial Login
142
154
txtlen = struct .unpack ("i" , self .request .recv (4 ))[0 ]
143
155
self .username = self .request .recv (txtlen ).decode ('utf-8' )
144
- self .position = None
145
156
load_player (self , "world" )
146
157
147
158
for player in self .server .players .values ():
148
159
player .sendchat ("$$y%s has connected." % self .username )
149
160
print ("%s's username is %s" % (self .client_address , self .username ))
150
161
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
162
+ if self .position is None :
163
+ # New player, set initial position
164
+ self .position = (0.0 , world .terraingen .get_height (0 , 0 ) + 2.0 , 0.0 )
165
+ elif self .position [1 ] < 0 :
166
+ # Somehow fell below the world, reset their height
167
+ self .position = (self .position [0 ], world .terraingen .get_height (0 , 0 ) + 2.0 , self .position [2 ])
153
168
154
169
# Send list of current players to the newcomer
155
170
for player in self .server .players .values ():
@@ -163,16 +178,15 @@ def loop(self):
163
178
player .sendpacket (2 + len (name ), b'\7 ' + struct .pack ("H" , self .id ) + name )
164
179
165
180
#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 )
181
+ sector = sectorize (self .position )
182
+ self .send_sector (world , sector )
183
+ if sector [1 ] > 0 :
184
+ sector_below = (sector [0 ], sector [1 ] - 1 , sector [2 ])
185
+ self .send_sector (world , sector_below )
172
186
173
187
#Send them their spawn position and world seed(for client side biome generator)
174
188
seed_packet = make_string_packet (G .SEED )
175
- self .sendpacket (12 + len (seed_packet ), struct .pack ("B" ,255 ) + struct .pack ("iii " , * position ) + seed_packet )
189
+ self .sendpacket (12 + len (seed_packet ), struct .pack ("B" ,255 ) + struct .pack ("fff " , * self . position ) + seed_packet )
176
190
self .sendpacket (4 * 40 , b"\6 " + self .inventory )
177
191
else :
178
192
print ("Received unknown packettype" , packettype )
0 commit comments