database.c 5.44 KB
Newer Older
1 2
/* meta-server/database.c - Database functions
 *
3
 * Copyright (C) 2007 Romain Bignon  <Progs@headfucking.net>
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * $Id$
 */

21 22 23
#include <stdio.h>
#include <string.h>
#include <assert.h>
24
#include "database.h"
25 26 27 28 29 30 31 32 33 34 35 36
#include "sockets.h"
#include "clients.h"

struct RegUser* reguser_head = 0;

void strip_newline(char *string)
{
   register char *p = string;
   while(*p && *p != '\n' && *p != '\r') ++p;
   *p = '\0';
}

37
struct RegUser* add_reguser(const char* name, const char* passwd, int nb_games, ullint losses, ullint killed,
38
                            ullint creations, ullint score, ullint best_revenu, int victories, time_t reg_timestamp,
39
                            time_t last_visit)
40
{
41
	struct RegUser *reguser = calloc(1, sizeof* reguser), *head = reguser_head, *u, *prev;
42 43 44 45 46 47

	if(!reguser)
		return 0;

	strncpy(reguser->name, name, NICKLEN);
	strncpy(reguser->passwd, passwd, PASSWDLEN);
48
	reguser->cookie[0] = 0;
49
	reguser->nb_games = nb_games;
50
	reguser->losses = losses;
51 52 53 54
	reguser->killed = killed;
	reguser->creations = creations;
	reguser->score = score;
	reguser->best_revenu = best_revenu;
55
	reguser->victories = victories;
56 57
	reguser->reg_timestamp = reg_timestamp;
	reguser->last_visit = last_visit;
58 59 60

	reguser->user = 0;

61
	for (u = head, prev = NULL; u && u->score > score; prev = u, u = u->next)
62 63 64 65 66
		;
	if (u == head)
		reguser_head = reguser;
	reguser->next = u;
	if (u) reguser->prev = u->prev;
67
	else if (prev) reguser->prev = prev;
68 69
	if (reguser->prev) reguser->prev->next = reguser;
	if (reguser->next) reguser->next->prev = reguser;
70

progs's avatar
progs committed
71 72
	nb_tregs++;

73 74 75
	return reguser;
}

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
void switch_regusers(struct RegUser* u1, struct RegUser* u2)
{
	struct RegUser *prev, *next;

	prev = u1->prev;
	next = u2->next;

	if (prev) prev->next = u2;
	u2->prev = prev;
	u2->next = u1;
	u1->prev = u2;
	u1->next = next;
	if (next) next->prev = u1;
}

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
struct RegUser* find_reguser(const char* nick)
{
	struct RegUser* reg = reguser_head;
	for(; reg; reg = reg->next)
		if(!strcasecmp(nick, reg->name))
			return reg;

	return 0;
}

void remove_reguser(struct RegUser* reguser)
{
	assert(reguser);

	if(reguser->user)
		reguser->user->reguser = 0;

108 109
	if(reguser->next) reguser->next->prev = reguser->prev;
	if(reguser->prev) reguser->prev->next = reguser->next;
110 111
	else reguser_head = reguser->next;

progs's avatar
progs committed
112 113
	nb_tregs--;

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
	free(reguser);
}

int load_users(const char* file)
{
	FILE* fp = fopen(file, "r");
	char buf[500];
	char *parv[20];
	int version = 0;

	if(!fp)
	{
		if((fp = fopen(file, "w")))
		{
			fclose(fp);
			return -1;
		}
		else
			return 0;
	}

	while(fgets(buf, sizeof buf, fp))
	{
		int parc = SplitBuf(buf, parv, sizeof parv / sizeof *parv);

		if(parc < 2) continue;

		strip_newline(parv[parc-1]);

143
		// NICK <name> <pass> <nb_games> <losses> <killed> <creations> <score> <meilleurs revenu> <victoires> <reg_timestamp> <last_game>
144 145
		if(!strcmp(buf, "VERSION"))
			version = atoi(parv[1]);
146 147
		else if(!version)
			printf("WARNING[config]: Skip %s line, there isn't any version\n", buf);
progs's avatar
progs committed
148 149 150 151
		else if(!strcmp(buf, "NBCHAN"))
			nb_tchan = atoi(parv[1]);
		else if(!strcmp(buf, "NBUSER"))
			nb_tusers = atoi(parv[1]);
152 153
		else if(!strcmp(buf, "NICK"))
		{
154 155 156
			/* parv[1] = name
			 * parv[2] = passws
			 * parv[3] = nb_games
157 158
			 * parv[4] = killed
			 * parv[5] = losses
159 160 161 162 163 164 165
			 * parv[6] = creations
			 * parv[7] = score
			 * parv[8] = best income
			 * parv[9] = victoires
			 * parv[10]= reg_timestamp
			 * parv[11]= last_game
			 */
166
			int victories = 0;
167 168
			time_t reg_timestamp = 0, last_game = 0;
			if(parc < 9 || (version >= 3 && parc < 11))
169
			{
170
				printf("WARNING[config]: Unable to load %s reguser\n", parc > 1 ? parv[1] : "unknown");
171 172
				continue;
			}
173 174 175 176
			if(version >= 2)
				victories = atoi(parv[9]);
			else
				victories = atoi(parv[3]);
177 178 179 180 181 182

			if(version >= 3)
			{
				reg_timestamp = atoi(parv[10]);
				last_game = atoi(parv[11]);
			}
183
			add_reguser(parv[1], parv[2], atoi(parv[3]), strtoull(parv[5], 0, 10), strtoull(parv[4], 0, 10), strtoull(parv[6], 0, 10),
184
			            strtoull(parv[7], 0, 10), strtoull(parv[8], 0, 10), victories, reg_timestamp, last_game);
185
		}
186 187
		else
			printf("WARNING[config]: Unable to recognize %s line\n", buf);
188 189 190 191 192 193 194 195 196 197 198 199 200 201
	}
	fclose(fp);
	return 1;
}

int write_users(const char* file)
{
	FILE* fp = fopen(file, "w");
	struct RegUser* reg = reguser_head;

	if(!fp)
		return 0;

	fprintf(fp, "VERSION %d\n", DBVERSION);
progs's avatar
progs committed
202 203
	fprintf(fp, "NBCHAN %d\n", nb_tchan);
	fprintf(fp, "NBUSER %d\n", nb_tusers);
204 205

	for(; reg; reg = reg->next)
206 207
		fprintf(fp, "NICK %s %s %u %llu %llu %llu %llu %llu %u %ld %ld\n", reg->name, reg->passwd, reg->nb_games, reg->killed,
		                                                                   reg->losses, reg->creations, reg->score, reg->best_revenu, reg->victories,
208
		                                                                   reg->reg_timestamp, reg->last_visit);
209

210 211
	fclose(fp);

212 213
	return 1;
}