1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Control packets contain all player input in the message queue */
19 
20 #ifndef INC_C4Control
21 #define INC_C4Control
22 
23 #include "control/C4PlayerInfo.h"
24 #include "gui/C4KeyboardInput.h"
25 #include "network/C4PacketBase.h"
26 #include "network/C4Client.h"
27 #include "object/C4Id.h"
28 #include "object/C4ObjectList.h"
29 
30 // *** control base classes
31 
32 class C4ControlPacket : public C4PacketBase
33 {
34 public:
35 	C4ControlPacket();
36 	~C4ControlPacket() override;
37 
38 protected:
39 	int32_t iByClient;
40 
41 public:
getByClient()42 	int32_t getByClient() const { return iByClient; }
43 	bool LocalControl() const;
HostControl()44 	bool HostControl() const { return iByClient == C4ClientIDHost; }
45 
46 	void SetByClient(int32_t iByClient);
47 
PreExecute()48 	virtual bool PreExecute() const { return true; }
49 	virtual void Execute() const = 0;
PreRec(C4Record * pRecord)50 	virtual void PreRec(C4Record *pRecord) { }
51 
52 	// allowed in lobby (without dynamic loaded)?
Lobby()53 	virtual bool Lobby() const { return false; }
54 	// allowed as direct/private control?
Sync()55 	virtual bool Sync() const { return true; }
56 
57 	void CompileFunc(StdCompiler *pComp) override;
58 };
59 
60 #define DECLARE_C4CONTROL_VIRTUALS \
61   void Execute() const override; \
62   void CompileFunc(StdCompiler *pComp) override;
63 
64 class C4Control : public C4PacketBase
65 {
66 public:
67 	C4Control();
68 	~C4Control() override;
69 
70 protected:
71 	C4PacketList Pkts;
72 
73 public:
74 
75 	void Clear();
76 
77 	// packet list wrappers
firstPkt()78 	C4IDPacket *firstPkt() const { return Pkts.firstPkt(); }
nextPkt(C4IDPacket * pPkt)79 	C4IDPacket *nextPkt(C4IDPacket *pPkt) const { return Pkts.nextPkt(pPkt); }
80 
AddHead(C4PacketType eType,C4ControlPacket * pCtrl)81 	void AddHead(C4PacketType eType, C4ControlPacket *pCtrl) { Pkts.AddHead(eType, pCtrl); }
Add(C4PacketType eType,C4ControlPacket * pCtrl)82 	void Add(C4PacketType eType, C4ControlPacket *pCtrl)  { Pkts.Add(eType, pCtrl); }
83 
Take(C4Control & Ctrl)84 	void Take(C4Control &Ctrl) { Pkts.Take(Ctrl.Pkts); }
Append(const C4Control & Ctrl)85 	void Append(const C4Control &Ctrl) { Pkts.Append(Ctrl.Pkts); }
Copy(const C4Control & Ctrl)86 	void Copy(const C4Control &Ctrl) { Clear(); Pkts.Append(Ctrl.Pkts); }
Remove(C4IDPacket * pPkt)87 	void Remove(C4IDPacket *pPkt) { Pkts.Remove(pPkt); }
Delete(C4IDPacket * pPkt)88 	void Delete(C4IDPacket *pPkt) { Pkts.Delete(pPkt); }
89 
90 	// control execution
91 	bool PreExecute() const;
92 	void Execute() const;
93 	void PreRec(C4Record *pRecord) const;
94 
95 	void CompileFunc(StdCompiler *pComp) override;
96 };
97 
98 // *** control packets
99 
100 enum C4CtrlValueType
101 {
102 	C4CVT_None = -1,
103 	C4CVT_ControlRate = 0,
104 	C4CVT_DisableDebug = 1,
105 	C4CVT_MaxPlayer = 2,
106 	C4CVT_TeamDistribution = 3,
107 	C4CVT_TeamColors = 4,
108 };
109 
110 class C4ControlSet : public C4ControlPacket // sync, lobby
111 {
112 public:
113 	C4ControlSet() = default;
C4ControlSet(C4CtrlValueType eValType,int32_t iData)114 	C4ControlSet(C4CtrlValueType eValType, int32_t iData)
115 			: eValType(eValType), iData(iData)
116 	{ }
117 protected:
118 	C4CtrlValueType eValType{C4CVT_None};
119 	int32_t iData{0};
120 public:
121 	// C4CVT_TeamDistribution and C4CVT_TeamColors are lobby-packets
Lobby()122 	bool Lobby() const override { return eValType == C4CVT_TeamDistribution || eValType == C4CVT_TeamColors; }
123 
124 	DECLARE_C4CONTROL_VIRTUALS
125 };
126 
127 class C4ControlScript : public C4ControlPacket // sync
128 {
129 public:
130 	enum { SCOPE_Console=-2, SCOPE_Global=-1 }; // special scopes to be passed as target objects
131 
132 	C4ControlScript() = default;
133 	C4ControlScript(const char *szScript, int32_t iTargetObj, bool fUseVarsFromCallerContext = false, bool editor_select_result = false)
iTargetObj(iTargetObj)134 			: iTargetObj(iTargetObj), fUseVarsFromCallerContext(fUseVarsFromCallerContext), Script(szScript, true), editor_select_result(editor_select_result)
135 	{ }
136 protected:
137 	int32_t iTargetObj{-1};
138 	bool fUseVarsFromCallerContext{false};
139 	bool editor_select_result; // if true and executed script from local client in editor mode, select the object returned by this script
140 	StdStrBuf Script;
141 public:
SetTargetObj(int32_t iObj)142 	void SetTargetObj(int32_t iObj) { iTargetObj = iObj; }
143 	DECLARE_C4CONTROL_VIRTUALS
144 };
145 
146 class C4ControlMsgBoardReply : public C4ControlPacket // sync
147 {
148 public:
C4ControlMsgBoardReply()149 	C4ControlMsgBoardReply()
150 		: player(NO_OWNER)
151 	{}
C4ControlMsgBoardReply(const char * reply,int32_t target,int32_t player)152 	C4ControlMsgBoardReply(const char *reply, int32_t target, int32_t player)
153 		: reply(reply), target(target), player(player)
154 	{}
155 
156 private:
157 	StdCopyStrBuf reply;
158 	int32_t target{-1};
159 	int32_t player;
160 
161 public:
162 	DECLARE_C4CONTROL_VIRTUALS
163 };
164 
165 class C4ControlMsgBoardCmd : public C4ControlPacket // sync
166 {
167 public:
C4ControlMsgBoardCmd()168 	C4ControlMsgBoardCmd()
169 		: player(NO_OWNER)
170 	{}
C4ControlMsgBoardCmd(const char * command,const char * parameter,int32_t player)171 	C4ControlMsgBoardCmd(const char *command, const char *parameter, int32_t player)
172 		: command(command), parameter(parameter), player(player)
173 	{}
174 
175 private:
176 	StdCopyStrBuf command;
177 	StdCopyStrBuf parameter;
178 	int32_t player;
179 
180 public:
181 	DECLARE_C4CONTROL_VIRTUALS
182 };
183 
184 class C4ControlPlayerSelect : public C4ControlPacket // sync
185 {
186 public:
187 	C4ControlPlayerSelect() = default;
188 	C4ControlPlayerSelect(int32_t iPlr, const C4ObjectList &Objs, bool fIsAlt);
~C4ControlPlayerSelect()189 	~C4ControlPlayerSelect() override { delete[] pObjNrs; }
190 protected:
191 	int32_t iPlr{-1};
192 	bool fIsAlt{false};
193 	int32_t iObjCnt{0};
194 	int32_t *pObjNrs{nullptr};
195 public:
196 	DECLARE_C4CONTROL_VIRTUALS
197 };
198 
199 class C4ControlPlayerControl : public C4ControlPacket // sync
200 {
201 public:
202 	C4ControlPlayerControl() = default;
C4ControlPlayerControl(int32_t iPlr,C4PlayerControl::ControlState state,const C4KeyEventData & rExtraData)203 	C4ControlPlayerControl(int32_t iPlr, C4PlayerControl::ControlState state, const C4KeyEventData &rExtraData)
204 			: iPlr(iPlr), state(state), ExtraData(rExtraData) { }
C4ControlPlayerControl(int32_t iPlr,int32_t iControl,int32_t iExtraData)205 	C4ControlPlayerControl(int32_t iPlr, int32_t iControl, int32_t iExtraData) // old-style menu com emulation
206 			: iPlr(iPlr), state(C4PlayerControl::CONS_Down), ExtraData(iExtraData,0,0,0,0) { AddControl(iControl,0); }
207 
208 	struct ControlItem
209 	{
210 		int32_t iControl{-1};
211 		int32_t iTriggerMode{0};
212 		ControlItem() = default;
ControlItemControlItem213 		ControlItem(int32_t iControl, int32_t iTriggerMode) : iControl(iControl), iTriggerMode(iTriggerMode) {}
214 		void CompileFunc(StdCompiler *pComp);
215 		bool operator ==(const struct ControlItem &cmp) const { return iControl==cmp.iControl && iTriggerMode == cmp.iTriggerMode; }
216 	};
217 	typedef std::vector<ControlItem> ControlItemVec;
218 protected:
219 	int32_t iPlr{-1};
220 	int32_t state{C4PlayerControl::CONS_Down};
221 	C4KeyEventData ExtraData;
222 	ControlItemVec ControlItems;
223 public:
224 	DECLARE_C4CONTROL_VIRTUALS
AddControl(int32_t iControl,int32_t iTriggerMode)225 	void AddControl(int32_t iControl, int32_t iTriggerMode)
226 	{ ControlItems.emplace_back(iControl, iTriggerMode); }
GetControlItems()227 	const ControlItemVec &GetControlItems() const { return ControlItems; }
GetState()228 	C4PlayerControl::ControlState GetState() const { return static_cast<C4PlayerControl::ControlState>(state); }
GetExtraData()229 	const C4KeyEventData &GetExtraData() const { return ExtraData; }
SetExtraData(const C4KeyEventData & new_extra_data)230 	void SetExtraData(const C4KeyEventData &new_extra_data) { ExtraData = new_extra_data; }
231 };
232 
233 class C4ControlPlayerMouse : public C4ControlPacket // sync
234 {
235 public:
236 	enum Action
237 	{
238 		CPM_NoAction = 0,
239 
240 		CPM_Hover = 0x01,
241 		CPM_Drop = 0x02
242 	};
243 
C4ControlPlayerMouse()244 	C4ControlPlayerMouse() : player(NO_OWNER) {}
245 	static C4ControlPlayerMouse *Hover(const C4Player *player, const C4Object *target, const C4Object *old_target, const C4Object *drag = nullptr);
246 	static C4ControlPlayerMouse *DragDrop(const C4Player *player, const C4Object *target, const C4Object *drag);
247 
248 private:
249 	int32_t action{CPM_NoAction};
250 	int32_t player;
251 	int32_t target_obj{0};
252 	int32_t drag_obj{0};
253 	int32_t old_obj{0};
254 public:
255 	DECLARE_C4CONTROL_VIRTUALS
256 };
257 
258 class C4ControlMenuCommand : public C4ControlPacket // sync
259 {
260 public:
261 	C4ControlMenuCommand() = default;
262 	C4ControlMenuCommand(int32_t actionID, int32_t player, int32_t menuID, int32_t subwindowID,
263 	                       C4Object *target, int32_t actionType);
264 protected:
265 	int32_t actionID, player, menuID{0}, subwindowID{0}, target, actionType;
266 public:
267 	DECLARE_C4CONTROL_VIRTUALS
268 };
269 
270 class C4ControlPlayerAction : public C4ControlPacket // sync
271 {
272 public:
273 	enum Action
274 	{
275 		CPA_NoAction = 0,
276 
277 		CPA_Surrender = 0x01,
278 		CPA_ActivateGoal = 0x02,
279 		CPA_ActivateGoalMenu = 0x03,
280 		CPA_Eliminate = 0x04,
281 
282 		CPA_SetHostility = 0x10,
283 		CPA_SetTeam = 0x11,
284 
285 		CPA_InitScenarioPlayer = 0x20,
286 		CPA_InitPlayerControl = 0x21
287 	};
288 
289 	C4ControlPlayerAction(const C4Player *source = nullptr);
290 	static C4ControlPlayerAction *Surrender(const C4Player *source);
291 	static C4ControlPlayerAction *Eliminate(const C4Player *source);
292 	static C4ControlPlayerAction *ActivateGoalMenu(const C4Player *source);
293 	static C4ControlPlayerAction *ActivateGoal(const C4Player *source, const C4Object *target);
294 	static C4ControlPlayerAction *SetHostility(const C4Player *source, const C4Player *target, bool hostile);
295 	static C4ControlPlayerAction *SetTeam(const C4Player *source, int32_t team);
296 	static C4ControlPlayerAction *InitScenarioPlayer(const C4Player *source, int32_t team);
297 	static C4ControlPlayerAction *InitPlayerControl(const C4Player *source, const C4PlayerControlAssignmentSet *ctrl_set = nullptr);
298 
299 private:
300 	Action action{CPA_NoAction};
301 	int32_t source;
302 	int32_t target;
303 	int32_t param_int{0};
304 	StdCopyStrBuf param_str;
305 
306 	enum IpcParam
307 	{
308 		CPA_IPC_HasKeyboard = 1<<0,
309 		CPA_IPC_HasMouse = 1<<1,
310 		CPA_IPC_HasGamepad = 1<<2
311 	};
312 
313 public:
314 	DECLARE_C4CONTROL_VIRTUALS
315 };
316 
317 class C4ControlSyncCheck : public C4ControlPacket // not sync
318 {
319 public:
320 	C4ControlSyncCheck();
321 protected:
322 	int32_t Frame;
323 	int32_t ControlTick;
324 	int32_t RandomCount;
325 	int32_t AllCrewPosX;
326 	int32_t PXSCount;
327 	int32_t MassMoverIndex;
328 	int32_t ObjectCount;
329 	int32_t ObjectEnumerationIndex;
330 	int32_t SectShapeSum;
331 public:
332 	void Set();
getFrame()333 	int32_t getFrame() const { return Frame; }
Sync()334 	bool Sync() const override { return false; }
335 	DECLARE_C4CONTROL_VIRTUALS
336 protected:
337 	static int32_t GetAllCrewPosX();
338 };
339 
340 class C4ControlSynchronize : public C4ControlPacket // sync
341 {
342 public:
343 	C4ControlSynchronize(bool fSavePlrFiles = false, bool fSyncClearance = false)
fSavePlrFiles(fSavePlrFiles)344 			: fSavePlrFiles(fSavePlrFiles), fSyncClearance(fSyncClearance)
345 	{ }
346 protected:
347 	bool fSavePlrFiles, fSyncClearance;
348 public:
349 	DECLARE_C4CONTROL_VIRTUALS
350 };
351 
352 class C4ControlClientJoin : public C4ControlPacket // not sync, lobby
353 {
354 public:
355 	C4ControlClientJoin() = default;
C4ControlClientJoin(const C4ClientCore & Core)356 	C4ControlClientJoin(const C4ClientCore &Core) : Core(Core) { }
357 public:
358 	C4ClientCore Core;
359 public:
Sync()360 	bool Sync() const override { return false; }
Lobby()361 	bool Lobby() const override { return true; }
362 	DECLARE_C4CONTROL_VIRTUALS
363 };
364 
365 enum C4ControlClientUpdType
366 {
367 	CUT_None = -1, CUT_Activate = 0, CUT_SetObserver = 1, CUT_SetReady = 2
368 };
369 
370 class C4ControlClientUpdate : public C4ControlPacket // sync, lobby
371 {
372 public:
373 	C4ControlClientUpdate() = default;
374 	C4ControlClientUpdate(int32_t iID, C4ControlClientUpdType eType, int32_t iData = 0)
iID(iID)375 			: iID(iID), eType(eType), iData(iData)
376 	{ }
377 private:
378 	static const int32_t MinReadyAnnouncementDelay = 1; // seconds that need to pass between ready-state announcements to prevent spam
379 public:
380 	int32_t iID{0};
381 	C4ControlClientUpdType eType{CUT_None};
382 	int32_t iData{0};
383 public:
Sync()384 	bool Sync() const override { return false; }
Lobby()385 	bool Lobby() const override { return true; }
386 	DECLARE_C4CONTROL_VIRTUALS
387 };
388 
389 class C4ControlClientRemove : public C4ControlPacket // not sync, lobby
390 {
391 public:
392 	C4ControlClientRemove() = default;
iID(iID)393 	C4ControlClientRemove(int32_t iID, const char *szReason = "") : iID(iID), strReason(szReason) { }
394 public:
395 	int32_t iID;
396 	StdCopyStrBuf strReason;
397 public:
Sync()398 	bool Sync() const override { return false; }
Lobby()399 	bool Lobby() const override { return true; }
400 	DECLARE_C4CONTROL_VIRTUALS
401 };
402 
403 // control used for initial player info, as well as for player info updates
404 class C4ControlPlayerInfo : public C4ControlPacket // not sync, lobby
405 {
406 public:
407 	C4ControlPlayerInfo() = default;
C4ControlPlayerInfo(const C4ClientPlayerInfos & PlrInfo)408 	C4ControlPlayerInfo(const C4ClientPlayerInfos &PlrInfo)
409 			: PlrInfo(PlrInfo)
410 	{ }
411 protected:
412 	C4ClientPlayerInfos PlrInfo;
413 public:
GetInfo()414 	const C4ClientPlayerInfos &GetInfo() const { return PlrInfo; }
Sync()415 	bool Sync() const override { return false; }
Lobby()416 	bool Lobby() const override { return true; }
417 	DECLARE_C4CONTROL_VIRTUALS
418 };
419 
420 struct C4ControlJoinPlayer : public C4ControlPacket // sync
421 {
422 public:
423 	C4ControlJoinPlayer() = default;
424 	C4ControlJoinPlayer(const char *szFilename, int32_t iAtClient, int32_t iIDInfo, C4Network2ResCore ResCore);
425 	C4ControlJoinPlayer(const char *szFilename, int32_t iAtClient, int32_t iIDInfo);
426 protected:
427 	StdStrBuf Filename;
428 	int32_t iAtClient{-1};
429 	int32_t idInfo{-1};
430 	bool fByRes{false};
431 	StdBuf PlrData;               // for fByRes == false
432 	C4Network2ResCore ResCore;    // for fByRes == true
433 public:
434 	DECLARE_C4CONTROL_VIRTUALS
435 	bool PreExecute() const override;
436 	void PreRec(C4Record *pRecord) override;
437 	void Strip();
438 };
439 
440 enum C4ControlEMObjectAction
441 {
442 	EMMO_Move,      // move objects by offset
443 	EMMO_MoveForced,// move objects by offset and ignore HorizontalFixed
444 	EMMO_Enter,     // enter objects into iTargetObj
445 	EMMO_Duplicate, // duplicate objects at same position; reset EditCursor
446 	EMMO_Script,    // execute Script
447 	EMMO_Remove,    // remove objects
448 	EMMO_Exit,      // exit objects
449 	EMMO_Create,    // create a new object (used by C4Game::DropDef)
450 	EMMO_Transform  // adjust rotation / con of selected object
451 };
452 
453 class C4ControlEMMoveObject : public C4ControlPacket // sync
454 {
455 public:
C4ControlEMMoveObject()456 	C4ControlEMMoveObject() : tx(Fix0), ty(Fix0) { }
457 	C4ControlEMMoveObject(C4ControlEMObjectAction eAction, C4Real tx, C4Real ty, C4Object *pTargetObj,
458 	                      int32_t iObjectNum = 0, int32_t *pObjects = nullptr, const char *szScript = nullptr, bool drag_finished = false);
459 	static C4ControlEMMoveObject *CreateObject(const C4ID &id, C4Real x, C4Real y, C4Object *container);
460 	~C4ControlEMMoveObject() override;
461 protected:
462 	C4ControlEMObjectAction eAction{EMMO_Move}; // action to be performed
463 	C4Real tx,ty;        // target position
464 	int32_t iTargetObj{0};   // enumerated ptr to target object
465 	int32_t iObjectNum{0};   // number of objects moved
466 	int32_t *pObjects{nullptr};    // pointer on array of objects moved
467 	StdStrBuf StringParam; // script to execute, or ID of object to create
468 	bool drag_finished{false};    // Movement only: Set when mouse drag operation concluded (i.e. mouse up)
469 private:
470 	void MoveObject(C4Object *moved_object, bool move_forced) const;
471 public:
472 	DECLARE_C4CONTROL_VIRTUALS
473 };
474 
475 enum C4ControlEMDrawAction
476 {
477 	EMDT_SetMode,     // set new landscape mode
478 	EMDT_Brush,       // drawing tool
479 	EMDT_Fill,        // drawing tool
480 	EMDT_Line,        // drawing tool
481 	EMDT_Rect       // drawing tool
482 };
483 
484 enum class LandscapeMode;
485 class C4ControlEMDrawTool : public C4ControlPacket // sync
486 {
487 public:
488 	C4ControlEMDrawTool() = default;
489 	C4ControlEMDrawTool(C4ControlEMDrawAction eAction, LandscapeMode iMode,
490 	                    int32_t iX=-1, int32_t iY=-1, int32_t iX2=-1, int32_t iY2=-1, int32_t iGrade=-1,
491 	                    const char *szMaterial=nullptr, const char *szTexture=nullptr,
492 	                    const char *szBackMaterial=nullptr, const char *szBackTexture=nullptr);
493 protected:
494 	C4ControlEMDrawAction eAction{EMDT_SetMode};  // action to be performed
495 	LandscapeMode iMode;        // new mode, or mode action was performed in (action will fail if changed)
496 	int32_t iX{0},iY{0},iX2{0},iY2{0},iGrade{0}; // drawing parameters
497 	StdStrBuf Material; // used material
498 	StdStrBuf Texture;  // used texture
499 	StdStrBuf BackMaterial; // used background material
500 	StdStrBuf BackTexture;  // used background texture
501 public:
502 	DECLARE_C4CONTROL_VIRTUALS
503 };
504 
505 enum C4ControlMessageType
506 {
507 	C4CMT_Normal    = 0,
508 	C4CMT_Me        = 1,
509 	C4CMT_Say       = 2,
510 	C4CMT_Team      = 3,
511 	C4CMT_Private   = 4,
512 	C4CMT_Sound     = 5, // "message" is played as a sound instead
513 	C4CMT_Alert     = 6, // no message. just flash taskbar for inactive clients.
514 	C4CMT_System    = 10
515 };
516 
517 class C4ControlMessage : public C4ControlPacket // not sync, lobby
518 {
519 public:
520 	C4ControlMessage() = default;
521 	C4ControlMessage(C4ControlMessageType eType, const char *szMessage, int32_t iPlayer = -1, int32_t iToPlayer = -1)
eType(eType)522 			: eType(eType), iPlayer(iPlayer), iToPlayer(iToPlayer), Message(szMessage, true)
523 	{ }
524 protected:
525 	C4ControlMessageType eType{C4CMT_Normal};
526 	int32_t iPlayer{-1}, iToPlayer;
527 	StdStrBuf Message;
528 public:
Sync()529 	bool Sync() const override { return false; }
Lobby()530 	bool Lobby() const override { return true; }
531 	DECLARE_C4CONTROL_VIRTUALS
532 };
533 
534 class C4ControlRemovePlr : public C4ControlPacket // sync
535 {
536 public:
537 	C4ControlRemovePlr() = default;
C4ControlRemovePlr(int32_t iPlr,bool fDisconnected)538 	C4ControlRemovePlr(int32_t iPlr, bool fDisconnected)
539 			: iPlr(iPlr), fDisconnected(fDisconnected) { }
540 protected:
541 	int32_t iPlr{-1};
542 	bool fDisconnected{false};
543 public:
544 	DECLARE_C4CONTROL_VIRTUALS
545 };
546 
547 class C4ControlDebugRec : public C4ControlPacket // sync
548 {
549 public:
550 	C4ControlDebugRec() = default;
C4ControlDebugRec(StdBuf & Data)551 	C4ControlDebugRec(StdBuf &Data)
552 			: Data(Data) { }
553 protected:
554 	StdBuf Data;
555 public:
556 	DECLARE_C4CONTROL_VIRTUALS
557 };
558 
559 enum C4ControlVoteType
560 {
561 	VT_None = -1,
562 	VT_Cancel,
563 	VT_Kick,
564 	VT_Pause
565 };
566 
567 class C4ControlVote : public C4ControlPacket
568 {
569 public:
570 	C4ControlVote(C4ControlVoteType eType = VT_None, bool fApprove = true, int iData = 0)
eType(eType)571 			: eType(eType), fApprove(fApprove), iData(iData)
572 	{ }
573 
574 private:
575 	C4ControlVoteType eType;
576 	bool fApprove;
577 	int32_t iData;
578 
579 public:
getType()580 	C4ControlVoteType getType() const { return eType; }
isApprove()581 	bool isApprove() const { return fApprove; }
getData()582 	int32_t getData() const { return iData; }
583 
584 	StdStrBuf getDesc() const;
585 	StdStrBuf getDescWarning() const;
586 
Sync()587 	bool Sync() const override { return false; }
588 
589 	DECLARE_C4CONTROL_VIRTUALS
590 };
591 
592 class C4ControlVoteEnd : public C4ControlVote
593 {
594 public:
595 	C4ControlVoteEnd(C4ControlVoteType eType = VT_None, bool fApprove = true, int iData = 0)
C4ControlVote(eType,fApprove,iData)596 			: C4ControlVote(eType, fApprove, iData)
597 	{ }
598 
Sync()599 	bool Sync() const override { return true; }
600 
601 	DECLARE_C4CONTROL_VIRTUALS
602 };
603 
604 struct C4ControlReInitScenario : public C4ControlPacket // sync
605 {
606 public:
607 	C4ControlReInitScenario();
608 protected:
609 	StdBuf data;
610 public:
611 	DECLARE_C4CONTROL_VIRTUALS
612 };
613 
614 class C4ControlEditGraph : public C4ControlPacket // sync
615 {
616 public:
617 	enum Action
618 	{
619 		CEG_None=0,
620 		CEG_SetVertexPos,
621 		CEG_EditEdge,
622 		CEG_InsertVertex,
623 		CEG_InsertEdge,
624 		CEG_RemoveVertex,
625 		CEG_RemoveEdge
626 	};
627 	C4ControlEditGraph() = default;
C4ControlEditGraph(const char * path,Action action,int32_t index,int32_t x,int32_t y)628 	C4ControlEditGraph(const char *path, Action action, int32_t index, int32_t x, int32_t y)
629 		: path(path), action(action), index(index), x(x), y(y) { }
630 private:
631 	StdCopyStrBuf path;
632 	Action action=CEG_None;
633 	int32_t index=-1, x=0, y=0;
634 public:
635 	DECLARE_C4CONTROL_VIRTUALS
636 
GetPath()637 	const char *GetPath() const { return path.getData(); }
GetAction()638 	Action GetAction() const { return action; }
GetIndex()639 	int32_t GetIndex() const { return index; }
GetX()640 	int32_t GetX() const { return x; }
GetY()641 	int32_t GetY() const { return y; }
642 };
643 
644 #endif
645