OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4Network2Reference.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-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 #include "C4Include.h"
18 
19 #include "C4Version.h"
20 #include "control/C4RoundResults.h"
21 #include "game/C4Application.h"
22 
23 #include <zlib.h>
24 
25 // *** C4Network2Reference
26 
28  : GameMode(), NetpuncherGameID(C4NetpuncherID())
29 {
30 
31 }
32 
34 
36 {
37  source = ip;
38  if (iAddrCnt < C4ClientMaxAddr)
39  Addrs[++iAddrCnt].SetAddr(ip);
40 }
41 
43 {
44  // Copy all game parameters
46 
47  // Discard player resources (we don't want these infos in the reference)
48  // Add league performance (but only after game end)
49  C4ClientPlayerInfos *pClientInfos; C4PlayerInfo *pPlayerInfo;
50  int32_t i, j;
51  for (i = 0; (pClientInfos = Parameters.PlayerInfos.GetIndexedInfo(i)); i++)
52  for (j = 0; (pPlayerInfo = pClientInfos->GetPlayerInfo(j)); j++)
53  {
54  pPlayerInfo->DiscardResource();
55  if(::Game.GameOver)
56  pPlayerInfo->SetLeaguePerformance(::Game.RoundResults.GetLeaguePerformance(pPlayerInfo->GetID()));
57  }
58 
59  // Special additional information in reference
60  Icon = ::Game.C4S.Head.Icon;
62  GameMode = ::Game.C4S.Game.Mode;
63  GameStatus = ::Network.Status;
64  Time = ::Game.Time;
65  Frame = ::Game.FrameCounter;
66  StartTime = ::Game.StartTime;
67  LeaguePerformance = ::Game.RoundResults.GetLeaguePerformance();
68  Comment = Config.Network.Comment;
69  JoinAllowed = ::Network.isJoinAllowed();
70  ObservingAllowed = ::Network.isObservingAllowed();
71  PasswordNeeded = ::Network.isPassworded();
72  IsEditor = !!::Application.isEditor;
73  NetpuncherGameID = ::Network.getNetpuncherGameID();
74  NetpuncherAddr = ::Network.getNetpuncherAddr();
75  Statistics = ::Game.RoundResults.GetStatistics();
76  Game.Set();
77 
78  // Addresses
79  C4Network2Client *pLocalNetClient = ::Game.Clients.getLocal()->getNetClient();
80  iAddrCnt = pLocalNetClient->getAddrCnt();
81  for (i = 0; i < iAddrCnt; i++)
82  Addrs[i] = pLocalNetClient->getAddr(i);
83 
84 }
85 
87 {
88  // Sort all addresses with zero IP to back of list
89  int iSortAddrCnt = iAddrCnt;
90  for (int i = 0; i < iSortAddrCnt; i++)
91  if (Addrs[i].isIPNull())
92  {
93  C4Network2Address Addr = Addrs[i];
94  for (int j = i + 1; j < iAddrCnt; j++)
95  Addrs[j - 1] = Addrs[j];
96  Addrs[iAddrCnt - 1] = Addr;
97  // Correct position
98  i--; iSortAddrCnt--;
99  }
100 }
101 
103 {
104  pComp->Value(mkNamingAdapt(Icon, "Icon", 0));
105  pComp->Value(mkNamingAdapt(Title, "Title", "No title"));
106  pComp->Value(mkNamingAdapt(mkParAdapt(GameMode, StdCompiler::RCT_IdtfAllowEmpty), "GameMode", ""));
107  pComp->Value(mkParAdapt(GameStatus, true));
108  pComp->Value(mkNamingAdapt(Time, "Time", 0));
109  pComp->Value(mkNamingAdapt(Frame, "Frame", 0));
110  pComp->Value(mkNamingAdapt(StartTime, "StartTime", 0));
111  pComp->Value(mkNamingAdapt(LeaguePerformance, "LeaguePerformance",0));
112  pComp->Value(mkNamingAdapt(Comment, "Comment", ""));
113  pComp->Value(mkNamingAdapt(JoinAllowed, "JoinAllowed", true));
114  pComp->Value(mkNamingAdapt(ObservingAllowed, "ObservingAllowed", true));
115  pComp->Value(mkNamingAdapt(PasswordNeeded, "PasswordNeeded", false));
116  pComp->Value(mkNamingAdapt(IsEditor, "IsEditor", false));
117  pComp->Value(mkNamingAdapt(mkIntPackAdapt(iAddrCnt), "AddressCount", 0));
118  iAddrCnt = std::min<uint8_t>(C4ClientMaxAddr, iAddrCnt);
119  pComp->Value(mkNamingAdapt(mkArrayAdapt(Addrs, iAddrCnt, C4Network2Address()), "Address"));
120  pComp->Value(mkNamingAdapt(Game.sEngineName, "Game", "None"));
121  pComp->Value(mkNamingAdapt(mkArrayAdaptDM(Game.iVer,0),"Version" ));
122  pComp->Value(mkNamingAdapt(OfficialServer, "OfficialServer", false));
123  pComp->Value(mkNamingAdapt(NetpuncherGameID, "NetpuncherID", C4NetpuncherID(), false, false));
124  pComp->Value(mkNamingAdapt(NetpuncherAddr, "NetpuncherAddr", "", false, false));
125  pComp->Value(mkNamingAdapt(mkParAdapt(Statistics, StdCompiler::RCT_All), "Statistics", "", false, false));
126 
127  pComp->Value(Parameters);
128 }
129 
130 int32_t C4Network2Reference::getSortOrder() const // Don't go over 100, because that's for the masterserver...
131 {
132  C4GameVersion verThis;
133  int iOrder = 0;
134  // Official server
135  if (isOfficialServer() && !Config.Network.UseAlternateServer) iOrder += 50;
136  // Joinable
137  if (isJoinAllowed() && (getGameVersion() == verThis)) iOrder += 25;
138  // League game
139  if (Parameters.isLeague()) iOrder += 5;
140  // In lobby
141  if (getGameStatus().isLobbyActive()) iOrder += 3;
142  // No password needed
143  if (!isPasswordNeeded()) iOrder += 1;
144  // Done
145  return iOrder;
146 }
147 
149 {
150  if (GameMode.getLength() > 0)
151  {
152  // Prefer to derive string from game mode
153  return FormatString("%s: %s", LoadResStr("IDS_MENU_CPGOALS"), GameMode.getData());
154  }
155  else
156  {
157  // If not defined, fall back to goal string
158  return Parameters.GetGameGoalString();
159  }
160 }
161 
162 
163 // *** C4Network2RefServer
164 
166 
168 {
169  Clear();
170 }
171 
173 {
175  delete pReference; pReference = nullptr;
176 }
177 
179 {
180  CStdLock RefLock(&RefCSec);
181  delete pReference; pReference = pNewReference;
182 }
183 
185 {
186  // Just append the packet
187  rOutBuf.Append(rPacket);
188 }
189 
190 size_t C4Network2RefServer::UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &addr)
191 {
192  const char *pData = getBufPtr<char>(rInBuf);
193  // Check for complete header
194  const char *pHeaderEnd = strstr(pData, "\r\n\r\n");
195  if (!pHeaderEnd)
196  return 0;
197  // Check method (only GET is allowed for now)
198  if (!SEqual2(pData, "GET "))
199  {
200  RespondNotImplemented(addr, "Method not implemented");
201  return rInBuf.getSize();
202  }
203  // Check target
204  // TODO
205  RespondReference(addr);
206  return rInBuf.getSize();
207 }
208 
209 void C4Network2RefServer::RespondNotImplemented(const C4NetIO::addr_t &addr, const char *szMessage)
210 {
211  // Send the message
212  StdStrBuf Data = FormatString("HTTP/1.0 501 %s\r\n\r\n", szMessage);
213  Send(C4NetIOPacket(Data.getData(), Data.getLength(), false, addr));
214  // Close the connection
215  Close(addr);
216 }
217 
218 void C4Network2RefServer::RespondReference(const C4NetIO::addr_t &addr)
219 {
220  CStdLock RefLock(&RefCSec);
221  // Pack
222  StdStrBuf PacketData = DecompileToBuf<StdCompilerINIWrite>(mkNamingPtrAdapt(pReference, "Reference"));
223  // Create header
224  StdStrBuf Header = FormatString(
225  "HTTP/1.1 200 Found\r\n"
226  "Content-Length: %lu\r\n"
227  "Content-Type: text/plain; charset=UTF-8\r\n"
228  "Server: " C4ENGINENAME "/" C4VERSION "\r\n"
229  "\r\n",
230  static_cast<unsigned long>(PacketData.getLength()));
231  // Send back
232  Send(C4NetIOPacket(Header, Header.getLength(), false, addr));
233  Send(C4NetIOPacket(PacketData, PacketData.getLength(), false, addr));
234  // Close the connection
235  Close(addr);
236 }
237 
238 // *** C4Network2HTTPClient
239 
241 {
243 }
244 
246 
248 {
249  // Just append the packet
250  rOutBuf.Append(rPacket);
251 }
252 
254 {
255  // since new data arrived, increase timeout time
257  // Check for complete header
258  if (!iDataOffset)
259  {
260  // Copy data into string buffer (terminate)
261  StdStrBuf Data; Data.Copy(getBufPtr<char>(rInBuf), rInBuf.getSize());
262  const char *pData = Data.getData();
263  // Header complete?
264  const char *pContent = SSearch(pData, "\r\n\r\n");
265  if (!pContent)
266  return 0;
267  // Read the header
268  if (!ReadHeader(Data))
269  {
270  fBusy = fSuccess = false;
271  Close(addr);
272  return rInBuf.getSize();
273  }
274  }
275  iDownloadedSize = rInBuf.getSize() - iDataOffset;
276  // Check if the packet is complete
277  if (iTotalSize > iDownloadedSize)
278  {
279  return 0;
280  }
281  // Get data, uncompress it if needed
282  StdBuf Data = rInBuf.getPart(iDataOffset, iTotalSize);
283  if (fCompressed)
284  if (!Decompress(&Data))
285  {
286  fBusy = fSuccess = false;
287  Close(addr);
288  return rInBuf.getSize();
289  }
290  // Save the result
291  if (fBinary)
292  ResultBin.Copy(Data);
293  else
294  ResultString.Copy(getBufPtr<char>(Data), Data.getSize());
295  fBusy = false; fSuccess = true;
296  // Callback
297  OnPacket(C4NetIOPacket(Data, addr), this);
298  // Done
299  Close(addr);
300  return rInBuf.getSize();
301 }
302 
303 bool C4Network2HTTPClient::ReadHeader(StdStrBuf Data)
304 {
305  const char *pData = Data.getData();
306  const char *pContent = SSearch(pData, "\r\n\r\n");
307  if (!pContent)
308  return false;
309  // Parse header line
310  int iHTTPVer1, iHTTPVer2, iResponseCode, iStatusStringPtr;
311  if (sscanf(pData, "HTTP/%d.%d %d %n", &iHTTPVer1, &iHTTPVer2, &iResponseCode, &iStatusStringPtr) != 3)
312  {
313  Error = "Invalid status line!";
314  return false;
315  }
316  // Check HTTP version
317  if (iHTTPVer1 != 1)
318  {
319  Error.Format("Unsupported HTTP version: %d.%d!", iHTTPVer1, iHTTPVer2);
320  return false;
321  }
322  // Check code
323  if (iResponseCode != 200)
324  {
325  // Get status string
326  StdStrBuf StatusString; StatusString.CopyUntil(pData + iStatusStringPtr, '\r');
327  // Create error message
328  Error.Format("HTTP server responded %d: %s", iResponseCode, StatusString.getData());
329  return false;
330  }
331  // Get content length
332  const char *pContentLength = SSearch(pData, "\r\nContent-Length:");
333  int iContentLength;
334  if (!pContentLength || pContentLength > pContent ||
335  sscanf(pContentLength, "%d", &iContentLength) != 1)
336  {
337  Error.Format("Invalid server response: Content-Length is missing!");
338  return false;
339  }
340  iTotalSize = iContentLength;
341  iDataOffset = (pContent - pData);
342  // Get content encoding
343  const char *pContentEncoding = SSearch(pData, "\r\nContent-Encoding:");
344  if (pContentEncoding)
345  {
346  while (*pContentEncoding == ' ') pContentEncoding++;
347  StdStrBuf Encoding; Encoding.CopyUntil(pContentEncoding, '\r');
348  if (Encoding == "gzip")
349  fCompressed = true;
350  else
351  fCompressed = false;
352  }
353  else
354  fCompressed = false;
355  // Okay
356  return true;
357 }
358 
359 bool C4Network2HTTPClient::Decompress(StdBuf *pData)
360 {
361  size_t iSize = pData->getSize();
362  // Create buffer
363  uint32_t iOutSize = *getBufPtr<uint32_t>(*pData, pData->getSize() - sizeof(uint32_t));
364  iOutSize = std::min<uint32_t>(iOutSize, iSize * 1000);
365  StdBuf Out; Out.New(iOutSize);
366  // Prepare stream
367  z_stream zstrm;
368  ZeroMem(&zstrm, sizeof(zstrm));
369  zstrm.next_in = const_cast<Byte *>(getBufPtr<Byte>(*pData));
370  zstrm.avail_in = pData->getSize();
371  zstrm.next_out = getMBufPtr<Byte>(Out);
372  zstrm.avail_out = Out.getSize();
373  // Inflate...
374  if (inflateInit2(&zstrm, 15 + 16) != Z_OK)
375  {
376  Error.Format("Could not decompress data!");
377  return false;
378  }
379  // Inflate!
380  if (inflate(&zstrm, Z_FINISH) != Z_STREAM_END)
381  {
382  inflateEnd(&zstrm);
383  Error.Format("Could not decompress data!");
384  return false;
385  }
386  // Return the buffer
387  Out.SetSize(zstrm.total_out);
388  pData->Take(std::move(Out));
389  // Okay
390  inflateEnd(&zstrm);
391  return true;
392 }
393 
394 bool C4Network2HTTPClient::OnConn(const C4NetIO::addr_t &AddrPeer, const C4NetIO::addr_t &AddrConnect, const C4NetIO::addr_t *pOwnAddr, C4NetIO *pNetIO)
395 {
396  // Make sure we're actually waiting for this connection
397  if (fConnected || (AddrConnect != ServerAddr && AddrConnect != ServerAddrFallback))
398  return false;
399  // Save pack peer address
400  PeerAddr = AddrPeer;
401  // Send the request
402  if (!Send(C4NetIOPacket(Request, AddrPeer)))
403  {
404  Error.Format("Unable to send HTTP request: %s", Error.getData());
405  }
406  Request.Clear();
407  fConnected = true;
408  return true;
409 }
410 
411 void C4Network2HTTPClient::OnDisconn(const C4NetIO::addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason)
412 {
413  // Got no complete packet? Failure...
414  if (!fSuccess && Error.isNull())
415  {
416  fBusy = false;
417  Error.Format("Unexpected disconnect: %s", szReason);
418  }
419  fConnected = false;
420  // Notify
421  if (pNotify)
422  pNotify->PushEvent(Ev_HTTP_Response, this);
423 }
424 
425 void C4Network2HTTPClient::OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO)
426 {
427  // Everything worthwhile was already done in UnpackPacket. Only do notify callback
428  if (pNotify)
429  pNotify->PushEvent(Ev_HTTP_Response, this);
430 }
431 
433 {
434  // Check timeout
435  if (fBusy)
436  {
437  if (C4TimeMilliseconds::Now() > HappyEyeballsTimeout)
438  {
439  HappyEyeballsTimeout = C4TimeMilliseconds::PositiveInfinity;
440  Application.InteractiveThread.ThreadLogS("HTTP: Starting fallback connection to %s (%s)", Server.getData(), ServerAddrFallback.ToString().getData());
441  Connect(ServerAddrFallback);
442  }
443  if (time(nullptr) > iRequestTimeout)
444  {
445  Cancel("Request timeout");
446  return true;
447  }
448  }
449  // Execute normally
450  return C4NetIOTCP::Execute(iMaxTime);
451 }
452 
454 {
455  C4TimeMilliseconds tNetIOTCPTick = C4NetIOTCP::GetNextTick(tNow);
456  if (!fBusy)
457  return tNetIOTCPTick;
458 
459  C4TimeMilliseconds tHTTPClientTick = tNow + 1000 * std::max<time_t>(iRequestTimeout - time(nullptr), 0);
460 
461  C4TimeMilliseconds HappyEyeballsTick = tNow + std::max(HappyEyeballsTimeout - C4TimeMilliseconds::Now(), 0);
462 
463  return std::min({tNetIOTCPTick, tHTTPClientTick, HappyEyeballsTick});
464 }
465 
466 bool C4Network2HTTPClient::Query(const StdBuf &Data, bool fBinary)
467 {
468  if (Server.isNull()) return false;
469  // Cancel previous request
470  if (fBusy)
471  Cancel("Cancelled");
472  // No result known yet
474  // store mode
475  this->fBinary = fBinary;
476  // Create request
477  StdStrBuf Header;
478  if (Data.getSize())
479  Header.Format(
480  "POST %s HTTP/1.0\r\n"
481  "Host: %s\r\n"
482  "Connection: Close\r\n"
483  "Content-Length: %lu\r\n"
484  "Content-Type: text/plain; charset=utf-8\r\n"
485  "Accept-Charset: utf-8\r\n"
486  "Accept-Encoding: gzip\r\n"
487  "Accept-Language: %s\r\n"
488  "User-Agent: " C4ENGINENAME "/" C4VERSION "\r\n"
489  "\r\n",
490  RequestPath.getData(),
491  Server.getData(),
492  static_cast<unsigned long>(Data.getSize()),
494  else
495  Header.Format(
496  "GET %s HTTP/1.0\r\n"
497  "Host: %s\r\n"
498  "Connection: Close\r\n"
499  "Accept-Charset: utf-8\r\n"
500  "Accept-Encoding: gzip\r\n"
501  "Accept-Language: %s\r\n"
502  "User-Agent: " C4ENGINENAME "/" C4VERSION "\r\n"
503  "\r\n",
504  RequestPath.getData(),
505  Server.getData(),
507  // Compose query
508  Request.Take(Header.GrabPointer(), Header.getLength());
509  Request.Append(Data);
510  // Start connecting
511  if (!Connect(ServerAddr))
512  return false;
513  // Also try the fallback address after some time (if there is one)
514  if (!ServerAddrFallback.IsNull())
516  else
517  HappyEyeballsTimeout = C4TimeMilliseconds::PositiveInfinity;
518  // Okay, request will be performed when connection is complete
519  fBusy = true;
520  iDataOffset = 0;
522  ResetError();
523  return true;
524 }
525 
527 {
528  // timeout C4Network2HTTPQueryTimeout seconds from this point
529  iRequestTimeout = time(nullptr) + C4Network2HTTPQueryTimeout;
530 }
531 
532 void C4Network2HTTPClient::Cancel(const char *szReason)
533 {
534  // Close connection - and connection attempt
535  Close(ServerAddr); Close(ServerAddrFallback); Close(PeerAddr);
536  // Reset flags
537  fBusy = fSuccess = fConnected = fBinary = false;
538  iDownloadedSize = iTotalSize = iDataOffset = 0;
539  Error = szReason;
540 }
541 
543 {
544  fBusy = fSuccess = fConnected = fBinary = false;
545  iDownloadedSize = iTotalSize = iDataOffset = 0;
546  ResultBin.Clear();
548  Error.Clear();
549 }
550 
551 bool C4Network2HTTPClient::SetServer(const char *szServerAddress)
552 {
553  // Split address
554  const char *pRequestPath;
555  if ((pRequestPath = strchr(szServerAddress, '/')))
556  {
557  Server.CopyUntil(szServerAddress, '/');
558  RequestPath = pRequestPath;
559  }
560  else
561  {
562  Server = szServerAddress;
563  RequestPath = "/";
564  }
565  // Resolve address
566  ServerAddr.SetAddress(Server);
567  if (ServerAddr.IsNull())
568  {
569  SetError(FormatString("Could not resolve server address %s!", Server.getData()).getData());
570  return false;
571  }
572  ServerAddr.SetDefaultPort(GetDefaultPort());
573  if (ServerAddr.GetFamily() == C4NetIO::HostAddress::IPv6)
574  {
575  // Try to find a fallback IPv4 address for Happy Eyeballs.
576  ServerAddrFallback.SetAddress(Server, C4NetIO::HostAddress::IPv4);
577  ServerAddrFallback.SetDefaultPort(GetDefaultPort());
578  }
579  else
580  ServerAddrFallback.Clear();
581  // Remove port
582  const char *firstColon = strchr(Server.getData(), ':');
583  const char *lastColon = strrchr(Server.getData(), ':');
584  if (firstColon)
585  // hostname/IPv4 address or IPv6 address with port (e.g. [::1]:1234)
586  if (firstColon == lastColon || (Server[0] == '[' && *(lastColon - 1) == ']'))
587  Server.SetLength(lastColon - Server.getData());
588 
589  // Done
590  ResetError();
591  return true;
592 }
593 
594 // *** C4Network2UpdateClient
595 
597 {
598  // Perform an Query query
599  return Query(nullptr, false);
600 }
601 
603 {
604  // Sanity check
605  if (isBusy() || !isSuccess()) return false;
606  // Parse response
607  try
608  {
609  CompileFromBuf<StdCompilerINIRead>(mkNamingAdapt(
610  mkNamingAdapt(mkParAdapt(*pUpdateURL, StdCompiler::RCT_All), "UpdateURL", ""),
611  C4ENGINENAME), ResultString);
612  }
613  catch (StdCompiler::Exception *pExc)
614  {
615  SetError(pExc->Msg.getData());
616  return false;
617  }
618  // done; version OK!
619  return true;
620 }
621 
623 {
624  // Sanity check
625  if (isBusy() || !isSuccess()) return false;
626  // Parse response
627  try
628  {
629  CompileFromBuf<StdCompilerINIRead>(mkNamingAdapt(
630  mkNamingAdapt(mkParAdapt(*pVersion, StdCompiler::RCT_All), "Version", ""),
631  C4ENGINENAME), ResultString);
632  }
633  catch (StdCompiler::Exception *pExc)
634  {
635  SetError(pExc->Msg.getData());
636  return false;
637  }
638  // done; version OK!
639  return true;
640 }
641 
642 // *** C4Network2RefClient
643 
645 {
646  // Perform an Query query
647  return Query(nullptr, false);
648 }
649 
650 bool C4Network2RefClient::GetReferences(C4Network2Reference **&rpReferences, int32_t &rRefCount)
651 {
652  // Sanity check
653  if (isBusy() || !isSuccess()) return false;
654  // local update test
655  try
656  {
657  // Create compiler
658  StdCompilerINIRead Comp;
659  Comp.setInput(ResultString);
660  Comp.Begin();
661  // Read reference count
662  Comp.Value(mkNamingCountAdapt(rRefCount, "Reference"));
663  // Create reference array and initialize
664  rpReferences = new C4Network2Reference *[rRefCount];
665  for (int i = 0; i < rRefCount; i++)
666  rpReferences[i] = nullptr;
667  // Get references
668  Comp.Value(mkNamingAdapt(mkArrayAdaptMap(rpReferences, rRefCount, mkPtrAdaptNoNull<C4Network2Reference>), "Reference"));
669  mkPtrAdaptNoNull<C4Network2Reference>(*rpReferences);
670  // Done
671  Comp.End();
672  }
673  catch (StdCompiler::Exception *pExc)
674  {
675  SetError(pExc->Msg.getData());
676  return false;
677  }
678  // Set source ip
679  for (int i = 0; i < rRefCount; i++)
680  rpReferences[i]->SetSourceAddress(getServerAddress());
681  // Done
682  ResetError();
683  return true;
684 }
685 
const C4Network2Address & getAddr(int32_t i) const
bool Execute(int iMaxTime=TO_INF, pollfd *readyfds=nullptr) override
Definition: C4NetIO.cpp:914
const char * getData() const
Definition: StdBuf.h:442
StdCopyStrBuf Mode
Definition: C4Scenario.h:121
C4Client * getLocal() const
Definition: C4Client.h:161
void ResetError()
Definition: C4NetIO.h:285
int32_t Icon
Definition: C4Scenario.h:68
bool Send(const C4NetIOPacket &rPacket) override
Definition: C4NetIO.cpp:1248
C4Config Config
Definition: C4Config.cpp:833
char * GrabPointer()
Definition: StdBuf.h:459
Definition: StdBuf.h:29
void PackPacket(const C4NetIOPacket &rPacket, StdBuf &rOutBuf) override
void Take(void *pnData, size_t inSize)
Definition: StdBuf.h:124
size_t UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &addr) override
StdNamingCountAdapt< int_t > mkNamingCountAdapt(int_t &iCount, const char *szName)
Definition: StdAdaptors.h:976
C4Game Game
Definition: C4Globals.cpp:52
C4TimeMilliseconds GetNextTick(C4TimeMilliseconds tNow) override
C4Scenario C4S
Definition: C4Game.h:74
void Clear()
Definition: StdBuf.h:466
C4ConfigGeneral General
Definition: C4Config.h:251
void SetError(const char *strnError, bool fSockErr=false)
Definition: C4NetIO.cpp:745
virtual C4TimeMilliseconds GetNextTick(C4TimeMilliseconds tNow)
C4NetpuncherID::value & getNetpuncherGameID(C4NetIO::HostAddress::AddressFamily family)
bool ThreadLogS(const char *szMessage,...) GNUC_FORMAT_ATTRIBUTE_O
StdCopyStrBuf ScenarioTitle
Definition: C4Game.h:103
const char * SSearch(const char *szString, const char *szIndex)
Definition: Standard.cpp:341
void Clear()
Definition: StdBuf.h:190
virtual int32_t GetDefaultPort()
void SetCallback(CBClass *pnCallback) override
Definition: C4NetIO.h:486
const int C4Network2HTTPQueryTimeout
ValidatedStdCopyStrBuf< C4InVal::VAL_Comment > Comment
Definition: C4Config.h:146
StdStrBuf ToString(int flags=0) const
Definition: C4NetIO.cpp:599
C4Network2Status getGameStatus() const
void setInput(const InT &In)
Definition: StdCompiler.h:629
StdStrBuf getNetpuncherAddr() const
Definition: C4Network2.h:309
size_t UnpackPacket(const StdBuf &rInBuf, const C4NetIO::addr_t &addr) override
StdCopyStrBuf Error
Definition: C4NetIO.h:281
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174
bool PushEvent(C4InteractiveEventType eEventType, void *pData=nullptr)
bool isJoinAllowed() const
Definition: C4Network2.h:213
C4Network2Client * getNetClient() const
Definition: C4Client.h:117
void SetAddress(const sockaddr *addr)
Definition: C4NetIO.cpp:364
bool isObservingAllowed() const
Definition: C4Network2.h:214
void DiscardResource()
C4GameParameters & Parameters
Definition: C4Game.h:67
bool GetVersion(StdStrBuf *pVersion)
C4ClientPlayerInfos * GetIndexedInfo(int32_t iIndex) const
Definition: C4PlayerInfo.h:358
size_t getSize() const
Definition: StdBuf.h:101
StdBuf getPart(size_t iStart, size_t inSize) const
Definition: StdBuf.h:107
StdCopyStrBuf GetStatistics() const
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
void Cancel(const char *szReason)
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
bool GetUpdateURL(StdStrBuf *pUpdateURL)
void CompileFunc(StdCompiler *pComp)
int32_t FrameCounter
Definition: C4Game.h:128
C4PlayerInfo * GetPlayerInfo(int32_t iIndex) const
C4Network2 Network
Definition: C4Globals.cpp:53
int32_t StartTime
Definition: C4Game.h:132
bool isPasswordNeeded() const
bool GameOver
Definition: C4Game.h:114
StdStrBuf GetGameGoalString() const
bool GetReferences(C4Network2Reference **&rpReferences, int32_t &rRefCount)
void Copy(size_t inSize)
Definition: StdBuf.h:225
StdArrayAdapt< T > mkArrayAdapt(T *pArray, int iSize)
Definition: StdAdaptors.h:310
int32_t Time
Definition: C4Game.h:131
C4ConfigNetwork Network
Definition: C4Config.h:255
const int32_t C4ClientMaxAddr
int32_t getSortOrder() const
C4Network2Status Status
Definition: C4Network2.h:122
AddressFamily GetFamily() const
Definition: C4NetIO.cpp:520
void OnDisconn(const C4NetIO::addr_t &AddrPeer, C4NetIO *pNetIO, const char *szReason) override
void Value(const T &rStruct)
Definition: StdCompiler.h:161
char LanguageEx[CFG_MaxString+1]
Definition: C4Config.h:37
C4RoundResults & RoundResults
Definition: C4Game.h:73
bool Close() override
Definition: C4NetIO.cpp:852
void New(size_t inSize)
Definition: StdBuf.h:146
void CopyUntil(const char *szString, char cUntil)
Definition: StdBuf.h:613
#define mkArrayAdaptDM(A, D)
Definition: StdAdaptors.h:363
void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO) override
bool isJoinAllowed() const
const C4NetIO::addr_t & getServerAddress() const
void SetAddr(C4NetIO::addr_t naddr)
StdIntPackAdapt< T > mkIntPackAdapt(T &rVal)
Definition: StdAdaptors.h:759
void Append(const void *pnData, size_t inSize)
Definition: StdBuf.h:254
void SetSourceAddress(const C4NetIO::EndpointAddress &ip)
void Begin() override
const uint32_t C4Network2HTTPHappyEyeballsTimeout
bool isLobbyActive() const
Definition: C4Network2.h:87
void SetLeaguePerformance(int32_t iNewPerf)
Definition: C4PlayerInfo.h:137
bool isNull() const
Definition: StdBuf.h:441
bool OnConn(const C4NetIO::addr_t &AddrPeer, const C4NetIO::addr_t &AddrConnect, const addr_t *pOwnAddr, C4NetIO *pNetIO) override
C4PlayerInfoList PlayerInfos
bool isOfficialServer() const
void End() override
C4SGame Game
Definition: C4Scenario.h:232
bool SEqual2(const char *szStr1, const char *szStr2)
Definition: Standard.cpp:176
C4ClientList & Clients
Definition: C4Game.h:69
bool isPassworded() const
Definition: C4Network2.h:218
bool isLeague() const
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:458
bool IsNull() const
Definition: C4NetIO.cpp:503
size_t getLength() const
Definition: StdBuf.h:445
void PackPacket(const C4NetIOPacket &rPacket, StdBuf &rOutBuf) override
int32_t GetID() const
Definition: C4PlayerInfo.h:194
void SetLength(size_t iLength)
Definition: StdBuf.h:509
std::enable_if< std::is_pod< T >::value >::type ZeroMem(T *lpMem, size_t dwSize)
Definition: Standard.h:60
C4SHead Head
Definition: C4Scenario.h:230
StdPtrAdapt< T > mkNamingPtrAdapt(T *&rpObj, const char *szNaming)
Definition: StdAdaptors.h:604
bool Query(const StdBuf &Data, bool fBinary)
int32_t UseAlternateServer
Definition: C4Config.h:152
void SetDefaultPort(uint16_t port)
Definition: C4NetIO.cpp:536
const C4GameVersion & getGameVersion() const
StdArrayAdapt< T, M > mkArrayAdaptMap(T *pArray, int iSize, M &&map)
Definition: StdAdaptors.h:313
void Copy()
Definition: StdBuf.h:467
int32_t getAddrCnt() const
bool Execute(int iMaxTime, pollfd *readyfds) override
void CopyValidated(const char *szFromVal)
bool SetServer(const char *szServerAddress)
int32_t GetLeaguePerformance(int32_t idPlayer=0) const
C4Application Application
Definition: C4Globals.cpp:44
C4InteractiveThread InteractiveThread
Definition: C4Application.h:45
static C4TimeMilliseconds Now()
C4GameParameters Parameters
bool Connect(const addr_t &addr) override
Definition: C4NetIO.cpp:1149
int iSize
Definition: TstC4NetIO.cpp:32
void SetReference(C4Network2Reference *pReference)
StdStrBuf FormatString(const char *szFmt,...)
Definition: StdBuf.cpp:270
~C4Network2HTTPClient() override
StdStrBuf getGameGoalString() const