Skip to content

Instantly share code, notes, and snippets.

@maerlyn
Created December 2, 2011 08:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maerlyn/1422265 to your computer and use it in GitHub Desktop.
Save maerlyn/1422265 to your computer and use it in GitHub Desktop.
halo2 geptermi zh
#ifndef LLIST_C
#define LLIST_C
typedef struct _node {
int socket, szamlalo, jatszikmeg;
char ipport[256];
struct _node *next;
} node;
typedef struct _head {
node *first;
int count;
} head;
head* list_new() {
head* a = calloc(sizeof(head), 1);
return a;
}
void list_delete(head* head) {
node *n, *d;
n = head->first;
while (n) {
d = n;
n = n->next;
free(d);
}
free(head);
}
void list_add(head* h, node* n) {
node *curr;
if (!h->first) {
h->first = n;
h->count++;
return;
}
curr = h->first;
while (curr->next) { curr = curr->next; }
curr->next = n;
h->count++;
}
void list_delete_socket(head *h, int socket) {
node *curr = 0, *prev = 0;
curr = h->first;
if (h->first && h->first->socket == socket) {
curr = h->first;
h->first = h->first->next;
free(curr);
h->count--;
return;
}
while (curr && curr->socket != socket) { prev = curr; curr = curr->next; }
if (prev && curr && curr->socket == socket) {
prev->next = curr->next;
free(curr);
h->count--;
}
}
char* list_ipport_socket(head *h, int socket) {
node *curr = h->first;
while (curr && curr->socket != socket) curr = curr->next;
if (curr && curr->socket == socket) return curr->ipport;
}
void list_mindenki_nullazasa(head *h) {
node *curr;
for (curr = h->first; curr; curr = curr->next) {
curr->jatszikmeg = 1;
curr->szamlalo = 0;
}
}
int list_szamlalo_socket(head *h, int socket) {
node *curr;
for (curr = h->first; curr; curr = curr->next)
if (curr->socket == socket)
return curr->szamlalo;
return -1;
}
node* list_get_socket(head *h, int socket) {
node *curr;
for (curr = h->first; curr; curr = curr->next)
if (curr->socket == socket)
return curr;
return 0;
}
int list_hanyan_jatszanak_meg(head *h) {
int count = 0;
node *curr;
for (curr = h->first; curr; curr = curr->next) count += curr->jatszikmeg;
return count;
}
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <net/if.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/time.h>
#include "llist.c"
#define PORT "7462"
#define MAXCLIENTS 3
head *klienslista;
node *elem;
fd_set master_fds;
int listener;
pid_t gyerekpid;
int gyerekvagyok = 0;
char kliens_jelenlegi_allas[] = "jelenleg itt allsz: %d\nsorsoljak meg? ";
int maxfds() {
int i, max = 1;
for (i = 0; i <= 1024; ++i) if (FD_ISSET(i, &master_fds)) max = i;
return max;
}
void klienscim(char* hova, struct sockaddr clientaddr) {
struct sockaddr_in *sin = (struct sockaddr_in*)&clientaddr;
inet_ntop(AF_INET, &(sin->sin_addr), hova, 256);
sprintf(hova, "%s:%d", hova, ntohs(sin->sin_port));
}
void broadcast(char* buf) {
int j;
for (j = listener + 1; j <= maxfds(); ++j)
if (FD_ISSET(j, &master_fds))
send(j, buf, strlen(buf), 0);
}
int van_e_nyertes() {
int van = 0; node *elem;
for (elem = klienslista->first; elem; elem = elem->next) {
van += (elem->szamlalo > 21 ? 0 : 1);
}
return van;
}
node* nyertes() {
node *ny = 0, *elem;
for (elem = klienslista->first; elem; elem = elem->next)
if (elem->szamlalo <= 21 && (!ny || elem->szamlalo > ny->szamlalo))
ny = elem;
return ny;
}
int hanynak_van_ennyi_pontja(int pont) {
int darab = 0; node *elem;
for (elem = klienslista->first; elem; elem = elem->next)
if (elem->szamlalo == pont)
++darab;
return darab;
}
int main(void) {
struct addrinfo hints, *res;
int yes=1, i, newfd, j, nyertesszam;
fd_set read_fds;
struct timeval timeout = {10, 0};
struct sockaddr clientaddr; socklen_t clientaddrlen;
size_t bytes;
char buf[256];
int jatek_fut = 0, jatekvegi_kerdes = 0;
char tul_sok_kliens[] = "tul sok kliens van\n";
char mar_fut_a_jatek[] = "mar fut a jatek\n";
memset(&hints, 0, sizeof hints);
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_INET;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL, PORT, &hints, &res);
listener = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
bind(listener, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
listen(listener, 10);
FD_ZERO(&master_fds);
FD_SET(listener, &master_fds);
klienslista = list_new();
srand(time());
printf("figyelek...\n");
for (;;) {
read_fds = master_fds;
select(maxfds()+1, &read_fds, NULL, NULL, &timeout);
for (i = 0; i < maxfds()+1; ++i) {
if (FD_ISSET(i, &read_fds)) {
if (i == listener) {
clientaddrlen = sizeof clientaddr;
newfd = accept(listener, &clientaddr, &clientaddrlen);
if (klienslista->count >= MAXCLIENTS) {
send(newfd, tul_sok_kliens, strlen(tul_sok_kliens), 0);
close(newfd);
continue;
}
if (jatek_fut) {
//send(newfd, mar_fut_a_jatek, strlen(mar_fut_a_jatek), 0);
//close(newfd);
printf("fork jon\n");
gyerekpid = fork();
if (gyerekpid == 0) { /* gyerek vagyok - megy tovabb a mar futo jatek */
gyerekvagyok = 1;
close(i); /* == listener */
FD_CLR(i, &master_fds);
} else { /* szulo vagyok - uj jatek indul */
/* csinalunk egy uj klienslistat */
jatek_fut = 0;
list_delete(klienslista);
klienslista = list_new();
elem = calloc(sizeof(node), 1);
elem->socket = newfd;
klienscim(elem->ipport, clientaddr);
list_add(klienslista, elem);
printf("uj kliens innen: %s\n", elem->ipport);
/* es a master fds-t sem felejtjuk el nullazni */
FD_ZERO(&master_fds);
FD_SET(listener, &master_fds);
FD_SET(newfd, &master_fds);
/* FD_ZERO(&read_fds); */
}
continue;
}
elem = calloc(sizeof(node), 1);
elem->socket = newfd;
klienscim(elem->ipport, clientaddr);
list_add(klienslista, elem);
printf("uj kliens innen: %s\n", elem->ipport);
FD_SET(newfd, &master_fds);
}
else
{
bytes = recv(i, buf, sizeof buf, 0);
if (bytes == 0) { /* lekapcsolodott */
printf("lekapcsolodott kliens: %s\n", list_ipport_socket(klienslista, i));
list_delete_socket(klienslista, i);
FD_CLR(i, &master_fds);
} else {
/* valamit kuldott, de mit? */
buf[bytes] = 0;
/*printf("fut: %d, vegikerdes: %d, ezt kuldte egy kliens: %s", jatek_fut, jatekvegi_kerdes, buf);*/
if (!jatek_fut && strncmp(buf, "START", strlen("START")) == 0) {
jatek_fut = 1;
for (j = listener+1; j <= maxfds(); ++j) {
if (FD_ISSET(j, &master_fds)) {
list_mindenki_nullazasa(klienslista);
send(j, "KEZDODIK\n", strlen("KEZDODIK\n"), 0);
sprintf(buf, kliens_jelenlegi_allas, 0);
send(j, buf, strlen(buf), 0);
}
}
} else
if (jatek_fut && strncmp(buf, "I", 1) == 0 && list_get_socket(klienslista, i)->jatszikmeg == 1) {
int j = rand() % 10 + 2;
elem = list_get_socket(klienslista, i);
elem->szamlalo += j;
sprintf(buf, "ezt sorsoltam: %d\n", j);
send(elem->socket, buf, strlen(buf), 0);
if (elem->szamlalo > 21) {
elem->jatszikmeg = 0;
sprintf(buf, "osszesen %d, kiestel\n", elem->szamlalo);
} else {
sprintf(buf, kliens_jelenlegi_allas, elem->szamlalo);
}
send(elem->socket, buf, strlen(buf), 0);
} else
if (jatek_fut && strncmp(buf, "N", 1) == 0 && list_get_socket(klienslista, i)->jatszikmeg == 1) {
list_get_socket(klienslista, i)->jatszikmeg = 0;
} else
if (jatekvegi_kerdes && strncmp(buf, "I", 1) == 0) {
--jatekvegi_kerdes;
} else
if (jatekvegi_kerdes && strncmp(buf, "N", 1) == 0) {
printf("lekapcsolunk egy klienst...\n");
--jatekvegi_kerdes;
list_delete_socket(klienslista, i);
FD_CLR(i, &master_fds);
close(i);
} else
if (jatek_fut && strncmp(buf, "?", 1) == 0) {
sprintf(buf, "aktualis allasok:\n");
send(i, buf, strlen(buf), 0);
for (elem = klienslista->first; elem; elem = elem->next) {
sprintf(buf, "\t%s\t%d\n", elem->ipport, elem->szamlalo);
send(i, buf, strlen(buf), 0);
}
}
}
}
}
if (jatek_fut && list_hanyan_jatszanak_meg(klienslista) == 0) {
broadcast("mindenki vegzett, eredmenyhirdetes kovetkezik\n");
nyertesszam = van_e_nyertes();
printf("nyertesek: %ddb\n", nyertesszam);
if (nyertesszam == 0) {
broadcast("mindenki vesztett\n");
} else {
elem = nyertes();
if (hanynak_van_ennyi_pontja(elem->szamlalo) > 1) {
broadcast("holtverseny\n");
} else {
sprintf(buf, "nyertes: %s, pontjai: %d\n", elem->ipport, elem->szamlalo);
broadcast(buf);
}
}
jatek_fut = 0;
printf("gyerek? %d: kliensek: %ddb\n", gyerekvagyok, klienslista->count);
jatekvegi_kerdes = klienslista->count;
sprintf(buf, "akarsz jatszani megegyet? ");
broadcast(buf);
}
}
if (gyerekvagyok && klienslista->count == 0) {
list_delete(klienslista);
exit(0);
}
timeout.tv_sec = 10; timeout.tv_usec = 0;
}
list_delete(klienslista);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment