1 /// Transcription of steamnetworkingtypes.h to D. 2 /// 3 /// Translated by hand, based on v1.3.0 6be41e3 4 /// 5 /// Copyright: Valve Corporation, all rights reserved 6 module steam_gns.types; 7 8 import steam_gns.utils; 9 import steam_gns.sockets; 10 import steam_gns.client_public; 11 12 //import steam_gns.stypes; 13 //#include "steamclientpublic.h" 14 15 extern (C++): 16 align(4): 17 18 version = STEAMNETWORKINGSOCKETS_STANDALONELIB; 19 20 // Where are those defined‽ 21 struct SteamNetworkingMessagesSessionRequest_t; 22 struct SteamNetworkingMessagesSessionFailed_t; 23 struct SteamNetworkingFakeIPResult_t; 24 25 alias FnSteamNetConnectionStatusChanged = void function(SteamNetConnectionStatusChangedCallback_t*); 26 alias FnSteamNetAuthenticationStatusChanged = void function(SteamNetAuthenticationStatus_t*); 27 alias FnSteamRelayNetworkStatusChanged = void function(SteamRelayNetworkStatus_t*); 28 alias FnSteamNetworkingMessagesSessionRequest = void function(SteamNetworkingMessagesSessionRequest_t*); 29 alias FnSteamNetworkingMessagesSessionFailed = void function(SteamNetworkingMessagesSessionFailed_t*); 30 alias FnSteamNetworkingFakeIPResult = void function(SteamNetworkingFakeIPResult_t*); 31 32 /// Handle used to identify a connection to a remote host. 33 alias HSteamNetConnection = uint; 34 enum HSteamNetConnection k_HSteamNetConnection_Invalid = 0; 35 36 /// Handle used to identify a "listen socket". Unlike traditional 37 /// Berkeley sockets, a listen socket and a connection are two 38 /// different abstractions. 39 alias HSteamListenSocket = uint; 40 enum HSteamListenSocket k_HSteamListenSocket_Invalid = 0; 41 42 /// Handle used to identify a poll group, used to query many 43 /// connections at once efficiently. 44 alias HSteamNetPollGroup = uint; 45 enum HSteamNetPollGroup k_HSteamNetPollGroup_Invalid = 0; 46 47 /// Max length of diagnostic error message 48 enum int k_cchMaxSteamNetworkingErrMsg = 1024; 49 50 /// Used to return English-language diagnostic error messages to caller. 51 /// (For debugging or spewing to a console, etc. Not intended for UI.) 52 alias SteamNetworkingErrMsg = char[k_cchMaxSteamNetworkingErrMsg]; 53 54 /// Identifier used for a network location point of presence. (E.g. a Valve data center.) 55 /// Typically you won't need to directly manipulate these. 56 alias SteamNetworkingPOPID = uint; 57 58 /// A local timestamp. You can subtract two timestamps to get the number of elapsed 59 /// microseconds. This is guaranteed to increase over time during the lifetime 60 /// of a process, but not globally across runs. You don't need to worry about 61 /// the value wrapping around. Note that the underlying clock might not actually have 62 /// microsecond resolution. 63 alias SteamNetworkingMicroseconds = long; 64 65 /// Describe the status of a particular network resource 66 enum ESteamNetworkingAvailability { 67 68 // Negative values indicate a problem. 69 // 70 // In general, we will not automatically retry unless you take some action that 71 // depends on of requests this resource, such as querying the status, attempting 72 // to initiate a connection, receive a connection, etc. If you do not take any 73 // action at all, we do not automatically retry in the background. 74 CannotTry = -102, // A dependent resource is missing, so this service is unavailable. (E.g. we cannot talk to routers because Internet is down or we don't have the network config.) 75 Failed = -101, // We have tried for enough time that we would expect to have been successful by now. We have never been successful 76 Previously = -100, // We tried and were successful at one time, but now it looks like we have a problem 77 78 Retrying = -10, // We previously failed and are currently retrying 79 80 // Not a problem, but not ready either 81 NeverTried = 1, // We don't know because we haven't ever checked/tried 82 Waiting = 2, // We're waiting on a dependent resource to be acquired. (E.g. we cannot obtain a cert until we are logged into Steam. We cannot measure latency to relays until we have the network config.) 83 Attempting = 3, // We're actively trying now, but are not yet successful. 84 85 Current = 100, // Resource is online/available 86 87 88 Unknown = 0, // Internal dummy/sentinel, or value is not applicable in this context 89 _Force32bit = 0x7fffffff, 90 91 } 92 93 // 94 // Describing network hosts 95 // 96 97 /// Different methods of describing the identity of a network host 98 enum ESteamNetworkingIdentityType { 99 100 // Dummy/empty/invalid. 101 // Please note that if we parse a string that we don't recognize 102 // but that appears reasonable, we will NOT use this type. Instead 103 // we'll use k_ESteamNetworkingIdentityType_UnknownType. 104 Invalid = 0, 105 106 // 107 // Basic platform-specific identifiers. 108 // 109 SteamID = 16, // 64-bit CSteamID 110 111 // 112 // Special identifiers. 113 // 114 115 // Use their IP address (and port) as their "identity". 116 // These types of identities are always unauthenticated. 117 // They are useful for porting plain sockets code, and other 118 // situations where you don't care about authentication. In this 119 // case, the local identity will be "localhost", 120 // and the remote address will be their network address. 121 // 122 // We use the same type for either IPv4 or IPv6, and 123 // the address is always store as IPv6. We use IPv4 124 // mapped addresses to handle IPv4. 125 IPAddress = 1, 126 127 // Generic string/binary blobs. It's up to your app to interpret this. 128 // This library can tell you if the remote host presented a certificate 129 // signed by somebody you have chosen to trust, with this identity on it. 130 // It's up to you to ultimately decide what this identity means. 131 GenericString = 2, 132 GenericBytes = 3, 133 134 // This identity type is used when we parse a string that looks like is a 135 // valid identity, just of a kind that we don't recognize. In this case, we 136 // can often still communicate with the peer! Allowing such identities 137 // for types we do not recognize useful is very useful for forward 138 // compatibility. 139 UnknownType = 4, 140 141 // Make sure this enum is stored in an int. 142 _Force32bit = 0x7fffffff, 143 144 } 145 146 /// "Fake IPs" are assigned to hosts, to make it easier to interface with 147 /// older code that assumed all hosts will have an IPv4 address 148 enum ESteamNetworkingFakeIPType { 149 150 Invalid, // Error, argument was not even an IP address, etc. 151 NotFake, // Argument was a valid IP, but was not from the reserved "fake" range 152 GlobalIPv4, // Globally unique (for a given app) IPv4 address. Address space managed by Steam 153 LocalIPv4, // Locally unique IPv4 address. Address space managed by the local process. For internal use only; should not be shared! 154 155 _Force32Bit = 0x7fffffff 156 157 } 158 159 160 private extern (C) { 161 void SteamNetworkingIPAddr_ToString(const SteamNetworkingIPAddr* pAddr, char* buf, size_t cbBuf, bool bWithPort); 162 bool SteamNetworkingIPAddr_ParseString(SteamNetworkingIPAddr* pAddr, const(char*) pszStr); 163 ESteamNetworkingFakeIPType SteamNetworkingIPAddr_GetFakeIPType(const(SteamNetworkingIPAddr)* pAddr); 164 void SteamNetworkingIdentity_ToString(const(SteamNetworkingIdentity)* pIdentity, char* buf, size_t cbBuf); 165 bool SteamNetworkingIdentity_ParseString(const(SteamNetworkingIdentity)* pIdentity, size_t sizeofIdentity, 166 const(char)* pszStr); 167 168 } 169 170 171 /// Store an IP and port. IPv6 is always used; IPv4 is represented using 172 /// "IPv4-mapped" addresses: IPv4 aa.bb.cc.dd => IPv6 ::ffff:aabb:ccdd 173 /// (RFC 4291 section 2.5.5.2.) 174 align (1) struct SteamNetworkingIPAddr { 175 176 /// RFC4038, section 4.2 177 struct IPv4MappedAddress { 178 ulong m_8zeros; 179 ushort m_0000; 180 ushort m_ffff; 181 ubyte[4] m_ip; // NOTE: As bytes, i.e. network byte order 182 } 183 184 union { 185 ubyte[16] m_ipv6; 186 IPv4MappedAddress m_ipv4; 187 }; 188 ushort m_port; // Host byte order 189 190 /// Set everything to zero. E.g. [::]:0 191 void Clear() { 192 193 m_ipv6 = 0; 194 m_port = 0; 195 196 } 197 198 /// Return true if the IP is ::0. (Doesn't check port.) 199 bool IsIPv6AllZeros() const { 200 201 import std.algorithm; 202 203 return m_ipv6[].all!q{ a == 0 }; 204 205 } 206 207 //void SetIPv6(const(ubyte)* ipv6, ushort nPort); // Set IPv6 address. IP is interpreted as bytes, so there are no endian issues. (Same as inaddr_in6.) The IP can be a mapped IPv4 address 208 //void SetIPv4(uint nIP, ushort nPort); // Sets to IPv4 mapped address. IP and port are in host byte order. 209 210 /// Return true if IP is mapped IPv4 211 bool IsIPv4() const { 212 213 return m_ipv4.m_8zeros == 0 && m_ipv4.m_0000 == 0 && m_ipv4.m_ffff == 0xffff; 214 215 } 216 //uint GetIPv4() const; // Returns IP in host byte order (e.g. aa.bb.cc.dd as 0xaabbccdd). Returns 0 if IP is not mapped IPv4. 217 //void SetIPv6LocalHost(ushort nPort = 0); // Set to the IPv6 localhost address ::1, and the specified port. 218 219 /// Return true if this identity is localhost. (Either IPv6 ::1, or IPv4 127.0.0.1) 220 //bool IsLocalHost() const; 221 222 // Max length of the buffer needed to hold IP formatted using ToString, including '\0' 223 // ([0123:4567:89ab:cdef:0123:4567:89ab:cdef]:12345) 224 enum k_cchMaxString = 48; 225 226 /// Print to a string, with or without the port. Mapped IPv4 addresses are printed 227 /// as dotted decimal (12.34.56.78), otherwise this will print the canonical 228 /// form according to RFC5952. If you include the port, IPv6 will be surrounded by 229 /// brackets, e.g. [::1:2]:80. Your buffer should be at least k_cchMaxString bytes 230 /// to avoid truncation 231 /// 232 /// See also SteamNetworkingIdentityRender 233 void ToString(char* buf, size_t cbBuf, bool bWithPort) const { 234 235 SteamNetworkingIPAddr_ToString(&this, buf, cbBuf, bWithPort); 236 237 } 238 239 /// Parse an IP address and optional port. If a port is not present, it is set to 0. 240 /// (This means that you cannot tell if a zero port was explicitly specified.) 241 bool ParseString(const(char)* pszStr) { 242 243 return SteamNetworkingIPAddr_ParseString(&this, pszStr); 244 245 } 246 247 /// See if two addresses are identical 248 //bool opEquals(const ref SteamNetworkingIPAddr x) const; 249 250 /// Classify address as FakeIP. This function never returns 251 /// k_ESteamNetworkingFakeIPType_Invalid. 252 ESteamNetworkingFakeIPType GetFakeIPType() const { 253 254 return SteamNetworkingIPAddr_GetFakeIPType(&this); 255 256 } 257 258 /// Return true if we are a FakeIP 259 bool IsFakeIP() const { 260 return GetFakeIPType() > ESteamNetworkingFakeIPType.NotFake; 261 } 262 263 } 264 265 /// An abstract way to represent the identity of a network host. All identities can 266 /// be represented as simple string. Furthermore, this string representation is actually 267 /// used on the wire in several places, even though it is less efficient, in order to 268 /// facilitate forward compatibility. (Old client code can handle an identity type that 269 /// it doesn't understand.) 270 align(1) struct SteamNetworkingIdentity { 271 272 /// Type of identity. 273 ESteamNetworkingIdentityType m_eType; 274 275 // 276 // Get/Set in various formats. 277 // 278 279 void Clear(); 280 bool IsInvalid() const; // Return true if we are the invalid type. Does not make any other validity checks (e.g. is SteamID actually valid) 281 282 void SetSteamID(CSteamID steamID); 283 CSteamID GetSteamID() const; // Return black CSteamID (!IsValid()) if identity is not a SteamID 284 void SetSteamID64(ulong steamID); // Takes SteamID as raw 64-bit number 285 ulong GetSteamID64() const; // Returns 0 if identity is not SteamID 286 287 void SetIPAddr(const ref SteamNetworkingIPAddr addr); // Set to specified IP:port 288 const(SteamNetworkingIPAddr*) GetIPAddr() const; // returns null if we are not an IP address. 289 void SetIPv4Addr(uint nIPv4, ushort nPort ); // Set to specified IPv4:port 290 uint GetIPv4() const; // returns 0 if we are not an IPv4 address. 291 292 ESteamNetworkingFakeIPType GetFakeIPType() const { 293 return m_eType == ESteamNetworkingIdentityType.IPAddress 294 ? m_ip.GetFakeIPType() 295 : ESteamNetworkingFakeIPType.Invalid; 296 } 297 bool IsFakeIP() const { 298 return GetFakeIPType() > ESteamNetworkingFakeIPType.NotFake; 299 } 300 301 // "localhost" is equivalent for many purposes to "anonymous." Our remote 302 // will identify us by the network address we use. 303 void SetLocalHost(); // Set to localhost. (We always use IPv6 ::1 for this, not 127.0.0.1) 304 bool IsLocalHost() const; // Return true if this identity is localhost. 305 306 bool SetGenericString(const char* pszString); // Returns false if invalid length 307 const(char*) GetGenericString() const; // Returns nullptr if not generic string type 308 309 bool SetGenericBytes(const void* data, size_t cbLen); // Returns false if invalid size. 310 const(ubyte*) GetGenericBytes(ref int cbLen) const; // Returns null if not generic bytes type 311 312 /// See if two identities are identical 313 //bool opEquals(const ref SteamNetworkingIdentity x) const; 314 315 /// Print to a human-readable string. This is suitable for debug messages 316 /// or any other time you need to encode the identity as a string. It has a 317 /// URL-like format (type:<type-data>). Your buffer should be at least 318 /// k_cchMaxString bytes big to avoid truncation. 319 /// 320 /// See also SteamNetworkingIPAddrRender 321 void ToString(char* buf, size_t cbBuf) const; 322 323 /// Parse back a string that was generated using ToString. If we don't understand the 324 /// string, but it looks "reasonable" (it matches the pattern type:<type-data> and doesn't 325 /// have any funky characters, etc), then we will return true, and the type is set to 326 /// k_ESteamNetworkingIdentityType_UnknownType. false will only be returned if the string 327 /// looks invalid. 328 bool ParseString(const char* pszStr); 329 330 // Max sizes 331 enum { 332 k_cchMaxString = 128, // Max length of the buffer needed to hold any identity, formatted in string format by ToString 333 k_cchMaxGenericString = 32, // Max length of the string for generic string identities. Including terminating '\0' 334 k_cbMaxGenericBytes = 32, 335 } 336 337 // 338 // Internal representation. Don't access this directly, use the accessors! 339 // 340 // Number of bytes that are relevant below. This MUST ALWAYS be 341 // set. (Use the accessors!) This is important to enable old code to work 342 // with new identity types. 343 int m_cbSize; 344 345 union { 346 ulong m_steamID64; 347 char[k_cchMaxGenericString] m_szGenericString; 348 ubyte[k_cbMaxGenericBytes] m_genericBytes; 349 char[k_cchMaxString] m_szUnknownRawString; 350 SteamNetworkingIPAddr m_ip; 351 uint[32] m_reserved; // Pad structure to leave easy room for future expansion 352 }; 353 }; 354 355 // 356 // Connection status 357 // 358 359 /// High level connection status 360 enum ESteamNetworkingConnectionState { 361 362 /// Dummy value used to indicate an error condition in the API. 363 /// Specified connection doesn't exist or has already been closed. 364 None = 0, 365 366 /// We are trying to establish whether peers can talk to each other, 367 /// whether they WANT to talk to each other, perform basic auth, 368 /// and exchange crypt keys. 369 /// 370 /// - For connections on the "client" side (initiated locally): 371 /// We're in the process of trying to establish a connection. 372 /// Depending on the connection type, we might not know who they are. 373 /// Note that it is not possible to tell if we are waiting on the 374 /// network to complete handshake packets, or for the application layer 375 /// to accept the connection. 376 /// 377 /// - For connections on the "server" side (accepted through listen socket): 378 /// We have completed some basic handshake and the client has presented 379 /// some proof of identity. The connection is ready to be accepted 380 /// using AcceptConnection(). 381 /// 382 /// In either case, any unreliable packets sent now are almost certain 383 /// to be dropped. Attempts to receive packets are guaranteed to fail. 384 /// You may send messages if the send mode allows for them to be queued. 385 /// but if you close the connection before the connection is actually 386 /// established, any queued messages will be discarded immediately. 387 /// (We will not attempt to flush the queue and confirm delivery to the 388 /// remote host, which ordinarily happens when a connection is closed.) 389 Connecting = 1, 390 391 /// Some connection types use a back channel or trusted 3rd party 392 /// for earliest communication. If the server accepts the connection, 393 /// then these connections switch into the rendezvous state. During this 394 /// state, we still have not yet established an end-to-end route (through 395 /// the relay network), and so if you send any messages unreliable, they 396 /// are going to be discarded. 397 FindingRoute = 2, 398 399 /// We've received communications from our peer (and we know 400 /// who they are) and are all good. If you close the connection now, 401 /// we will make our best effort to flush out any reliable sent data that 402 /// has not been acknowledged by the peer. (But note that this happens 403 /// from within the application process, so unlike a TCP connection, you are 404 /// not totally handing it off to the operating system to deal with it.) 405 Connected = 3, 406 407 /// Connection has been closed by our peer, but not closed locally. 408 /// The connection still exists from an API perspective. You must close the 409 /// handle to free up resources. If there are any messages in the inbound queue, 410 /// you may retrieve them. Otherwise, nothing may be done with the connection 411 /// except to close it. 412 /// 413 /// This stats is similar to CLOSE_WAIT in the TCP state machine. 414 ClosedByPeer = 4, 415 416 /// A disruption in the connection has been detected locally. (E.g. timeout, 417 /// local internet connection disrupted, etc.) 418 /// 419 /// The connection still exists from an API perspective. You must close the 420 /// handle to free up resources. 421 /// 422 /// Attempts to send further messages will fail. Any remaining received messages 423 /// in the queue are available. 424 ProblemDetectedLocally = 5, 425 426 // 427 // The following values are used internally and will not be returned by any API. 428 // We document them here to provide a little insight into the state machine that is used 429 // under the hood. 430 // 431 432 /// We've disconnected on our side, and from an API perspective the connection is closed. 433 /// No more data may be sent or received. All reliable data has been flushed, or else 434 /// we've given up and discarded it. We do not yet know for sure that the peer knows 435 /// the connection has been closed, however, so we're just hanging around so that if we do 436 /// get a packet from them, we can send them the appropriate packets so that they can 437 /// know why the connection was closed (and not have to rely on a timeout, which makes 438 /// it appear as if something is wrong). 439 FinWait = -1, 440 441 /// We've disconnected on our side, and from an API perspective the connection is closed. 442 /// No more data may be sent or received. From a network perspective, however, on the wire, 443 /// we have not yet given any indication to the peer that the connection is closed. 444 /// We are in the process of flushing out the last bit of reliable data. Once that is done, 445 /// we will inform the peer that the connection has been closed, and transition to the 446 /// FinWait state. 447 /// 448 /// Note that no indication is given to the remote host that we have closed the connection, 449 /// until the data has been flushed. If the remote host attempts to send us data, we will 450 /// do whatever is necessary to keep the connection alive until it can be closed properly. 451 /// But in fact the data will be discarded, since there is no way for the application to 452 /// read it back. Typically this is not a problem, as application protocols that utilize 453 /// the lingering functionality are designed for the remote host to wait for the response 454 /// before sending any more data. 455 Linger = -2, 456 457 /// Connection is completely inactive and ready to be destroyed 458 Dead = -3, 459 460 _Force32Bit = 0x7fffffff 461 462 } 463 464 /// Enumerate various causes of connection termination. These are designed to work similar 465 /// to HTTP error codes: the numeric range gives you a rough classification as to the source 466 /// of the problem. 467 enum ESteamNetConnectionEnd { 468 // Invalid/sentinel value 469 Invalid = 0, 470 471 // 472 // Application codes. These are the values you will pass to 473 // ISteamNetworkingSockets::CloseConnection. You can use these codes if 474 // you want to plumb through application-specific reason codes. If you don't 475 // need this facility, feel free to always pass 476 // k_ESteamNetConnectionEnd_App_Generic. 477 // 478 // The distinction between "normal" and "exceptional" termination is 479 // one you may use if you find useful, but it's not necessary for you 480 // to do so. The only place where we distinguish between normal and 481 // exceptional is in connection analytics. If a significant 482 // proportion of connections terminates in an exceptional manner, 483 // this can trigger an alert. 484 // 485 486 // 1xxx: Application ended the connection in a "usual" manner. 487 // E.g.: user intentionally disconnected from the server, 488 // gameplay ended normally, etc 489 App_Min = 1000, 490 App_Generic = App_Min, 491 // Use codes in this range for "normal" disconnection 492 App_Max = 1999, 493 494 // 2xxx: Application ended the connection in some sort of exceptional 495 // or unusual manner that might indicate a bug or configuration 496 // issue. 497 // 498 AppException_Min = 2000, 499 AppException_Generic = AppException_Min, 500 // Use codes in this range for "unusual" disconnection 501 AppException_Max = 2999, 502 503 // 504 // System codes. These will be returned by the system when 505 // the connection state is k_ESteamNetworkingConnectionState_ClosedByPeer 506 // or k_ESteamNetworkingConnectionState_ProblemDetectedLocally. It is 507 // illegal to pass a code in this range to ISteamNetworkingSockets::CloseConnection 508 // 509 510 // 3xxx: Connection failed or ended because of problem with the 511 // local host or their connection to the Internet. 512 Local_Min = 3000, 513 514 // You cannot do what you want to do because you're running in offline mode. 515 Local_OfflineMode = 3001, 516 517 // We're having trouble contacting many (perhaps all) relays. 518 // Since it's unlikely that they all went offline at once, the best 519 // explanation is that we have a problem on our end. Note that we don't 520 // bother distinguishing between "many" and "all", because in practice, 521 // it takes time to detect a connection problem, and by the time 522 // the connection has timed out, we might not have been able to 523 // actively probe all of the relay clusters, even if we were able to 524 // contact them at one time. So this code just means that: 525 // 526 // * We don't have any recent successful communication with any relay. 527 // * We have evidence of recent failures to communicate with multiple relays. 528 Local_ManyRelayConnectivity = 3002, 529 530 // A hosted server is having trouble talking to the relay 531 // that the client was using, so the problem is most likely 532 // on our end 533 Local_HostedServerPrimaryRelay = 3003, 534 535 // We're not able to get the SDR network config. This is 536 // *almost* always a local issue, since the network config 537 // comes from the CDN, which is pretty darn reliable. 538 Local_NetworkConfig = 3004, 539 540 // Steam rejected our request because we don't have rights 541 // to do this. 542 Local_Rights = 3005, 543 544 // ICE P2P rendezvous failed because we were not able to 545 // determine our "public" address (e.g. reflexive address via STUN) 546 // 547 // If relay fallback is available (it always is on Steam), then 548 // this is only used internally and will not be returned as a high 549 // level failure. 550 Local_P2P_ICE_NoPublicAddresses = 3006, 551 552 Local_Max = 3999, 553 554 // 4xxx: Connection failed or ended, and it appears that the 555 // cause does NOT have to do with the local host or their 556 // connection to the Internet. It could be caused by the 557 // remote host, or it could be somewhere in between. 558 Remote_Min = 4000, 559 560 // The connection was lost, and as far as we can tell our connection 561 // to relevant services (relays) has not been disrupted. This doesn't 562 // mean that the problem is "their fault", it just means that it doesn't 563 // appear that we are having network issues on our end. 564 Remote_Timeout = 4001, 565 566 // Something was invalid with the cert or crypt handshake 567 // info you gave me, I don't understand or like your key types, 568 // etc. 569 Remote_BadCrypt = 4002, 570 571 // You presented me with a cert that was I was able to parse 572 // and *technically* we could use encrypted communication. 573 // But there was a problem that prevents me from checking your identity 574 // or ensuring that somebody int he middle can't observe our communication. 575 // E.g.: - the CA key was missing (and I don't accept unsigned certs) 576 // - The CA key isn't one that I trust, 577 // - The cert doesn't was appropriately restricted by app, user, time, data center, etc. 578 // - The cert wasn't issued to you. 579 // - etc 580 Remote_BadCert = 4003, 581 582 // These will never be returned 583 //k_ESteamNetConnectionEnd_Remote_NotLoggedIn_DEPRECATED = 4004, 584 //k_ESteamNetConnectionEnd_Remote_NotRunningApp_DEPRECATED = 4005, 585 586 // Something wrong with the protocol version you are using. 587 // (Probably the code you are running is too old.) 588 Remote_BadProtocolVersion = 4006, 589 590 // NAT punch failed failed because we never received any public 591 // addresses from the remote host. (But we did receive some 592 // signals form them.) 593 // 594 // If relay fallback is available (it always is on Steam), then 595 // this is only used internally and will not be returned as a high 596 // level failure. 597 Remote_P2P_ICE_NoPublicAddresses = 4007, 598 599 Remote_Max = 4999, 600 601 // 5xxx: Connection failed for some other reason. 602 Misc_Min = 5000, 603 604 // A failure that isn't necessarily the result of a software bug, 605 // but that should happen rarely enough that it isn't worth specifically 606 // writing UI or making a localized message for. 607 // The debug string should contain further details. 608 Misc_Generic = 5001, 609 610 // Generic failure that is most likely a software bug. 611 Misc_InternalError = 5002, 612 613 // The connection to the remote host timed out, but we 614 // don't know if the problem is on our end, in the middle, 615 // or on their end. 616 Misc_Timeout = 5003, 617 618 //k_ESteamNetConnectionEnd_Misc_RelayConnectivity_DEPRECATED = 5004, 619 620 // There's some trouble talking to Steam. 621 Misc_SteamConnectivity = 5005, 622 623 // A server in a dedicated hosting situation has no relay sessions 624 // active with which to talk back to a client. (It's the client's 625 // job to open and maintain those sessions.) 626 Misc_NoRelaySessionsToClient = 5006, 627 628 // While trying to initiate a connection, we never received 629 // *any* communication from the peer. 630 //k_ESteamNetConnectionEnd_Misc_ServerNeverReplied = 5007, 631 632 // P2P rendezvous failed in a way that we don't have more specific 633 // information 634 Misc_P2P_Rendezvous = 5008, 635 636 // NAT punch failed, probably due to NAT/firewall configuration. 637 // 638 // If relay fallback is available (it always is on Steam), then 639 // this is only used internally and will not be returned as a high 640 // level failure. 641 Misc_P2P_NAT_Firewall = 5009, 642 643 // Our peer replied that it has no record of the connection. 644 // This should not happen ordinarily, but can happen in a few 645 // exception cases: 646 // 647 // - This is an old connection, and the peer has already cleaned 648 // up and forgotten about it. (Perhaps it timed out and they 649 // closed it and were not able to communicate this to us.) 650 // - A bug or internal protocol error has caused us to try to 651 // talk to the peer about the connection before we received 652 // confirmation that the peer has accepted the connection. 653 // - The peer thinks that we have closed the connection for some 654 // reason (perhaps a bug), and believes that is it is 655 // acknowledging our closure. 656 Misc_PeerSentNoConnection = 5010, 657 658 Misc_Max = 5999, 659 660 _Force32Bit = 0x7fffffff 661 662 } 663 664 /// Max length, in bytes (including null terminator) of the reason string 665 /// when a connection is closed. 666 enum int k_cchSteamNetworkingMaxConnectionCloseReason = 128; 667 668 /// Max length, in bytes (include null terminator) of debug description 669 /// of a connection. 670 enum int k_cchSteamNetworkingMaxConnectionDescription = 128; 671 672 enum int k_nSteamNetworkConnectionInfoFlags_Unauthenticated = 1; // We don't have a certificate for the remote host. 673 enum int k_nSteamNetworkConnectionInfoFlags_Unencrypted = 2; // Information is being sent out over a wire unencrypted (by this library) 674 enum int k_nSteamNetworkConnectionInfoFlags_LoopbackBuffers = 4; // Internal loopback buffers. Won't be true for localhost. (You can check the address to determine that.) This implies k_nSteamNetworkConnectionInfoFlags_FastLAN 675 enum int k_nSteamNetworkConnectionInfoFlags_Fast = 8; // The connection is "fast" and "reliable". Either internal/localhost (check the address to find out), or the peer is on the same LAN. (Probably. It's based on the address and the ping time, this is actually hard to determine unambiguously). 676 enum int k_nSteamNetworkConnectionInfoFlags_Relayed = 16; // The connection is relayed somehow (SDR or TURN). 677 enum int k_nSteamNetworkConnectionInfoFlags_DualWifi = 32; // We're taking advantage of dual-wifi multi-path 678 679 /// Describe the state of a connection. 680 struct SteamNetConnectionInfo_t { 681 682 /// Who is on the other end? Depending on the connection type and phase of the connection, we might not know 683 SteamNetworkingIdentity m_identityRemote; 684 685 /// Arbitrary user data set by the local application code 686 long m_nUserData; 687 688 /// Handle to listen socket this was connected on, or k_HSteamListenSocket_Invalid if we initiated the connection 689 HSteamListenSocket m_hListenSocket; 690 691 /// Remote address. Might be all 0's if we don't know it, or if this is N/A. 692 /// (E.g. Basically everything except direct UDP connection.) 693 SteamNetworkingIPAddr m_addrRemote; 694 ushort m__pad1; 695 696 /// What data center is the remote host in? (0 if we don't know.) 697 SteamNetworkingPOPID m_idPOPRemote; 698 699 /// What relay are we using to communicate with the remote host? 700 /// (0 if not applicable.) 701 SteamNetworkingPOPID m_idPOPRelay; 702 703 /// High level state of the connection 704 ESteamNetworkingConnectionState m_eState; 705 706 /// Basic cause of the connection termination or problem. 707 /// See ESteamNetConnectionEnd for the values used 708 int m_eEndReason; 709 710 /// Human-readable, but non-localized explanation for connection 711 /// termination or problem. This is intended for debugging / 712 /// diagnostic purposes only, not to display to users. It might 713 /// have some details specific to the issue. 714 char[k_cchSteamNetworkingMaxConnectionCloseReason] m_szEndDebug; 715 716 /// Debug description. This includes the internal connection ID, 717 /// connection type (and peer information), and any name 718 /// given to the connection by the app. This string is used in various 719 /// internal logging messages. 720 char[k_cchSteamNetworkingMaxConnectionDescription] m_szConnectionDescription; 721 722 /// Misc flags. Bitmask of k_nSteamNetworkConnectionInfoFlags_Xxxx 723 int m_nFlags; 724 725 /// Internal stuff, room to change API easily 726 uint[63] reserved; 727 728 } 729 730 static assert(SteamNetConnectionInfo_t.sizeof == 696); 731 static assert(SteamNetConnectionInfo_t.alignof == 4); 732 733 /// Quick connection state, pared down to something you could call 734 /// more frequently without it being too big of a perf hit. 735 struct SteamNetworkingQuickConnectionStatus { 736 737 /// High level state of the connection 738 ESteamNetworkingConnectionState m_eState; 739 740 /// Current ping (ms) 741 int m_nPing; 742 743 /// Connection quality measured locally, 0...1. (Percentage of packets delivered 744 /// end-to-end in order). 745 float m_flConnectionQualityLocal; 746 747 /// Packet delivery success rate as observed from remote host 748 float m_flConnectionQualityRemote; 749 750 /// Current data rates from recent history. 751 float m_flOutPacketsPerSec; 752 float m_flOutBytesPerSec; 753 float m_flInPacketsPerSec; 754 float m_flInBytesPerSec; 755 756 /// Estimate rate that we believe that we can send data to our peer. 757 /// Note that this could be significantly higher than m_flOutBytesPerSec, 758 /// meaning the capacity of the channel is higher than you are sending data. 759 /// (That's OK!) 760 int m_nSendRateBytesPerSecond; 761 762 /// Number of bytes pending to be sent. This is data that you have recently 763 /// requested to be sent but has not yet actually been put on the wire. The 764 /// reliable number ALSO includes data that was previously placed on the wire, 765 /// but has now been scheduled for re-transmission. Thus, it's possible to 766 /// observe m_cbPendingReliable increasing between two checks, even if no 767 /// calls were made to send reliable data between the checks. Data that is 768 /// awaiting the Nagle delay will appear in these numbers. 769 int m_cbPendingUnreliable; 770 int m_cbPendingReliable; 771 772 /// Number of bytes of reliable data that has been placed the wire, but 773 /// for which we have not yet received an acknowledgment, and thus we may 774 /// have to re-transmit. 775 int m_cbSentUnackedReliable; 776 777 /// If you asked us to send a message right now, how long would that message 778 /// sit in the queue before we actually started putting packets on the wire? 779 /// (And assuming Nagle does not cause any packets to be delayed.) 780 /// 781 /// In general, data that is sent by the application is limited by the 782 /// bandwidth of the channel. If you send data faster than this, it must 783 /// be queued and put on the wire at a metered rate. Even sending a small amount 784 /// of data (e.g. a few MTU, say ~3k) will require some of the data to be delayed 785 /// a bit. 786 /// 787 /// In general, the estimated delay will be approximately equal to 788 /// 789 /// ( m_cbPendingUnreliable+m_cbPendingReliable ) / m_nSendRateBytesPerSecond 790 /// 791 /// plus or minus one MTU. It depends on how much time has elapsed since the last 792 /// packet was put on the wire. For example, the queue might have *just* been emptied, 793 /// and the last packet placed on the wire, and we are exactly up against the send 794 /// rate limit. In that case we might need to wait for one packet's worth of time to 795 /// elapse before we can send again. On the other extreme, the queue might have data 796 /// in it waiting for Nagle. (This will always be less than one packet, because as soon 797 /// as we have a complete packet we would send it.) In that case, we might be ready 798 /// to send data now, and this value will be 0. 799 SteamNetworkingMicroseconds m_usecQueueTime; 800 801 /// Internal stuff, room to change API easily 802 uint[16] reserved; 803 804 } 805 806 // 807 // Network messages 808 // 809 810 /// Max size of a single message that we can SEND. 811 /// Note: We might be wiling to receive larger messages, 812 /// and our peer might, too. 813 enum int k_cbMaxSteamNetworkingSocketsMessageSizeSend = 512 * 1024; 814 815 /// A message that has been received. 816 struct SteamNetworkingMessage_t { 817 818 /// Message payload 819 void* m_pData; 820 821 /// Size of the payload. 822 int m_cbSize; 823 824 /// For messages received on connections: what connection did this come from? 825 /// For outgoing messages: what connection to send it to? 826 /// Not used when using the ISteamNetworkingMessages interface 827 HSteamNetConnection m_conn; 828 829 /// For inbound messages: Who sent this to us? 830 /// For outbound messages on connections: not used. 831 /// For outbound messages on the ad-hoc ISteamNetworkingMessages interface: who should we send this to? 832 SteamNetworkingIdentity m_identityPeer; 833 834 /// For messages received on connections, this is the user data 835 /// associated with the connection. 836 /// 837 /// This is *usually* the same as calling GetConnection() and then 838 /// fetching the user data associated with that connection, but for 839 /// the following subtle differences: 840 /// 841 /// - This user data will match the connection's user data at the time 842 /// is captured at the time the message is returned by the API. 843 /// If you subsequently change the userdata on the connection, 844 /// this won't be updated. 845 /// - This is an inline call, so it's *much* faster. 846 /// - You might have closed the connection, so fetching the user data 847 /// would not be possible. 848 /// 849 /// Not used when sending messages. 850 long m_nConnUserData; 851 852 /// Local timestamp when the message was received 853 /// Not used for outbound messages. 854 SteamNetworkingMicroseconds m_usecTimeReceived; 855 856 /// Message number assigned by the sender. This is not used for outbound 857 /// messages. Note that if multiple lanes are used, each lane has its own 858 /// message numbers, which are assigned sequentially, so messages from 859 /// different lanes will share the same numbers. 860 long m_nMessageNumber; 861 862 /// Function used to free up m_pData. This mechanism exists so that 863 /// apps can create messages with buffers allocated from their own 864 /// heap, and pass them into the library. This function will 865 /// usually be something like: 866 /// 867 /// free( pMsg->m_pData ); 868 void function(SteamNetworkingMessage_t*) m_pfnFreeData; 869 870 /// Function to used to decrement the internal reference count and, if 871 /// it's zero, release the message. You should not set this function pointer, 872 /// or need to access this directly! Use the Release() function instead! 873 void function(SteamNetworkingMessage_t*) m_pfnRelease; 874 875 /// When using ISteamNetworkingMessages, the channel number the message was received on 876 /// (Not used for messages sent or received on "connections") 877 int m_nChannel; 878 879 /// Bitmask of k_nSteamNetworkingSend_xxx flags. 880 /// For received messages, only the k_nSteamNetworkingSend_Reliable bit is valid. 881 /// For outbound messages, all bits are relevant 882 int m_nFlags; 883 884 /// Arbitrary user data that you can use when sending messages using 885 /// ISteamNetworkingUtils::AllocateMessage and ISteamNetworkingSockets::SendMessage. 886 /// (The callback you set in m_pfnFreeData might use this field.) 887 /// 888 /// Not used for received messages. 889 long m_nUserData; 890 891 /// For outbound messages, which lane to use? See ISteamNetworkingSockets::ConfigureConnectionLanes. 892 /// For inbound messages, what lane was the message received on? 893 ushort m_idxLane; 894 ushort _pad1__; 895 896 /// You MUST call this when you're done with the object, 897 /// to free up memory, etc. 898 void Release() { 899 900 m_pfnRelease(&this); 901 902 } 903 904 // For code compatibility, some accessors 905 uint GetSize() const { return m_cbSize; } 906 const(void*) GetData() const { return m_pData; } 907 int GetChannel() const { return m_nChannel; } 908 HSteamNetConnection GetConnection() const { return m_conn; } 909 long GetConnectionUserData() const { return m_nConnUserData; } 910 SteamNetworkingMicroseconds GetTimeReceived() const { return m_usecTimeReceived; } 911 long GetMessageNumber() const { return m_nMessageNumber; } 912 913 } 914 915 // 916 // Flags used to set options for message sending 917 // 918 919 // Send the message unreliably. Can be lost. Messages *can* be larger than a 920 // single MTU (UDP packet), but there is no retransmission, so if any piece 921 // of the message is lost, the entire message will be dropped. 922 // 923 // The sending API does have some knowledge of the underlying connection, so 924 // if there is no NAT-traversal accomplished or there is a recognized adjustment 925 // happening on the connection, the packet will be batched until the connection 926 // is open again. 927 // 928 // Migration note: This is not exactly the same as k_EP2PSendUnreliable! You 929 // probably want k_ESteamNetworkingSendType_UnreliableNoNagle 930 enum int k_nSteamNetworkingSend_Unreliable = 0; 931 932 // Disable Nagle's algorithm. 933 // By default, Nagle's algorithm is applied to all outbound messages. This means 934 // that the message will NOT be sent immediately, in case further messages are 935 // sent soon after you send this, which can be grouped together. Any time there 936 // is enough buffered data to fill a packet, the packets will be pushed out immediately, 937 // but partially-full packets not be sent until the Nagle timer expires. See 938 // ISteamNetworkingSockets::FlushMessagesOnConnection, ISteamNetworkingMessages::FlushMessagesToUser 939 // 940 // NOTE: Don't just send every message without Nagle because you want packets to get there 941 // quicker. Make sure you understand the problem that Nagle is solving before disabling it. 942 // If you are sending small messages, often many at the same time, then it is very likely that 943 // it will be more efficient to leave Nagle enabled. A typical proper use of this flag is 944 // when you are sending what you know will be the last message sent for a while (e.g. the last 945 // in the server simulation tick to a particular client), and you use this flag to flush all 946 // messages. 947 enum int k_nSteamNetworkingSend_NoNagle = 1; 948 949 // Send a message unreliably, bypassing Nagle's algorithm for this message and any messages 950 // currently pending on the Nagle timer. This is equivalent to using k_ESteamNetworkingSend_Unreliable 951 // and then immediately flushing the messages using ISteamNetworkingSockets::FlushMessagesOnConnection 952 // or ISteamNetworkingMessages::FlushMessagesToUser. (But using this flag is more efficient since you 953 // only make one API call.) 954 enum int k_nSteamNetworkingSend_UnreliableNoNagle = k_nSteamNetworkingSend_Unreliable|k_nSteamNetworkingSend_NoNagle; 955 956 // If the message cannot be sent very soon (because the connection is still doing some initial 957 // handshaking, route negotiations, etc), then just drop it. This is only applicable for unreliable 958 // messages. Using this flag on reliable messages is invalid. 959 enum int k_nSteamNetworkingSend_NoDelay = 4; 960 961 // Send an unreliable message, but if it cannot be sent relatively quickly, just drop it instead of queuing it. 962 // This is useful for messages that are not useful if they are excessively delayed, such as voice data. 963 // NOTE: The Nagle algorithm is not used, and if the message is not dropped, any messages waiting on the 964 // Nagle timer are immediately flushed. 965 // 966 // A message will be dropped under the following circumstances: 967 // - the connection is not fully connected. (E.g. the "Connecting" or "FindingRoute" states) 968 // - there is a sufficiently large number of messages queued up already such that the current message 969 // will not be placed on the wire in the next ~200ms or so. 970 // 971 // If a message is dropped for these reasons, k_EResultIgnored will be returned. 972 enum int k_nSteamNetworkingSend_UnreliableNoDelay = k_nSteamNetworkingSend_Unreliable|k_nSteamNetworkingSend_NoDelay|k_nSteamNetworkingSend_NoNagle; 973 974 // Reliable message send. Can send up to k_cbMaxSteamNetworkingSocketsMessageSizeSend bytes in a single message. 975 // Does fragmentation/re-assembly of messages under the hood, as well as a sliding window for 976 // efficient sends of large chunks of data. 977 // 978 // The Nagle algorithm is used. See notes on k_ESteamNetworkingSendType_Unreliable for more details. 979 // See k_ESteamNetworkingSendType_ReliableNoNagle, ISteamNetworkingSockets::FlushMessagesOnConnection, 980 // ISteamNetworkingMessages::FlushMessagesToUser 981 // 982 // Migration note: This is NOT the same as k_EP2PSendReliable, it's more like k_EP2PSendReliableWithBuffering 983 enum int k_nSteamNetworkingSend_Reliable = 8; 984 985 // Send a message reliably, but bypass Nagle's algorithm. 986 // 987 // Migration note: This is equivalent to k_EP2PSendReliable 988 enum int k_nSteamNetworkingSend_ReliableNoNagle = k_nSteamNetworkingSend_Reliable|k_nSteamNetworkingSend_NoNagle; 989 990 // By default, message sending is queued, and the work of encryption and talking to 991 // the operating system sockets, etc is done on a service thread. This is usually a 992 // a performance win when messages are sent from the "main thread". However, if this 993 // flag is set, and data is ready to be sent immediately (either from this message 994 // or earlier queued data), then that work will be done in the current thread, before 995 // the current call returns. If data is not ready to be sent (due to rate limiting 996 // or Nagle), then this flag has no effect. 997 // 998 // This is an advanced flag used to control performance at a very low level. For 999 // most applications running on modern hardware with more than one CPU core, doing 1000 // the work of sending on a service thread will yield the best performance. Only 1001 // use this flag if you have a really good reason and understand what you are doing. 1002 // Otherwise you will probably just make performance worse. 1003 enum int k_nSteamNetworkingSend_UseCurrentThread = 16; 1004 1005 // When sending a message using ISteamNetworkingMessages, automatically re-establish 1006 // a broken session, without returning k_EResultNoConnection. Without this flag, 1007 // if you attempt to send a message, and the session was proactively closed by the 1008 // peer, or an error occurred that disrupted communications, then you must close the 1009 // session using ISteamNetworkingMessages::CloseSessionWithUser before attempting to 1010 // send another message. (Or you can simply add this flag and retry.) In this way, 1011 // the disruption cannot go unnoticed, and a more clear order of events can be 1012 // ascertained. This is especially important when reliable messages are used, since 1013 // if the connection is disrupted, some of those messages will not have been delivered, 1014 // and it is in general not possible to know which. Although a 1015 // SteamNetworkingMessagesSessionFailed_t callback will be posted when an error occurs 1016 // to notify you that a failure has happened, callbacks are asynchronous, so it is not 1017 // possible to tell exactly when it happened. And because the primary purpose of 1018 // ISteamNetworkingMessages is to be like UDP, there is no notification when a peer closes 1019 // the session. 1020 // 1021 // If you are not using any reliable messages (e.g. you are using ISteamNetworkingMessages 1022 // exactly as a transport replacement for UDP-style datagrams only), you may not need to 1023 // know when an underlying connection fails, and so you may not need this notification. 1024 enum int k_nSteamNetworkingSend_AutoRestartBrokenSession = 32; 1025 1026 // 1027 // Ping location / measurement 1028 // 1029 1030 /// Object that describes a "location" on the Internet with sufficient 1031 /// detail that we can reasonably estimate an upper bound on the ping between 1032 /// the two hosts, even if a direct route between the hosts is not possible, 1033 /// and the connection must be routed through the Steam Datagram Relay network. 1034 /// This does not contain any information that identifies the host. Indeed, 1035 /// if two hosts are in the same building or otherwise have nearly identical 1036 /// networking characteristics, then it's valid to use the same location 1037 /// object for both of them. 1038 /// 1039 /// NOTE: This object should only be used in the same process! Do not serialize it, 1040 /// send it over the wire, or persist it in a file or database! If you need 1041 /// to do that, convert it to a string representation using the methods in 1042 /// ISteamNetworkingUtils(). 1043 struct SteamNetworkPingLocation_t { 1044 ubyte[512] m_data; 1045 }; 1046 1047 /// Max possible length of a ping location, in string format. This is 1048 /// an extremely conservative worst case value which leaves room for future 1049 /// syntax enhancements. Most strings in practice are a lot shorter. 1050 /// If you are storing many of these, you will very likely benefit from 1051 /// using dynamic memory. 1052 enum int k_cchMaxSteamNetworkingPingLocationString = 1024; 1053 1054 /// Special values that are returned by some functions that return a ping. 1055 enum int k_nSteamNetworkingPing_Failed = -1; 1056 enum int k_nSteamNetworkingPing_Unknown = -2; 1057 1058 // 1059 // Configuration values 1060 // 1061 1062 /// Configuration values can be applied to different types of objects. 1063 enum ESteamNetworkingConfigScope { 1064 1065 /// Get/set global option, or defaults. Even options that apply to more specific scopes 1066 /// have global scope, and you may be able to just change the global defaults. If you 1067 /// need different settings per connection (for example), then you will need to set those 1068 /// options at the more specific scope. 1069 Global = 1, 1070 1071 /// Some options are specific to a particular interface. Note that all connection 1072 /// and listen socket settings can also be set at the interface level, and they will 1073 /// apply to objects created through those interfaces. 1074 SocketsInterface = 2, 1075 1076 /// Options for a listen socket. Listen socket options can be set at the interface layer, 1077 /// if you have multiple listen sockets and they all use the same options. 1078 /// You can also set connection options on a listen socket, and they set the defaults 1079 /// for all connections accepted through this listen socket. (They will be used if you don't 1080 /// set a connection option.) 1081 ListenSocket = 3, 1082 1083 /// Options for a specific connection. 1084 Connection = 4, 1085 1086 _Force32Bit = 0x7fffffff 1087 1088 } 1089 1090 // Different configuration values have different data types 1091 enum ESteamNetworkingConfigDataType { 1092 1093 Int32 = 1, 1094 Int64 = 2, 1095 Float = 3, 1096 String = 4, 1097 Ptr = 5, 1098 1099 _Force32Bit = 0x7fffffff 1100 1101 } 1102 1103 /// Configuration options 1104 enum ESteamNetworkingConfigValue { 1105 1106 Invalid = 0, 1107 1108 // 1109 // Connection options 1110 // 1111 1112 /// [connection int32] Timeout value (in ms) to use when first connecting 1113 TimeoutInitial = 24, 1114 1115 /// [connection int32] Timeout value (in ms) to use after connection is established 1116 TimeoutConnected = 25, 1117 1118 /// [connection int32] Upper limit of buffered pending bytes to be sent, 1119 /// if this is reached SendMessage will return k_EResultLimitExceeded 1120 /// Default is 512k (524288 bytes) 1121 SendBufferSize = 9, 1122 1123 /// [connection int64] Get/set userdata as a configuration option. 1124 /// The default value is -1. You may want to set the user data as 1125 /// a config value, instead of using ISteamNetworkingSockets::SetConnectionUserData 1126 /// in two specific instances: 1127 /// 1128 /// - You wish to set the userdata atomically when creating 1129 /// an outbound connection, so that the userdata is filled in properly 1130 /// for any callbacks that happen. However, note that this trick 1131 /// only works for connections initiated locally! For incoming 1132 /// connections, multiple state transitions may happen and 1133 /// callbacks be queued, before you are able to service the first 1134 /// callback! Be careful! 1135 /// 1136 /// - You can set the default userdata for all newly created connections 1137 /// by setting this value at a higher level (e.g. on the listen 1138 /// socket or at the global level.) Then this default 1139 /// value will be inherited when the connection is created. 1140 /// This is useful in case -1 is a valid userdata value, and you 1141 /// wish to use something else as the default value so you can 1142 /// tell if it has been set or not. 1143 /// 1144 /// HOWEVER: once a connection is created, the effective value is 1145 /// then bound to the connection. Unlike other connection options, 1146 /// if you change it again at a higher level, the new value will not 1147 /// be inherited by connections. 1148 /// 1149 /// Using the userdata field in callback structs is not advised because 1150 /// of tricky race conditions. Instead, you might try one of these methods: 1151 /// 1152 /// - Use a separate map with the HSteamNetConnection as the key. 1153 /// - Fetch the userdata from the connection in your callback 1154 /// using ISteamNetworkingSockets::GetConnectionUserData, to 1155 // ensure you have the current value. 1156 ConnectionUserData = 40, 1157 1158 /// [connection int32] Minimum/maximum send rate clamp, 0 is no limit. 1159 /// This value will control the min/max allowed sending rate that 1160 /// bandwidth estimation is allowed to reach. Default is 0 (no-limit) 1161 SendRateMin = 10, 1162 SendRateMax = 11, 1163 1164 /// [connection int32] Nagle time, in microseconds. When SendMessage is called, if 1165 /// the outgoing message is less than the size of the MTU, it will be 1166 /// queued for a delay equal to the Nagle timer value. This is to ensure 1167 /// that if the application sends several small messages rapidly, they are 1168 /// coalesced into a single packet. 1169 /// See historical RFC 896. Value is in microseconds. 1170 /// Default is 5000us (5ms). 1171 NagleTime = 12, 1172 1173 /// [connection int32] Don't automatically fail IP connections that don't have 1174 /// strong auth. On clients, this means we will attempt the connection even if 1175 /// we don't know our identity or can't get a cert. On the server, it means that 1176 /// we won't automatically reject a connection due to a failure to authenticate. 1177 /// (You can examine the incoming connection and decide whether to accept it.) 1178 /// 1179 /// This is a dev configuration value, and you should not let users modify it in 1180 /// production. 1181 IP_AllowWithoutAuth = 23, 1182 1183 /// [connection int32] Do not send UDP packets with a payload of 1184 /// larger than N bytes. If you set this, k_ESteamNetworkingConfig_MTU_DataSize 1185 /// is automatically adjusted 1186 MTU_PacketSize = 32, 1187 1188 /// [connection int32] (read only) Maximum message size you can send that 1189 /// will not fragment, based on k_ESteamNetworkingConfig_MTU_PacketSize 1190 MTU_DataSize = 33, 1191 1192 /// [connection int32] Allow unencrypted (and unauthenticated) communication. 1193 /// 0: Not allowed (the default) 1194 /// 1: Allowed, but prefer encrypted 1195 /// 2: Allowed, and preferred 1196 /// 3: Required. (Fail the connection if the peer requires encryption.) 1197 /// 1198 /// This is a dev configuration value, since its purpose is to disable encryption. 1199 /// You should not let users modify it in production. (But note that it requires 1200 /// the peer to also modify their value in order for encryption to be disabled.) 1201 Unencrypted = 34, 1202 1203 /// [connection int32] Set this to 1 on outbound connections and listen sockets, 1204 /// to enable "symmetric connect mode", which is useful in the following 1205 /// common peer-to-peer use case: 1206 /// 1207 /// - The two peers are "equal" to each other. (Neither is clearly the "client" 1208 /// or "server".) 1209 /// - Either peer may initiate the connection, and indeed they may do this 1210 /// at the same time 1211 /// - The peers only desire a single connection to each other, and if both 1212 /// peers initiate connections simultaneously, a protocol is needed for them 1213 /// to resolve the conflict, so that we end up with a single connection. 1214 /// 1215 /// This use case is both common, and involves subtle race conditions and tricky 1216 /// pitfalls, which is why the API has support for dealing with it. 1217 /// 1218 /// If an incoming connection arrives on a listen socket or via custom signaling, 1219 /// and the application has not attempted to make a matching outbound connection 1220 /// in symmetric mode, then the incoming connection can be accepted as usual. 1221 /// A "matching" connection means that the relevant endpoint information matches. 1222 /// (At the time this comment is being written, this is only supported for P2P 1223 /// connections, which means that the peer identities must match, and the virtual 1224 /// port must match. At a later time, symmetric mode may be supported for other 1225 /// connection types.) 1226 /// 1227 /// If connections are initiated by both peers simultaneously, race conditions 1228 /// can arise, but fortunately, most of them are handled internally and do not 1229 /// require any special awareness from the application. However, there 1230 /// is one important case that application code must be aware of: 1231 /// If application code attempts an outbound connection using a ConnectXxx 1232 /// function in symmetric mode, and a matching incoming connection is already 1233 /// waiting on a listen socket, then instead of forming a new connection, 1234 /// the ConnectXxx call will accept the existing incoming connection, and return 1235 /// a connection handle to this accepted connection. 1236 /// IMPORTANT: in this case, a SteamNetConnectionStatusChangedCallback_t 1237 /// has probably *already* been posted to the queue for the incoming connection! 1238 /// (Once callbacks are posted to the queue, they are not modified.) It doesn't 1239 /// matter if the callback has not been consumed by the app. Thus, application 1240 /// code that makes use of symmetric connections must be aware that, when processing a 1241 /// SteamNetConnectionStatusChangedCallback_t for an incoming connection, the 1242 /// m_hConn may refer to a new connection that the app has has not 1243 /// seen before (the usual case), but it may also refer to a connection that 1244 /// has already been accepted implicitly through a call to Connect()! In this 1245 /// case, AcceptConnection() will return k_EResultDuplicateRequest. 1246 /// 1247 /// Only one symmetric connection to a given peer (on a given virtual port) 1248 /// may exist at any given time. If client code attempts to create a connection, 1249 /// and a (live) connection already exists on the local host, then either the 1250 /// existing connection will be accepted as described above, or the attempt 1251 /// to create a new connection will fail. Furthermore, linger mode functionality 1252 /// is not supported on symmetric connections. 1253 /// 1254 /// A more complicated race condition can arise if both peers initiate a connection 1255 /// at roughly the same time. In this situation, each peer will receive an incoming 1256 /// connection from the other peer, when the application code has already initiated 1257 /// an outgoing connection to that peer. The peers must resolve this conflict and 1258 /// decide who is going to act as the "server" and who will act as the "client". 1259 /// Typically the application does not need to be aware of this case as it is handled 1260 /// internally. On both sides, the will observe their outbound connection being 1261 /// "accepted", although one of them one have been converted internally to act 1262 /// as the "server". 1263 /// 1264 /// In general, symmetric mode should be all-or-nothing: do not mix symmetric 1265 /// connections with a non-symmetric connection that it might possible "match" 1266 /// with. If you use symmetric mode on any connections, then both peers should 1267 /// use it on all connections, and the corresponding listen socket, if any. The 1268 /// behaviour when symmetric and ordinary connections are mixed is not defined by 1269 /// this API, and you should not rely on it. (This advice only applies when connections 1270 /// might possibly "match". For example, it's OK to use all symmetric mode 1271 /// connections on one virtual port, and all ordinary, non-symmetric connections 1272 /// on a different virtual port, as there is no potential for ambiguity.) 1273 /// 1274 /// When using the feature, you should set it in the following situations on 1275 /// applicable objects: 1276 /// 1277 /// - When creating an outbound connection using ConnectXxx function 1278 /// - When creating a listen socket. (Note that this will automatically cause 1279 /// any accepted connections to inherit the flag.) 1280 /// - When using custom signaling, before accepting an incoming connection. 1281 /// 1282 /// Setting the flag on listen socket and accepted connections will enable the 1283 /// API to automatically deal with duplicate incoming connections, even if the 1284 /// local host has not made any outbound requests. (In general, such duplicate 1285 /// requests from a peer are ignored internally and will not be visible to the 1286 /// application code. The previous connection must be closed or resolved first.) 1287 SymmetricConnect = 37, 1288 1289 /// [connection int32] For connection types that use "virtual ports", this can be used 1290 /// to assign a local virtual port. For incoming connections, this will always be the 1291 /// virtual port of the listen socket (or the port requested by the remote host if custom 1292 /// signaling is used and the connection is accepted), and cannot be changed. For 1293 /// connections initiated locally, the local virtual port will default to the same as the 1294 /// requested remote virtual port, if you do not specify a different option when creating 1295 /// the connection. The local port is only relevant for symmetric connections, when 1296 /// determining if two connections "match." In this case, if you need the local and remote 1297 /// port to differ, you can set this value. 1298 /// 1299 /// You can also read back this value on listen sockets. 1300 /// 1301 /// This value should not be read or written in any other context. 1302 LocalVirtualPort = 38, 1303 1304 /// [connection int32] True to enable diagnostics reporting through 1305 /// generic platform UI. (Only available on Steam.) 1306 EnableDiagnosticsUI = 46, 1307 1308 // 1309 // Simulating network conditions 1310 // 1311 // These are global (not per-connection) because they apply at 1312 // a relatively low UDP layer. 1313 // 1314 1315 /// [global float, 0--100] Randomly discard N pct of packets instead of sending/recv 1316 /// This is a global option only, since it is applied at a low level 1317 /// where we don't have much context 1318 FakePacketLoss_Send = 2, 1319 FakePacketLoss_Recv = 3, 1320 1321 /// [global int32]. Delay all outbound/inbound packets by N ms 1322 FakePacketLag_Send = 4, 1323 FakePacketLag_Recv = 5, 1324 1325 /// [global float] 0-100 Percentage of packets we will add additional delay 1326 /// to (causing them to be reordered) 1327 FakePacketReorder_Send = 6, 1328 FakePacketReorder_Recv = 7, 1329 1330 /// [global int32] Extra delay, in ms, to apply to reordered packets. 1331 FakePacketReorder_Time = 8, 1332 1333 /// [global float 0--100] Globally duplicate some percentage of packets we send 1334 FakePacketDup_Send = 26, 1335 FakePacketDup_Recv = 27, 1336 1337 /// [global int32] Amount of delay, in ms, to delay duplicated packets. 1338 /// (We chose a random delay between 0 and this value) 1339 FakePacketDup_TimeMax = 28, 1340 1341 /// [global int32] Trace every UDP packet, similar to Wireshark or tcpdump. 1342 /// Value is max number of bytes to dump. -1 disables tracing. 1343 // 0 only traces the info but no actual data bytes 1344 PacketTraceMaxBytes = 41, 1345 1346 1347 // [global int32] Global UDP token bucket rate limits. 1348 // "Rate" refers to the steady state rate. (Bytes/sec, the 1349 // rate that tokens are put into the bucket.) "Burst" 1350 // refers to the max amount that could be sent in a single 1351 // burst. (In bytes, the max capacity of the bucket.) 1352 // Rate=0 disables the limiter entirely, which is the default. 1353 // Burst=0 disables burst. (This is not realistic. A 1354 // burst of at least 4K is recommended; the default is higher.) 1355 FakeRateLimit_Send_Rate = 42, 1356 FakeRateLimit_Send_Burst = 43, 1357 FakeRateLimit_Recv_Rate = 44, 1358 FakeRateLimit_Recv_Burst = 45, 1359 1360 // 1361 // Callbacks 1362 // 1363 1364 // On Steam, you may use the default Steam callback dispatch mechanism. If you prefer 1365 // to not use this dispatch mechanism (or you are not running with Steam), or you want 1366 // to associate specific functions with specific listen sockets or connections, you can 1367 // register them as configuration values. 1368 // 1369 // Note also that ISteamNetworkingUtils has some helpers to set these globally. 1370 1371 /// [connection FnSteamNetConnectionStatusChanged] Callback that will be invoked 1372 /// when the state of a connection changes. 1373 /// 1374 /// IMPORTANT: callbacks are dispatched to the handler that is in effect at the time 1375 /// the event occurs, which might be in another thread. For example, immediately after 1376 /// creating a listen socket, you may receive an incoming connection. And then immediately 1377 /// after this, the remote host may close the connection. All of this could happen 1378 /// before the function to create the listen socket has returned. For this reason, 1379 /// callbacks usually must be in effect at the time of object creation. This means 1380 /// you should set them when you are creating the listen socket or connection, or have 1381 /// them in effect so they will be inherited at the time of object creation. 1382 /// 1383 /// For example: 1384 /// 1385 /// exterm void MyStatusChangedFunc( SteamNetConnectionStatusChangedCallback_t *info ); 1386 /// SteamNetworkingConfigValue_t opt; opt.SetPtr( k_ESteamNetworkingConfig_Callback_ConnectionStatusChanged, MyStatusChangedFunc ); 1387 /// SteamNetworkingIPAddr localAddress; localAddress.Clear(); 1388 /// HSteamListenSocket hListenSock = SteamNetworkingSockets()->CreateListenSocketIP( localAddress, 1, &opt ); 1389 /// 1390 /// When accepting an incoming connection, there is no atomic way to switch the 1391 /// callback. However, if the connection is DOA, AcceptConnection() will fail, and 1392 /// you can fetch the state of the connection at that time. 1393 /// 1394 /// If all connections and listen sockets can use the same callback, the simplest 1395 /// method is to set it globally before you create any listen sockets or connections. 1396 Callback_ConnectionStatusChanged = 201, 1397 1398 /// [global FnSteamNetAuthenticationStatusChanged] Callback that will be invoked 1399 /// when our auth state changes. If you use this, install the callback before creating 1400 /// any connections or listen sockets, and don't change it. 1401 /// See: ISteamNetworkingUtils::SetGlobalCallback_SteamNetAuthenticationStatusChanged 1402 Callback_AuthStatusChanged = 202, 1403 1404 /// [global FnSteamRelayNetworkStatusChanged] Callback that will be invoked 1405 /// when our auth state changes. If you use this, install the callback before creating 1406 /// any connections or listen sockets, and don't change it. 1407 /// See: ISteamNetworkingUtils::SetGlobalCallback_SteamRelayNetworkStatusChanged 1408 Callback_RelayNetworkStatusChanged = 203, 1409 1410 /// [global FnSteamNetworkingMessagesSessionRequest] Callback that will be invoked 1411 /// when a peer wants to initiate a SteamNetworkingMessagesSessionRequest. 1412 /// See: ISteamNetworkingUtils::SetGlobalCallback_MessagesSessionRequest 1413 Callback_MessagesSessionRequest = 204, 1414 1415 /// [global FnSteamNetworkingMessagesSessionFailed] Callback that will be invoked 1416 /// when a session you have initiated, or accepted either fails to connect, or loses 1417 /// connection in some unexpected way. 1418 /// See: ISteamNetworkingUtils::SetGlobalCallback_MessagesSessionFailed 1419 Callback_MessagesSessionFailed = 205, 1420 1421 /// [global FnSteamNetworkingSocketsCreateConnectionSignaling] Callback that will 1422 /// be invoked when we need to create a signaling object for a connection 1423 /// initiated locally. See: ISteamNetworkingSockets::ConnectP2P, 1424 /// ISteamNetworkingMessages. 1425 Callback_CreateConnectionSignaling = 206, 1426 1427 /// [global FnSteamNetworkingFakeIPResult] Callback that's invoked when 1428 /// a FakeIP allocation finishes. See: ISteamNetworkingSockets::BeginAsyncRequestFakeIP, 1429 /// ISteamNetworkingUtils::SetGlobalCallback_FakeIPResult 1430 Callback_FakeIPResult = 207, 1431 1432 // 1433 // P2P connection settings 1434 // 1435 1436 // /// [listen socket int32] When you create a P2P listen socket, we will automatically 1437 // /// open up a UDP port to listen for LAN connections. LAN connections can be made 1438 // /// without any signaling: both sides can be disconnected from the Internet. 1439 // /// 1440 // /// This value can be set to zero to disable the feature. 1441 // k_ESteamNetworkingConfig_P2P_Discovery_Server_LocalPort = 101, 1442 // 1443 // /// [connection int32] P2P connections can perform broadcasts looking for the peer 1444 // /// on the LAN. 1445 // k_ESteamNetworkingConfig_P2P_Discovery_Client_RemotePort = 102, 1446 1447 /// [connection string] Comma-separated list of STUN servers that can be used 1448 /// for NAT piercing. If you set this to an empty string, NAT piercing will 1449 /// not be attempted. Also if "public" candidates are not allowed for 1450 /// P2P_Transport_ICE_Enable, then this is ignored. 1451 P2P_STUN_ServerList = 103, 1452 1453 /// [connection int32] What types of ICE candidates to share with the peer. 1454 /// See k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_xxx values 1455 P2P_Transport_ICE_Enable = 104, 1456 1457 /// [connection int32] When selecting P2P transport, add various 1458 /// penalties to the scores for selected transports. (Route selection 1459 /// scores are on a scale of milliseconds. The score begins with the 1460 /// route ping time and is then adjusted.) 1461 P2P_Transport_ICE_Penalty = 105, 1462 P2P_Transport_SDR_Penalty = 106, 1463 P2P_TURN_ServerList = 107, 1464 P2P_TURN_UserList = 108, 1465 P2P_TURN_PassList = 109, 1466 //k_ESteamNetworkingConfig_P2P_Transport_LANBeacon_Penalty = 107, 1467 1468 // 1469 // Settings for SDR relayed connections 1470 // 1471 1472 /// [int32 global] If the first N pings to a port all fail, mark that port as unavailable for 1473 /// a while, and try a different one. Some ISPs and routers may drop the first 1474 /// packet, so setting this to 1 may greatly disrupt communications. 1475 SDRClient_ConsecutitivePingTimeoutsFailInitial = 19, 1476 1477 /// [int32 global] If N consecutive pings to a port fail, after having received successful 1478 /// communication, mark that port as unavailable for a while, and try a 1479 /// different one. 1480 SDRClient_ConsecutitivePingTimeoutsFail = 20, 1481 1482 /// [int32 global] Minimum number of lifetime pings we need to send, before we think our estimate 1483 /// is solid. The first ping to each cluster is very often delayed because of NAT, 1484 /// routers not having the best route, etc. Until we've sent a sufficient number 1485 /// of pings, our estimate is often inaccurate. Keep pinging until we get this 1486 /// many pings. 1487 SDRClient_MinPingsBeforePingAccurate = 21, 1488 1489 /// [int32 global] Set all steam datagram traffic to originate from the same 1490 /// local port. By default, we open up a new UDP socket (on a different local 1491 /// port) for each relay. This is slightly less optimal, but it works around 1492 /// some routers that don't implement NAT properly. If you have intermittent 1493 /// problems talking to relays that might be NAT related, try toggling 1494 /// this flag 1495 SDRClient_SingleSocket = 22, 1496 1497 /// [global string] Code of relay cluster to force use. If not empty, we will 1498 /// only use relays in that cluster. E.g. 'iad' 1499 SDRClient_ForceRelayCluster = 29, 1500 1501 /// [connection string] For debugging, generate our own (unsigned) ticket, using 1502 /// the specified gameserver address. Router must be configured to accept unsigned 1503 /// tickets. 1504 SDRClient_DebugTicketAddress = 30, 1505 1506 /// [global string] For debugging. Override list of relays from the config with 1507 /// this set (maybe just one). Comma-separated list. 1508 SDRClient_ForceProxyAddr = 31, 1509 1510 /// [global string] For debugging. Force ping times to clusters to be the specified 1511 /// values. A comma separated list of <cluster>=<ms> values. E.g. "sto=32,iad=100" 1512 /// 1513 /// This is a dev configuration value, you probably should not let users modify it 1514 /// in production. 1515 SDRClient_FakeClusterPing = 36, 1516 1517 // 1518 // Log levels for debugging information of various subsystems. 1519 // Higher numeric values will cause more stuff to be printed. 1520 // See ISteamNetworkingUtils::SetDebugOutputFunction for more 1521 // information 1522 // 1523 // The default for all values is k_ESteamNetworkingSocketsDebugOutputType_Warning. 1524 // 1525 LogLevel_AckRTT = 13, // [connection int32] RTT calculations for inline pings and replies 1526 LogLevel_PacketDecode = 14, // [connection int32] log SNP packets send/recv 1527 LogLevel_Message = 15, // [connection int32] log each message send/recv 1528 LogLevel_PacketGaps = 16, // [connection int32] dropped packets 1529 LogLevel_P2PRendezvous = 17, // [connection int32] P2P rendezvous messages 1530 LogLevel_SDRRelayPings = 18, // [global int32] Ping relays 1531 1532 1533 // Deleted, do not use 1534 DELETED_EnumerateDevVars = 35, 1535 1536 _Force32Bit = 0x7fffffff 1537 1538 } 1539 1540 // Bitmask of types to share 1541 enum int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Default = -1; // Special value - use user defaults 1542 enum int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Disable = 0; // Do not do any ICE work at all or share any IP addresses with peer 1543 enum int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Relay = 1; // Relayed connection via TURN server. 1544 enum int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Private = 2; // host addresses that appear to be link-local or RFC1918 addresses 1545 enum int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Public = 4; // STUN reflexive addresses, or host address that isn't a "private" address 1546 enum int k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_All = 0x7fffffff; 1547 1548 /// In a few places we need to set configuration options on listen sockets and connections, and 1549 /// have them take effect *before* the listen socket or connection really starts doing anything. 1550 /// Creating the object and then setting the options "immediately" after creation doesn't work 1551 /// completely, because network packets could be received between the time the object is created and 1552 /// when the options are applied. To set options at creation time in a reliable way, they must be 1553 /// passed to the creation function. This structure is used to pass those options. 1554 /// 1555 /// For the meaning of these fields, see ISteamNetworkingUtils::SetConfigValue. Basically 1556 /// when the object is created, we just iterate over the list of options and call 1557 /// ISteamNetworkingUtils::SetConfigValueStruct, where the scope arguments are supplied by the 1558 /// object being created. 1559 struct SteamNetworkingConfigValue_t { 1560 1561 /// Which option is being set 1562 ESteamNetworkingConfigValue m_eValue; 1563 1564 /// Which field below did you fill in? 1565 ESteamNetworkingConfigDataType m_eDataType; 1566 1567 /// Option value 1568 union Value_t { 1569 1570 int m_int32; 1571 long m_int64; 1572 float m_float; 1573 const(char)* m_string; // Points to your '\0'-terminated buffer 1574 void* m_ptr; 1575 } 1576 1577 Value_t m_val; 1578 1579 // 1580 // Shortcut helpers to set the type and value in a single call 1581 // 1582 void SetInt32(ESteamNetworkingConfigValue eVal, int data) { 1583 m_eValue = eVal; 1584 m_eDataType = ESteamNetworkingConfigDataType.Int32; 1585 m_val.m_int32 = data; 1586 } 1587 1588 void SetInt64(ESteamNetworkingConfigValue eVal, long data) { 1589 m_eValue = eVal; 1590 m_eDataType = ESteamNetworkingConfigDataType.Int64; 1591 m_val.m_int64 = data; 1592 } 1593 1594 void SetFloat(ESteamNetworkingConfigValue eVal, float data) { 1595 m_eValue = eVal; 1596 m_eDataType = ESteamNetworkingConfigDataType.Float; 1597 m_val.m_float = data; 1598 } 1599 1600 void SetPtr(ESteamNetworkingConfigValue eVal, void* data) { 1601 m_eValue = eVal; 1602 m_eDataType = ESteamNetworkingConfigDataType.Ptr; 1603 m_val.m_ptr = data; 1604 } 1605 1606 void SetString(ESteamNetworkingConfigValue eVal, const(char)* data) { // WARNING - Just saves your pointer. Does NOT make a copy of the string 1607 m_eValue = eVal; 1608 m_eDataType = ESteamNetworkingConfigDataType.Ptr; 1609 m_val.m_string = data; 1610 } 1611 1612 } 1613 1614 /// Return value of ISteamNetworkintgUtils::GetConfigValue 1615 enum ESteamNetworkingGetConfigValueResult { 1616 1617 BadValue = -1, // No such configuration value 1618 BadScopeObj = -2, // Bad connection handle, etc 1619 BufferTooSmall = -3, // Couldn't fit the result in your buffer 1620 OK = 1, 1621 OKInherited = 2, // A value was not set at this level, but the effective (inherited) value was returned. 1622 1623 _Force32Bit = 0x7fffffff 1624 1625 } 1626 1627 // 1628 // Debug output 1629 // 1630 1631 /// Detail level for diagnostic output callback. 1632 /// See ISteamNetworkingUtils::SetDebugOutputFunction 1633 enum ESteamNetworkingSocketsDebugOutputType { 1634 1635 None = 0, 1636 Bug = 1, // You used the API incorrectly, or an internal error happened 1637 Error = 2, // Run-time error condition that isn't the result of a bug. (E.g. we are offline, cannot bind a port, etc) 1638 Important = 3, // Nothing is wrong, but this is an important notification 1639 Warning = 4, 1640 Msg = 5, // Recommended amount 1641 Verbose = 6, // Quite a bit 1642 Debug = 7, // Practically everything 1643 Everything = 8, // Wall of text, detailed packet contents breakdown, etc 1644 1645 _Force32Bit = 0x7fffffff 1646 1647 } 1648 1649 /// Setup callback for debug output, and the desired verbosity you want. 1650 alias FSteamNetworkingSocketsDebugOutput = void function(ESteamNetworkingSocketsDebugOutputType nType, 1651 const char* pszMsg); 1652 1653 // 1654 // Valve data centers 1655 // 1656 1657 /// Convert 3- or 4-character ID to 32-bit int. 1658 SteamNetworkingPOPID CalculateSteamNetworkingPOPIDFromString(const char* pszCode) { 1659 1660 // OK we made a bad decision when we decided how to pack 3-character codes into a uint32. We'd like to support 1661 // 4-character codes, but we don't want to break compatibility. The migration path has some subtleties that make 1662 // this nontrivial, and there are already some IDs stored in SQL. Ug, so the 4 character code "abcd" will 1663 // be encoded with the digits like "0xddaabbcc". 1664 // 1665 // Also: we don't currently use 1- or 2-character codes, but if ever do in the future, let's make sure don't read 1666 // past the end of the string and access uninitialized memory. (And if the string is empty, we always want 1667 // to return 0 and not read bytes past the '\0'.) 1668 // 1669 // There is also extra paranoia to make sure the bytes are not treated as signed. 1670 SteamNetworkingPOPID result = cast(ushort) cast(ubyte) pszCode[0] << 16U; 1671 if (pszCode[1]) { 1672 result |= (cast(ushort) cast(ubyte) pszCode[1] << 8U ); 1673 if (pszCode[2]) { 1674 result |= cast(ushort) cast(ubyte) pszCode[2] | (cast(ushort) cast(ubyte) pszCode[3] << 24U); 1675 } 1676 } 1677 return result; 1678 } 1679 1680 /+ 1681 1682 /// Unpack integer to string representation, including terminating '\0' 1683 /// 1684 /// See also SteamNetworkingPOPIDRender 1685 void GetSteamNetworkingLocationPOPStringFromID(int N)(SteamNetworkingPOPID id, ref char[N] szCode) { 1686 static assert( N >= 5, "Fixed-size buffer not big enough to hold SDR POP ID" ); 1687 szCode[0] = cast(char) (id >> 16U); 1688 szCode[1] = cast(char) (id >> 8U); 1689 szCode[2] = cast(char) (id); 1690 szCode[3] = cast(char) (id >> 24U); // See comment above about deep regret and sadness 1691 szCode[4] = 0; 1692 } 1693 1694 +/ 1695 1696 /// The POPID "dev" is used in non-production environments for testing. 1697 enum SteamNetworkingPOPID k_SteamDatagramPOPID_dev = (cast(uint)'d' << 16U) | (cast(uint)'e' << 8U ) | cast(uint)'v'; 1698 1699 /// Utility class for printing a SteamNetworkingPOPID. 1700 struct SteamNetworkingPOPIDRender { 1701 1702 //this(SteamNetworkingPOPID x) { GetSteamNetworkingLocationPOPStringFromID( x, buf ); } 1703 1704 const(char)* c_str() const return { return buf.ptr; } 1705 1706 private: 1707 1708 char[8] buf; 1709 1710 } 1711 1712 1713 /+ Implemented locally, not here 1714 1715 /////////////////////////////////////////////////////////////////////////////// 1716 // 1717 // Internal stuff 1718 #ifndef API_GEN 1719 1720 // For code compatibility 1721 typedef SteamNetworkingMessage_t ISteamNetworkingMessage; 1722 typedef SteamNetworkingErrMsg SteamDatagramErrMsg; 1723 1724 inline void SteamNetworkingIPAddr::Clear() { memset( this, 0, sizeof(*this) ); } 1725 inline bool SteamNetworkingIPAddr::IsIPv6AllZeros() const { const uint64 *q = (const uint64 *)m_ipv6; return q[0] == 0 && q[1] == 0; } 1726 inline void SteamNetworkingIPAddr::SetIPv6( const uint8 *ipv6, uint16 nPort ) { memcpy( m_ipv6, ipv6, 16 ); m_port = nPort; } 1727 inline void SteamNetworkingIPAddr::SetIPv4( uint32 nIP, uint16 nPort ) { m_ipv4.m_8zeros = 0; m_ipv4.m_0000 = 0; m_ipv4.m_ffff = 0xffff; m_ipv4.m_ip[0] = uint8(nIP>>24); m_ipv4.m_ip[1] = uint8(nIP>>16); m_ipv4.m_ip[2] = uint8(nIP>>8); m_ipv4.m_ip[3] = uint8(nIP); m_port = nPort; } 1728 inline bool SteamNetworkingIPAddr::IsIPv4() const { return m_ipv4.m_8zeros == 0 && m_ipv4.m_0000 == 0 && m_ipv4.m_ffff == 0xffff; } 1729 inline uint32 SteamNetworkingIPAddr::GetIPv4() const { return IsIPv4() ? ( (uint32(m_ipv4.m_ip[0])<<24) | (uint32(m_ipv4.m_ip[1])<<16) | (uint32(m_ipv4.m_ip[2])<<8) | uint32(m_ipv4.m_ip[3]) ) : 0; } 1730 inline void SteamNetworkingIPAddr::SetIPv6LocalHost( uint16 nPort ) { m_ipv4.m_8zeros = 0; m_ipv4.m_0000 = 0; m_ipv4.m_ffff = 0; m_ipv6[12] = 0; m_ipv6[13] = 0; m_ipv6[14] = 0; m_ipv6[15] = 1; m_port = nPort; } 1731 inline bool SteamNetworkingIPAddr::IsLocalHost() const { return ( m_ipv4.m_8zeros == 0 && m_ipv4.m_0000 == 0 && m_ipv4.m_ffff == 0 && m_ipv6[12] == 0 && m_ipv6[13] == 0 && m_ipv6[14] == 0 && m_ipv6[15] == 1 ) || ( GetIPv4() == 0x7f000001 ); } 1732 inline bool SteamNetworkingIPAddr::operator==(const SteamNetworkingIPAddr &x ) const { return memcmp( this, &x, sizeof(SteamNetworkingIPAddr) ) == 0; } 1733 1734 inline void SteamNetworkingIdentity::Clear() { memset( this, 0, sizeof(*this) ); } 1735 inline bool SteamNetworkingIdentity::IsInvalid() const { return m_eType == k_ESteamNetworkingIdentityType_Invalid; } 1736 inline void SteamNetworkingIdentity::SetSteamID( CSteamID steamID ) { SetSteamID64( steamID.ConvertToUint64() ); } 1737 inline CSteamID SteamNetworkingIdentity::GetSteamID() const { return CSteamID( GetSteamID64() ); } 1738 inline void SteamNetworkingIdentity::SetSteamID64( uint64 steamID ) { m_eType = k_ESteamNetworkingIdentityType_SteamID; m_cbSize = sizeof( m_steamID64 ); m_steamID64 = steamID; } 1739 inline uint64 SteamNetworkingIdentity::GetSteamID64() const { return m_eType == k_ESteamNetworkingIdentityType_SteamID ? m_steamID64 : 0; } 1740 inline void SteamNetworkingIdentity::SetIPAddr( const SteamNetworkingIPAddr &addr ) { m_eType = k_ESteamNetworkingIdentityType_IPAddress; m_cbSize = (int)sizeof(m_ip); m_ip = addr; } 1741 inline const SteamNetworkingIPAddr *SteamNetworkingIdentity::GetIPAddr() const { return m_eType == k_ESteamNetworkingIdentityType_IPAddress ? &m_ip : NULL; } 1742 inline void SteamNetworkingIdentity::SetIPv4Addr( uint32 nIPv4, uint16 nPort ) { m_eType = k_ESteamNetworkingIdentityType_IPAddress; m_cbSize = (int)sizeof(m_ip); m_ip.SetIPv4( nIPv4, nPort ); } 1743 inline uint32 SteamNetworkingIdentity::GetIPv4() const { return m_eType == k_ESteamNetworkingIdentityType_IPAddress ? m_ip.GetIPv4() : 0; } 1744 inline ESteamNetworkingFakeIPType SteamNetworkingIdentity::GetFakeIPType() const { return m_eType == k_ESteamNetworkingIdentityType_IPAddress ? m_ip.GetFakeIPType() : k_ESteamNetworkingFakeIPType_Invalid; } 1745 inline void SteamNetworkingIdentity::SetLocalHost() { m_eType = k_ESteamNetworkingIdentityType_IPAddress; m_cbSize = (int)sizeof(m_ip); m_ip.SetIPv6LocalHost(); } 1746 inline bool SteamNetworkingIdentity::IsLocalHost() const { return m_eType == k_ESteamNetworkingIdentityType_IPAddress && m_ip.IsLocalHost(); } 1747 inline bool SteamNetworkingIdentity::SetGenericString( const char *pszString ) { size_t l = strlen( pszString ); if ( l >= sizeof(m_szGenericString) ) return false; 1748 m_eType = k_ESteamNetworkingIdentityType_GenericString; m_cbSize = int(l+1); memcpy( m_szGenericString, pszString, m_cbSize ); return true; } 1749 inline const char *SteamNetworkingIdentity::GetGenericString() const { return m_eType == k_ESteamNetworkingIdentityType_GenericString ? m_szGenericString : NULL; } 1750 inline bool SteamNetworkingIdentity::SetGenericBytes( const void *data, size_t cbLen ) { if ( cbLen > sizeof(m_genericBytes) ) return false; 1751 m_eType = k_ESteamNetworkingIdentityType_GenericBytes; m_cbSize = int(cbLen); memcpy( m_genericBytes, data, m_cbSize ); return true; } 1752 inline const uint8 *SteamNetworkingIdentity::GetGenericBytes( int &cbLen ) const { if ( m_eType != k_ESteamNetworkingIdentityType_GenericBytes ) return NULL; 1753 cbLen = m_cbSize; return m_genericBytes; } 1754 inline bool SteamNetworkingIdentity::operator==(const SteamNetworkingIdentity &x ) const { return m_eType == x.m_eType && m_cbSize == x.m_cbSize && memcmp( m_genericBytes, x.m_genericBytes, m_cbSize ) == 0; } 1755 inline void SteamNetworkingMessage_t::Release() { (*m_pfnRelease)( this ); } 1756 1757 #endif // #ifndef API_GEN 1758 1759 #endif // #ifndef STEAMNETWORKINGTYPES 1760 1761 +/