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