2 Copyright (c) 2000 Dan Papasian
3 Copyright (C) Andrew Tridgell 2002
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 enum { SEEKOPEN = 0, SEEKCLOSED };
24 /* The values of the follwing enums cannot be changed as they will end up */
25 /* Being seen by the client- we can add values later but the ones */
26 /* Here, after being documented, have to be here forever */
27 enum { LIGHTNING = 0, STANDARD, BLITZ, UNTIMED };
31 enum { BLACK = 0, WHITE};
34 static int get_empty_seekslot(void);
35 static char *form_ad(struct pending * ad, int i);
37 int com_seek(int p, param_list param)
39 struct player *pp = &player_globals.parray[p];
41 int num; /* sought ID */
43 char board[1], category[1];
48 if (!CheckPFlag(p, PFLAG_REG)) {
49 pprintf(p, "Only registered players can use the seek command.\n");
54 if ((pp->game >= 0) && ((game_globals.garray[pp->game].status == GAME_EXAMINE) || (game_globals.garray[pp->game].status == GAME_SETUP))) {
55 pprintf(p, "ERROR: You can't seek a game while you are examining one.\n");
59 pprintf(p, "ERROR: You can't seek a game while you are playing one.\n");
62 num = get_empty_seekslot();
64 pprintf(p, "ERROR: Sorry, all available slots for seek are closed.\n");
67 seek_globals.ads[num].status = SEEKCLOSED;
68 seek_globals.ads[num].whofrom = p;
70 if (param[0].type == TYPE_INT)
71 seek_globals.ads[num].wtime = param[0].val.integer; /* White time */
73 seek_globals.ads[num].wtime = pp->d_time;
75 if (param[1].type == TYPE_INT)
76 seek_globals.ads[num].winc = param[1].val.integer; /* White increment */
78 seek_globals.ads[num].winc = pp->d_inc;
80 seek_globals.ads[num].btime = seek_globals.ads[num].wtime; /* Black time */
81 seek_globals.ads[num].binc = seek_globals.ads[num].winc; /* Black increment */
83 if (param[2].type == TYPE_INT) {
84 if (param[2].val.integer == UNRATED || !CheckPFlag(p, PFLAG_REG) || seek_globals.ads[num].wtime == 0)
85 seek_globals.ads[num].rated = UNRATED; /* unrated */
86 else if (param[2].val.integer == RATED)
87 seek_globals.ads[num].rated = RATED; /* rated */
89 seek_globals.ads[num].rated = BoolCheckPFlag(p, PFLAG_RATED);
92 if (param[3].type == TYPE_INT) {
93 if (param[3].val.integer == WHITE)
94 seek_globals.ads[num].seek_color = WHITE;
95 else if (param[3].val.word[0] == BLACK)
96 seek_globals.ads[num].seek_color = BLACK;
98 seek_globals.ads[num].seek_color = random() % 2;
102 /* FIXME- use proper values */
103 seek_globals.ads[num].category = strdup(category);
104 seek_globals.ads[num].board_type = strdup(board);
106 seek_globals.ads[num].next = NULL;
108 msgtxt = form_ad(&seek_globals.ads[num], num);
110 for (p1 = 0; p1 < player_globals.p_num; p1++) {
111 if ((p1 == p) || !CheckPFlag(p1, PFLAG_ADS)
112 || (player_globals.parray[p1].status != PLAYER_PROMPT)
113 || (player_censored(p1, p)))
116 pprintf(p1, "%s", msgtxt);
118 pprintf(p, "%s", msgtxt);
124 int com_play(int p, param_list param)
128 game = param[0].val.integer;
130 if (seek_globals.ads[game].status != SEEKCLOSED) {
131 pprintf(p, "ERROR: Either that game has already started or "
132 "it is no longer available.\n");
135 if (!CheckPFlag(p, PFLAG_REG) && seek_globals.ads[game].rated == 1) {
136 pprintf(p, "ERROR: Unregistred users cannot play rated games.\n");
139 if (seek_globals.ads[game].whofrom == p) {
140 pprintf(p, "ERROR: You cannot respond to your own seek ads\n");
143 seek_globals.ads[game].whoto = p;
145 decline_withdraw_offers(p, -1, PEND_ALL, DO_DECLINE | DO_WITHDRAW);
146 decline_withdraw_offers(seek_globals.ads[game].whofrom, -1, PEND_ALL, DO_DECLINE | DO_WITHDRAW);
148 accept_match(&seek_globals.ads[game], p, seek_globals.ads[game].whofrom);
150 free(seek_globals.ads[game].category);
151 free(seek_globals.ads[game].board_type);
156 int com_sought(int p, param_list param)
160 for (i = 0; i < seek_globals.max_ads; i++) {
161 if (seek_globals.ads[i].status == SEEKCLOSED) {
162 char *msgtxt = form_ad(&seek_globals.ads[i], i);
163 pprintf(p, "%s", msgtxt);
171 int com_unseek(int p, param_list param)
173 /* TODO: need to add parameters */
178 void withdraw_seeks(int p)
182 for (i = 0; i < seek_globals.max_ads; i++) {
183 if (seek_globals.ads[i].whofrom == p &&
184 seek_globals.ads[i].status == SEEKCLOSED) {
185 seek_globals.ads[i].status = SEEKOPEN;
187 for (p1 = 0; p1 < player_globals.p_num; p1++) {
188 if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT) ||
189 (player_censored(p1, p)) || !CheckPFlag(p1,PFLAG_ADS))
191 pprintf_prompt(p1, "AD_DESTROY: %d\n", i);
193 pprintf(p, "AD_DESTROY: %d\n", i);
194 FREE(seek_globals.ads[i].category);
195 FREE(seek_globals.ads[i].board_type);
200 static int get_empty_seekslot(void)
204 for (i = 0; i < seek_globals.max_ads; i++) {
205 if (seek_globals.ads[i].status != SEEKCLOSED)
209 if (seek_globals.max_ads >= config_get_int("MAX_SOUGHT", DEFAULT_MAX_SOUGHT)) {
210 d_printf("Too many seeks! please raise MAX_SOUGHT\n");
214 seek_globals.max_ads += 100;
215 seek_globals.ads = (struct pending *)realloc(seek_globals.ads,
216 seek_globals.max_ads * sizeof(struct pending));
218 ZERO_STRUCT(seek_globals.ads[i]);
223 static char *form_ad(struct pending * ad, int i)
227 int rating, total, type;
229 total = ad->wtime * 60 + ad->winc * 40;
233 rating = player_globals.parray[ad->whofrom].l_stats.rating;
234 } else if (total < 180) {
236 rating = player_globals.parray[ad->whofrom].l_stats.rating;
237 } else if (total >= 900) {
239 rating = player_globals.parray[ad->whofrom].s_stats.rating;
242 rating = player_globals.parray[ad->whofrom].b_stats.rating;
245 asprintf(&final, "%3u %4u %-17s %3u %3u %-7s %-10s\n",
248 player_globals.parray[ad->whofrom].name,
251 ad->rated?"rated":"unrated",
252 TypeStrings[ad->seek_color]);