FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   ConectarConectar 
Tablas de records on-line

 
Publicar nuevo tema   Responder al tema    Índice del foro -> Desarrollo
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
traperic
Usuario avanzado


Registrado: 10 Abr 2005
Mensajes: 72

MensajePublicado: Sab Dic 24, 2005 12:41 pm    Asunto: Tablas de records on-line Responder citando

Hola, estoy intentando hacer la tabla de records on-line para Phantomas, y francamente, es un tema que nunca he tocado y no tengo ni idea de cómo hacerlo.

He hecho los cgis que deben controlar ingresar un record, mostrarlo y eso y funcionan bien, lo que ocurre es que no tengo ni idea de cómo mandar/recibir los datos entre el programa y el servidor.

Me he bajado el código fuente del F1 Spirit y he investigado un poco, he pasado a C la clase F1Shttp (un poco por encima para hacer pruebas) pero no sé ni cómo usarlo bien.

Popolon, si lees esto y me puedes echar una mano te lo agradecería, y si ya es un mini ejemplo, mucho más si cabe Wink.

Este es el código del programa que se encarga de ingresar un record, básicamente coge una cadena con el nombre, el lugar y los puntos en la forma http://xxx.yyy.zzz/este_cgi/name=tu_nombre/place=tu_ciudad/points=tu_puntuacion y lo mete en el lugar correspondiente en la tabla de records.

Código:

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>


#define MAXRECORDS   10
#define NAMESIZE   50
#define PLACESIZE    50


typedef struct SIMPLEREG
{
   char *name;
   char *place;
   int points;
} SIMPLEREG;


typedef struct RECORDS
{
   char *name[MAXRECORDS];
   int points[MAXRECORDS];
   char *place[MAXRECORDS];
   long time[MAXRECORDS];
} RECORDS;


RECORDS * init_records(void);
SIMPLEREG * init_simplereg(void);
void destroy_records(RECORDS *r);
void destroy_simplereg(SIMPLEREG *s);
void view_records(RECORDS *r);
int save_records(RECORDS *r);
RECORDS * load_records(char *filename, RECORDS *r);
int compare_ints(const void *a, const void *b);
RECORDS * input_new_record(RECORDS *r, char *name, char *place, int points);
RECORDS * move_record_table(RECORDS *r, int position);
RECORDS * copy_table(RECORDS *r);
void export_html(RECORDS *r, SIMPLEREG *s);
void parse_commandline(int argc, char **argv, RECORDS *blank);
void view_env(RECORDS *r);
SIMPLEREG * parse_pathinfo(char * pathinfo, SIMPLEREG *aux);


int main(void)
{
RECORDS *r, *blank;
SIMPLEREG *aux;

   r=init_records();
   aux=init_simplereg();
   blank=copy_table(r);
   r=load_records("normal.rec",r);
   aux=parse_pathinfo(getenv("PATH_INFO"),aux);
   if (aux==NULL)
   {
      export_html(r,aux);
      destroy_records(blank);
      destroy_records(r);
      return 0;
   }
   else
   {
      input_new_record(r,aux->name,aux->place,aux->points);
      save_records(r);
   }
   export_html(r,aux);
   destroy_simplereg(aux);
   destroy_records(blank);
   destroy_records(r);
   return 0;
}


RECORDS * init_records(void)
{
RECORDS *aux;
int i;

   aux=(struct RECORDS *)malloc(sizeof(struct RECORDS));
   if (aux==NULL) return NULL;
   memset(aux,0,sizeof(struct RECORDS));
   for (i=0;i<MAXRECORDS;i++)
   {
      aux->name[i]=(char *)malloc(sizeof(char)*NAMESIZE);
      if (aux->name[i]==NULL) return NULL;
      memset(aux->name[i],0,sizeof(char)*NAMESIZE);
      sprintf(aux->name[i],"Desconocido");
      aux->place[i]=(char *)malloc(sizeof(char)*PLACESIZE);
      if (aux->place[i]==NULL) return NULL;
      memset(aux->place[i],0,sizeof(char)*PLACESIZE);
      strcpy(aux->place[i],"Sin especificar");
      aux->points[i]=0;
   }
   return aux;
}

SIMPLEREG * init_simplereg(void)
{
SIMPLEREG *aux;

   aux=(struct SIMPLEREG *)malloc(sizeof(struct SIMPLEREG));
   if (aux==NULL) return NULL;
   memset(aux,0,sizeof(struct SIMPLEREG));
   aux->name=(char *)malloc(sizeof(char)*NAMESIZE);
   if (aux->name==NULL) return NULL;
   memset(aux->name,0,sizeof(char)*NAMESIZE);
   aux->place=(char *)malloc(sizeof(char)*PLACESIZE);
   if (aux->place==NULL) return NULL;
   memset(aux->place,0,sizeof(char)*PLACESIZE);
   aux->points=0;
   return aux;
}


void destroy_records(RECORDS *r)
{
int i;

   for (i=0;i<MAXRECORDS;i++)
   {
      free(r->name[i]);
      free(r->place[i]);
   }
   free(r);
}


void destroy_simplereg(SIMPLEREG *s)
{
   free(s->name);
   free(s->place);
   free(s);
}

void view_records(RECORDS *r)
{
int i;

   for (i=0;i<MAXRECORDS;i++)
   {
      printf("Name:%s Points:%d Place:%s\n"\
         ,r->name[i],r->points[i],r->place[i]);
   }
}


int save_records(RECORDS *r)
{
FILE *f;
int i;

   f=fopen("normal.rec","wb");
   if (f==NULL) return -1;

   for (i=0;i<MAXRECORDS;i++)
   {
      fwrite(r->name[i],sizeof(char)*NAMESIZE,1,f);
      fwrite(r->place[i],sizeof(char)*PLACESIZE,1,f);
      fwrite(&r->points[i],sizeof(int),1,f);
   }
   fclose(f);
   return 0;
}


RECORDS * load_records(char *filename, RECORDS *r)
{
FILE *f;
int i;

   f=fopen(filename,"rb");
   if (f==NULL) return NULL;
   for (i=0;i<MAXRECORDS;i++)
   {
      fread(r->name[i],sizeof(char)*NAMESIZE,1,f);
      fread(r->place[i],sizeof(char)*PLACESIZE,1,f);
      fread(&r->points[i],sizeof(int),1,f);
   }
   return r;
}


int compare_ints(const void *a, const void *b)
{
const int *da=(const int *)a;
const int *db=(const int *)b;
   return (*db>*da)-(*db<*da);
}


RECORDS * input_new_record(RECORDS *r, char *name, char *place, int points)
{
int i=MAXRECORDS-1;

   while(points>=r->points[i-1])
   {
      i--;
      if (i==0) break;
   }
   move_record_table(r,i);
   memset(r->name[i],0,sizeof(char)*NAMESIZE);
   memset(r->place[i],0,sizeof(char)*PLACESIZE);
   strcpy(r->name[i],name);
   strcpy(r->place[i],place);
   r->points[i]=points;
   return r;
}


RECORDS * move_record_table(RECORDS *r, int position)
{
RECORDS *aux;
int i=0;

   aux=copy_table(r);

   for (i=position;i<MAXRECORDS-1;i++)
   {
      strcpy(r->name[i+1],aux->name[i]);
      strcpy(r->place[i+1],aux->place[i]);
      r->points[i+1]=aux->points[i];
   }

   for (i=0;i<MAXRECORDS;i++)
   {
      free(aux->name[i]);
      free(aux->place[i]);
   }
   free(aux);
   return r;
}


RECORDS * copy_table(RECORDS *r)
{
RECORDS *aux;
int i;

   aux=(struct RECORDS *)malloc(sizeof(struct RECORDS));
   if (aux==NULL) return NULL;
   memset(aux,0,sizeof(struct RECORDS));
   
   for (i=0;i<MAXRECORDS;i++)
   {
      aux->name[i]=(char *)malloc(sizeof(char)*NAMESIZE);
      if (aux->name[i]==NULL) return NULL;
      memset(aux->name[i],0,sizeof(char)*NAMESIZE);
      strcpy(aux->name[i],r->name[i]);
      aux->place[i]=(char *)malloc(sizeof(char)*PLACESIZE);
      if (aux->place[i]==NULL) return NULL;
      memset(aux->place[i],0,sizeof(char)*PLACESIZE);
      strcpy(aux->place[i],r->place[i]);
      aux->points[i]=r->points[i];
   }
   
   return aux;
}


void export_html(RECORDS *r, SIMPLEREG *s)
{
int i;
FILE *f;
char *buf;
unsigned long int size=0L;

   printf("Content-type: text/html\n\n");
   f=fopen("part1.txt","rb");
   fseek(f,0L,SEEK_END);
   size=ftell(f);
   fseek(f,0L,SEEK_SET);
   buf=(char *)malloc((sizeof(char)*size)+1);
   if (buf==NULL) return;
   memset(buf,0,(sizeof(char)*size)+1);
   fread(buf,(sizeof(char)*size)+1,1,f);
   fclose(f);
   printf("%s",buf);
   free(buf);
   printf("<TABLE align=center border=0 cellpadding=5 cellspacing=2>");
   printf("<TR>");
   printf("<TD align=center bgcolor=Black><font color=White>Nombre</font></TD>");
   printf("<TD align=center bgcolor=Black><font color=White>Lugar</font></TD>");
   printf("<TD align=center bgcolor=Black><font color=White>Puntuaci&oacute;n</font></TD>");
   printf("</TR>");
   for (i=0;i<MAXRECORDS>>1;i++)
   {
      printf("<TR>");
      printf("<TD align=left bgcolor=Silver><font color=Black>%s</font></TD>",r->name[i]);
      printf("<TD align=center bgcolor=Silver><font color=Black>%s</font></TD>",r->place[i]);
      printf("<TD align=center bgcolor=Silver><font color=Black>%d</font></TD>",r->points[i]);
      printf("</TR>");
      printf("<TR>");
      printf("<TD align=left bgcolor=Gray><font color=Black>%s</font></TD>",r->name[i+1]);
      printf("<TD align=center bgcolor=Gray><font color=Black>%s</font></TD>",r->place[i+1]);
      printf("<TD align=center bgcolor=Gray><font color=Black>%d</font></TD>",r->points[i+1]);
      printf("</TR>");
   }
   f=fopen("part2.txt","rb");
   fseek(f,0L,SEEK_END);
   size=ftell(f);
   fseek(f,0L,SEEK_SET);
   buf=(char *)malloc((sizeof(char)*size)+1);
   if (buf==NULL) return;
   memset(buf,0,(sizeof(char)*size)+1);
   fread(buf,(sizeof(char)*size)+1,1,f);
   printf("%s",buf);
   free(buf);
   fclose(f);
}


void parse_commandline(int argc, char **argv, RECORDS *blank)
{
   if (argc>1)
   {
      if (!strcmp(argv[1],"password"))
      {
         if (!strcmp(argv[2],"remove"))
         {
            save_records(blank);
         }
      }
   }   
}


void view_env(RECORDS *r)
{
   if (getenv("SERVER_NAME")==NULL)
   {
      printf("NULL");
   };

}


SIMPLEREG * parse_pathinfo(char * pathinfo, SIMPLEREG *aux)
{
char *buf;
int i;
unsigned long int namesize;
unsigned long int placesize;
unsigned long int pointsize;
unsigned long int startnpos=0L;
unsigned long int endnpos=0L;
unsigned long int startppos=0L;
unsigned long int endppos=0L;
unsigned long int startpopos=0L;
unsigned long int endpopos=0L;
char *name;
char *place;
char *points;

   if (pathinfo==NULL) return NULL;
   buf=(char *)malloc(sizeof(char)*(strlen(pathinfo)+1));
   if (buf==NULL) return NULL;
   memset(buf,0,sizeof(char)*(strlen(pathinfo)+1));
   strcpy(buf,pathinfo);
   if (strlen(buf)<20) return NULL;

   /* Primero miramos a ver si hay caracteres especiales, si los hay salimos
   el / y el = no cuenta */
   for (i=0;i<strlen(buf);i++)
   {
      if (buf[i]!=0)
      {
         if (buf[i]!=32)
         {
            if (buf[i]<47 || buf[i]>122)
            {
               free(buf);
               return NULL;
            }
            if (buf[i]>=58 && buf[i]<=60)
            {
               free(buf);
               return NULL;
            }
            if (buf[i]>=62 && buf[i]<=64)
            {
               free(buf);
               return NULL;
            }
            if (buf[i]>=91 && buf[i]<=96)
            {
               free(buf);
               return NULL;
            }
         }
      }
   }
   
   /* Comprobamos que no haya 2 o mas caracteres especiales permitidos seguidos */
   for (i=0;i<strlen(buf)-1;i++)
   {
      if ((buf[i]=='/' && buf[i+1]=='/') || (buf[i]=='/' && buf[i+1]=='=') ||(buf[i]=='/' && buf[i+1]==' ') ||
      (buf[i]=='=' && buf[i+1]=='/') || (buf[i]=='=' && buf[i+1]=='=') ||(buf[i]=='=' && buf[i+1]==' ') ||
      (buf[i]==' ' && buf[i+1]=='/') || (buf[i]==' ' && buf[i+1]=='=') ||(buf[i]==' ' && buf[i+1]==' '))
      {
         free(buf);
         return NULL;
      }
   }

   /* Bueno, la cadena parece válida, mirar a ver el tamaño de cada campo */
   /* Primero el nombre */
   startnpos=i=6;
   while(i<strlen(buf))
   {
      if (buf[i]=='/')
      {
         namesize=i-6;
         endnpos=i;
         if (namesize>=NAMESIZE)
         {
            free(buf);
            return NULL;
         }
         break;
      }
      i++;
   }

   startppos=i=endnpos+7;
   while(i<strlen(buf))
   {
      if (buf[i]=='/')
      {
         placesize=i-startppos;
         endppos=i;
         if (placesize>=PLACESIZE)
         {
            free(buf);
            return NULL;
         }
         break;
      }
      i++;
   }

   startpopos=i=endppos+8;
   while(buf[i]!='\0') i++;
   
   pointsize=i-startpopos;
   endpopos=i;
   if (pointsize>=40)
   {
      free(buf);
      return NULL;
   }
   
   
   /* Coger el nombre */
   name=(char *)malloc((sizeof(char)*namesize)+1);
   if (name==NULL)
   {
      free(buf);
      return NULL;
   }
   memset(name,0,(sizeof(char)*namesize)+1);
   for (i=startnpos;i<endnpos;i++)
   {
      name[i-6]=buf[i];
   }

   /* Coger el lugar */
   place=(char *)malloc((sizeof(char)*placesize)+1);
   if (place==NULL)
   {
      free(buf);
      return NULL;
   }
   memset(place,0,(sizeof(char)*placesize)+1);
   for (i=startppos;i<endppos;i++)
   {
      place[i-startppos]=buf[i];
   }

   /* Coger los puntos */
   points=(char *)malloc((sizeof(char)*pointsize)+1);
   if (points==NULL)
   {
      free(buf);
      return NULL;
   }
   memset(points,0,(sizeof(char)*pointsize)+1);
   for (i=startpopos;i<endpopos;i++)
   {
      points[i-startpopos]=buf[i];
   }

   free(buf);
   strcpy(aux->name,name);
   strcpy(aux->place,place);
   aux->points=(int)atoi(points);
   free(name);
   free(place);
   free(points);
   
   return aux;
}


Lo dicho, estoy perdidísimo y cualquier ayuda será bienvenida.

Saludos y gracias.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor MSN Messenger
Popolon
Usuario avanzado


Registrado: 13 May 2003
Mensajes: 474
Residencia: Lloret de Mar

MensajePublicado: Sab Dic 24, 2005 2:09 pm    Asunto: Responder citando

Buenas Traperic,

ahora no tengo mucho tiempo, o sea que no puedo mirarme con mucho detalle el código que has puesto. Pero básicamente, si quieres usar la clase F1Shttp, te explico cómo funciona:

- al constructor le pasas una URL (por ejemplo: http://www.google.com)
- di te fijas, el constructor crea un nuevo thread, que lo que hace es intentar acceder a ésa dirección web
- con la función "get_web" puedes comprobar si la web ya ha sido accedida o no. Si todavía no ha podido acceder, devuelve un 0, si ya ha accedido, devuelve el texto correspondiente a la web.

te pongo un ejemplillo: (lo estoy improvisando, o sea que a lo mejor hay algún error):

void main(void)
{
int wait_time=10; // esperar 10 segundos como mucho
F1Shttp *web;

web=new F1Shttp("http://www.google.com");
while(web->get_web()==0 && wait_time>0) {
sleep(1000); // esperar un segundo más
wait_time--;
}

if (web->get_web()!=0) {
printf("la web accedida contiene éste texto: \n%s\n",web->get_web());
} else {
print("Ha pasado demasiado tiempo...\n");
}
delete web;
}

bueno, espero que te sirva. La verdad es que yo también lo pasé fatal hasta que conseguí encontrar la librería CURL que hace casi todo el trabajo! ya me explicarás si te funciona!

un saludo

santi
Volver arriba
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor
traperic
Usuario avanzado


Registrado: 10 Abr 2005
Mensajes: 72

MensajePublicado: Sab Dic 24, 2005 4:27 pm    Asunto: Responder citando

¡Muchas gracias Popolon!, ya funciona, he pasado la clase totalmente a C y a sintaxis 'phantomera' Very Happy y con el ejemplo que me has pasado funciona perfectamente, ahora tengo que ver como eliminar las dependecias de SDL...

Ya te contaré.

Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor MSN Messenger
traperic
Usuario avanzado


Registrado: 10 Abr 2005
Mensajes: 72

MensajePublicado: Sab Dic 24, 2005 4:41 pm    Asunto: Responder citando

Si lo se no posteo, ya está hecho. La parte de recibir los datos del servidor ya está... pero ahora hay que mandarlos, es decir, pasarle la cadena que te comentaba anteriormente al cgi, ¿podrías mandarme otro ejemplillo cuando tengas un rato? Cool Rolling Eyes
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor MSN Messenger
Popolon
Usuario avanzado


Registrado: 13 May 2003
Mensajes: 474
Residencia: Lloret de Mar

MensajePublicado: Lun Dic 26, 2005 12:17 am    Asunto: Responder citando

Vaya! me alegro de que funcione! Si no recuerdo mal, el único vínculo entre la clase F1Shttp y SDL es una llamada que hay para crear un thread. Supongo que si subsituyes esa llamada por una utilizando la librería "pthread" o cualquier otra librería de threads, tiene que seguir funcionando... Pero bueno, si dices que ya lo has solucionado seguro que ya has hecho algo así...

Sobre cómo enviar datos al servidor, no hay que hacer nada especial, en la línia donde crees el obejto F1Shttp (o PhantomasHttp, o como le hayas llamado a tu versión) puedes hacer directamente:

web=new F1Shttp("http://www.phantomas.hiscores.com?jugador=traperic&puntos=10000");

y ya está, no tiene más secreto que ese.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor
traperic
Usuario avanzado


Registrado: 10 Abr 2005
Mensajes: 72

MensajePublicado: Lun Dic 26, 2005 10:12 am    Asunto: Responder citando

Cita:

Vaya! me alegro de que funcione! Si no recuerdo mal, el único vínculo entre la clase F1Shttp y SDL es una llamada que hay para crear un thread. Supongo que si subsituyes esa llamada por una utilizando la librería "pthread" o cualquier otra librería de threads, tiene que seguir funcionando... Pero bueno, si dices que ya lo has solucionado seguro que ya has hecho algo así...


Bueno, la verdad que lo único que hice fué comentar las llamadas a SDL y unas ligeras modificaciones al código, el programa entonces se queda congelado cuando accede al servidor pero es que me parecía demasiada carga de librerías (curl+pthreads) para tan poca funcionalidad, no obstante, no se nota la congelación ya que el programa no tiene música en el momento en que consulta/manda los records ni tiene animaciones ni nada.

Cita:

Sobre cómo enviar datos al servidor, no hay que hacer nada especial, en la línia donde crees el obejto F1Shttp (o PhantomasHttp, o como le hayas llamado a tu versión) puedes hacer directamente:

web=new F1Shttp("http://www.phantomas.hiscores.com?jugador=traperic&puntos=10000");

Es lo primero que probé, pero por un estúpido error mio, pasaba un caracter incorrecto en la cadena y ya no funcionaba Embarassed

Pero bueno, ya está corregido y funciona perfectamente, la próxima versión del juego ya usará la tabla de records. Muchas gracias por todo Popolon, te has ganado un merecido puesto en los créditos. Wink
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email Visitar sitio web del autor MSN Messenger
Popolon
Usuario avanzado


Registrado: 13 May 2003
Mensajes: 474
Residencia: Lloret de Mar

MensajePublicado: Lun Dic 26, 2005 12:10 pm    Asunto: Responder citando

Pues me alegro de que funcione!!

Estaremos esperando la siguiente versión!!!! Very Happy
Volver arriba
Ver perfil de usuario Enviar mensaje privado Visitar sitio web del autor
Mostrar mensajes de anteriores:   
Publicar nuevo tema   Responder al tema    Índice del foro -> Desarrollo Todas las horas son GMT
Página 1 de 1

 
Cambiar a:  
Puedes publicar nuevos temas en este foro
Puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en encuestas en este foro


Powered by phpBB © 2001, 2002 phpBB Group