#!/usr/bin/env python # -*- coding: utf-8 -*- # Enlace_Red_JAMtank.py por: # Flavio Danesse # CeibalJAM! - Uruguay - Plan Ceibal # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import gc gc.enable() import socket, time import os import sys from Jugador_JAMtank import Jugador_JAMtank TERMINATOR = "\r\n\r\n" class Enlace_Red_JAMtank(): def __init__(self, ip="localhost", PUERTO=5000, protagonista=None, objetos_graficos=None, nombre=None): # El socket con el server self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # La direccion de escucha del server self.direccion_servidor = (ip, PUERTO) self.socket.connect(self.direccion_servidor) self.socket.setblocking(0) # Datos del Jugador Local self.nombre = nombre # identifica al jugador local en el server self.protagonista = protagonista # es el jugador local # Debe informarse de los cambios a los objetos gráficos self.objetos_graficos = objetos_graficos # Diccionario de jugadores en el juego self.jugadores = {} # Diccionario=> key=nombre:value=Jugador_JAMtank(pygame.sprite.Sprite) # Datos entrantes y salientes self.buffer_de_salida = None # Latencia en la red self.TIEMPO_ENVIO = 0.0 self.TIEMPO_RECIBO = 0.0 self.LATENCIA = 0.0 def desconectarse (self): # cierra el socket, el server debe hacer finish print "Desconectandose de la Red . . ." self.socket.close() time.sleep(0.2) def enviar_datos(self): # Envia datos al server, el buffer es llenado desde JAMtank #print "Enviando Datos en Enlace_Red_JAMtank: ", self.buffer_de_salida # calculo de latencia self.TIEMPO_ENVIO = time.time() try: self.socket.send(self.buffer_de_salida) except socket.error, e: #print "Error en Cliente al Enviar Datos: ", self.buffer_de_salida, "Error %s" % (e) return self.buffer_de_salida = "" def get_jugadores_puntos(self): # devuelve una lista puntos-nombre para armar un ranking lista = [] for jugador in self.jugadores.values(): puntaje, nombre = jugador.puntaje, jugador.nombre lista.append( (puntaje, nombre) ) return lista def recibir_datos(self): # recibe los datos del server (incluyendo los propios) buffer_de_entrada = None mensajes = None try: buffer_de_entrada = self.socket.recv(512) mensajes = list(buffer_de_entrada.split(TERMINATOR)) self.procesar_datos(mensajes) except socket.error, e: #print "Error en Cliente al Recibir Datos: ", buffer_de_entrada, "Error %s" % (e) return ''' # calculo de latencia self.TIEMPO_RECIBO = time.time() tiempo = self.TIEMPO_RECIBO-self.TIEMPO_ENVIO if tiempo > self.LATENCIA: self.LATENCIA = tiempo print self.LATENCIA ''' def procesar_datos(self, lista_mesajes): # Se recibe una lista de mensajes y se procesan según su tipo for mensaje in lista_mesajes: # para todos los mensajes valores = mensaje.split() # separar los datos if "T" in valores: # Recibe los datos de posición de un tanque try: nombre, angulo, x, y = int(valores[0]), int(valores[2]), int(valores[3]), int(valores[4]) except: return if nombre not in self.jugadores.keys(): # Si es un nuevo jugador, lo agrega al diccionario if nombre == self.nombre: # Si es el jugador local es el protagonista self.jugadores[nombre] = self.protagonista else: # Si no es el jugador local img = self.objetos_graficos.directorio_de_imagenes+"Tanque_Enemigo.bmp" self.jugadores[nombre] = Jugador_JAMtank(imagen=img,nombre=nombre, angulo=angulo, x=x, y=y,resolucion_monitor=self.objetos_graficos.resolucion_monitor, directorio_de_imagenes=self.objetos_graficos.directorio_de_imagenes) self.jugadores[nombre].setup() self.objetos_graficos.tanques.add(self.jugadores[nombre]) self.objetos_graficos.set_play_motor() # Ranking #self.objetos_graficos.set_menu_jugadores(self.get_jugadores_puntos()) # Actualiza la posicion del tanque if nombre != self.nombre: self.jugadores[nombre].set_posicion(angulo=angulo, x=x, y=y) # actualiza la posición elif "DES" in valores: # un jugador se ha desconectado nombre = int(valores[1]) self.jugadores[nombre].kill() del self.jugadores[nombre] elif "B" in valores: # Recibe los datos de una bala try: nombre, angulo, x, y = int(valores[0]), int(valores[2]), int(valores[3]), int(valores[4]) except: return self.jugadores[nombre].crear_disparo(nombre, angulo, (x,y)) self.objetos_graficos.todas_las_balas.add(self.jugadores[nombre].bala) self.objetos_graficos.set_play_bala() if nombre == self.nombre: # si la bala es propia, se informa de que se recibió, cuando la bala desaparezca, se pondrá en None self.protagonista.estado_bala = "recibida" elif "D" in valores: # Recibe el puntaje de un jugador # self.puntos = "%s %s %s %s%s" % (self.nombre, "D", energia, puntaje, TERMINATOR) try: nombre, energia, puntaje = int(valores[0]), int(valores[2]), int(valores[3]) except: return self.jugadores[nombre].set_puntaje(energia, puntaje) elif "P" in valores: pass else: if valores: print "recibiendo cosas raras en el cliente:", valores pass