OpenClonk
C4League.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2006-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-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 
17 /* engine handler of league system */
18 
19 #include "C4Include.h"
20 #include "network/C4League.h"
21 
22 #include "control/C4RoundResults.h"
24 
25 // *** C4LeagueRequestHead
26 
28 {
29 
31  {
32  { "Start", C4LA_Start },
33  { "Update", C4LA_Update },
34  { "End", C4LA_End },
35  { "Join", C4LA_PlrAuthCheck },
36 
37  { "", C4LA_RefQuery },
38  { "Auth", C4LA_PlrAuth },
39 
40  { "ReportDisconnect", C4LA_ReportDisconnect },
41  };
42 
43  pComp->Value(mkNamingAdapt(mkEnumAdaptT<uint8_t>(eAction, Actions), "Action", C4LA_RefQuery));
46 
47  // Auth
48  pComp->Value(mkNamingAdapt(mkParAdapt(Account, StdCompiler::RCT_All), "Account", ""));
49  pComp->Value(mkNamingAdapt(mkParAdapt(Password, StdCompiler::RCT_All), "Password", ""));
50  pComp->Value(mkNamingAdapt(mkParAdapt(NewAccount, StdCompiler::RCT_All), "NewAccount", ""));
51  pComp->Value(mkNamingAdapt(mkParAdapt(NewPassword, StdCompiler::RCT_All), "NewPassword", ""));
52  pComp->Value(mkNamingAdapt(fRememberLogin, "RememberLogin", false));
53 
54 }
55 
56 void C4LeagueRequestHead::SetAuth(const char *szAccount, const char *szPassword, bool fRememberLogin)
57 {
58  Account = szAccount;
59  Password = szPassword;
60  this->fRememberLogin = fRememberLogin;
61 }
62 
63 void C4LeagueRequestHead::SetNewAccount(const char *szNewAccount)
64 {
65  NewAccount = szNewAccount;
66 }
67 
68 void C4LeagueRequestHead::SetNewPassword(const char *szNewPassword)
69 {
70  NewPassword = szNewPassword;
71 }
72 
73 // *** C4LeagueReportDisconnectHead
74 
76 {
77  // inherited fields
79  // reason
81  {
82  { "", C4LDR_Unknown },
83  { "ConnectionFailed", C4LDR_ConnectionFailed},
84  { "Desync", C4LDR_Desync },
85  };
86  pComp->Value(mkNamingAdapt(mkEnumAdaptT<uint8_t>(eReason, Reasons), "Reason", C4LDR_Unknown));
87 }
88 
89 // *** C4LeagueRequestHeadEnd
90 
92 {
94  pComp->Value(mkNamingAdapt(mkParAdapt(RecordName, StdCompiler::RCT_All), "RecordName", ""));
95  if (RecordName.getLength())
96  pComp->Value(mkNamingAdapt(mkHexAdapt(RecordSHA, sizeof(RecordSHA)), "RecordSHA"));
97 }
98 
99 // *** C4LeagueResponseHead
100 
102 {
103  pComp->Value(mkNamingAdapt(mkParAdapt(Status, StdCompiler::RCT_IdtfAllowEmpty), "Status", ""));
105  pComp->Value(mkNamingAdapt(mkParAdapt(Message, StdCompiler::RCT_All), "Message", ""));
106 
107  // Auth
108  pComp->Value(mkNamingAdapt(mkParAdapt(Account, StdCompiler::RCT_All), "Account", ""));
109  pComp->Value(mkNamingAdapt(mkParAdapt(AUID, StdCompiler::RCT_All), "AUID", ""));
110  pComp->Value(mkNamingAdapt(mkParAdapt(FBID, StdCompiler::RCT_All), "FBID", ""));
111  pComp->Value(mkNamingAdapt(mkParAdapt(LoginToken, StdCompiler::RCT_All), "LoginToken", ""));
112 }
113 
114 // *** C4LeagueResponseHeadStart
115 
117 {
118  // Base members
120 
121  // League name
122  pComp->Value(mkNamingAdapt(League, "League", ""));
123  pComp->Value(mkNamingAdapt(StreamingAddr, "StreamTo", ""));
124  pComp->Value(mkNamingCountAdapt(fHaveSeed, "Seed"));
125  if (fHaveSeed)
126  pComp->Value(mkNamingAdapt(iSeed, "Seed", (int32_t)0));
127  pComp->Value(mkNamingAdapt(iMaxPlayers, "MaxPlayers", (int32_t)0));
128 }
129 
130 // *** C4LeagueResponseHeadUpdate
131 
133 {
134  // Base members
136 
137  // League name
138  pComp->Value(mkNamingAdapt(League, "League", ""));
139 
140  // player infos
141  pComp->Value(mkNamingAdapt(PlrInfos, "PlayerInfos"));
142 }
143 
144 // *** C4LeagueRequestHeadAuthCheck
145 
146 int32_t C4LeagueResponseHeadAuthCheck::getScore(const char *szLeague) const
147 {
148  for (int32_t i = 0; i < C4NetMaxLeagues; i++)
149  if (Leagues[i] == szLeague)
150  return Scores[i];
151  return 0;
152 }
153 
154 int32_t C4LeagueResponseHeadAuthCheck::getRank(const char *szLeague) const
155 {
156  for (int32_t i = 0; i < C4NetMaxLeagues; i++)
157  if (Leagues[i] == szLeague)
158  return Ranks[i];
159  return 0;
160 }
161 
162 int32_t C4LeagueResponseHeadAuthCheck::getRankSymbol(const char *szLeague) const
163 {
164  for (int32_t i = 0; i < C4NetMaxLeagues; i++)
165  if (Leagues[i] == szLeague)
166  return RankSymbols[i];
167  return 0;
168 }
169 
170 const char *C4LeagueResponseHeadAuthCheck::getProgressData(const char *szLeague) const
171 {
172  // progress data is the same for all leagues
173  return ProgressData.getData();
174 }
175 
177 {
178  // Base members
180 
181  // Leagues, Scores, Ranks
182  pComp->Value(mkNamingAdapt(mkArrayAdapt(Leagues, C4NetMaxLeagues, ""), "League"));
183  pComp->Value(mkNamingAdapt(mkArrayAdapt(Scores, C4NetMaxLeagues, 0), "Score"));
184  pComp->Value(mkNamingAdapt(mkArrayAdapt(Ranks, C4NetMaxLeagues, 0), "Rank"));
185  pComp->Value(mkNamingAdapt(mkArrayAdapt(RankSymbols, C4NetMaxLeagues, 0), "RankSymbol"));
186 
187  // Progress data (per scenario; not per league)
188  pComp->Value(mkNamingAdapt(mkParAdapt(ProgressData, StdCompiler::RCT_All), "ProgressData", ""));
189 
190  // Clan tag
191  pComp->Value(mkNamingAdapt(mkParAdapt(ClanTag, StdCompiler::RCT_All), "ClanTag", ""));
192 
193 }
194 
195 // *** C4LeagueFBIDList
196 
198 {
199  while (pFirst)
200  {
201  FBIDItem *pDel = pFirst;
202  pFirst = pDel->pNext;
203  delete pDel;
204  }
205 }
206 
207 bool C4LeagueFBIDList::FindFBIDByAccount(const char *szAccount, StdStrBuf *pFBIDOut)
208 {
209  assert(szAccount);
210  if (!szAccount) return false;
211  for (FBIDItem *pItem = pFirst; pItem; pItem = pItem->pNext)
212  if (pItem->Account == szAccount)
213  {
214  if (pFBIDOut) pFBIDOut->Copy(pItem->FBID);
215  return true;
216  }
217  return false;
218 }
219 
220 void C4LeagueFBIDList::RemoveFBIDByAccount(const char *szAccount)
221 {
222  FBIDItem *pPrev = nullptr, *pItem = pFirst;
223  while (pItem)
224  {
225  // Delete?
226  if (pItem->Account == szAccount)
227  {
228  (pPrev ? pPrev->pNext : pFirst) = pItem->pNext;
229  delete pItem;
230  return;
231  }
232  // Next
233  pPrev = pItem; pItem = pItem->pNext;
234  }
235 }
236 
237 void C4LeagueFBIDList::AddFBID(const char *szFBID, const char *szAccount)
238 {
239  // add new FBID item to head of list
240  assert(szFBID); assert(szAccount);
241  // remove any existing FBIDs
242  RemoveFBIDByAccount(szAccount);
243  // add new entry
244  FBIDItem *pNewItem = new FBIDItem();
245  pNewItem->FBID.Copy(szFBID);
246  pNewItem->Account.Copy(szAccount);
247  pNewItem->pNext = pFirst;
248  pFirst = pNewItem;
249 }
250 
252 {
253 private:
254  C4LeagueFBIDList &rFBIDList;
255  const C4ClientPlayerInfos &rPlayerInfos;
256 
257 public:
258  DisconnectData(C4LeagueFBIDList &rFBIDList, const C4ClientPlayerInfos &rPlayerInfos)
259  : rFBIDList(rFBIDList), rPlayerInfos(rPlayerInfos) {}
260 
262  {
263  if (pComp->isDeserializer())
264  {
265  // compiling not yet needed
266  assert(!"DisconnectData::CompileFunc not defined for compiler!");
267  }
268  else
269  {
270  // decompiling: Compile all joined and not removed player infos.
271  // Compile them even if they're not in the FBID-List, but omit
272  // the FBID (used for host message)
273  int32_t i=0; C4PlayerInfo *pInfo;
274  while ((pInfo = rPlayerInfos.GetPlayerInfo(i++)))
275  if (pInfo->IsJoined() && !pInfo->IsRemoved())
276  {
277  pComp->Name("Player");
278  try
279  {
280  pComp->Value(mkNamingAdapt(mkDecompileAdapt(pInfo->GetID()), "ID"));
281  StdCopyStrBuf sFBID;
282  if (rFBIDList.FindFBIDByAccount(pInfo->getLeagueAccount(), &sFBID)) pComp->Value(mkNamingAdapt(mkParAdapt(sFBID, StdCompiler::RCT_IdtfAllowEmpty), "FBID"));
283  }
284  catch (StdCompiler::Exception *)
285  {
286  pComp->NameEnd();
287  throw;
288  }
289  pComp->NameEnd();
290  }
291  }
292  }
293 };
294 
295 
296 // *** C4LeagueClient
297 
299 {
300  // Create query
301  eCurrAction = C4LA_Start;
302  C4LeagueRequestHead Head(eCurrAction);
303  StdStrBuf QueryText = DecompileToBuf<StdCompilerINIWrite>(
305  mkNamingAdapt(Head, "Request"),
306  mkNamingAdapt(mkDecompileAdapt(Ref), "Reference"),
307  false));
308  // Perform query
309  return Query(QueryText.getData(), false);
310 }
311 
312 bool C4LeagueClient::GetStartReply(StdStrBuf *pMessage, StdStrBuf *pLeague, StdStrBuf *pStreamingAddr, int32_t *pSeed, int32_t *pMaxPlayers)
313 {
314  if (!isSuccess() || eCurrAction != C4LA_Start) return false;
315  // Parse response head
317  if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(mkNamingAdapt(Head, "Response"), ResultString, "Start Reply"))
318  return false;
319  // Get message, league and seed
320  if (pMessage)
321  pMessage->Copy(Head.getMessage());
322  if (pLeague)
323  pLeague->Copy(Head.getLeague());
324  if (pStreamingAddr)
325  pStreamingAddr->Copy(Head.getStreamingAddr());
326  if (pSeed && Head.haveSeed())
327  *pSeed = Head.getSeed();
328  if (pMaxPlayers)
329  *pMaxPlayers = Head.getMaxPlayers();
330  // No success?
331  if (!Head.isSuccess())
332  return false;
333  // Got no CSID or empty CSID?
334  if (!Head.getCSID() || !*Head.getCSID() || *Head.getCSID() == '\0')
335  {
336  if (pMessage)
337  pMessage->Copy(LoadResStr("IDS_LGA_INVALIDRESPONSE3"));
338  return false;
339  }
340  // So save back CSID
341  CSID = Head.getCSID();
342  return true;
343 }
344 
346 {
347  assert(CSID.getLength());
348  // Create query
349  eCurrAction = C4LA_Update;
350  C4LeagueRequestHead Head(eCurrAction, CSID.getData());
351  StdStrBuf QueryText = DecompileToBuf<StdCompilerINIWrite>(
353  mkNamingAdapt(Head, "Request"),
354  mkNamingAdapt(mkDecompileAdapt(Ref), "Reference"),
355  false));
356  // Perform query
357  return Query(QueryText.getData(), false);
358 }
359 
361 {
363  if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(mkNamingAdapt(Reply, "Response"), ResultString, "Update Reply"))
364  return false;
365  // Get message
366  if (pMessage)
367  pMessage->Copy(Reply.getMessage());
368  // get plr infos
369  if (pPlayerLeagueInfos)
370  *pPlayerLeagueInfos = Reply.GetPlrInfos();
371  // Success
372  return true;
373 }
374 
375 bool C4LeagueClient::End(const C4Network2Reference &Ref, const char *szRecordName, const BYTE *pRecordSHA)
376 {
377  assert(CSID.getLength());
378  // Create query
379  eCurrAction = C4LA_End;
380  C4LeagueRequestHeadEnd Head(eCurrAction, CSID.getData(), szRecordName, pRecordSHA);
381  StdStrBuf QueryText = DecompileToBuf<StdCompilerINIWrite>(
383  mkNamingAdapt(Head, "Request"),
384  mkNamingAdapt(mkDecompileAdapt(Ref), "Reference"),
385  false));
386  // Perform query
387  return Query(QueryText.getData(), false);
388 }
389 
391 {
392  // Parse response head
394  if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(mkNamingAdapt(Head, "Response"), ResultString, "End Reply"))
395  return false;
396  // Get message
397  if (pMessage)
398  pMessage->Copy(Head.getMessage());
399  if (pRoundResults)
400  CompileFromBuf_LogWarn<StdCompilerINIRead>(mkNamingAdapt(mkNamingAdapt(*pRoundResults, "PlayerInfos"), "Response"), ResultString, "Round Results");
401  // Done
402  return Head.isSuccess();
403 }
404 
405 bool C4LeagueClient::Auth(const C4PlayerInfo &PlrInfo, const char *szAccount, const char *szPassword, const char *szNewAccount, const char *szNewPassword, bool fRememberLogin)
406 {
407  // Build header
408  eCurrAction = C4LA_PlrAuth;
409  C4LeagueRequestHead Head(eCurrAction);
410  Head.SetAuth(szAccount, szPassword, fRememberLogin);
411  if (szNewAccount)
412  Head.SetNewAccount(szNewAccount);
413  if (szNewPassword)
414  Head.SetNewPassword(szNewPassword);
415  // Create query
416  StdStrBuf QueryText = DecompileToBuf<StdCompilerINIWrite>(
418  mkNamingAdapt(Head, "Request"),
419  mkNamingAdapt(mkDecompileAdapt(PlrInfo), "PlrInfo"),
420  false));
421  // Perform query
422  return Query(QueryText.getData(), false);
423 }
424 
425 bool C4LeagueClient::GetAuthReply(StdStrBuf *pMessage, StdStrBuf *pAUID, StdStrBuf *pAccount, bool *pRegister, StdStrBuf *pLoginToken)
426 {
428  if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(mkNamingAdapt(Head, "Response"), ResultString, "Auth Reply"))
429  return false;
430  // Get message & account
431  if (pMessage)
432  pMessage->Copy(Head.getMessage());
433  if (pAccount)
434  pAccount->Copy(Head.getAccount());
435  if (pRegister)
436  *pRegister = Head.isStatusRegister();
437  if (pLoginToken)
438  pLoginToken->Copy(Head.getLoginToken());
439  // No success?
440  if (!Head.isSuccess())
441  return false;
442  // Check AUID
443  if (!Head.getAUID() || !*Head.getAUID())
444  {
445  pMessage->Ref(LoadResStr("IDS_MSG_LEAGUESERVERREPLYWITHOUTA"));
446  return false;
447  }
448  // Success
449  if (pAUID)
450  pAUID->Copy(Head.getAUID());
451  FBIDList.AddFBID(Head.getFBID(), Head.getAccount());
452  return true;
453 }
454 
456 {
457  assert(CSID.getLength());
458  // Build header
459  eCurrAction = C4LA_PlrAuthCheck;
460  C4LeagueRequestHead Head(eCurrAction, CSID.getData(), PlrInfo.getAuthID());
461  // Create query
462  StdStrBuf QueryText = DecompileToBuf<StdCompilerINIWrite>(
464  mkNamingAdapt(Head, "Request"),
465  mkNamingAdapt(mkDecompileAdapt(PlrInfo), "PlrInfo"),
466  false));
467  // Perform query
468  return Query(QueryText.getData(), false);
469 }
470 
471 bool C4LeagueClient::GetAuthCheckReply(StdStrBuf *pMessage, const char *szLeague, C4PlayerInfo *pPlrInfo)
472 {
473  // Parse response head
475  if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(mkNamingAdapt(Head, "Response"), ResultString, "Auth Check Reply"))
476  return false;
477  // Get message and additional data
478  if (pMessage)
479  pMessage->Copy(Head.getMessage());
480  if (szLeague && pPlrInfo)
481  pPlrInfo->SetLeagueData(Head.getAccount(), Head.getClanTag(), Head.getScore(szLeague), Head.getRank(szLeague), Head.getRankSymbol(szLeague), Head.getProgressData(szLeague));
482  return Head.isSuccess();
483 }
484 
486 {
487  // Build header
488  eCurrAction = C4LA_ReportDisconnect;
489  C4LeagueReportDisconnectHead Head(CSID.getData(), eReason);
490  // Create query
491  StdStrBuf QueryText = DecompileToBuf<StdCompilerINIWrite>(
493  mkNamingAdapt(Head, "Request"),
494  mkNamingAdapt(DisconnectData(FBIDList, rFeedbackClient), "PlayerInfos"),
495  false));
496  // Perform query
497  return Query(QueryText.getData(), false);
498 }
499 
501 {
502  // Parse response head
504  if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(mkNamingAdapt(Head, "Response"), ResultString, "Report Disconnect"))
505  return false;
506  // Get message
507  if (pMessage)
508  pMessage->Copy(Head.getMessage());
509  // Done
510  return Head.isSuccess();
511 }
512 
513 // *** C4LeagueSignupDialog
514 
515 C4LeagueSignupDialog::C4LeagueSignupDialog(const char *szPlayerName, const char *szLeagueName, const char *szLeagueServerName, const char *szAccountPref, const char *szPassPref, bool fWarnThirdParty, bool fRegister, bool fRememberLogin)
516  : C4GUI::Dialog(C4GUI_MessageDlgWdt, 100 /* will be resized as needed */, FormatString(LoadResStr("IDS_DLG_LEAGUESIGNUPON"), szLeagueServerName).getData(), false), strPlayerName(szPlayerName), pChkRememberLogin(nullptr)
517 {
518  // get positions
520  // place icon
521  C4Rect rcIcon = caMain.GetFromLeft(C4GUI_IconWdt); rcIcon.Hgt = C4GUI_IconHgt;
522  C4GUI::Icon *pIcon = new C4GUI::Icon(rcIcon, C4GUI::Ico_Ex_League); AddElement(pIcon);
523  caMain.GetFromRight(C4GUI_IconWdt/2);
524  // place message label
525  // use text with line breaks
526  StdStrBuf sMsg, sMsgBroken;
527  if (fRegister)
528  sMsg.Format(LoadResStr("IDS_MSG_LEAGUE_REGISTRATION"), szPlayerName);
529  else
530  sMsg.Format(LoadResStr("IDS_MSG_PASSWORDFORPLAYER"), szPlayerName);
531  int32_t iLabelHgt = ::GraphicsResource.TextFont.BreakMessage(sMsg.getData(), caMain.GetInnerWidth(), &sMsgBroken, true);
532  C4GUI::Label *pLblMessage = new C4GUI::Label(sMsgBroken.getData(), caMain.GetFromTop(iLabelHgt), ALeft, C4GUI_MessageFontClr, &::GraphicsResource.TextFont);
533  AddElement(pLblMessage);
534  // registering and no account pref available
535  if (fRegister && (!szAccountPref || !szAccountPref[0]))
536  // use player name as default for league name
537  szAccountPref = szPlayerName;
538  // place username input box
539  bool fSideEdits=true; int iCtrlHeight;
540  StdStrBuf sAccountTxt; sAccountTxt.Copy(LoadResStr("IDS_CTL_LEAGUE_ACCOUNT"));
541  C4GUI::LabeledEdit::GetControlSize(nullptr, &iCtrlHeight, sAccountTxt.getData(), nullptr, fSideEdits);
542  AddElement(pEdtAccount = new C4GUI::LabeledEdit(caMain.GetFromTop(iCtrlHeight), sAccountTxt.getData(), fSideEdits, szAccountPref));
543  // registering? Make password field optional
544  if (fRegister)
545  {
546  // place the checkbox
547  const char *szChkPasswordCaption = LoadResStr("IDS_CTL_LEAGUE_CHK_PLRPW");
548  C4GUI::CheckBox::GetStandardCheckBoxSize(nullptr, &iCtrlHeight, szChkPasswordCaption, nullptr);
549  AddElement(pChkPassword = new C4GUI::CheckBox(caMain.GetFromTop(iCtrlHeight), szChkPasswordCaption, false));
550  pChkPassword->SetOnChecked(new C4GUI::CallbackHandlerNoPar<C4LeagueSignupDialog>(this, &C4LeagueSignupDialog::OnChkPassword));
551  pChkPassword->SetToolTip(LoadResStr("IDS_DESC_LEAGUECHECKPASSWORD"));
552  // place password edit boxes
553  C4GUI::ComponentAligner caTemp = caMain;
554  const char *szEdtPassCaption = LoadResStr("IDS_CTL_LEAGUE_PLRPW");
555  const char *szEdtPass2Caption = LoadResStr("IDS_CTL_LEAGUE_PLRPW2");
556  C4GUI::LabeledEdit::GetControlSize(nullptr, &iCtrlHeight, szEdtPassCaption, nullptr, fSideEdits);
557  AddElement(pEdtPass = new C4GUI::LabeledEdit(caTemp.GetFromTop(iCtrlHeight), szEdtPassCaption, fSideEdits, szPassPref));
558  AddElement(pEdtPass2 = new C4GUI::LabeledEdit(caTemp.GetFromTop(iCtrlHeight), szEdtPass2Caption, fSideEdits, szPassPref));
559  // hide them
560  pEdtPass->SetVisibility(false);
561  pEdtPass2->SetVisibility(false);
562  // save how much to move the controls later
563  iEdtPassSpace = caTemp.GetHeight() - caMain.GetHeight();
564  }
565  else
566  {
567  // No password checkbox
568  pChkPassword = nullptr;
569  // But a password edit box
570  const char *szEdtPassCaption = LoadResStr("IDS_CTL_LEAGUE_PLRPW");
571  C4GUI::LabeledEdit::GetControlSize(nullptr, &iCtrlHeight, szEdtPassCaption, nullptr, fSideEdits);
572  AddElement(pEdtPass = new C4GUI::LabeledEdit(caMain.GetFromTop(iCtrlHeight), szEdtPassCaption, fSideEdits, szPassPref));
573  // No second password edit box
574  pEdtPass2 = nullptr;
575  // remember login-checkbox
576  const char *szRememberPasswordCaption = LoadResStr("IDS_CTL_LEAGUE_CHK_REMEMBERLOGIN");
577  C4GUI::CheckBox::GetStandardCheckBoxSize(nullptr, &iCtrlHeight, szRememberPasswordCaption, nullptr);
578  AddElement(pChkRememberLogin = new C4GUI::CheckBox(caMain.GetFromTop(iCtrlHeight), szRememberPasswordCaption, fRememberLogin));
579  pChkRememberLogin->SetToolTip(LoadResStr("IDS_DESC_REMEMBERLOGIN"));
580  }
581  // Set password box options
582  pEdtPass->GetEdit()->SetPasswordMask('*');
583  if (pEdtPass2)
584  {
585  pEdtPass2->GetEdit()->SetPasswordMask('*');
586  }
587  // place confirmation buttons
588  C4GUI::ComponentAligner caButtonArea(caMain.GetFromTop(C4GUI_ButtonAreaHgt), 0,0);
590  rcBtn.Wdt = C4GUI_DefButton2Wdt;
591  pBtnOK = new C4GUI::OKButton(rcBtn);
592  AddElement(pBtnOK);
594  pBtnAbort = new C4GUI::CancelButton(rcBtn);
595  AddElement(pBtnAbort);
596  // resize to actually needed size
597  SetClientSize(GetClientRect().Wdt, GetClientRect().Hgt - caMain.GetHeight());
598  // initial focus
599  SetFocus(fRegister ? pEdtAccount->GetEdit() : pEdtPass->GetEdit(), false);
600 }
601 
603 {
604  // Abort? That's always okay
605  if (!fOK)
606  {
607  Dialog::UserClose(fOK);
608  ::pGUI->ShowMessageModal(FormatString(LoadResStr("IDS_MSG_LEAGUESIGNUPCANCELLED"), strPlayerName.getData()).getData(), LoadResStr("IDS_DLG_LEAGUESIGNUP"), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Notify);
609  return;
610  }
611  // Check for empty account name
612  const char *szAccount = pEdtAccount->GetText();
613  if (!szAccount || !*szAccount)
614  {
615  SetFocus(pEdtAccount->GetEdit(), false);
616  ::pGUI->ShowMessageModal(LoadResStr("IDS_MSG_LEAGUEMISSINGUSERNAME"), LoadResStr("IDS_DLG_INVALIDENTRY"), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error);
617  return;
618  }
619  // Check for valid username if this is registration
620  if (pEdtPass2)
621  {
622  // Username contains invalid characters
623  if (SCharCountEx(szAccount, C4League_Name_Valid_Characters) != SLen(szAccount))
624  {
625  SetFocus(pEdtAccount->GetEdit(), false);
626  ::pGUI->ShowMessageModal(LoadResStr("IDS_MSG_LEAGUEINVALIDUSERNAME"), LoadResStr("IDS_DLG_INVALIDENTRY"), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error);
627  return;
628  }
629  // Username is too short
630  if (SLen(szAccount) < 3)
631  {
632  SetFocus(pEdtAccount->GetEdit(), false);
633  ::pGUI->ShowMessageModal(LoadResStr("IDS_MSG_LEAGUEUSERNAMETOOSHORT"), LoadResStr("IDS_DLG_INVALIDENTRY"), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error);
634  return;
635  }
636  }
637  // Check password
638  if (!pChkPassword || pChkPassword->GetChecked())
639  {
640  // Check for empty password
641  const char *szPassword = pEdtPass->GetText();
642  if (!szPassword || !*szPassword)
643  {
644  SetFocus(pEdtPass->GetEdit(), false);
645  ::pGUI->ShowMessageModal(LoadResStr("IDS_MSG_LEAGUEMISSINGPASSWORD"), LoadResStr("IDS_DLG_INVALIDENTRY"), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error);
646  return;
647  }
648  // Check second password
649  if (pEdtPass2 && !SEqual(szPassword, pEdtPass2->GetText()))
650  {
651  SetFocus(pEdtPass2->GetEdit(), false);
652  pEdtPass2->GetEdit()->SetText("", false);
653  ::pGUI->ShowMessageModal(LoadResStr("IDS_MSG_LEAGUEMISMATCHPASSWORD"), LoadResStr("IDS_DLG_INVALIDENTRY"), C4GUI::MessageDialog::btnOK, C4GUI::Ico_Error);
654  return;
655  }
656  }
657  // Okay then
658  Dialog::UserClose(fOK);
659 }
660 
661 bool C4LeagueSignupDialog::ShowModal(const char *szPlayerName, const char *szLeagueName, const char *szLeagueServerName, StdStrBuf *psCUID, StdStrBuf *psPass, bool fWarnThirdParty, bool fRegister, bool *pfRememberLogin)
662 {
663  // show league signup dlg modally; return whether user pressed OK and change user and pass buffers in that case
664  assert(psCUID); assert(psPass);
665  if (!psCUID || !psPass) return false;
666  C4LeagueSignupDialog *pDlg = new C4LeagueSignupDialog(szPlayerName, szLeagueName, szLeagueServerName, psCUID->getData(), psPass->getData(), fWarnThirdParty, fRegister, *pfRememberLogin);
667  bool fResult = ::pGUI->ShowModalDlg(pDlg, false);
668  if (fResult)
669  {
670  psCUID->Copy(pDlg->GetAccount());
671  if (pDlg->HasPass())
672  psPass->Copy(pDlg->GetPass());
673  else
674  psPass->Clear();
675  *pfRememberLogin = pDlg->GetRememberLogin();
676  }
677  delete pDlg;
678  return fResult;
679 }
680 
681 void C4LeagueSignupDialog::OnChkPassword()
682 {
683  if (!pChkPassword) return;
684  // Show password elements?
685  if (!pChkPassword->GetChecked())
686  {
687  // Enlarge dialog
688  C4Rect bnds = GetClientRect();
689  SetClientSize(bnds.Wdt, bnds.Hgt + iEdtPassSpace);
690  // Show edit controls
691  pEdtPass->SetVisibility(false);
692  pEdtPass2->SetVisibility(false);
693  // Move controls down
694  bnds = pBtnOK->GetBounds();
695  pBtnOK->SetPos(bnds.x, bnds.y + iEdtPassSpace);
696  bnds = pBtnAbort->GetBounds();
697  pBtnAbort->SetPos(bnds.x, bnds.y + iEdtPassSpace);
698  }
699  else
700  {
701  // Shrink dialog
702  C4Rect bnds = GetClientRect();
703  SetClientSize(bnds.Wdt, bnds.Hgt - iEdtPassSpace);
704  // Hide edit controls
705  pEdtPass->SetVisibility(true);
706  pEdtPass2->SetVisibility(true);
707  // Move controls down
708  bnds = pBtnOK->GetBounds();
709  pBtnOK->SetPos(bnds.x, bnds.y - iEdtPassSpace);
710  bnds = pBtnAbort->GetBounds();
711  pBtnAbort->SetPos(bnds.x, bnds.y - iEdtPassSpace);
712  }
713 }
C4LeagueDisconnectReason
Definition: C4Constants.h:143
@ C4LDR_Unknown
Definition: C4Constants.h:144
@ C4LDR_ConnectionFailed
Definition: C4Constants.h:145
@ C4LDR_Desync
Definition: C4Constants.h:146
C4GraphicsResource GraphicsResource
C4GUIScreen * pGUI
Definition: C4Gui.cpp:1191
#define C4GUI_IconHgt
Definition: C4Gui.h:94
#define C4GUI_ButtonAreaHgt
Definition: C4Gui.h:113
#define C4GUI_DefDlgIndent
Definition: C4Gui.h:132
#define C4GUI_DefButton2Wdt
Definition: C4Gui.h:115
#define C4GUI_MessageFontClr
Definition: C4Gui.h:43
#define C4GUI_IconWdt
Definition: C4Gui.h:93
#define C4GUI_MessageDlgWdt
Definition: C4Gui.h:127
#define C4GUI_ButtonHgt
Definition: C4Gui.h:111
#define C4GUI_DefButton2HSpace
Definition: C4Gui.h:116
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
#define C4League_Name_Valid_Characters
Definition: C4League.h:26
@ C4LA_RefQuery
Definition: C4League.h:40
@ C4LA_PlrAuthCheck
Definition: C4League.h:38
@ C4LA_ReportDisconnect
Definition: C4League.h:43
@ C4LA_Update
Definition: C4League.h:36
@ C4LA_PlrAuth
Definition: C4League.h:41
@ C4LA_End
Definition: C4League.h:37
@ C4LA_Start
Definition: C4League.h:35
const int32_t C4NetMaxLeagues
Definition: C4League.h:29
const int ALeft
Definition: C4Surface.h:41
uint8_t BYTE
unsigned int SCharCountEx(const char *szString, const char *szCharList)
Definition: Standard.cpp:343
bool SEqual(const char *szStr1, const char *szStr2)
Definition: Standard.h:93
size_t SLen(const char *sptr)
Definition: Standard.h:74
StdInsertAdapt< T, I > mkInsertAdapt(T &&rObj, I &&rIns, bool fBefore=true)
Definition: StdAdaptors.h:469
StdDecompileAdapt< T > mkDecompileAdapt(const T &rValue)
Definition: StdAdaptors.h:153
StdArrayAdapt< T > mkArrayAdapt(T *pArray, int iSize)
Definition: StdAdaptors.h:336
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:490
StdNamingCountAdapt< int_t > mkNamingCountAdapt(int_t &iCount, const char *szName)
Definition: StdAdaptors.h:1008
StdHexAdapt mkHexAdapt(void *pData, size_t iSize)
Definition: StdAdaptors.h:1037
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
Definition: StdAdaptors.h:795
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270
C4PlayerInfo * GetPlayerInfo(int32_t iIndex) const
void SetOnChecked(BaseCallbackHandler *pCB)
static bool GetStandardCheckBoxSize(int *piWdt, int *piHgt, const char *szForCaptionText, CStdFont *pUseFont)
bool GetChecked() const
Definition: C4Gui.h:1478
bool GetFromLeft(int32_t iWdt, int32_t iHgt, C4Rect &rcOut)
Definition: C4Gui.cpp:1076
bool GetCentered(int32_t iWdt, int32_t iHgt, C4Rect &rcOut)
Definition: C4Gui.cpp:1133
int32_t GetHeight() const
Definition: C4Gui.h:2804
int32_t GetInnerWidth() const
Definition: C4Gui.h:2808
bool GetFromRight(int32_t iWdt, int32_t iHgt, C4Rect &rcOut)
Definition: C4Gui.cpp:1093
bool GetFromTop(int32_t iHgt, int32_t iWdt, C4Rect &rcOut)
Definition: C4Gui.cpp:1059
void AddElement(Element *pChild)
void SetVisibility(bool fToValue) override
void SetFocus(Control *pCtrl, bool fByMouse)
bool fOK
Definition: C4Gui.h:2083
void SetClientSize(int32_t iToWdt, int32_t iToHgt)
bool SetText(const char *szText, bool fUser)
Definition: C4Gui.h:1293
void SetPasswordMask(char cNewPasswordMask)
Definition: C4Gui.h:1294
void SetToolTip(const char *szNewTooltip, bool is_immediate=false)
Definition: C4Gui.cpp:409
C4Rect & GetBounds()
Definition: C4Gui.h:445
static bool GetControlSize(int *piWdt, int *piHgt, const char *szForText, CStdFont *pForFont, bool fMultiline)
Definition: C4GuiEdit.cpp:812
C4GUI::Edit * GetEdit() const
Definition: C4Gui.h:1437
const char * GetText() const
Definition: C4Gui.h:1436
bool ShowModalDlg(Dialog *pDlg, bool fDestruct=true)
bool ShowMessageModal(const char *szMessage, const char *szCaption, DWORD dwButtons, Icons icoIcon, int32_t *piConfigDontShowAgainSetting=nullptr)
void SetPos(int32_t iXPos, int32_t iYPos)
Definition: C4Gui.h:860
C4Rect & GetClientRect() override
Definition: C4Gui.h:864
bool isSuccess() const
Definition: C4HTTP.h:88
bool Query(const StdBuf &Data, bool fBinary)
Definition: C4HTTP.cpp:158
StdCopyStrBuf ResultString
Definition: C4HTTP.h:78
bool Start(const C4Network2Reference &Ref)
Definition: C4League.cpp:298
bool GetAuthReply(StdStrBuf *pMessage, StdStrBuf *pAUID, StdStrBuf *pAccount, bool *pRegister, StdStrBuf *pLoginToken)
Definition: C4League.cpp:425
bool GetStartReply(StdStrBuf *pMessage, StdStrBuf *pLeague, StdStrBuf *pStreamingAddr, int32_t *pSeed, int32_t *pMaxPlayers)
Definition: C4League.cpp:312
bool GetReportDisconnectReply(StdStrBuf *pMessage)
Definition: C4League.cpp:500
bool GetAuthCheckReply(StdStrBuf *pMessage, const char *szLeague, class C4PlayerInfo *pPlrInfo)
Definition: C4League.cpp:471
bool ReportDisconnect(const C4ClientPlayerInfos &rSendPlayerFBIDs, C4LeagueDisconnectReason eReason)
Definition: C4League.cpp:485
bool Auth(const C4PlayerInfo &PlrInfo, const char *szAccount, const char *szPassword, const char *szNewAccount=nullptr, const char *szNewPassword=nullptr, bool fRememberLogin=false)
Definition: C4League.cpp:405
bool GetEndReply(StdStrBuf *pMessage, class C4RoundResultsPlayers *pRoundResults)
Definition: C4League.cpp:390
bool Update(const C4Network2Reference &Ref)
Definition: C4League.cpp:345
bool GetUpdateReply(StdStrBuf *pMessage, C4ClientPlayerInfos *pPlayerLeagueInfos)
Definition: C4League.cpp:360
bool AuthCheck(const C4PlayerInfo &PlrInfo)
Definition: C4League.cpp:455
bool End(const C4Network2Reference &Ref, const char *szRecordName, const BYTE *pRecordSHA)
Definition: C4League.cpp:375
void RemoveFBIDByAccount(const char *szAccount)
Definition: C4League.cpp:220
bool FindFBIDByAccount(const char *szAccount, StdStrBuf *pFBIDOut)
Definition: C4League.cpp:207
void AddFBID(const char *szFBID, const char *szAccount)
Definition: C4League.cpp:237
void CompileFunc(StdCompiler *pComp)
Definition: C4League.cpp:75
void CompileFunc(StdCompiler *pComp)
Definition: C4League.cpp:91
void SetNewPassword(const char *szNewPassword)
Definition: C4League.cpp:68
void CompileFunc(StdCompiler *pComp)
Definition: C4League.cpp:27
void SetAuth(const char *szAccount, const char *szPassword, bool fRememberLogin)
Definition: C4League.cpp:56
void SetNewAccount(const char *szNewAccount)
Definition: C4League.cpp:63
int32_t getRank(const char *szLeague) const
Definition: C4League.cpp:154
int32_t getRankSymbol(const char *szLeague) const
Definition: C4League.cpp:162
void CompileFunc(StdCompiler *pComp)
Definition: C4League.cpp:176
const char * getClanTag() const
Definition: C4League.h:178
int32_t getScore(const char *szLeague) const
Definition: C4League.cpp:146
const char * getProgressData(const char *szLeague) const
Definition: C4League.cpp:170
bool isSuccess() const
Definition: C4League.h:121
bool isStatusRegister() const
Definition: C4League.h:122
const char * getAUID() const
Definition: C4League.h:124
void CompileFunc(StdCompiler *pComp)
Definition: C4League.cpp:101
const char * getFBID() const
Definition: C4League.h:125
const char * getAccount() const
Definition: C4League.h:123
const char * getLoginToken() const
Definition: C4League.h:126
const char * getCSID() const
Definition: C4League.h:119
const char * getMessage() const
Definition: C4League.h:120
void CompileFunc(StdCompiler *pComp)
Definition: C4League.cpp:116
const char * getStreamingAddr() const
Definition: C4League.h:142
const char * getLeague() const
Definition: C4League.h:141
bool haveSeed() const
Definition: C4League.h:143
int32_t getSeed() const
Definition: C4League.h:144
int32_t getMaxPlayers() const
Definition: C4League.h:145
const C4ClientPlayerInfos & GetPlrInfos() const
Definition: C4League.h:158
void CompileFunc(StdCompiler *pComp)
Definition: C4League.cpp:132
void UserClose(bool fOK) override
Definition: C4League.cpp:602
static bool ShowModal(const char *szPlayerName, const char *szLeagueName, const char *szLeagueServerName, StdStrBuf *psAccount, StdStrBuf *psPass, bool fWarnThirdParty, bool fRegister, bool *pfRememberLogin)
Definition: C4League.cpp:661
const char * GetPass()
Definition: C4League.h:259
C4LeagueSignupDialog(const char *szPlayerName, const char *szLeagueName, const char *szLeagueServerName, const char *szAccountPref, const char *szPassPref, bool fWarnThirdParty, bool fRegister, bool fRememberLogin)
Definition: C4League.cpp:515
const char * GetAccount()
Definition: C4League.h:257
bool GetRememberLogin()
Definition: C4League.h:260
const char * getAuthID() const
Definition: C4PlayerInfo.h:183
void SetLeagueData(const char *szAccount, const char *szNewClanTag, int32_t iScore, int32_t iRank, int32_t iRankSymbol, const char *szProgressData)
Definition: C4PlayerInfo.h:135
bool IsRemoved() const
Definition: C4PlayerInfo.h:164
const char * getLeagueAccount() const
Definition: C4PlayerInfo.h:184
int32_t GetID() const
Definition: C4PlayerInfo.h:194
bool IsJoined() const
Definition: C4PlayerInfo.h:166
Definition: C4Rect.h:28
int32_t y
Definition: C4Rect.h:30
int32_t Hgt
Definition: C4Rect.h:30
int32_t Wdt
Definition: C4Rect.h:30
int32_t x
Definition: C4Rect.h:30
std::tuple< std::string, int > BreakMessage(const char *szMsg, int iWdt, bool fCheckMarkup, float fZoom=1.0f)
DisconnectData(C4LeagueFBIDList &rFBIDList, const C4ClientPlayerInfos &rPlayerInfos)
Definition: C4League.cpp:258
void CompileFunc(StdCompiler *pComp)
Definition: C4League.cpp:261
void Value(const T &rStruct)
Definition: StdCompiler.h:161
virtual void NameEnd(bool fBreak=false)
Definition: StdCompiler.h:78
virtual bool isDeserializer()
Definition: StdCompiler.h:53
@ RCT_IdtfAllowEmpty
Definition: StdCompiler.h:140
virtual bool Name(const char *szName)
Definition: StdCompiler.h:77
void Ref(const char *pnData)
Definition: StdBuf.h:455
const char * getData() const
Definition: StdBuf.h:442
void Copy()
Definition: StdBuf.h:467
void Clear()
Definition: StdBuf.h:466
size_t getLength() const
Definition: StdBuf.h:445
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174
@ Ico_Notify
Definition: C4Gui.h:642
@ Ico_Ex_League
Definition: C4Gui.h:706
@ Ico_Error
Definition: C4Gui.h:652