#!/usr/bin/env python
# -*- coding: utf-8 -*-


#
# Server side of the NetworkDemo application
#


#
# External dependencies
#
import socket
import sys
import threading
import time


#
# Thread to compute the position of the ball
#
class NetworkBallServer( threading.Thread ) :
	
	#
	# Initialization
	#
	def __init__( self ) :

		# Initialize the thread
		super( NetworkBallServer, self ).__init__()

		# Client list
		self.clients = []

	#
	# Thread main loop
	#
	def run( self ) :
		
		self.running = True

		# Screen size
		sw = 1920
		sh = 1200

		# Ball coordinates and speed
		x, y, v, dx, dv = 50, 50, 0, 12, 5

		# Border
		sh = sh - 100 - 30

		# Thread running
		while self.running :
			
			# No clients
			if not self.clients :
				time.sleep( 0.1 )
				continue

			# Horizontal move
			if x > len(self.clients)*sw or x < 0 :     # rebond sur les parois latérales :
				dx = -dx             # on inverse le déplacement
			x = x + dx

			# Vertical speed variation
			v = v + dv

			# Vertical move
			y = y + v 
			if y > sh :              # niveau du sol à 240 pixels : 
				y = sh             #  défense d'aller + loin !
				v = -v               # rebond : la vitesse s'inverse

			# Send ball coordinates to the clients
			for n, client in enumerate( self.clients ) :
				
			#	print( 'Coordonnées ({},{}) envoyées à {}:{}'.format( x, y, *chost ) )

				# Send the coordinates
				try : client.send( '{},{}.\n'.format( x-n*sw, y ) )
				
				# Client isn't here anymore
				except :
					print( 'Connection lost...' )
					client.close()
					self.clients.remove( client )
					# Initialize ball parameters
					if self.clients : x -= sw

			# Timer
			time.sleep( 0.03 )


# Set up Internet TCP socket
server = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
server.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )

# Bind socket to port 10000
server.bind( ( '', 10000 ) )

# Start listening for contacts from clients
server.listen( 5 )

# Ball thread
ball_thread = NetworkBallServer()
ball_thread.start()

try :

	# Client connection
	while True :
		
		connection, _ = server.accept()
		print( 'Connection from {}:{}...'.format( *connection.getpeername() ) )
		ball_thread.clients.append( connection )

except :
	
	# Close the server
	server.close()
	ball_thread.running = False
	ball_thread.join()
	for client in ball_thread.clients :
		client.connection.close()

@@ -138,19 +138,8 @@
 ket%0A
-import sys%0A
 impo
@@ -1582,55 +1582,79 @@
 %09%09# 
-Initialize ball parameters%0A%09%09%09%09%09if self.clients
+Fix ball position%0A%09%09%09%09%09if self.clients and x %3E len( self.clients ) * sw
  : x
@@ -1990,23 +1990,16 @@
 ead%0Aball
-_thread
  = Netwo
@@ -2017,23 +2017,16 @@
 r()%0Aball
-_thread
 .start()
@@ -2182,31 +2182,24 @@
 ) ) )%0A%09%09ball
-_thread
 .clients.app
@@ -2269,23 +2269,16 @@
 ()%0A%09ball
-_thread
 .running
@@ -2291,23 +2291,16 @@
 se%0A%09ball
-_thread
 .join()%0A
@@ -2322,15 +2322,8 @@
 ball
-_thread
 .cli
@@ -2338,27 +2338,16 @@
 %09client.
-connection.
 close()%0A

Fix ball position on client disconnection.