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