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