1 /* 2 * OpenClonk, http://www.openclonk.org 3 * 4 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/ 5 * Copyright (c) 2013-2016, The OpenClonk Team and contributors 6 * 7 * Distributed under the terms of the ISC license; see accompanying file 8 * "COPYING" for details. 9 * 10 * "Clonk" is a registered trademark of Matthes Bender, used with permission. 11 * See accompanying file "TRADEMARK" for details. 12 * 13 * To redistribute this file separately, substitute the full license texts 14 * for the above references. 15 */ 16 // the ingame-lobby 17 18 #ifndef INC_C4GameLobby 19 #define INC_C4GameLobby 20 21 #include "gui/C4Gui.h" 22 #include "network/C4PacketBase.h" 23 24 namespace C4GameLobby 25 { 26 // countdown time from which the elevator sound starts and team selection becomes unavailable 27 const int32_t AlmostStartCountdownTime = 10; // seconds 28 29 extern bool UserAbort; 30 31 // * PID_LobbyCountdown 32 // initiates or aborts countdown 33 class C4PacketCountdown : public C4PacketBase 34 { 35 private: 36 int32_t iCountdown{Abort}; // countdown timer, or zero for abort 37 public: 38 enum { Abort = -1 }; 39 C4PacketCountdown(int32_t iaCountdown)40 C4PacketCountdown(int32_t iaCountdown) : iCountdown(iaCountdown) { } // ctor 41 C4PacketCountdown() = default; // std ctor 42 IsAbort()43 bool IsAbort() const { return iCountdown == Abort; } GetCountdown()44 int32_t GetCountdown() const { return iCountdown; } 45 StdStrBuf GetCountdownMsg(bool fInitialMsg=false) const; 46 47 void CompileFunc(StdCompiler *pComp) override; 48 }; 49 50 class C4PacketSetScenarioParameter : public C4PacketBase 51 { 52 private: 53 StdCopyStrBuf ID; 54 int32_t Value{0}; 55 public: C4PacketSetScenarioParameter(const char * id,int32_t v)56 C4PacketSetScenarioParameter(const char *id, int32_t v) : ID(id), Value(v) {} // ctor 57 C4PacketSetScenarioParameter() = default; // std ctor 58 GetID()59 const char *GetID() const { return ID.getData(); } GetValue()60 int32_t GetValue() const { return Value; } 61 62 void CompileFunc(StdCompiler *pComp) override; 63 }; 64 65 // scneario info tab: displays scenario description 66 class ScenDesc : public C4GUI::Window, private C4ApplicationSec1Timer 67 { 68 private: 69 C4GUI::Label *pTitle; // scenario title or warning label if unloaded 70 C4GUI::TextWindow *pDescBox; // scenario description box 71 bool fDescFinished; // if set, scenario resource has been loaded 72 73 void Update(); 74 75 public: 76 ScenDesc(const C4Rect &rcBounds, bool fActive); // ctor ~ScenDesc()77 ~ScenDesc() override { Deactivate(); } 78 OnSec1Timer()79 void OnSec1Timer() override { Update(); } 80 // activate/deactivate periodic updates 81 void Activate(); 82 void Deactivate(); 83 }; 84 85 class MainDlg : public C4GUI::FullscreenDialog, private C4ApplicationSec1Timer 86 { 87 private: 88 time_t tLastPingUpdate; // time when pings were updated last time 89 enum CountdownState { CDS_None=0, CDS_LongCountdown=1, CDS_Countdown=2, CDS_Start=3 } eCountdownState; // nonzero when a packet was received that the game is about to start (starts elevator sound, etc.) 90 int32_t iBackBufferIndex; // chat message history index 91 C4KeyBinding *pKeyHistoryUp, *pKeyHistoryDown; // keys used to scroll through chat history 92 93 enum { SheetIdx_PlayerList = 0, SheetIdx_Res = 1, SheetIdx_Options = 2, SheetIdx_Scenario = 3 }; 94 C4PlayerInfoListBox *pPlayerList; 95 C4Network2ResDlg *pResList; 96 C4GameOptionButtons *pGameOptionButtons; 97 C4GameOptionsList *pOptionsList; 98 ScenDesc *pScenarioInfo; 99 C4GUI::TextWindow *pChatBox; 100 C4GUI::Label *pRightTabLbl; 101 C4GUI::Tabular *pRightTab; 102 C4GUI::Edit *pEdt; // chat input 103 C4GUI::CallbackButton<MainDlg> *btnRun; // host only 104 C4GUI::CallbackButton<MainDlg, C4GUI::IconButton> *btnPlayers, *btnResources, *btnTeams, *btnOptions, *btnScenario, *btnChat; // right list sheet selection 105 C4GUI::CheckBox *checkReady; 106 107 protected: 108 void OnReadyCheck(C4GUI::Element *pCheckBox); // callback: checkbox ticked 109 void OnRunBtn(C4GUI::Control *btn); // callback: run button pressed 110 void OnExitBtn(C4GUI::Control *btn); // callback: exit button pressed 111 bool KeyHistoryUpDown(bool fUp); // key callback 112 C4GUI::Edit::InputResult OnChatInput(C4GUI::Edit *edt, bool fPasting, bool fPastingMore); // callback: chat input performed 113 114 void OnClosed(bool fOK) override; // callback when dlg is closed 115 void OnSec1Timer() override; // timer proc; update pings 116 117 C4GUI::ContextMenu *OnRightTabContext(C4GUI::Element *pLabel, int32_t iX, int32_t iY); // open context menu OnCtxTabPlayers(C4GUI::Element * pListItem)118 void OnCtxTabPlayers(C4GUI::Element *pListItem) { OnTabPlayers(nullptr); } 119 void OnTabPlayers(C4GUI::Control *btn); OnCtxTabTeams(C4GUI::Element * pListItem)120 void OnCtxTabTeams(C4GUI::Element *pListItem) { OnTabTeams(nullptr); } 121 void OnTabTeams(C4GUI::Control *btn); OnCtxTabRes(C4GUI::Element * pListItem)122 void OnCtxTabRes(C4GUI::Element *pListItem) { OnTabRes(nullptr); } 123 void OnTabRes(C4GUI::Control *btn); OnCtxTabOptions(C4GUI::Element * pListItem)124 void OnCtxTabOptions(C4GUI::Element *pListItem) { OnTabOptions(nullptr); } 125 void OnTabOptions(C4GUI::Control *btn); OnCtxTabScenario(C4GUI::Element * pListItem)126 void OnCtxTabScenario(C4GUI::Element *pListItem) { OnTabScenario(nullptr); } 127 void OnTabScenario(C4GUI::Control *btn); 128 void UpdateRightTab(); // update label and tooltips for sheet change 129 void OnBtnChat(C4GUI::Control *btn); 130 GetDefaultControl()131 class C4GUI::Control *GetDefaultControl() override { return pEdt; } // def focus chat input 132 133 private: 134 void SetCountdownState(CountdownState eToState, int32_t iTimer); 135 int32_t ValidatedCountdownTime(int32_t iTimeout); // correct invalid timeout settings 136 137 void UpdatePlayerList(); 138 139 public: 140 MainDlg(bool fHost); // ctor 141 ~MainDlg() override; // dtor 142 143 // callback by network system 144 void OnClientJoin(C4Client *pNewClient); // called when a new client joined (connection not necessarily ready) 145 void OnClientConnect(C4Client *pClient, C4Network2IOConnection *pConn); // called when new clinet connection is established (notice of lobby status) 146 void OnClientPart(C4Client *pPartClient); // called when a client disconnects 147 bool OnMessage(C4Client *pOfClient, const char *szMessage); // display message in chat window 148 void OnClientSound(C4Client *pOfClient); // show that someone played a sound 149 void OnLog(const char *szLogMsg, DWORD dwClr=C4GUI_LogFontClr); // log callback 150 void OnError(const char *szErrMsg); // error sound + log in red OnPlayersChange()151 void OnPlayersChange() { UpdatePlayerList(); } OnClientReadyStateChange()152 void OnClientReadyStateChange() { UpdatePlayerList(); } 153 void OnClientAddPlayer(const char *szFilename, int32_t idClient); 154 // packet callbacks from C4Network2 155 void HandlePacket(char cStatus, const C4PacketBase *pBasePkt, C4Network2Client *pClient); 156 void OnCountdownPacket(const C4PacketCountdown &Pkt); // called when a countdown packet is received: Update countdown state 157 158 bool IsCountdown(); 159 void Start(int32_t iCountdownTime); // host only: Do game start with specified countdown time (forwards to network system) 160 void UpdatePassword(); 161 void ClearLog(); 162 }; 163 164 // helper 165 void LobbyError(const char *szErrorMsg); 166 167 // lobby countdown: Moves game from lobby to go state. Only created by host. 168 class Countdown : private C4ApplicationSec1Timer 169 { 170 private: 171 int32_t iStartTimer; // countdown timer for round start; 0 for not started, -1 for start overdue 172 173 public: 174 void OnSec1Timer() override; // timer proc; count down; send important countdown packets 175 176 public: 177 Countdown(int32_t iStartTimer); // ctor: Init; sends initial countdown packet 178 ~Countdown() override; 179 180 void Abort(); 181 }; 182 183 } 184 185 #endif 186