Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
NetClientDlg.cpp
Go to the documentation of this file.
1 /* Project Starshatter 5.0
2  Destroyer Studios LLC
3  Copyright © 1997-2007. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: NetClientDlg.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Main Menu Dialog Active Window class
13 */
14 
15 #include "MemDebug.h"
16 #include "NetClientDlg.h"
17 #include "NetClientConfig.h"
18 #include "NetLobbyClient.h"
19 #include "MenuScreen.h"
20 #include "Starshatter.h"
21 #include "Ship.h"
22 #include "HUDView.h"
23 
24 #include "NetAddr.h"
25 
26 #include "DataLoader.h"
27 #include "Button.h"
28 #include "ListBox.h"
29 #include "Slider.h"
30 #include "Video.h"
31 #include "Keyboard.h"
32 #include "MachineInfo.h"
33 
34 // +--------------------------------------------------------------------+
35 // DECLARE MAPPING FUNCTIONS:
36 
37 DEF_MAP_CLIENT(NetClientDlg, OnSelect);
40 DEF_MAP_CLIENT(NetClientDlg, OnServer);
43 DEF_MAP_CLIENT(NetClientDlg, OnCancel);
44 
45 // +--------------------------------------------------------------------+
46 
48 : FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr),
49 server_index(-1), ping_index(0), hnet(0)
50 {
52  Init(def);
53 }
54 
56 {
57  StopNetProc();
58 }
59 
60 void
62 {
63  if (hnet != 0) {
64  WaitForSingleObject(hnet, 500);
65  CloseHandle(hnet);
66  hnet = 0;
67  }
68 }
69 
70 // +--------------------------------------------------------------------+
71 
72 void
74 {
75  btn_add = (Button*) FindControl(101);
76  btn_del = (Button*) FindControl(102);
78  lbl_info = FindControl(210);
79  btn_server = (Button*) FindControl(301);
80  btn_host = (Button*) FindControl(302);
81  btn_join = (Button*) FindControl(303);
83 
91 }
92 
93 // +--------------------------------------------------------------------+
94 
95 void
97 {
98  int selected_index = -1;
99 
100  if (!IsShown()) {
102 
103  // try to retrieve list of active servers from web broker
104  if (config && lst_servers) {
105  selected_index = config->GetServerIndex();
107  config->Download();
108  }
109  }
110 
111  if (config && lst_servers) {
113  ShowServers();
114  else
115  UpdateServers();
116 
117  if (selected_index >= 0 && selected_index < lst_servers->NumItems()) {
118  config->SetServerIndex(selected_index);
119  lst_servers->SetSelected(selected_index);
120  OnSelect(0);
121  }
122  }
123 }
124 
125 // +--------------------------------------------------------------------+
126 
127 void
129 {
130  if (!config || !lst_servers) return;
131 
133  ShowServers();
134  else
135  UpdateServers();
136 
138 
139  bool del_enabled = info != 0;
140  bool join_enabled = info != 0 && info->status > NetServerInfo::OFFLINE;
141  bool host_enabled = join_enabled && info->hosted == 0;
142 
143  if (btn_host)
144  btn_host->SetEnabled(host_enabled);
145 
146  if (btn_join)
147  btn_join->SetEnabled(join_enabled);
148 
149  if (btn_del)
150  btn_del->SetEnabled(del_enabled);
151 }
152 
153 // +--------------------------------------------------------------------+
154 
155 void
157 {
158  if (!config || !lst_servers) return;
159 
163 
164  int i = 0;
166  while (++iter) {
167  NetServerInfo* info = iter.value();
168 
169  lst_servers->AddItemWithData(info->name, (DWORD) i);
170  lst_servers->SetItemText(i, 1, info->type);
171  lst_servers->SetItemText(i, 2, info->password);
172  lst_servers->SetItemText(i, 3, Game::GetText("NetClientDlg.offline"));
173  lst_servers->SetItemText(i, 4, "0");
174  lst_servers->SetItemText(i, 5, Game::GetText("NetClientDlg.not-avail"));
175 
176  i++;
177  }
178 
179  ping_index = 0;
180  server_index = -1;
181 
182  if (btn_host) btn_host->SetEnabled(false);
183  if (btn_join) btn_join->SetEnabled(false);
184  if (btn_del) btn_del->SetEnabled(false);
185 }
186 
187 void
189 {
190  if (!config || !lst_servers || lst_servers->NumItems() < 1) return;
191 
192  if (!PingComplete())
193  return;
194 
196 
197  for (int i = 0; i < lst_servers->NumItems(); i++) {
198  int n = lst_servers->GetItemData(i);
199 
200  NetServerInfo* info = config->GetServerList().at(n);
201  lst_servers->SetItemText(i, 0, info->name);
202 
203  Text status = Game::GetText("NetClientDlg.offline");
204 
205  if (info->ping_time > 0 && info->ping_time < 10000) {
206  char buffer[32];
207  sprintf_s(buffer, "%d ms", info->ping_time);
208  lst_servers->SetItemText(i, 5, buffer);
209 
210  switch (info->status) {
211  default:
212  case NetServerInfo::OFFLINE: status = Game::GetText("NetClientDlg.offline"); break;
213  case NetServerInfo::LOBBY: status = Game::GetText("NetClientDlg.lobby"); break;
214  case NetServerInfo::BRIEFING: status = Game::GetText("NetClientDlg.briefing"); break;
215  case NetServerInfo::ACTIVE: status = Game::GetText("NetClientDlg.active"); break;
216  case NetServerInfo::DEBRIEFING: status = Game::GetText("NetClientDlg.debriefing"); break;
217  case NetServerInfo::PERSISTENT: status = Game::GetText("NetClientDlg.persistent"); break;
218  }
219  }
220  else {
221  lst_servers->SetItemText(i, 5, Game::GetText("NetClientDlg.not-avail"));
222  }
223 
224  lst_servers->SetItemText(i, 3, status);
225 
226  char num_users[16];
227  sprintf_s(num_users, "%d", info->nplayers);
228  lst_servers->SetItemText(i, 4, num_users);
229  }
230 }
231 
232 // +--------------------------------------------------------------------+
233 
234 DWORD WINAPI NetClientPingProc(LPVOID link);
235 
236 void
238 {
239  if (hnet == 0) {
241  if (!config) return;
242 
243  NetServerInfo* info = config->GetServerInfo(n);
244  if (!info) return;
245 
246  // copy info from server list
247  ping_info = *info;
248 
249  DWORD thread_id = 0;
250  hnet = CreateThread(0, 4096, NetClientPingProc, (LPVOID) &ping_info, 0, &thread_id);
251 
252  if (hnet == 0) {
253  static int report = 10;
254  if (report > 0) {
255  ::Print("WARNING: NetClientDlg() failed to create PING thread for server '%s' (err=%08x)\n", info->name.data(), GetLastError());
256  report--;
257 
258  if (report == 0)
259  ::Print(" Further warnings of this type will be supressed.\n");
260  }
261  }
262  }
263 }
264 
265 bool
267 {
268  if (hnet != 0) {
269  DWORD result = 0;
270  GetExitCodeThread(hnet, &result);
271 
272  if (result != STILL_ACTIVE) {
273  CloseHandle(hnet);
274  hnet = 0;
275 
277  if (config) {
278  NetServerInfo* info = config->GetServerInfo(ping_index);
279  if (info) {
280  // copy result back into server list
282  info->gameport = ping_info.gameport;
283  info->status = ping_info.status;
284  info->nplayers = ping_info.nplayers;
285  info->hosted = ping_info.hosted;
286  info->ping_time = ping_info.ping_time;
287  }
288  }
289 
291  ping_index = 0;
292  else
293  ping_index++;
294  }
295  }
296 
297  return !hnet;
298 }
299 
300 // +--------------------------------------------------------------------+
301 
302 DWORD WINAPI NetClientPingProc(LPVOID link)
303 {
304  NetServerInfo* info = (NetServerInfo*) link;
305  if (!info) {
306  Print("NetClientPingProc() no link\n");
307  Sleep(200);
308  return 1;
309  }
310 
311  NetAddr addr = info->addr;
312  if (!addr.IPAddr()) {
313  Sleep(200);
314  return 1;
315  }
316 
317  NetLobbyClient conn(addr);
318 
319  if (conn.Ping()) {
320  info->machine_info = conn.GetMachineInfo();
321  info->gameport = conn.GetGamePort();
322  info->status = conn.GetStatus();
323  info->nplayers = conn.NumUsers();
324  info->hosted = conn.HasHost();
325  info->ping_time = conn.GetLag();
326  }
327 
328  else {
329  info->machine_info = Text();
330  info->nplayers = 0;
331  info->hosted = 0;
333  info->ping_time = 0;
334  }
335 
336  return 0;
337 }
338 
339 // +--------------------------------------------------------------------+
340 
341 void
343 {
345 }
346 
347 void
349 {
350  if (config && server_index >= 0)
352 }
353 
354 void
356 {
357  if (lst_servers) {
360 
361  if (lbl_info) {
362  if (info)
363  lbl_info->SetText(info->machine_info);
364  else
365  lbl_info->SetText("");
366  }
367 
368  if (btn_host) {
369  btn_host->SetEnabled(info && info->status > NetServerInfo::OFFLINE && info->hosted == 0);
370  }
371 
372  if (btn_join) {
374  }
375  }
376 }
377 
378 // +--------------------------------------------------------------------+
379 
380 void
382 {
384 }
385 
386 void
388 {
389  if (config) {
391  config->SetHostRequest(true);
392  config->Save();
393 
395  if (info && info->password == "Yes") {
397  }
398  else {
400  }
401  }
402 }
403 
404 void
406 {
407  if (config) {
409  config->SetHostRequest(false);
410  config->Save();
411 
413  if (info && info->password == "Yes") {
415  }
416  else {
418  }
419  }
420 }
421 
422 void
424 {
425  if (config) {
426  config->Save();
427  config->SetServerIndex(-1);
428  }
429 
430  manager->ShowMenuDlg();
431 }