123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393 |
- /* $Id: run_tournois.c,v 1.6 2001/05/07 02:41:36 kilobug Exp $ */
- #include "mclient.h"
- #include "tournois.h"
- #include <signal.h>
- #define ALLOWED_CHARS "_+-$&*!@#~.éáàèëïûôêîìä"
- static rt_t *gl_rt;
- static void trn_start_new_match(rt_t *rt);
- static void trn_display_line(rt_t *rt, const char *buf)
- {
- GtkAdjustment *adj;
- int l;
- if (rt->textarea == NULL)
- return;
- gtk_text_freeze(GTK_TEXT(rt->textarea));
- l = gtk_text_get_length(GTK_TEXT(rt->textarea));
- l -= 5000;
- if (l > 0)
- {
- while ((GTK_TEXT_INDEX(GTK_TEXT(rt->textarea), l) != '\n') && l > 0)
- l--;
- if (l > 0)
- {
- gtk_text_set_point(GTK_TEXT(rt->textarea), 0);
- gtk_text_forward_delete(GTK_TEXT(rt->textarea), l);
- gtk_text_set_point(GTK_TEXT(rt->textarea),
- gtk_text_get_length(GTK_TEXT(rt->textarea)));
- }
- }
- gtk_text_insert(GTK_TEXT(rt->textarea), NULL,
- NULL, NULL, buf, -1);
- gtk_text_thaw(GTK_TEXT(rt->textarea));
- adj = GTK_TEXT(rt->textarea)->vadj;
- gtk_adjustment_set_value(adj, adj->upper);
- }
- static void trn_end(rt_t *rt)
- {
- int r, i, j, class, class2;
- char buf[MYSQL_BUFFER_SIZE];
- char *s;
- alarm(0);
- if (rt->gdki > 0)
- {
- gdk_input_remove(rt->gdki);
- close(rt->fd);
- }
- rt->gdki = -1;
- if (!rt->timeout)
- for (i = 0; i < rt->nbp; i++)
- if (rt->scores[i] != 0)
- {
- class2 = class = 1;
- for (j = 0; j < rt->nbp; j++)
- if (rt->scores[j] > rt->scores[i])
- {
- class *= 2;
- class2++;
- }
- r = rt->nbp * 100 / class;
- mysql_do_query(gl_config->mysql,
- "UPDATE Champions "
- "SET nbmap=nbmap+1, total=total+%d "
- "WHERE id=%d",
- r, rt->champ[rt->chmp[i]]);
- mysql_do_query(gl_config->mysql,
- "UPDATE Champions "
- "SET score=total/nbmap, best=GREATEST(best, %f) "
- "WHERE id=%d", rt->scores[i],
- rt->champ[rt->chmp[i]]);
-
- s = mysql_get_str(gl_config->mysql,
- "SELECT login FROM Bitmaps B, Champions C "
- "WHERE B.id = C.auteur AND C.id=%d",
- rt->champ[rt->chmp[i]]);
- g_snprintf(buf, MYSQL_BUFFER_SIZE, "Joueur %s: %f (%d) => %d.\n",
- s, rt->scores[i], class2, r);
- trn_display_line(rt, buf);
- g_free(s);
- }
- trn_start_new_match(rt);
- }
- static void sigalarm(int foo)
- {
- gl_rt->timeout = TRUE;
- system("killall server");
- fprintf(stderr, "!!!!!!! Timeout.\n");
- trn_end(gl_rt);
- }
- static void nothing(int foo)
- {
- }
- static void trn_check_score(rt_t *rt, const char *buf)
- {
- int i;
- float f;
- char *s;
- if (strncmp(buf, "<server> Player ", 16))
- return;
- i = strtol(buf + 16, &s, 10);
- s += 3;
- f = atof(s);
- mysql_do_query(gl_config->mysql,
- "INSERT INTO Scores SET champion=%d, score='%f', match_id=%d",
- rt->champ[rt->chmp[i - 1]], f, rt->mysql_id);
- rt->scores[i - 1] = f;
- }
- static gboolean trn_treat_line(rt_t *rt, const char *buf)
- {
- alarm(10);
- if (!strcmp(buf, "Bye!\n"))
- {
- trn_display_line(rt, "\nMatch terminé.\n");
- trn_end(rt);
- return FALSE;
- }
- if (strncmp(buf, "<server>", 8))
- trn_display_line(rt, buf);
- else
- trn_check_score(rt, buf);
- return TRUE;
- }
- static void trn_get_data(rt_t *rt, int fd, GdkInputCondition foo)
- {
- char buf[MYSQL_BUFFER_SIZE], *s, *p;
- int sz;
- gboolean r;
- if (rt == NULL)
- return;
- sz = read(fd, buf, MYSQL_BUFFER_SIZE - 1);
- if (sz == -1)
- {
- trn_end(rt);
- return;
- }
- buf[sz] = 0;
- s = g_strconcat(rt->buf, buf, NULL);
- g_free(rt->buf);
- rt->buf = s;
- while ((p = strchr(rt->buf, '\n')) != NULL)
- {
- s = rt->buf;
- rt->buf = g_strdup(p + 1);
- p[1] = 0;
- r = trn_treat_line(rt, s);
- g_free(s);
- if (!r)
- break;
- }
- }
- static void trn_do_start_match(rt_t *rt)
- {
- int i, j;
- char buf[11];
- char buf2[MYSQL_BUFFER_SIZE];
- int fd[2];
- char *s, *n, *f;
- fprintf(stderr, "\nStarting match %d of %d between: ", rt->cur, rt->nbm);
- for (i = 0; i < rt->nbp; i++)
- {
- fprintf(stderr, "%d ", rt->chmp[i]);
- }
- fprintf(stderr, "\n");
- g_snprintf(buf2, MYSQL_BUFFER_SIZE,
- "INSERT INTO Matchs SET map=%d, host='%s', port=%d, statut=1,"
- " joueurs=%d, auteur=%d, public=%d",
- rt->mapid,
- (gl_config->host == NULL) ? gl_config->hostname : gl_config->host,
- 4242, rt->nbp, getuid(), FALSE);
- mysql_query_gtk(gl_config->mysql, buf2);
- rt->mysql_id = mysql_insert_id(gl_config->mysql);
- pipe(fd);
- if (!fork())
- {
- g_snprintf(buf, 11, "%d", rt->nbt);
- close(1);
- dup2(fd[1], 1);
- close(fd[0]);
- /* Memory leak mais suivi d'un execlp */
- s = g_strconcat(gl_config->server, " -n ", buf, " -m ", rt->map, " -q ",
- rt->cmd, " ", NULL);
- for (i = 0; i < rt->nbp; i++)
- {
- n = mysql_get_str(gl_config->mysql,
- "SELECT nom FROM Champions "
- "WHERE id=%d",
- rt->champ[rt->chmp[i]]);
- for (j = 0; n[j]; j++)
- if (!isalnum(n[j]) && (strchr(ALLOWED_CHARS, n[j]) == NULL))
- n[j] = '_';
- f = mysql_get_str(gl_config->mysql,
- "SELECT fichier FROM Champions "
- "WHERE id=%d",
- rt->champ[rt->chmp[i]]);
- if ((n != NULL) && (f != NULL))
- s = g_strconcat(s, " ", n, ":", f, NULL);
- g_free(n);
- g_free(f);
- }
- sleep(1);
- if (gl_config->host == NULL)
- execlp("sh", "sh", "-c", s, NULL);
- else
- execlp("ssh", "ssh", gl_config->host, s, NULL);
- _exit(1);
- }
- close(fd[1]);
- fcntl(fd[0], F_SETFL, O_NONBLOCK);
- for (i = 0; i < rt->nbp; i++)
- rt->scores[i] = 0;
- rt->fd = fd[0];
- rt->gdki = gdk_input_add(fd[0], GDK_INPUT_READ,
- (GdkInputFunction) (trn_get_data), rt);
- alarm(20);
- }
- typedef struct _trn_comb_t
- {
- int *max_allowed;
- int *cnt;
- } trn_comb_t;
- typedef struct _trn_rand_t
- {
- int *cnt;
- } trn_rand_t;
- static void trn_make_rand(rt_t *rt)
- {
- int i;
- int max;
- trn_rand_t *randd;
- randd = rt->data;
- max = rt->nbm * rt->nbp / rt->nbc + 1;
- for (i = 0; i < rt->nbp; i++)
- {
- do
- rt->chmp[i] = random() % rt->nbc;
- while (randd->cnt[rt->chmp[i]] >= max);
- randd->cnt[rt->chmp[i]]++;
- }
- }
- static void trn_make_comb(rt_t *rt)
- {
- trn_comb_t *comb;
- int j, i;
-
- comb = rt->data;
- for (i = 0; i < rt->nbp; i++)
- rt->chmp[i] = comb->cnt[i];
- for (j = rt->nbp - 1; j > 0; j--)
- if (comb->cnt[j] < comb->max_allowed[j])
- break;
- comb->cnt[j]++;
- if (comb->cnt[j] > comb->max_allowed[j])
- for (i = 0; i < rt->nbp; i++)
- comb->cnt[i] = i;
- else
- for (j++; j < rt->nbp - 1; j++)
- comb->cnt[j] = comb->cnt[j - 1] + 1;
- }
- static void trn_start_new_match(rt_t *rt)
- {
- if (rt->cur >= rt->nbm)
- {
- trn_display_line(rt, "\nTournois terminé.\n");
- rt->run = FALSE;
- trn_free(rt);
- return;
- }
- rt->timeout = FALSE;
- gl_rt = rt;
- rt->cur++;
- switch (rt->methode)
- {
- case met_rand:
- trn_make_rand(rt);
- break;
- case met_comb:
- trn_make_comb(rt);
- break;
- case met_pyr:
- trn_make_rand(rt);
- break;
- case met_rot:
- trn_make_rand(rt);
- break;
- default:
- fprintf(stderr, "Internal error in trn_init. Aborting.\n");
- exit(1);
- break;
- }
- trn_do_start_match(rt);
- }
- void trn_init(rt_t *rt)
- {
- int i;
- trn_comb_t *comb;
- trn_rand_t *rand;
- switch (rt->methode)
- {
- case met_rand:
- rt->data = rand = g_malloc(sizeof(*rand));
- rand->cnt = g_malloc(sizeof(int) * rt->nbc);
- bzero(rand->cnt, sizeof(int) * rt->nbc);
- break;
- case met_pyr:
- case met_rot:
- rt->data = NULL;
- break;
- case met_comb:
- rt->data = comb = g_malloc(sizeof(*comb));
- comb->cnt = g_malloc(sizeof(int) * rt->nbp);
- comb->max_allowed = g_malloc(sizeof(int) * rt->nbp);
- for (i = 0; i < rt->nbp; i++)
- {
- comb->cnt[i] = i;
- comb->max_allowed[i] = rt->nbc - (rt->nbp - i);
- }
- break;
- default:
- fprintf(stderr, "Internal error in trn_init. Aborting.\n");
- exit(1);
- break;
- }
- rt->gdki = -1;
- gl_rt = rt;
- signal(SIGALRM, sigalarm);
- trn_start_new_match(rt);
- }
- void trn_free(rt_t *rt)
- {
- trn_comb_t *comb;
- trn_rand_t *rand;
- if (rt->run || rt->disp)
- return;
- switch (rt->methode)
- {
- case met_rand:
- rand = rt->data;
- g_free(rand->cnt);
- g_free(rand);
- break;
- case met_pyr:
- case met_rot:
- break;
- case met_comb:
- comb = rt->data;
- g_free(comb->cnt);
- g_free(comb->max_allowed);
- g_free(comb);
- break;
- default:
- fprintf(stderr, "Internal error in trn_init. Aborting.\n");
- exit(1);
- break;
- }
- g_free(rt->cmd);
- g_free(rt->chmp);
- g_free(rt->map);
- if (rt->buf != NULL)
- g_free(rt->buf);
- g_free(rt->scores);
- g_free(rt);
- }
|