2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on the
11 #include "stand_gui.h"
12 #include "osregistry.h"
14 #include "wx/statline.h"
15 #include "wx/filename.h"
16 #include "wx/stdpaths.h"
18 #include "wx/msgdlg.h"
19 #include "wx/process.h"
22 // taken from psnet.h and psnet2.h
24 #define DEFAULT_GAME_PORT 4000
25 #elif defined(FS2_DEMO)
26 #define DEFAULT_GAME_PORT 7802
28 #define DEFAULT_GAME_PORT 7808
33 IMPLEMENT_APP(StandaloneApp)
35 bool StandaloneApp::OnInit()
37 if ( !wxApp::OnInit() ) {
41 std_client = new Standalone(NULL);
44 if ( !std_client->startFreeSpace(argc, argv) ) {
45 throw "Unable to start FreeSpace";
50 if ( !std_client->wsInitialize() ) {
51 throw "Unable to initialize WebSocket";
53 } catch (const char *err) {
54 wxMessageBox(err, "Error!");
59 std_client->Show(true);
60 SetTopWindow(std_client);
65 StandaloneTimer::StandaloneTimer(Standalone *stand)
70 StandaloneTimer::~StandaloneTimer()
74 void StandaloneTimer::Notify()
79 StandPopup::StandPopup( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style )
81 this->SetSizeHints( wxSize( 350,100 ), wxDefaultSize );
84 bSizer2 = new wxBoxSizer( wxVERTICAL );
86 wxFlexGridSizer* fgSizer3;
87 fgSizer3 = new wxFlexGridSizer( 0, 2, 0, 0 );
88 fgSizer3->AddGrowableRow(0, 1);
90 m_Label1 = new wxStaticText( this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
92 fgSizer3->Add( m_Label1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
94 m_Label2 = new wxStaticText( this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
96 fgSizer3->Add( m_Label2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
99 bSizer2->Add( fgSizer3, 1, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 10 );
102 this->SetSizer( bSizer2 );
104 bSizer2->Fit( this );
106 this->Centre( wxBOTH );
109 StandPopup::~StandPopup()
113 wxBEGIN_EVENT_TABLE(Standalone, wxDialog)
114 EVT_CLOSE(Standalone::OnClose)
115 EVT_BUTTON(ID_B_SHUTDOWN, Standalone::OnShutdown)
116 EVT_BUTTON(ID_B_KICK, Standalone::OnKick)
117 EVT_BUTTON(ID_B_MREFRESH, Standalone::OnMissionRefresh)
118 EVT_BUTTON(ID_B_RESET_ALL, Standalone::OnResetAll)
119 EVT_SLIDER(ID_FPS_SLIDER, Standalone::OnFPSSel)
120 EVT_TEXT_ENTER(ID_T_MSG, Standalone::OnServerMsg)
121 EVT_TEXT_ENTER(ID_T_SERVER_NAME, Standalone::OnServerNameChange)
122 EVT_TEXT_ENTER(ID_T_HOST_PASS, Standalone::OnHostPassChange)
123 EVT_CHOICE(ID_C_P_PLAYERS, Standalone::OnPinfoPlayer)
126 Standalone::Standalone( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
128 this->SetSizeHints( wxDefaultSize, wxDefaultSize );
131 fsport = DEFAULT_GAME_PORT;
132 stand_context = NULL;
133 wsi_standalone = NULL;
136 m_timer = new StandaloneTimer(this);
137 m_timer->Start(1000/30);
139 m_popup = new StandPopup(this);
140 m_popup->Show(false);
143 bSizer1 = new wxBoxSizer( wxVERTICAL );
145 wxNotebook* nbook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
147 createTab_Server(nbook);
148 createTab_Multi(nbook);
149 createTab_Player(nbook);
150 createTab_GodStuff(nbook);
151 createTab_Debug(nbook);
153 bSizer1->Add( nbook, 1, wxEXPAND | wxALL, 5 );
155 wxButton* bshutdown = new wxButton( this, ID_B_SHUTDOWN, wxT("Shutdown"), wxDefaultPosition, wxDefaultSize, 0 );
156 bSizer1->Add( bshutdown, 0, wxALIGN_CENTER|wxALL, 5 );
159 this->SetSizer( bSizer1 );
161 bSizer1->SetSizeHints(this);
163 this->Centre( wxBOTH );
166 Standalone::~Standalone()
171 void Standalone::OnClose( wxCloseEvent& WXUNUSED(event) )
176 void Standalone::OnShutdown( wxCommandEvent& WXUNUSED(event) )
181 void Standalone::Shutdown()
184 std::string msg("shutdown");
187 lws_service(stand_context, 50);
189 lws_context_destroy(stand_context);
192 if ( wxProcess::Exists(fspid) ) {
193 // wait a little bit, and if process still exists then kill it
196 if ( wxProcess::Exists(fspid) ) {
197 wxProcess::Kill(fspid, wxSIGTERM);
204 void Standalone::OnServerNameChange(wxCommandEvent& WXUNUSED(event) )
206 std::string msg("S:name ");
208 msg.append( m_S_ServerName->GetValue().c_str() );
213 void Standalone::OnHostPassChange(wxCommandEvent& WXUNUSED(event) )
215 std::string msg("S:pass ");
217 msg.append( m_S_HostPass->GetValue().c_str() );
222 void Standalone::OnKick( wxCommandEvent& WXUNUSED(event) )
224 std::string msg("S:kick ");
226 wxString id = m_S_Connections->GetStringSelection();
228 if ( id.IsEmpty() ) {
232 wxArrayString ipaddr = wxSplit(id, ',');
234 msg.append( ipaddr.Item(0).c_str() );
239 void Standalone::OnMissionRefresh( wxCommandEvent& WXUNUSED(event) )
241 std::string msg("G:mrefresh");
246 void Standalone::OnResetAll( wxCommandEvent& WXUNUSED(event) )
248 std::string msg("reset");
253 void Standalone::OnFPSSel( wxCommandEvent& WXUNUSED(event) )
255 wxString fps = wxString::Format("%d", m_M_sliderFPS->GetValue());
257 m_M_FPS->SetLabel(fps);
259 std::string msg("M:fps ");
265 void Standalone::OnServerMsg( wxCommandEvent& WXUNUSED(event) )
267 if ( m_GS_msg->GetValue().IsEmpty() ) {
271 std::string msg("G:smsg ");
273 msg.append( m_GS_msg->GetValue().c_str() );
275 // strip off return char which GetValue() has
276 size_t pos = msg.find_last_not_of("\r\n");
278 if (pos != std::string::npos) {
287 void Standalone::OnPinfoPlayer(wxCommandEvent& WXUNUSED(event) )
289 int idx = m_P_Players->GetCurrentSelection();
291 if (idx == wxNOT_FOUND) {
295 std::string msg("P:info ");
297 msg.append( m_P_Players->GetString(idx).c_str() );
302 void Standalone::createTab_Server(wxNotebook* parent)
304 wxPanel* panel = new wxPanel( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
306 wxBoxSizer *panelSizer = new wxBoxSizer( wxVERTICAL );
308 wxBoxSizer* bSizer = new wxBoxSizer( wxVERTICAL );
310 wxFlexGridSizer* fgSizer5 = new wxFlexGridSizer( 0, 2, 0, 0 );
311 fgSizer5->AddGrowableCol(1, 1);
313 wxStaticText* m_staticText6 = new wxStaticText( panel, wxID_ANY, wxT("Server Name"), wxDefaultPosition, wxDefaultSize, 0 );
314 fgSizer5->Add( m_staticText6, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
316 m_S_ServerName = new wxTextCtrl( panel, ID_T_SERVER_NAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
317 m_S_ServerName->SetMaxLength( 31 );
318 fgSizer5->Add( m_S_ServerName, 0, wxALL|wxEXPAND, 5 );
320 wxStaticText* m_staticText7 = new wxStaticText( panel, wxID_ANY, wxT("Host Password"), wxDefaultPosition, wxDefaultSize, 0 );
321 fgSizer5->Add( m_staticText7, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
323 m_S_HostPass = new wxTextCtrl( panel, ID_T_HOST_PASS, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
324 m_S_HostPass->SetMaxLength( 16 );
325 fgSizer5->Add( m_S_HostPass, 0, wxALL|wxEXPAND, 5 );
327 bSizer->Add( fgSizer5, 0, wxEXPAND, 0 );
329 wxStaticLine* m_staticline1 = new wxStaticLine( panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
330 bSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
332 wxFlexGridSizer* fgSizer7 = new wxFlexGridSizer( 0, 2, 0, 0 );
333 fgSizer7->SetFlexibleDirection( wxBOTH );
334 fgSizer7->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
336 wxStaticText* m_staticText9 = new wxStaticText( panel, wxID_ANY, wxT("# Connections :"), wxDefaultPosition, wxDefaultSize, 0 );
337 fgSizer7->Add( m_staticText9, 0, wxALL, 5 );
339 m_S_NumConn = new wxStaticText( panel, wxID_ANY, wxT("0"), wxDefaultPosition, wxDefaultSize, 0|wxSUNKEN_BORDER );
340 fgSizer7->Add( m_S_NumConn, 0, wxALL, 5 );
342 bSizer->Add( fgSizer7, 0, wxEXPAND, 5 );
344 wxStaticText* m_staticText8 = new wxStaticText( panel, wxID_ANY, wxT("Address and Ping"), wxDefaultPosition, wxDefaultSize, 0 );
345 bSizer->Add( m_staticText8, 0, wxALL, 5 );
347 wxFlexGridSizer* fgSizer3 = new wxFlexGridSizer( 0, 2, 0, 0 );
348 fgSizer3->SetFlexibleDirection( wxBOTH );
349 fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
351 m_S_Connections = new wxTextCtrl( panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 300,300 ), wxTE_MULTILINE|wxTE_READONLY );
352 fgSizer3->Add( m_S_Connections, 0, wxALL|wxEXPAND, 5 );
354 wxBoxSizer* bbSizer = new wxBoxSizer( wxVERTICAL );
356 m_S_btnKick = new wxButton( panel, ID_B_KICK, wxT("Kick"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
357 bbSizer->Add( m_S_btnKick, 1, wxALL, 5 );
359 m_S_btnMRefresh = new wxButton( panel, ID_B_MREFRESH, wxT(" Refresh\nMissions"), wxDefaultPosition, wxDefaultSize, 0 );
360 bbSizer->Add( m_S_btnMRefresh, 2, wxALL, 5 );
362 m_S_btnResetAll = new wxButton( panel, ID_B_RESET_ALL, wxT("Reset All"), wxDefaultPosition, wxDefaultSize, 0 );
363 bbSizer->Add( m_S_btnResetAll, 3, wxALL, 5 );
365 fgSizer3->Add( bbSizer, 1, wxEXPAND, 5 );
367 bSizer->Add( fgSizer3, 0, wxEXPAND, 5 );
369 panelSizer->Add( bSizer, 1, wxALL|wxEXPAND, 5 );
371 panel->SetSizer( panelSizer );
372 panelSizer->Fit( panel );
373 panelSizer->SetSizeHints( panel );
375 parent->AddPage( panel, wxT("Server"), true );
378 void Standalone::createTab_Multi(wxNotebook* parent)
380 wxPanel* panel = new wxPanel( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
382 wxBoxSizer* panelSizer = new wxBoxSizer(wxVERTICAL);
384 wxBoxSizer* bSizer = new wxBoxSizer(wxVERTICAL);
386 m_M_sliderFPS = new wxSlider( panel, ID_FPS_SLIDER, 30, 15, 60, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL );
387 bSizer->Add( m_M_sliderFPS, 0, wxALL|wxEXPAND, 5 );
389 wxFlexGridSizer* fgSizer8;
390 fgSizer8 = new wxFlexGridSizer( 0, 5, 0, 0 );
391 fgSizer8->AddGrowableCol(2, 1);
393 wxStaticText* m_staticText71 = new wxStaticText( panel, wxID_ANY, wxT("Frame Cap : "), wxDefaultPosition, wxDefaultSize, 0 );
394 m_staticText71->Wrap( -1 );
395 fgSizer8->Add( m_staticText71, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
397 wxPanel* fpsPanel = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
398 wxBoxSizer* fpsSizer = new wxBoxSizer(wxHORIZONTAL);
399 m_M_FPS = new wxStaticText( fpsPanel, wxID_ANY, "30", wxDefaultPosition, wxSize(60, -1), 0 );
401 fpsSizer->Add( m_M_FPS, 0, wxALL, 2 );
402 fpsPanel->SetSizer(fpsSizer);
403 fpsSizer->Fit(fpsPanel);
404 fgSizer8->Add(fpsPanel, 0, wxALL, 3);
407 fgSizer8->Add( 0, 0, 1, wxEXPAND );
409 wxStaticText* m_staticText81 = new wxStaticText( panel, wxID_ANY, wxT("Realized FPS : "), wxDefaultPosition, wxDefaultSize, 0 );
410 m_staticText81->Wrap( -1 );
411 fgSizer8->Add( m_staticText81, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
413 wxPanel*fpscapPanel = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
414 wxBoxSizer* fpscapSizer = new wxBoxSizer(wxHORIZONTAL);
415 m_M_FPSRel = new wxStaticText( fpscapPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(60, -1), 0 );
416 m_M_FPSRel->Wrap( -1 );
417 fpscapSizer->Add( m_M_FPSRel, 0, wxALL, 2 );
418 fpscapPanel->SetSizer(fpscapSizer);
419 fpscapSizer->Fit(fpscapPanel);
420 fgSizer8->Add(fpscapPanel, 0, wxALL, 3);
423 bSizer->Add( fgSizer8, 0, wxEXPAND, 5 );
425 wxStaticLine* m_staticline2 = new wxStaticLine( panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
426 bSizer->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
429 bSizer->Add( 0, 0, 0, wxALL, 20 );
432 wxFlexGridSizer* fgSizer9;
433 fgSizer9 = new wxFlexGridSizer( 0, 2, 0, 0 );
434 fgSizer9->SetFlexibleDirection( wxBOTH );
435 fgSizer9->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
437 wxStaticText* m_staticText91 = new wxStaticText( panel, wxID_ANY, wxT("Mission Name : "), wxDefaultPosition, wxDefaultSize, 0 );
438 m_staticText91->Wrap( -1 );
439 fgSizer9->Add( m_staticText91, 0, wxALL, 5 );
441 wxPanel* mnPanel = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
442 wxBoxSizer* mnSizer = new wxBoxSizer(wxHORIZONTAL);
443 m_M_MissionName = new wxStaticText( mnPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0 );
444 m_M_MissionName->Wrap( -1 );
445 mnSizer->Add( m_M_MissionName, 0, wxALL, 2 );
446 mnPanel->SetSizer(mnSizer);
447 mnSizer->Fit(mnPanel);
448 fgSizer9->Add(mnPanel, 0, wxALL, 3);
450 wxStaticText* m_staticText101 = new wxStaticText( panel, wxID_ANY, wxT("Mission Time : "), wxDefaultPosition, wxDefaultSize, 0 );
451 m_staticText101->Wrap( -1 );
452 fgSizer9->Add( m_staticText101, 0, wxALL, 5 );
454 wxPanel* mtPanel = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
455 wxBoxSizer* mtSizer = new wxBoxSizer(wxHORIZONTAL);
456 m_M_MissionTime = new wxStaticText( mtPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(150, -1), 0 );
457 m_M_MissionTime->Wrap( -1 );
458 mtSizer->Add( m_M_MissionTime, 0, wxALL, 2 );
459 mtPanel->SetSizer(mtSizer);
460 mtSizer->Fit(mtPanel);
461 fgSizer9->Add(mtPanel, 0, wxALL, 3);
464 bSizer->Add( fgSizer9, 0, wxEXPAND, 5 );
467 bSizer->Add( 0, 0, 0, wxALL, 20 );
469 wxBoxSizer* bSizer3 = new wxBoxSizer(wxHORIZONTAL);
471 wxBoxSizer* bSizer4 = new wxBoxSizer(wxVERTICAL);
473 wxStaticText* m_staticText11 = new wxStaticText( panel, wxID_ANY, wxT("Mission Goals"), wxDefaultPosition, wxDefaultSize, 0 );
474 m_staticText11->Wrap( -1 );
475 bSizer4->Add( m_staticText11, 0, wxALL, 5 );
477 m_M_Goals = new wxTreeCtrl( panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE|wxTR_HIDE_ROOT );
478 bSizer4->Add( m_M_Goals, 1, wxALL|wxEXPAND, 5 );
480 bSizer3->Add(bSizer4, 1, wxEXPAND);
482 wxBoxSizer* bSizer5 = new wxBoxSizer(wxVERTICAL);
484 wxStaticText* m_staticText12 = new wxStaticText( panel, wxID_ANY, wxT("Netgame Information"), wxDefaultPosition, wxDefaultSize, 0 );
485 m_staticText12->Wrap( -1 );
486 bSizer5->Add( m_staticText12, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5 );
488 wxFlexGridSizer* fgSizer11;
489 fgSizer11 = new wxFlexGridSizer( 0, 2, 0, 15 );
490 fgSizer11->AddGrowableRow(0, 1);
491 fgSizer11->AddGrowableRow(1, 1);
492 fgSizer11->AddGrowableRow(2, 1);
493 fgSizer11->AddGrowableRow(3, 1);
495 wxStaticText* m_staticText13 = new wxStaticText( panel, wxID_ANY, wxT("Max Players"), wxDefaultPosition, wxDefaultSize, 0 );
496 m_staticText13->Wrap( -1 );
497 fgSizer11->Add( m_staticText13, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
499 m_M_ngMaxPlayers = new wxStaticText( panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
500 m_M_ngMaxPlayers->Wrap( -1 );
501 fgSizer11->Add( m_M_ngMaxPlayers, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
503 wxStaticText* m_staticText15 = new wxStaticText( panel, wxID_ANY, wxT("Max Observers"), wxDefaultPosition, wxDefaultSize, 0 );
504 m_staticText15->Wrap( -1 );
505 fgSizer11->Add( m_staticText15, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
507 m_M_ngMaxObservers = new wxStaticText( panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
508 m_M_ngMaxObservers->Wrap( -1 );
509 fgSizer11->Add( m_M_ngMaxObservers, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
511 wxStaticText* m_staticText17 = new wxStaticText( panel, wxID_ANY, wxT("Security"), wxDefaultPosition, wxDefaultSize, 0 );
512 m_staticText17->Wrap( -1 );
513 fgSizer11->Add( m_staticText17, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
515 m_M_ngSecurity = new wxStaticText( panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
516 m_M_ngSecurity->Wrap( -1 );
517 fgSizer11->Add( m_M_ngSecurity, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
519 wxStaticText* m_staticText19 = new wxStaticText( panel, wxID_ANY, wxT("Respawns"), wxDefaultPosition, wxDefaultSize, 0 );
520 m_staticText19->Wrap( -1 );
521 fgSizer11->Add( m_staticText19, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
523 m_M_ngRespawns = new wxStaticText( panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
524 m_M_ngRespawns->Wrap( -1 );
525 fgSizer11->Add( m_M_ngRespawns, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
527 bSizer5->Add( fgSizer11, 1, wxEXPAND );
529 bSizer3->Add(bSizer5, 1, wxEXPAND);
531 bSizer->Add( bSizer3, 1, wxEXPAND, 5 );
533 panelSizer->Add(bSizer, 1, wxALL|wxEXPAND, 5);
535 panel->SetSizer( panelSizer );
536 panelSizer->Fit( panel );
537 panelSizer->SetSizeHints( panel );
539 parent->AddPage( panel, wxT("Multi-Player") );
542 void Standalone::createTab_Player(wxNotebook* parent)
544 wxPanel* panel = new wxPanel( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
546 wxBoxSizer* panelSizer = new wxBoxSizer( wxVERTICAL );
548 wxBoxSizer* bSizer = new wxBoxSizer( wxVERTICAL );
550 wxBoxSizer* bSizer21;
551 bSizer21 = new wxBoxSizer( wxHORIZONTAL );
553 wxStaticText* m_staticText211 = new wxStaticText( panel, wxID_ANY, wxT("Player"), wxDefaultPosition, wxDefaultSize, 0 );
554 m_staticText211->Wrap( -1 );
555 bSizer21->Add( m_staticText211, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
557 wxArrayString m_choice11Choices;
558 m_P_Players = new wxChoice( panel, ID_C_P_PLAYERS, wxDefaultPosition, wxSize(200, -1), m_choice11Choices, 0 );
559 m_P_Players->SetSelection( wxNOT_FOUND );
560 bSizer21->Add( m_P_Players, 0, wxALL, 5 );
562 bSizer->Add( bSizer21, 0, wxEXPAND );
565 wxStaticLine* m_staticline4 = new wxStaticLine( panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
566 bSizer->Add( m_staticline4, 0, wxEXPAND | wxALL, 5 );
568 wxFlexGridSizer* fgSizer14;
569 fgSizer14 = new wxFlexGridSizer( 0, 2, 0, 0 );
571 wxStaticText* m_staticText26 = new wxStaticText( panel, wxID_ANY, wxT("Ship Type"), wxDefaultPosition, wxDefaultSize, 0 );
572 m_staticText26->Wrap( -1 );
573 fgSizer14->Add( m_staticText26, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
575 wxPanel* stPanel = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
576 wxBoxSizer* stSizer = new wxBoxSizer(wxHORIZONTAL);
577 m_P_ShipType = new wxStaticText( stPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(150, -1), 0 );
578 m_P_ShipType->Wrap( -1 );
579 stSizer->Add(m_P_ShipType, 0, wxALL, 2);
580 stPanel->SetSizer(stSizer);
581 stSizer->Fit(stPanel);
582 fgSizer14->Add( stPanel, 0, wxALL, 5 );
584 wxStaticText* m_staticText28 = new wxStaticText( panel, wxID_ANY, wxT("Avg Ping"), wxDefaultPosition, wxDefaultSize, 0 );
585 m_staticText28->Wrap( -1 );
586 fgSizer14->Add( m_staticText28, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
588 wxPanel* apPanel = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
589 wxBoxSizer* apSizer = new wxBoxSizer(wxHORIZONTAL);
590 m_P_AvgPing = new wxStaticText( apPanel, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(150, -1), 0 );
591 m_P_AvgPing->Wrap( -1 );
592 apSizer->Add(m_P_AvgPing, 0, wxALL, 2);
593 apPanel->SetSizer(apSizer);
594 apSizer->Fit(apPanel);
595 fgSizer14->Add( apPanel, 0, wxALL, 5 );
597 bSizer->Add( fgSizer14, 0, wxEXPAND );
599 bSizer->Add( 0, 0, 0, wxALL, 10);
602 bSizer6 = new wxBoxSizer( wxHORIZONTAL );
608 wxBoxSizer* atsboxSizer = new wxBoxSizer( wxVERTICAL );
610 wxStaticText* atsText = new wxStaticText( panel, wxID_ANY, wxT("All Time Stats") );
611 atsboxSizer->Add( atsText, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
613 wxFlexGridSizer* atsgSizer = new wxFlexGridSizer( 0, 2, 0, 0 );
614 atsgSizer->AddGrowableCol(1, 1);
618 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Primary Shots"), wxDefaultPosition, wxDefaultSize, 0 );
620 atsgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
621 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
622 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
623 m_P_atsPriShots = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
624 m_P_atsPriShots->Wrap( -1 );
625 p1sizer->Add( m_P_atsPriShots, 1, wxALL|wxEXPAND, 1);
626 p1->SetSizer( p1sizer );
628 atsgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
633 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Primary Hits"), wxDefaultPosition, wxDefaultSize, 0 );
635 atsgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
636 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
637 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
638 m_P_atsPriHits = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
639 m_P_atsPriHits->Wrap( -1 );
640 p1sizer->Add( m_P_atsPriHits, 0, wxALL|wxEXPAND, 1);
641 p1->SetSizer( p1sizer );
643 atsgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
648 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Primary BH Hits"), wxDefaultPosition, wxDefaultSize, 0 );
650 atsgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
651 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
652 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
653 m_P_atsPriBHHits = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
654 m_P_atsPriBHHits->Wrap( -1 );
655 p1sizer->Add( m_P_atsPriBHHits, 0, wxALL|wxEXPAND, 1);
656 p1->SetSizer( p1sizer );
658 atsgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
663 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Primary Hit %"), wxDefaultPosition, wxDefaultSize, 0 );
665 atsgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
666 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
667 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
668 m_P_atsPriHitPer = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
669 m_P_atsPriHitPer->Wrap( -1 );
670 p1sizer->Add( m_P_atsPriHitPer, 0, wxALL|wxEXPAND, 1);
671 p1->SetSizer( p1sizer );
673 atsgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
678 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Primary BH Hit %"), wxDefaultPosition, wxDefaultSize, 0 );
680 atsgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
681 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
682 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
683 m_P_atsPriBHHitPer = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
684 m_P_atsPriBHHitPer->Wrap( -1 );
685 p1sizer->Add( m_P_atsPriBHHitPer, 0, wxALL|wxEXPAND, 1);
686 p1->SetSizer( p1sizer );
688 atsgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
693 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Secondary Shots"), wxDefaultPosition, wxDefaultSize, 0 );
695 atsgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
696 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
697 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
698 m_P_atsSecShots = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
699 m_P_atsSecShots->Wrap( -1 );
700 p1sizer->Add( m_P_atsSecShots, 0, wxALL|wxEXPAND, 1);
701 p1->SetSizer( p1sizer );
703 atsgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
708 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Secondary Hits"), wxDefaultPosition, wxDefaultSize, 0 );
710 atsgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
711 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
712 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
713 m_P_atsSecHits = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
714 m_P_atsSecHits->Wrap( -1 );
715 p1sizer->Add( m_P_atsSecHits, 0, wxALL|wxEXPAND, 1);
716 p1->SetSizer( p1sizer );
718 atsgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
723 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Secondary BH Hits"), wxDefaultPosition, wxDefaultSize, 0 );
725 atsgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
726 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
727 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
728 m_P_atsSecBHHits = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
729 m_P_atsSecBHHits->Wrap( -1 );
730 p1sizer->Add( m_P_atsSecBHHits, 0, wxALL|wxEXPAND, 1);
731 p1->SetSizer( p1sizer );
733 atsgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
738 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Secondary Hit %"), wxDefaultPosition, wxDefaultSize, 0 );
740 atsgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
741 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
742 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
743 m_P_atsSecHitPer = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
744 m_P_atsSecHitPer->Wrap( -1 );
745 p1sizer->Add( m_P_atsSecHitPer, 0, wxALL|wxEXPAND, 1);
746 p1->SetSizer( p1sizer );
748 atsgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
751 // secondary BH hit %
753 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Secondary BH Hit %"), wxDefaultPosition, wxDefaultSize, 0 );
755 atsgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
756 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
757 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
758 m_P_atsSecBHHitPer = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
759 m_P_atsSecBHHitPer->Wrap( -1 );
760 p1sizer->Add( m_P_atsSecBHHitPer, 0, wxALL|wxEXPAND, 1);
761 p1->SetSizer( p1sizer );
763 atsgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
768 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Assists"), wxDefaultPosition, wxDefaultSize, 0 );
770 atsgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
771 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
772 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
773 m_P_atsAssists = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
774 m_P_atsAssists->Wrap( -1 );
775 p1sizer->Add( m_P_atsAssists, 0, wxALL|wxEXPAND, 1);
776 p1->SetSizer( p1sizer );
778 atsgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
781 atsboxSizer->Add( atsgSizer, 1, wxEXPAND );
783 bSizer6->Add( atsboxSizer, 1, wxEXPAND, 5 );
785 wxStaticLine* m_staticline3 = new wxStaticLine( panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
786 bSizer6->Add( m_staticline3, 0, wxEXPAND | wxALL, 5 );
792 wxBoxSizer* msboxSizer = new wxBoxSizer( wxVERTICAL );
794 wxStaticText* msText = new wxStaticText( panel, wxID_ANY, wxT("Mission Stats") );
795 msboxSizer->Add( msText, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
797 wxFlexGridSizer* msgSizer = new wxFlexGridSizer( 0, 2, 0, 0 );
798 msgSizer->AddGrowableCol(1, 1);
802 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Primary Shots"), wxDefaultPosition, wxDefaultSize, 0 );
804 msgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
805 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
806 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
807 m_P_msPriShots = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
808 m_P_msPriShots->Wrap( -1 );
809 p1sizer->Add( m_P_msPriShots, 1, wxALL|wxEXPAND, 1);
810 p1->SetSizer( p1sizer );
812 msgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
817 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Primary Hits"), wxDefaultPosition, wxDefaultSize, 0 );
819 msgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
820 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
821 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
822 m_P_msPriHits = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
823 m_P_msPriHits->Wrap( -1 );
824 p1sizer->Add( m_P_msPriHits, 0, wxALL|wxEXPAND, 1);
825 p1->SetSizer( p1sizer );
827 msgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
832 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Primary BH Hits"), wxDefaultPosition, wxDefaultSize, 0 );
834 msgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
835 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
836 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
837 m_P_msPriBHHits = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
838 m_P_msPriBHHits->Wrap( -1 );
839 p1sizer->Add( m_P_msPriBHHits, 0, wxALL|wxEXPAND, 1);
840 p1->SetSizer( p1sizer );
842 msgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
847 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Primary Hit %"), wxDefaultPosition, wxDefaultSize, 0 );
849 msgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
850 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
851 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
852 m_P_msPriHitPer = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
853 m_P_msPriHitPer->Wrap( -1 );
854 p1sizer->Add( m_P_msPriHitPer, 0, wxALL|wxEXPAND, 1);
855 p1->SetSizer( p1sizer );
857 msgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
862 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Primary BH Hit %"), wxDefaultPosition, wxDefaultSize, 0 );
864 msgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
865 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
866 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
867 m_P_msPriBHHitPer = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
868 m_P_msPriBHHitPer->Wrap( -1 );
869 p1sizer->Add( m_P_msPriBHHitPer, 0, wxALL|wxEXPAND, 1);
870 p1->SetSizer( p1sizer );
872 msgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
877 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Secondary Shots"), wxDefaultPosition, wxDefaultSize, 0 );
879 msgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
880 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
881 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
882 m_P_msSecShots = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
883 m_P_msSecShots->Wrap( -1 );
884 p1sizer->Add( m_P_msSecShots, 0, wxALL|wxEXPAND, 1);
885 p1->SetSizer( p1sizer );
887 msgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
892 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Secondary Hits"), wxDefaultPosition, wxDefaultSize, 0 );
894 msgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
895 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
896 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
897 m_P_msSecHits = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
898 m_P_msSecHits->Wrap( -1 );
899 p1sizer->Add( m_P_msSecHits, 0, wxALL|wxEXPAND, 1);
900 p1->SetSizer( p1sizer );
902 msgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
907 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Secondary BH Hits"), wxDefaultPosition, wxDefaultSize, 0 );
909 msgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
910 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
911 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
912 m_P_msSecBHHits = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
913 m_P_msSecBHHits->Wrap( -1 );
914 p1sizer->Add( m_P_msSecBHHits, 0, wxALL|wxEXPAND, 1);
915 p1->SetSizer( p1sizer );
917 msgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
922 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Secondary Hit %"), wxDefaultPosition, wxDefaultSize, 0 );
924 msgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
925 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
926 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
927 m_P_msSecHitPer = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
928 m_P_msSecHitPer->Wrap( -1 );
929 p1sizer->Add( m_P_msSecHitPer, 0, wxALL|wxEXPAND, 1);
930 p1->SetSizer( p1sizer );
932 msgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
935 // secondary BH hit %
937 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Secondary BH Hit %"), wxDefaultPosition, wxDefaultSize, 0 );
939 msgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
940 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
941 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
942 m_P_msSecBHHitPer = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
943 m_P_msSecBHHitPer->Wrap( -1 );
944 p1sizer->Add( m_P_msSecBHHitPer, 0, wxALL|wxEXPAND, 1);
945 p1->SetSizer( p1sizer );
947 msgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
952 wxStaticText* itxt = new wxStaticText( panel, wxID_ANY, wxT("Assists"), wxDefaultPosition, wxDefaultSize, 0 );
954 msgSizer->Add( itxt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
955 wxPanel* p1 = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER);
956 wxBoxSizer* p1sizer = new wxBoxSizer( wxHORIZONTAL );
957 m_P_msAssists = new wxStaticText( p1, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, 0 );
958 m_P_msAssists->Wrap( -1 );
959 p1sizer->Add( m_P_msAssists, 0, wxALL|wxEXPAND, 1);
960 p1->SetSizer( p1sizer );
962 msgSizer->Add( p1, 0, wxALL|wxEXPAND, 1 );
965 msboxSizer->Add( msgSizer, 1, wxEXPAND );
967 bSizer6->Add( msboxSizer, 1, wxEXPAND );
969 bSizer->Add( bSizer6, 1, wxEXPAND );
971 panelSizer->Add( bSizer, 1, wxALL|wxEXPAND, 5 );
973 panel->SetSizer( panelSizer );
974 panelSizer->Fit( panel );
975 panelSizer->SetSizeHints(panel);
977 parent->AddPage( panel, wxT("Player Info") );
980 void Standalone::createTab_GodStuff(wxNotebook* parent)
982 wxPanel* panel = new wxPanel( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
984 wxBoxSizer* panelSizer = new wxBoxSizer( wxVERTICAL );
986 wxBoxSizer* bSizer = new wxBoxSizer( wxVERTICAL );
988 wxBoxSizer* bSizer2 = new wxBoxSizer( wxHORIZONTAL );
990 wxStaticText* m_staticText21 = new wxStaticText( panel, wxID_ANY, wxT("Player"), wxDefaultPosition, wxDefaultSize, 0 );
991 bSizer2->Add( m_staticText21, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
993 wxArrayString m_choice1Choices;
994 m_GS_Players = new wxChoice( panel, wxID_ANY, wxDefaultPosition, wxSize(200, -1), m_choice1Choices, 0 );
995 m_GS_Players->SetSelection( wxNOT_FOUND );
996 bSizer2->Add( m_GS_Players, 0, wxALL|wxEXPAND, 5 );
998 bSizer->Add( bSizer2, 0, wxEXPAND, 5 );
1000 bSizer->Add( 0, 0, 0, wxALL, 10 );
1002 wxStaticText* m_staticText22 = new wxStaticText( panel, wxID_ANY, wxT("Server Message"), wxDefaultPosition, wxDefaultSize, 0 );
1003 bSizer->Add( m_staticText22, 0, wxALL, 5 );
1005 m_GS_msg = new wxTextCtrl( panel, ID_T_MSG, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
1006 m_GS_msg->SetMaxLength(150);
1007 bSizer->Add( m_GS_msg, 0, wxALL|wxEXPAND, 5 );
1009 bSizer->Add( 0, 0, 0, wxALL, 5 );
1011 m_GS_Messages = new wxTextCtrl( panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY );
1012 bSizer->Add( m_GS_Messages, 1, wxALL|wxEXPAND, 5 );
1014 panelSizer->Add( bSizer, 1, wxALL|wxEXPAND, 5 );
1016 panel->SetSizer( panelSizer );
1017 panelSizer->Fit( panel );
1018 panelSizer->SetSizeHints( panel );
1020 parent->AddPage( panel, wxT("God Stuff") );
1023 void Standalone::createTab_Debug(wxNotebook* parent)
1025 wxPanel* panel = new wxPanel( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
1027 wxBoxSizer* bSizer = new wxBoxSizer( wxVERTICAL );
1029 wxBoxSizer* hbSizer = new wxBoxSizer( wxHORIZONTAL );
1031 wxStaticText* m_staticText1 = new wxStaticText( panel, wxID_ANY, wxT("Standalone State :"), wxDefaultPosition, wxDefaultSize, 0 );
1032 hbSizer->Add( m_staticText1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1034 wxPanel* p1 = new wxPanel( panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER );
1036 wxBoxSizer* p1Sizer = new wxBoxSizer( wxHORIZONTAL );
1038 m_D_State = new wxStaticText( p1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
1039 p1Sizer->Add( m_D_State, 1, wxALL|wxEXPAND, 2);
1041 p1->SetSizer( p1Sizer );
1044 hbSizer->Add( p1, 1, wxALL|wxEXPAND, 5 );
1046 bSizer->Add( hbSizer, 0, wxALL|wxEXPAND, 5 );
1048 panel->SetSizer( bSizer );
1051 bSizer->Fit( panel );
1053 parent->AddPage( panel, wxT("Debug") );
1056 bool Standalone::startFreeSpace(int argc, wxCmdLineArgsArray &argv)
1058 wxString epath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(true);
1061 epath.Append( wxT("freespace") );
1063 epath.Append( wxT("freespace2") );
1067 epath.Append( wxT("_demo") );
1071 epath.Append( wxT(".exe") );
1074 epath.Append( wxT(" -standalone") );
1076 for (int i = 1; i < argc; i++) {
1077 wxString arg( argv[i] );
1079 // check if -port argument and set var
1080 if ( arg.IsSameAs( wxT("-port"), false) && (argc > i+1) ) {
1081 fsport = wxAtoi(argv[i+1]);
1084 epath.Append( wxT(" ") );
1088 fspid = wxExecute(epath, wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER | wxEXEC_HIDE_CONSOLE);
1093 void Standalone::ResetAll()
1095 m_popup->Show(false);
1097 m_S_ServerName->Clear();
1098 m_S_HostPass->Clear();
1099 m_S_NumConn->SetLabel( wxT("0") );
1100 m_S_Connections->Clear();
1102 m_M_sliderFPS->SetValue(30);
1103 m_M_FPS->SetLabel("30");
1104 m_M_FPSRel->SetLabel( wxT("0.0") );
1105 m_M_MissionName->SetLabel("");
1106 m_M_MissionTime->SetLabel("");
1107 m_M_ngMaxPlayers->SetLabel("");
1108 m_M_ngMaxObservers->SetLabel("");
1109 m_M_ngSecurity->SetLabel("");
1110 m_M_ngRespawns->SetLabel("");
1111 m_M_Goals->DeleteAllItems();
1113 m_P_Players->Clear();
1114 m_P_ShipType->SetLabel("");
1115 m_P_AvgPing->SetLabel("");
1116 m_P_atsPriShots->SetLabel("");
1117 m_P_atsPriHits->SetLabel("");
1118 m_P_atsPriBHHits->SetLabel("");
1119 m_P_atsPriHitPer->SetLabel("");
1120 m_P_atsPriBHHitPer->SetLabel("");
1121 m_P_atsSecShots->SetLabel("");
1122 m_P_atsSecHits->SetLabel("");
1123 m_P_atsSecBHHits->SetLabel("");
1124 m_P_atsSecHitPer->SetLabel("");
1125 m_P_atsSecBHHitPer->SetLabel("");
1126 m_P_atsAssists->SetLabel("");
1127 m_P_msPriShots->SetLabel("");
1128 m_P_msPriHits->SetLabel("");
1129 m_P_msPriBHHits->SetLabel("");
1130 m_P_msPriHitPer->SetLabel("");
1131 m_P_msPriBHHitPer->SetLabel("");
1132 m_P_msSecShots->SetLabel("");
1133 m_P_msSecHits->SetLabel("");
1134 m_P_msSecBHHits->SetLabel("");
1135 m_P_msSecHitPer->SetLabel("");
1136 m_P_msSecBHHitPer->SetLabel("");
1137 m_P_msAssists->SetLabel("");
1139 m_GS_Players->Clear();
1141 m_GS_Messages->Clear();
1143 m_D_State->SetLabel("");
1146 static int callback_standalone_client(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
1148 #define MAX_BUF_SIZE 1050
1149 unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_BUF_SIZE + LWS_SEND_BUFFER_POST_PADDING];
1150 unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
1155 case LWS_CALLBACK_CLIENT_ESTABLISHED:
1156 lwsl_notice("CLIENT_ESTABLISHED\n");
1157 lws_callback_on_writable(wsi);
1160 case LWS_CALLBACK_CLOSED:
1161 lwsl_notice("CLOSED\n");
1162 wxGetApp().Client().wsDisconnect();
1165 case LWS_CALLBACK_CLIENT_RECEIVE:
1166 lwsl_notice("CLIENT_RECEIVE => in: %s, len: %lu\n", in ? (char*)in : "nul", len);
1167 wxGetApp().Client().wsMessage( (const char *)in, len );
1170 case LWS_CALLBACK_CLIENT_WRITEABLE: {
1171 if ( !wxGetApp().Client().wsGetSendBuffer().empty() ) {
1172 std::string msg = wxGetApp().Client().wsGetSendBuffer().front();
1174 lwsl_notice("CLIENT_WRITEABLE => msg: %s\n", msg.c_str());
1175 size = wxStrlcpy((char *)p, msg.c_str(), MAX_BUF_SIZE);
1177 rval = lws_write(wsi, p, size, LWS_WRITE_TEXT);
1180 lwsl_err("ERROR sending buffer!\n");
1184 wxGetApp().Client().wsGetSendBuffer().pop_front();
1186 lws_callback_on_writable(wsi);
1187 } else lwsl_notice("CLIENT_WRITEABLE <empty>\n");
1193 case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
1194 lwsl_notice("CONNECTION_ERROR\n");
1195 wxGetApp().Client().wsDisconnect();
1205 static struct lws_protocols protocols[] = {
1208 callback_standalone_client,
1212 { NULL, NULL, 0, 0 }
1215 bool Standalone::wsInitialize()
1217 struct lws_context_creation_info info;
1219 memset(&info, 0, sizeof(info));
1220 memset(&ccinfo, 0, sizeof(ccinfo));
1222 info.port = CONTEXT_PORT_NO_LISTEN;
1223 info.protocols = protocols;
1227 stand_context = lws_create_context(&info);
1229 if (stand_context == NULL) {
1233 ccinfo.context = stand_context;
1234 ccinfo.address = "127.0.0.1";
1235 ccinfo.port = fsport;
1237 ccinfo.host = ccinfo.address;
1238 ccinfo.origin = ccinfo.address;
1239 ccinfo.ietf_version_or_minus_one = -1;
1240 ccinfo.protocol = protocols[0].name;
1242 // async call, actual connection to occur later
1243 wsi_standalone = lws_client_connect_via_info(&ccinfo);
1245 lws_service(stand_context, 0);
1250 void Standalone::wsDoFrame()
1252 if ( !stand_context ) {
1256 // if connection is lost attempt reconnect every 2 seconds
1257 if ( !wsi_standalone && !(++m_rate_limit % 60) ) {
1258 wsi_standalone = lws_client_connect_via_info(&ccinfo);
1262 lws_service(stand_context, 0);
1265 void Standalone::wsDisconnect()
1267 lwsl_notice("disconnect!\n");
1268 wsi_standalone = NULL;
1271 void Standalone::wsMessage(const char *msg, size_t len)
1273 if (msg == NULL || len < 5) {
1277 if ( !wxStrcmp(msg, "reset") ) {
1282 if ( !wxStrncmp(msg, "popup ", 6) ) {
1284 m_popup->Show(false);
1286 wxArrayString popmsg = wxSplit(msg+6, ';');
1288 m_popup->SetTitle( popmsg.Item(0) );
1289 m_popup->SetLabel1( popmsg.Item(1) );
1290 m_popup->SetLabel2( popmsg.Item(2) );
1292 m_popup->CenterOnParent();
1293 m_popup->Show(true);
1299 char mtype = msg[0];
1303 } else if (mtype == 'D') {
1304 m_D_State->SetLabel(msg+2);
1307 else if (mtype == 'S') {
1308 wxString cmd(msg+2, 4);
1310 if (cmd == "name") {
1311 m_S_ServerName->SetValue(msg+7);
1312 } else if (cmd == "pass") {
1313 m_S_HostPass->SetValue(msg+7);
1314 } else if (cmd == "conn") {
1315 wxArrayString conns = wxSplit(msg+7, ';');
1317 size_t n_conn = conns.size();
1319 // always ends up with empty entry at end
1325 m_S_NumConn->SetLabel( wxString::Format("%u", (unsigned int)n_conn) );
1327 m_S_Connections->Clear();
1329 for (size_t idx = 0; idx < n_conn; idx++) {
1330 wxArrayString m_conn = wxSplit(conns.Item(idx), ',');
1332 m_P_Players->Append( m_conn.Item(0) );
1333 m_GS_Players->Append( m_conn.Item(0) );
1335 if ( m_conn.Item(2).IsEmpty() ) {
1336 m_S_Connections->AppendText( m_conn.Item(1) );
1338 wxString con( m_conn.Item(1) );
1340 con.Append( m_conn.Item(2) );
1342 m_S_Connections->AppendText( con );
1345 } else if (cmd == "ping") {
1346 wxArrayString iplist = wxSplit(msg+7, ';');
1348 // always ends up with empty entry at end
1351 size_t n_addr = iplist.size();
1353 for (size_t idx = 0; idx < n_addr; idx++) {
1354 wxArrayString ip_ping = wxSplit(iplist.Item(idx), ',');
1356 wxString new_ping(ip_ping.Item(0));
1357 new_ping.Append(", ");
1358 new_ping.Append(ip_ping.Item(1));
1360 long from_pos = m_S_Connections->GetValue().find( ip_ping.Item(0) );
1361 long to_pos = m_S_Connections->GetValue().find_first_of("\n", from_pos);
1363 m_S_Connections->Replace(from_pos, to_pos, new_ping);
1368 else if (mtype == 'M') {
1369 wxString cmd(msg+2, 4);
1371 if (cmd == "name") {
1372 m_M_MissionName->SetLabel(msg+7);
1373 } else if (cmd == "time") {
1374 m_M_MissionTime->SetLabel(msg+7);
1375 } else if (cmd == "info") {
1376 wxArrayString ng_info = wxSplit(msg+7, ',');
1378 m_M_ngMaxPlayers->SetLabel( ng_info.Item(0) );
1379 m_M_ngMaxObservers->SetLabel( ng_info.Item(1) );
1380 m_M_ngSecurity->SetLabel( ng_info.Item(2) );
1381 m_M_ngRespawns->SetLabel( ng_info.Item(3) );
1382 } else if (cmd == "fps ") {
1383 m_M_FPSRel->SetLabel(msg+6);
1384 } else if (cmd == "goal") {
1389 else if (mtype == 'P') {
1390 wxString cmd(msg+2, 4);
1392 if (cmd == "info") {
1393 wxArrayString pinfo = wxSplit(msg+7, ';');
1394 wxArrayString stats;
1396 m_P_ShipType->SetLabel( pinfo.Item(0) );
1397 m_P_AvgPing->SetLabel( pinfo.Item(1) );
1399 stats = wxSplit(pinfo.Item(2), ',');
1401 m_P_atsPriShots->SetLabel( stats.Item(0) );
1402 m_P_atsPriHits->SetLabel( stats.Item(1) );
1403 m_P_atsPriBHHits->SetLabel( stats.Item(2) );
1404 m_P_atsPriHitPer->SetLabel( stats.Item(3) );
1405 m_P_atsPriBHHitPer->SetLabel( stats.Item(4) );
1406 m_P_atsSecShots->SetLabel( stats.Item(5) );
1407 m_P_atsSecHits->SetLabel( stats.Item(6) );
1408 m_P_atsSecBHHits->SetLabel( stats.Item(7) );
1409 m_P_atsSecHitPer->SetLabel( stats.Item(8) );
1410 m_P_atsSecBHHitPer->SetLabel( stats.Item(9) );
1411 m_P_atsAssists->SetLabel( stats.Item(10) );
1413 stats = wxSplit(pinfo.Item(3), ',');
1415 m_P_msPriShots->SetLabel( stats.Item(0) );
1416 m_P_msPriHits->SetLabel( stats.Item(1) );
1417 m_P_msPriBHHits->SetLabel( stats.Item(2) );
1418 m_P_msPriHitPer->SetLabel( stats.Item(3) );
1419 m_P_msPriBHHitPer->SetLabel( stats.Item(4) );
1420 m_P_msSecShots->SetLabel( stats.Item(5) );
1421 m_P_msSecHits->SetLabel( stats.Item(6) );
1422 m_P_msSecBHHits->SetLabel( stats.Item(7) );
1423 m_P_msSecHitPer->SetLabel( stats.Item(8) );
1424 m_P_msSecBHHitPer->SetLabel( stats.Item(9) );
1425 m_P_msAssists->SetLabel( stats.Item(10) );
1429 else if (mtype == 'G') {
1430 wxString cmd(msg+2, 4);
1432 if (cmd == "mesg") {
1433 m_GS_Messages->AppendText(msg+7);
1438 void Standalone::wsSend(std::string &msg)
1440 send_buf.push_back(msg);
1442 if (wsi_standalone) {
1443 lws_callback_on_writable(wsi_standalone);