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