1 // _________ __ __
2 // / _____// |_____________ _/ |______ ____ __ __ ______
3 // \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
4 // / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
5 // /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
6 // \/ \/ \//_____/ \/
7 // ______________________ ______________________
8 // T H E W A R B E G I N S
9 // Stratagus - A free fantasy real time strategy game engine
10 //
11 /**@name games.cpp - Basic games query process. */
12 //
13 // (c) Copyright 2005 by Jimmy Salmon
14 //
15 // This program is free software; you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation; only version 2 of the License.
18 //
19 // This program is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU General Public License for more details.
23 //
24 // You should have received a copy of the GNU General Public License
25 // along with this program; if not, write to the Free Software
26 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 // 02111-1307, USA.
28 //
29
30 //@{
31
32 /*----------------------------------------------------------------------------
33 -- Includes
34 ----------------------------------------------------------------------------*/
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include "stratagus.h"
41 #include "games.h"
42 #include "netdriver.h"
43
44 /*----------------------------------------------------------------------------
45 -- Variables
46 ----------------------------------------------------------------------------*/
47
48 static GameData *Games;
49 int GameID;
50
51 /*----------------------------------------------------------------------------
52 -- Functions
53 ----------------------------------------------------------------------------*/
54
55 /**
56 ** Create a game
57 */
CreateGame(Session * session,char * description,char * map,char * players,char * ip,char * port,char * password)58 void CreateGame(Session *session, char *description, char *map,
59 char *players, char *ip, char *port, char *password)
60 {
61 GameData *game;
62
63 game = new GameData;
64
65 strcpy(game->IP, ip);
66 strcpy(game->Port, port);
67 strcpy(game->Description, description);
68 strcpy(game->Map, map);
69 game->MaxSlots = atoi(players);
70 game->OpenSlots = game->MaxSlots - 1;
71 if (password) {
72 strcpy(game->Password, password);
73 } else {
74 game->Password[0] = '\0';
75 }
76
77 game->NumSessions = 1;
78 game->Sessions[0] = session;
79 game->ID = GameID++;
80 game->Started = 0;
81
82 game->GameName = session->UserData.GameName;
83 game->Version = session->UserData.Version;
84
85 if (Games) {
86 Games->Prev = game;
87 }
88 game->Next = Games;
89 game->Prev = NULL;
90 Games = game;
91
92 session->Game = game;
93 }
94
95 /**
96 ** Cancel a game
97 */
CancelGame(Session * session)98 int CancelGame(Session *session)
99 {
100 GameData *game;
101 int i;
102
103 game = session->Game;
104
105 if (game->Sessions[0] != session) {
106 return -1; // Not the host
107 }
108
109 if (game->Next) {
110 game->Next->Prev = game->Prev;
111 }
112 if (game->Prev) {
113 game->Prev->Next = game->Next;
114 }
115 if (Games == game) {
116 Games = game->Next;
117 }
118
119 for (i = 0; i < game->NumSessions; ++i) {
120 game->Sessions[i]->Game = NULL;
121 }
122
123 delete game;
124 return 0;
125 }
126
127 /**
128 ** Start a game
129 */
StartGame(Session * session)130 int StartGame(Session *session)
131 {
132 if (session->Game->Sessions[0] != session) {
133 return -1; // Not the host
134 }
135
136 session->Game->Started = 1;
137 return 0;
138 }
139
140 /**
141 ** Join a game
142 */
JoinGame(Session * session,int id,char * password)143 int JoinGame(Session *session, int id, char *password)
144 {
145 GameData *game;
146
147 if (session->Game) {
148 return -1; // Already in a game
149 }
150
151 game = Games;
152 while (game) {
153 if (game->ID == id) {
154 break;
155 }
156 game = game->Next;
157 }
158 if (!game) {
159 return -2; // ID not found
160 }
161
162 if (game->Password[0]) {
163 if (!password || strcmp(game->Password, password)) {
164 return -3; // Wrong password
165 }
166 }
167 if (!game->OpenSlots) {
168 return -4; // Game full
169 }
170 game->Sessions[game->NumSessions++] = session;
171 session->Game = game;
172
173 return 0;
174 }
175
176 /**
177 ** Leave a game
178 */
PartGame(Session * session)179 int PartGame(Session *session)
180 {
181 GameData *game;
182 int i;
183
184 game = session->Game;
185
186 if (!game) {
187 return -1; // Not in a game
188 }
189 if (game->Started) {
190 return -2;
191 }
192
193 if (game->Sessions[0] == session) {
194 // The host left, cancel the game
195 CancelGame(session);
196 return 0;
197 }
198
199 for (i = 1; i < game->NumSessions; ++i) {
200 if (game->Sessions[i] == session) {
201 for (; i < game->NumSessions - 1; ++i) {
202 game->Sessions[i] = game->Sessions[i + 1];
203 }
204 game->NumSessions--;
205 break;
206 }
207 }
208
209 session->Game = NULL;
210
211 return 0;
212 }
213
MatchGameType(Session * session,GameData * game)214 static int MatchGameType(Session *session, GameData *game)
215 {
216 return (!*game->GameName || !strcmp(session->UserData.GameName, game->GameName)) &&
217 (!*game->Version || !strcmp(session->UserData.Version, game->Version));
218 }
219
220 /**
221 ** List games
222 */
ListGames(Session * session)223 void ListGames(Session *session)
224 {
225 GameData *game;
226 char buf[1024];
227
228 game = Games;
229 while (game) {
230 if (!game->Started && MatchGameType(session, game)) {
231 sprintf(buf, "LISTGAMES %d \"%s\" \"%s\" %d %d %s %s\n",
232 game->ID, game->Description, game->Map,
233 game->OpenSlots, game->MaxSlots, game->IP, game->Port);
234 Send(session, buf);
235 }
236 game = game->Next;
237 }
238 }
239