server
authorhgn <hgodden00@gmail.com>
Sun, 7 Aug 2022 07:36:19 +0000 (08:36 +0100)
committerhgn <hgodden00@gmail.com>
Sun, 7 Aug 2022 07:36:19 +0000 (08:36 +0100)
src/vg/vg.h
src/vg/vg_io.h
src/vg/vg_m.h
src/vg/vg_platform.h
src/vg/vg_stdint.h [new file with mode: 0644]
src/vg/vg_steam.h [new file with mode: 0644]
src/vg/vg_steam_http.h [new file with mode: 0644]
src/vg/vg_steam_networking.h [new file with mode: 0644]

index 31cfa8065529233f091bad686717ae2b166ac12d..a2a85fdbc06d54605f12f747da2196d749e080f4 100644 (file)
@@ -6,14 +6,19 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <dirent.h>
-#include <stdint.h>
 #include <string.h>
 #include <stdarg.h>
 #include <ctype.h>
 #include <math.h>
 
-#include "glad/glad.h"
-#include "glfw/glfw3.h"
+#if defined(VG_SERVER) || defined(VG_TOOLS)
+ #define VG_NON_CLIENT
+#endif
+
+#ifndef VG_SERVER
+#include "../../dep/glad/glad.h"
+#include "../../dep/glfw/glfw3.h"
+#endif
 
 #define STB_DS_IMPLEMENTATION
 #include "stb/stb_ds.h"
 #define QOI_IMPLEMENTATION
 #include "phoboslab/qoi.h"
 
-#include "vg/vg_platform.h"
+#include "vg_stdint.h"
+#include "vg_platform.h"
 
 void vg_register_exit( void( *funcptr )(void), const char *name );
 void vg_exiterr( const char *strErr );
 
-#include "vg/vg_m.h"
-#include "vg/vg_io.h"
-#include "vg/vg_gldiag.h"
+#include "vg_m.h"
+#include "vg_io.h"
 
-#ifndef VG_TOOLS
+#ifdef VG_STEAM
+//#include "vg_steamworks.h"
+#include "vg_steam.h"
+#endif
+
+#ifndef VG_NON_CLIENT
+#include "vg_gldiag.h"
+#endif
+
+#ifndef VG_NON_CLIENT
 
 /* Engine globals */
 GLFWwindow* vg_window;
@@ -57,18 +71,14 @@ double vg_time,
        vg_time_last,
        vg_time_delta;
 
-#include "vg/vg_audio.h"
-#include "vg/vg_shader.h"
-#include "vg/vg_tex.h"
-#include "vg/vg_input.h"
-#include "vg/vg_ui.h"
-#include "vg/vg_console.h"
-#include "vg/vg_lines.h"
-#include "vg/vg_debug.h"
-
-#ifdef VG_STEAM
-#include "vg/vg_steamworks.h"
-#endif
+#include "vg_audio.h"
+#include "vg_shader.h"
+#include "vg_tex.h"
+#include "vg_input.h"
+#include "vg_ui.h"
+#include "vg_console.h"
+#include "vg_lines.h"
+#include "vg_debug.h"
 
 #ifndef VG_RELEASE
 void vg_checkgl( const char *src_info )
index 376dfdac5f41ab297e1bea0e845a3066cc35bcbf..56e6219e33f6782c40706e353d796d48766d08cd 100644 (file)
@@ -45,6 +45,7 @@ static void NAME(const char *fmt, ...)       \
 
 VG_LOGX( vg_success, stdout, (KGRN "success" KWHT "| " KGRN) )
 VG_LOGX( vg_info,    stdout, (KNRM "   info" KWHT "| " KNRM) )
+VG_LOGX( vg_log,     stdout, (KWHT "    log" KWHT "| " KWHT) )
 VG_LOGX( vg_warn,    stdout, (KYEL "   warn" KWHT "| " KYEL) )
 VG_LOGX( vg_error,   stderr, (KRED "  error" KWHT "| " KRED) )
 
index 8ecadbdbdf1a19eddaa336f5c6f82efc2a4fa1d9..7e827a531ca74db784c2a86620306af5fd97af35 100644 (file)
@@ -23,6 +23,11 @@ static inline float vg_signf( float a )
    return a < 0.0f? -1.0f: 1.0f;
 }
 
+static inline float vg_fractf( float a )
+{
+   return a - floorf( a );
+}
+
 static inline float vg_randf(void)
 {
    return (float)rand()/(float)(RAND_MAX);
@@ -69,6 +74,11 @@ static inline void v2_copy( v2f a, v2f b )
        b[0] = a[0]; b[1] = a[1];
 }
 
+static inline void v2_zero( v2f a )
+{
+       a[0] = 0.f; a[1] = 0.f;
+}
+
 static inline void v2i_copy( v2i a, v2i b )
 {
        b[0] = a[0]; b[1] = a[1];
index b0794baa7d955ea0b161e9011a0b1d46baf3eb80..ca8b55a88cb3ff58bcd8b63e6a19394d2e08b3a6 100644 (file)
@@ -3,15 +3,6 @@
 
 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
 
-typedef uint8_t  u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-typedef uint64_t u64;
-typedef int8_t i8;
-typedef int16_t i16;
-typedef int32_t i32;
-typedef int64_t i64;
-
 typedef unsigned int uint;
 
 typedef int            v2i[2];
diff --git a/src/vg/vg_stdint.h b/src/vg/vg_stdint.h
new file mode 100644 (file)
index 0000000..7f9928a
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef VG_STDINT_H
+#define VG_STDINT_H
+
+#include <stdint.h>
+
+typedef uint8_t  u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t i8;
+typedef int16_t i16;
+typedef int32_t i32;
+typedef int64_t i64;
+
+#endif /* VG_STDINT_H */
diff --git a/src/vg/vg_steam.h b/src/vg/vg_steam.h
new file mode 100644 (file)
index 0000000..d6866b2
--- /dev/null
@@ -0,0 +1,570 @@
+#ifndef VG_STEAM_H
+#define VG_STEAM_H
+
+#include "vg.h"
+
+#if defined(__linux__) || defined(__APPLE__) 
+/* 
+ * The 32-bit version of gcc has the alignment requirement for u64 and double 
+ * set to 4 meaning that even with #pragma pack(8) these types will only be 
+ * four-byte aligned. The 64-bit version of gcc has the alignment requirement 
+ * for these types set to 8 meaning that unless we use #pragma pack(4) our 
+ * structures will get bigger. The 64-bit structure packing has to match the 
+ * 32-bit structure packing for each platform.
+ */
+ #define VALVE_CALLBACK_PACK_SMALL
+ #pragma pack( push, 4 )
+#else
+ #define VALVE_CALLBACK_PACK_LARGE
+ #pragma pack( push, 8 )
+#endif
+
+typedef i32    HSteamPipe;
+typedef i32    HSteamUser;
+
+typedef int E_iCallBack_t;
+
+typedef u64    u64_steamid;
+typedef u64 SteamAPICall_t;
+
+enum { k_iSteamUserCallbacks = 100 };
+enum { k_iSteamGameServerCallbacks = 200 };
+enum { k_iSteamFriendsCallbacks = 300 };
+enum { k_iSteamBillingCallbacks = 400 };
+enum { k_iSteamMatchmakingCallbacks = 500 };
+enum { k_iSteamContentServerCallbacks = 600 };
+enum { k_iSteamUtilsCallbacks = 700 };
+enum { k_iClientFriendsCallbacks = 800 };
+enum { k_iClientUserCallbacks = 900 };
+enum { k_iSteamAppsCallbacks = 1000 };
+enum { k_iSteamUserStatsCallbacks = 1100 };
+enum { k_iSteamNetworkingCallbacks = 1200 };
+enum { k_iSteamNetworkingSocketsCallbacks = 1220 };
+enum { k_iSteamNetworkingMessagesCallbacks = 1250 };
+enum { k_iSteamNetworkingUtilsCallbacks = 1280 };
+enum { k_iClientRemoteStorageCallbacks = 1300 };
+enum { k_iClientDepotBuilderCallbacks = 1400 };
+enum { k_iSteamGameServerItemsCallbacks = 1500 };
+enum { k_iClientUtilsCallbacks = 1600 };
+enum { k_iSteamGameCoordinatorCallbacks = 1700 };
+enum { k_iSteamGameServerStatsCallbacks = 1800 };
+enum { k_iSteam2AsyncCallbacks = 1900 };
+enum { k_iSteamGameStatsCallbacks = 2000 };
+enum { k_iClientHTTPCallbacks = 2100 };
+enum { k_iClientScreenshotsCallbacks = 2200 };
+enum { k_iSteamScreenshotsCallbacks = 2300 };
+enum { k_iClientAudioCallbacks = 2400 };
+enum { k_iClientUnifiedMessagesCallbacks = 2500 };
+enum { k_iSteamStreamLauncherCallbacks = 2600 };
+enum { k_iClientControllerCallbacks = 2700 };
+enum { k_iSteamControllerCallbacks = 2800 };
+enum { k_iClientParentalSettingsCallbacks = 2900 };
+enum { k_iClientDeviceAuthCallbacks = 3000 };
+enum { k_iClientNetworkDeviceManagerCallbacks = 3100 };
+enum { k_iClientMusicCallbacks = 3200 };
+enum { k_iClientRemoteClientManagerCallbacks = 3300 };
+enum { k_iClientUGCCallbacks = 3400 };
+enum { k_iSteamStreamClientCallbacks = 3500 };
+enum { k_IClientProductBuilderCallbacks = 3600 };
+enum { k_iClientShortcutsCallbacks = 3700 };
+enum { k_iClientRemoteControlManagerCallbacks = 3800 };
+enum { k_iSteamAppListCallbacks = 3900 };
+enum { k_iSteamMusicCallbacks = 4000 };
+enum { k_iSteamMusicRemoteCallbacks = 4100 };
+enum { k_iClientVRCallbacks = 4200 };
+enum { k_iClientGameNotificationCallbacks = 4300 }; 
+enum { k_iSteamGameNotificationCallbacks = 4400 }; 
+enum { k_iSteamHTMLSurfaceCallbacks = 4500 };
+enum { k_iClientVideoCallbacks = 4600 };
+enum { k_iClientInventoryCallbacks = 4700 };
+enum { k_iClientBluetoothManagerCallbacks = 4800 };
+enum { k_iClientSharedConnectionCallbacks = 4900 };
+enum { k_ISteamParentalSettingsCallbacks = 5000 };
+enum { k_iClientShaderCallbacks = 5100 };
+enum { k_iSteamGameSearchCallbacks = 5200 };
+enum { k_iSteamPartiesCallbacks = 5300 };
+enum { k_iClientPartiesCallbacks = 5400 };
+enum { k_iSteamSTARCallbacks = 5500 };
+enum { k_iClientSTARCallbacks = 5600 };
+enum { k_iSteamRemotePlayCallbacks = 5700 };
+enum { k_iClientCompatCallbacks = 5800 };
+enum { k_iSteamChatCallbacks = 5900 };
+
+// General result codes
+typedef enum EResult
+{
+       k_EResultNone = 0,                                      // no result
+       k_EResultOK     = 1,                                            // success
+       k_EResultFail = 2,                                      // generic failure 
+       k_EResultNoConnection = 3,                      // no/failed network connection
+//     k_EResultNoConnectionRetry = 4, // OBSOLETE - removed
+       k_EResultInvalidPassword = 5,           // password/ticket is invalid
+       k_EResultLoggedInElsewhere = 6, // same user logged in elsewhere
+       k_EResultInvalidProtocolVer = 7,        // protocol version is incorrect
+       k_EResultInvalidParam = 8,                      // a parameter is incorrect
+       k_EResultFileNotFound = 9,                      // file was not found
+       k_EResultBusy = 10,                                     // called method busy - action not taken
+       k_EResultInvalidState = 11,             // called object was in an invalid state
+       k_EResultInvalidName = 12,                 // name is invalid
+       k_EResultInvalidEmail = 13,             // email is invalid
+       k_EResultDuplicateName = 14,            // name is not unique
+       k_EResultAccessDenied = 15,             // access is denied
+       k_EResultTimeout = 16,                     // operation timed out
+       k_EResultBanned = 17,                           // VAC2 banned
+       k_EResultAccountNotFound = 18,  // account not found
+       k_EResultInvalidSteamID = 19,           // steamID is invalid
+       k_EResultServiceUnavailable = 20,// The requested service is currently 
+                                    // unavailable
+       k_EResultNotLoggedOn = 21,       // The user is not logged on
+       k_EResultPending = 22,                          // Request is pending (may be in process, or
+                                    // waiting on third party)
+       k_EResultEncryptionFailure = 23,                // Encryption or Decryption failed
+       k_EResultInsufficientPrivilege = 24,// Insufficient privilege
+       k_EResultLimitExceeded = 25,                    // Too much of a good thing
+       k_EResultRevoked = 26,                          // Access has been revoked (used for revoked
+                                    // guest passes)
+       k_EResultExpired = 27,                          // License/Guest pass the user is trying to 
+                                    // access is expired
+       k_EResultAlreadyRedeemed = 28,  // Guest pass has already been redeemed by 
+                                    // account, cannot be acked again
+       k_EResultDuplicateRequest = 29, // The request is a duplicate and the action
+                                    // has already occurred in the past, ignored
+                                    // this time
+       k_EResultAlreadyOwned = 30,             // All the games in this guest pass 
+                                    // redemption request are already owned by 
+                                    // the user
+       k_EResultIPNotFound = 31,                       // IP address not found
+       k_EResultPersistFailed = 32,            // failed to write change to the data store
+       k_EResultLockingFailed = 33,            // failed to acquire access lock for this 
+                                    // operation
+       k_EResultLogonSessionReplaced = 34,
+       k_EResultConnectFailed = 35,
+       k_EResultHandshakeFailed = 36,
+       k_EResultIOFailure = 37,
+       k_EResultRemoteDisconnect = 38,
+       k_EResultShoppingCartNotFound = 39,     // failed to find the shopping cart 
+                                       // requested
+       k_EResultBlocked = 40,                                  // a user didn't allow it
+       k_EResultIgnored = 41,                                  // target is ignoring sender
+       k_EResultNoMatch = 42,                                  // nothing matching the request found
+       k_EResultAccountDisabled = 43,
+       k_EResultServiceReadOnly = 44,          // this service is not accepting content 
+                                       // changes right now
+       k_EResultAccountNotFeatured = 45,       // account doesn't have value, so this 
+                                       // feature isn't available
+       k_EResultAdministratorOK = 46,          // allowed to take this action, but only 
+                                       // because requester is admin
+       k_EResultContentVersion = 47,                   // A Version mismatch in content 
+                                       // transmitted within the Steam protocol.
+       k_EResultTryAnotherCM = 48,                     // The current CM can't service the user 
+                                       // making a request, user should try 
+                                       // another.
+       k_EResultPasswordRequiredToKickSession = 49, // You are already logged in 
+                                       // elsewhere, this cached credential 
+                                       // login has failed.
+       k_EResultAlreadyLoggedInElsewhere = 50, // You are already logged in 
+                                           // elsewhere, you must wait
+       k_EResultSuspended = 51,   // Long running operation (content download) 
+                              // suspended/paused
+       k_EResultCancelled = 52,   // Operation canceled (typically by user: 
+                              // content download)
+       k_EResultDataCorruption = 53,   // Operation canceled because data is ill 
+                                 // formed or unrecoverable
+       k_EResultDiskFull = 54,                 // Operation canceled - not enough disk space.
+       k_EResultRemoteCallFailed = 55, // an remote call or IPC call failed
+       k_EResultPasswordUnset = 56,            // Password could not be verified as it's 
+                                    // unset server side
+       k_EResultExternalAccountUnlinked = 57,  // External account (PSN, Facebook...)
+                                          // is not linked to a Steam account
+       k_EResultPSNTicketInvalid = 58,                 // PSN ticket was invalid
+       k_EResultExternalAccountAlreadyLinked = 59,     // External account (PSN, 
+         // Facebook...) is already linked to some other account, 
+         // must explicitly request to replace/delete the link first
+       k_EResultRemoteFileConflict = 60, // The sync cannot resume due to a conflict
+                                     // between the local and remote files
+       k_EResultIllegalPassword = 61,   // The requested new password is not legal
+       k_EResultSameAsPreviousValue = 62,// new value is the same as the old one ( 
+                                     // secret question and answer )
+       k_EResultAccountLogonDenied = 63, // account login denied due to 2nd factor 
+                                     // authentication failure
+       k_EResultCannotUseOldPassword = 64,     // The requested new password is not 
+                                       // legal
+       k_EResultInvalidLoginAuthCode = 65,     // account login denied due to auth code 
+                                       // invalid
+       k_EResultAccountLogonDeniedNoMail = 66, // account login denied due to 2nd 
+                                           // factor auth failure - and no mail 
+                                           // has been sent
+       k_EResultHardwareNotCapableOfIPT = 67,
+       k_EResultIPTInitError = 68,
+       k_EResultParentalControlRestricted = 69,// operation failed due to parental 
+                                           // control restrictions for current 
+                                           // user
+       k_EResultFacebookQueryError = 70,                // Facebook query returned an error
+       k_EResultExpiredLoginAuthCode = 71,              // account login denied due to auth 
+                                           // code expired
+       k_EResultIPLoginRestrictionFailed = 72,
+       k_EResultAccountLockedDown = 73,
+       k_EResultAccountLogonDeniedVerifiedEmailRequired = 74,
+       k_EResultNoMatchingURL = 75,
+       k_EResultBadResponse = 76,              // parse failure, missing field, etc.
+       k_EResultRequirePasswordReEntry = 77, // The user cannot complete the action 
+                                         // until they re-enter their password
+       k_EResultValueOutOfRange = 78,  // the value entered is outside the 
+                                    // acceptable range
+       k_EResultUnexpectedError = 79,  // something happened that we didn't expect
+                                    // to ever happen
+       k_EResultDisabled = 80,                         // The requested service has been configured
+                                    // to be unavailable
+       k_EResultInvalidCEGSubmission = 81,     // The set of files submitted to the CEG 
+                                       // server are not valid !
+       k_EResultRestrictedDevice = 82,         // The device being used is not allowed 
+                                       // to perform this action
+       k_EResultRegionLocked = 83,                     // The action could not be complete 
+                                       // because it is region restricted
+       k_EResultRateLimitExceeded = 84,        // Temporary rate limit exceeded, try 
+                                    // again later, different from 
+                                    // k_EResultLimitExceeded which may be 
+                                    // permanent
+       k_EResultAccountLoginDeniedNeedTwoFactor = 85, // Need two-factor code to 
+                                                  // login
+       k_EResultItemDeleted = 86,      // The thing we're trying to access has been 
+                              // deleted
+       k_EResultAccountLoginDeniedThrottle = 87,       // login attempt failed, try to 
+                                             // throttle response to possible 
+                                             // attacker
+       k_EResultTwoFactorCodeMismatch = 88,            // two factor code mismatch
+       k_EResultTwoFactorActivationCodeMismatch = 89,  // activation code for 
+                                                   // two-factor didn't match
+       k_EResultAccountAssociatedToMultiplePartners = 90,      // account has been 
+                                          // associated with multiple partners
+       k_EResultNotModified = 91,                                      // data not modified
+       k_EResultNoMobileDevice = 92,   // the account does not have a mobile 
+                                 // device associated with it
+       k_EResultTimeNotSynced = 93,    // the time presented is out of range or 
+                                 // tolerance
+       k_EResultSmsCodeFailed = 94,    // SMS code failure (no match, none pending, 
+                                 // etc.)
+       k_EResultAccountLimitExceeded = 95,     // Too many accounts access this resource
+       k_EResultAccountActivityLimitExceeded = 96,// Too many changes to 
+                                              // this account
+       k_EResultPhoneActivityLimitExceeded = 97,       // Too many changes to this phone
+       k_EResultRefundToWallet = 98,   // Cannot refund to payment method, must use 
+                                 // wallet
+       k_EResultEmailSendFailure = 99, // Cannot send an email
+       k_EResultNotSettled = 100,      // Can't perform operation till payment 
+                              // has settled
+       k_EResultNeedCaptcha = 101,// Needs to provide a valid captcha
+       k_EResultGSLTDenied = 102,      // a game server login token owned by this token's
+                              // owner has been banned
+       k_EResultGSOwnerDenied = 103,   // game server owner is denied for other reason
+                        // (account lock, community ban, vac ban, missing phone)
+       k_EResultInvalidItemType = 104,// the type of thing we were requested to act 
+                                  // on is invalid
+       k_EResultIPBanned = 105,// the ip address has been banned from taking this 
+                           // action
+       k_EResultGSLTExpired = 106,// this token has expired from disuse; can be 
+                              // reset for use
+       k_EResultInsufficientFunds = 107,// user doesn't have enough wallet funds to 
+                                    // complete the action
+       k_EResultTooManyPending = 108,  // There are too many of this thing pending 
+                                    // already
+       k_EResultNoSiteLicensesFound = 109,     // No site licenses found
+       k_EResultWGNetworkSendExceeded = 110,// the WG couldn't send a response
+                              // because we exceeded max network send size
+       k_EResultAccountNotFriends = 111, // the user is not mutually friends
+       k_EResultLimitedUserAccount = 112,// the user is limited
+       k_EResultCantRemoveItem = 113,   // item can't be removed
+       k_EResultAccountDeleted = 114,   // account has been deleted
+       k_EResultExistingUserCancelledLicense = 115,    
+   // A license for this already exists, but cancelled
+       k_EResultCommunityCooldown = 116,       // access is denied because of a 
+            // community cooldown (probably from support profile data resets)
+       k_EResultNoLauncherSpecified = 117,     // No launcher was specified, but a 
+   // launcher was needed to choose correct realm for operation.
+       k_EResultMustAgreeToSSA = 118,// User must agree to china SSA or global SSA 
+                                 // before login
+       k_EResultLauncherMigrated = 119,        // The specified launcher type is no longer 
+                           // supported; the user should be directed elsewhere
+       k_EResultSteamRealmMismatch = 120,      // The user's realm does not match the 
+                                       // realm of the requested resource
+       k_EResultInvalidSignature = 121,                        // signature check did not match
+       k_EResultParseFailure = 122,            // Failed to parse input
+       k_EResultNoVerifiedPhone = 123, // account does not have a verified phone 
+                                    // number
+} EResult;
+
+typedef struct {
+
+       HSteamUser m_hSteamUser;        // Specific user to whom this callback applies.
+       int m_iCallback; 
+       u8 *m_pubParam;                 // Points to the callback structure
+       int m_cubParam;                 // Size of the data pointed to by m_pubParam
+       
+} CallbackMsg_t;
+
+typedef struct {
+
+       SteamAPICall_t m_hAsyncCall;
+       int m_iCallback;
+       u32 m_cubParam;
+       
+} SteamAPICallCompleted_t;
+
+enum { k_iSteamAPICallCompleted = k_iSteamUtilsCallbacks + 3 };
+
+// Steam universes.  Each universe is a self-contained Steam instance.
+typedef enum {
+       k_EUniverseInvalid = 0,
+       k_EUniversePublic = 1,
+       k_EUniverseBeta = 2,
+       k_EUniverseInternal = 3,
+       k_EUniverseDev = 4,
+       // k_EUniverseRC = 5,                           // no such universe anymore
+       k_EUniverseMax
+} EUniverse_t;
+
+struct SteamIDComponent_t
+{
+#ifdef VALVE_BIG_ENDIAN
+   EUniverse_t                 m_EUniverse : 8
+   unsigned int                m_EAccountType : 4;
+   unsigned int                m_unAccountInstance : 20;
+   u32                                 m_unAccountID : 32;
+#else
+   u32                                 m_unAccountID : 32;
+   unsigned int                m_unAccountInstance : 20;
+   unsigned int                m_EAccountType : 4;
+   EUniverse_t                 m_EUniverse : 8;
+#endif
+};
+
+typedef struct 
+{
+       // 64 bits total
+       union 
+   {
+      struct SteamIDComponent_t m_comp;
+               u64 m_unAll64Bits;
+       };
+} 
+CSteamID;
+
+typedef struct GameID_t
+{
+#ifdef VALVE_BIG_ENDIAN
+       unsigned int m_nModID : 32;
+       unsigned int m_nType : 8;
+       unsigned int m_nAppID : 24;
+#else
+       unsigned int m_nAppID : 24;
+       unsigned int m_nType : 8;
+       unsigned int m_nModID : 32;
+#endif
+} CGameID;
+
+#pragma pack( pop )
+
+/*
+ * Standard login
+ * =============================================================================
+ */
+
+int   SteamAPI_RestartAppIfNecessary( u32 unOwnAppID );
+int   SteamAPI_Init(void);
+void  SteamAPI_Shutdown(void);
+
+/*
+ * Server mode login
+ * =============================================================================
+ */
+
+typedef enum EServerMode EServerMode;
+enum EServerMode
+{
+       eServerModeInvalid = 0,
+       eServerModeNoAuthentication = 1,
+       eServerModeAuthentication = 2,
+       eServerModeAuthenticationAndSecure = 3,
+};
+
+int SteamInternal_GameServer_Init( u32 unIP, u16 usLegacySteamPort, 
+                                   u16 usGamePort, u16 usQueryPort, 
+                                   EServerMode eServerMode, 
+                                   const char *pchVersionString );
+
+/* Initialize SteamGameServer client and interface objects, and set server 
+ * properties which may not be changed.
+ * After calling this function, you should set any additional server parameters, 
+ * and then call ISteamGameServer::LogOnAnonymous() or ISteamGameServer::LogOn()
+ *
+ * - unIP will usually be zero.  If you are on a machine with multiple IP 
+ *   addresses, you can pass a non-zero value here and the relevant sockets will
+ *   be bound to that IP.  This can be used to ensure that the IP you desire is 
+ *   the one used in the server browser.
+ * - usGamePort is the port that clients will connect to for gameplay. You will
+ *   usually open up your own socket bound to this port.
+ * - usQueryPort is the port that will manage server browser related duties and 
+ *   info pings from clients.  If you pass STEAMGAMESERVER_QUERY_PORT_SHARED for
+ *   usQueryPort, then it will use "GameSocketShare" mode, which means that the
+ *   game is responsible for sending and receiving UDP packets for the master
+ *   server updater.  (See ISteamGameServer::HandleIncomingPacket and 
+ *   ISteamGameServer::GetNextOutgoingPacket.)
+ * - The version string should be in the form x.x.x.x, and is used by the master
+ *   server to detect when the server is out of date. (Only servers with the 
+ *   latest version will be listed.)
+ */
+int   SteamGameServer_Init( u32 unIP, u16 usGamePort, u16 usQueryPort, 
+                            EServerMode eServerMode, 
+                            const char *pchVersionString )
+{
+   return SteamInternal_GameServer_Init( unIP, 0, usGamePort, usQueryPort,
+                                         eServerMode, pchVersionString );
+}
+
+void SteamGameServer_Shutdown(void);
+
+int  SteamGameServer_BSecure(void);
+u64  SteamGameServer_GetSteamID(void);
+
+/*
+ * Async callbacks
+ * =============================================================================
+ */
+typedef struct steam_async steam_async;
+struct steam_async
+{
+   SteamAPICall_t id;
+   void *data;
+
+   void (*p_handler)( void *result, void *userdata );
+}
+static steam_async_trackers[32];
+static u32 steam_async_track_count;
+
+steam_async *steam_new_async(void)
+{
+   if( steam_async_track_count == vg_list_size(steam_async_trackers) )
+   {
+      vg_error( "Maximum concurrent API calls exceeded (%u)\n",
+                steam_async_track_count );
+      return NULL;
+   }
+
+   return &steam_async_trackers[ steam_async_track_count ++ ];
+}
+
+/*
+ * Event loop
+ */
+HSteamPipe SteamAPI_GetHSteamPipe(void);
+HSteamPipe SteamGameServer_GetHSteamPipe(void);
+HSteamUser SteamAPI_GetHSteamUser(void);
+void   SteamAPI_ManualDispatch_Init(void);
+void   SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteamPipe );
+int    SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe, 
+                                               CallbackMsg_t *pCallbackMsg );
+void   SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe hSteamPipe );
+int    SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe, 
+         SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, 
+         int iCallbackExpected, int *pbFailed );
+
+void   SteamAPI_ReleaseCurrentThreadMemory(void);
+
+static void steamworks_event_loop( HSteamPipe pipe, 
+                                   void(*callback_handler)(CallbackMsg_t *msg) )
+{
+       SteamAPI_ManualDispatch_RunFrame( pipe );
+       CallbackMsg_t callback;
+       
+       while( SteamAPI_ManualDispatch_GetNextCallback( pipe, &callback ) )
+       {
+               vg_log( "steamworks_event::callback( %i )\n", callback.m_iCallback );
+       
+               /* Check for dispatching API call results */
+               if( callback.m_iCallback == k_iSteamAPICallCompleted )
+      {
+                       SteamAPICallCompleted_t *pCallCompleted = 
+            (SteamAPICallCompleted_t *)callback.m_pubParam;
+
+                       void *pTmpCallResult = malloc( pCallCompleted->m_cubParam );
+                       int bFailed;
+                       
+                       if( SteamAPI_ManualDispatch_GetAPICallResult( 
+                               pipe,
+                               pCallCompleted->m_hAsyncCall, 
+                               pTmpCallResult,
+                               pCallCompleted->m_cubParam, 
+                               pCallCompleted->m_iCallback, 
+                               &bFailed ) 
+                       )
+                       {
+                               /* 
+             * Dispatch the call result to the registered handler(s) for the
+                                * call identified by pCallCompleted->m_hAsyncCall 
+             */
+                               
+                               vg_info( "steamworks_event::api_call_completed( %lu )\n", 
+                  pCallCompleted->m_hAsyncCall );
+            
+            int j=0;
+            for( int i=0; i<steam_async_track_count; i++ )
+            {
+               if( steam_async_trackers[j].id != pCallCompleted->m_hAsyncCall )
+               {
+                  steam_async_trackers[j ++] = steam_async_trackers[i];
+               }
+               else
+               {
+                  steam_async *pasync = &steam_async_trackers[j];
+                  pasync->p_handler( pTmpCallResult, pasync->data );
+               }
+            }
+
+            if( steam_async_track_count == j )
+            {
+               vg_error( "No tracker was register for API call\n" );
+            }
+
+            steam_async_track_count = j;
+                       } 
+                       else 
+                       { 
+#if 0
+                               typedef enum ESteamAPICallFailure
+                               {
+                                       k_ESteamAPICallFailureNone = -1,
+                                       k_ESteamAPICallFailureSteamGone = 0, 
+                                       k_ESteamAPICallFailureNetworkFailure = 1,       
+                                       k_ESteamAPICallFailureInvalidHandle = 2,
+                                       k_ESteamAPICallFailureMismatchedCallback = 3,
+                               } 
+
+            ESteamAPICallFailure;
+                               ESteamAPICallFailure fail_why = 
+                               SteamAPI_ISteamUtils_GetAPICallFailureReason( 
+                  steam_api_classes.utils, pCallCompleted->m_hAsyncCall );
+                       
+                               vg_error( "steamworks_event: error getting call result on"
+                      "%lu (code %d)\n", 
+                      pCallCompleted->m_hAsyncCall, fail_why );
+#endif
+                       }
+                       
+                       free( pTmpCallResult );
+               } 
+               else 
+               {
+                       /* 
+          * Look at callback.m_iCallback to see what kind of callback it is,
+                        * and dispatch to appropriate handler(s)
+                        * void *data = callback.m_pubParam;
+          */
+
+         callback_handler(&callback);
+               }
+               
+               SteamAPI_ManualDispatch_FreeLastCallback( pipe );
+       }
+}
+
+#endif /* VG_STEAM_H */
diff --git a/src/vg/vg_steam_http.h b/src/vg/vg_steam_http.h
new file mode 100644 (file)
index 0000000..f4b6bd1
--- /dev/null
@@ -0,0 +1,162 @@
+#ifndef VG_STEAM_HTTP_H
+#define VG_STEAM_HTTP_H
+
+#include "vg_steam.h"
+
+/* 
+ * HTTP Status codes that the server can send in response to a request, see 
+ * rfc2616 section 10.3 for descriptions of each of these. 
+ */
+typedef enum EHTTPStatusCode
+{
+       /* Invalid status code (this isn't defined in HTTP, used to indicate unset 
+    * in our code) */
+
+       k_EHTTPStatusCodeInvalid =                                         0,
+
+       /* Informational codes */
+       k_EHTTPStatusCode100Continue =                          100,
+       k_EHTTPStatusCode101SwitchingProtocols =        101,
+
+       /* Success codes */
+       k_EHTTPStatusCode200OK =                                           200,
+       k_EHTTPStatusCode201Created =                              201,
+       k_EHTTPStatusCode202Accepted =                          202,
+       k_EHTTPStatusCode203NonAuthoritative =          203,
+       k_EHTTPStatusCode204NoContent =                         204,
+       k_EHTTPStatusCode205ResetContent =                      205,
+       k_EHTTPStatusCode206PartialContent =            206,
+
+       /* Redirection codes */
+       k_EHTTPStatusCode300MultipleChoices =           300,
+       k_EHTTPStatusCode301MovedPermanently =          301,
+       k_EHTTPStatusCode302Found =                                     302,
+       k_EHTTPStatusCode303SeeOther =                          303,
+       k_EHTTPStatusCode304NotModified =                       304,
+       k_EHTTPStatusCode305UseProxy =                          305,
+
+   /* (used in old HTTP spec, now unused in 1.1)
+       k_EHTTPStatusCode306Unused =                               306, 
+   */
+   
+       k_EHTTPStatusCode307TemporaryRedirect = 307,
+
+       /* Error codes */
+       k_EHTTPStatusCode400BadRequest =                           400,
+
+   /* 
+    * You probably want 403 or something else. 401 implies you're sending a 
+    * WWW-Authenticate header and the client can sent an Authorization header in 
+    * response.
+    */
+       k_EHTTPStatusCode401Unauthorized =                      401,
+
+   /* This is reserved for future HTTP specs, not really supported by clients */
+       k_EHTTPStatusCode402PaymentRequired =           402, 
+       k_EHTTPStatusCode403Forbidden =                         403,
+       k_EHTTPStatusCode404NotFound =                          404,
+       k_EHTTPStatusCode405MethodNotAllowed =          405,
+       k_EHTTPStatusCode406NotAcceptable =                     406,
+       k_EHTTPStatusCode407ProxyAuthRequired = 407,
+       k_EHTTPStatusCode408RequestTimeout =            408,
+       k_EHTTPStatusCode409Conflict =                          409,
+       k_EHTTPStatusCode410Gone =                                         410,
+       k_EHTTPStatusCode411LengthRequired =            411,
+       k_EHTTPStatusCode412PreconditionFailed =        412,
+       k_EHTTPStatusCode413RequestEntityTooLarge=413,
+       k_EHTTPStatusCode414RequestURITooLong = 414,
+       k_EHTTPStatusCode415UnsupportedMediaType =415,
+       k_EHTTPStatusCode416RequestedRangeNotSatisfiable = 416,
+       k_EHTTPStatusCode417ExpectationFailed = 417,
+
+   /* 418 is reserved, so we'll use it to mean unknown */
+       k_EHTTPStatusCode4xxUnknown =                           418, 
+       k_EHTTPStatusCode429TooManyRequests     =               429,
+       k_EHTTPStatusCode444ConnectionClosed =          444, /* nginx only? */
+
+       /* Server error codes */
+       k_EHTTPStatusCode500InternalServerError =       500,
+       k_EHTTPStatusCode501NotImplemented =            501,
+       k_EHTTPStatusCode502BadGateway =                           502,
+       k_EHTTPStatusCode503ServiceUnavailable =        503,
+       k_EHTTPStatusCode504GatewayTimeout =            504,
+       k_EHTTPStatusCode505HTTPVersionNotSupported = 505,
+       k_EHTTPStatusCode5xxUnknown =                              599,
+}
+EHTTPStatusCode;
+
+enum EHTTPMethod
+{
+       k_EHTTPMethodInvalid = 0,
+       k_EHTTPMethodGET,
+       k_EHTTPMethodHEAD,
+       k_EHTTPMethodPOST,
+       k_EHTTPMethodPUT,
+       k_EHTTPMethodDELETE,
+       k_EHTTPMethodOPTIONS,
+       k_EHTTPMethodPATCH,
+
+   /* The remaining HTTP methods are not yet supported, per rfc2616 section 
+    * 5.1.1 only GET and HEAD are required for a compliant general purpose 
+    * server.  We'll likely add more as we find uses for them.
+    *
+        * k_EHTTPMethodTRACE,
+        * k_EHTTPMethodCONNECT
+    */
+};
+typedef enum EHTTPMethod EHTTPMethod;
+
+typedef u32 HTTPRequestHandle;
+
+#ifdef VALVE_CALLBACK_PACK_SMALL
+ #pragma pack( push, 4 )
+#else
+ #pragma pack( push, 8 )
+#endif
+
+typedef struct HTTPRequestCompleted_t HTTPRequestCompleted_t;
+struct HTTPRequestCompleted_t
+{
+       HTTPRequestHandle m_hRequest;
+       u64 m_ulContextValue;
+       int m_bRequestSuccessful;
+       EHTTPStatusCode m_eStatusCode;
+       u32 m_unBodySize;
+};
+
+#pragma pack(pop)
+
+/*
+ * Methods
+ *  TODO: Copy steamworks documentation here
+ */
+
+void *SteamAPI_SteamGameServerHTTP_v003(void);
+void *SteamAPI_SteamGameServerHTTP(void)
+{ 
+   return SteamAPI_SteamGameServerHTTP_v003(); 
+}
+
+/* Interfaces */
+void *SteamAPI_SteamHTTP_v003(void);
+void *SteamAPI_SteamHTTP(void)
+{ 
+   return SteamAPI_SteamHTTP_v003();
+}
+
+HTTPRequestHandle SteamAPI_ISteamHTTP_CreateHTTPRequest( 
+      void *self, EHTTPMethod eHTTPRequestMethod, const char *pchAbsoluteURL );
+
+int SteamAPI_ISteamHTTP_SendHTTPRequest( void* self, HTTPRequestHandle hRequest,
+                                         SteamAPICall_t * pCallHandle );
+
+int SteamAPI_ISteamHTTP_ReleaseHTTPRequest( void *self, 
+                                            HTTPRequestHandle hRequest );
+
+int SteamAPI_ISteamHTTP_GetHTTPResponseBodySize( void *self, 
+      HTTPRequestHandle hRequest, u32 *unBodySize );
+
+int SteamAPI_ISteamHTTP_GetHTTPResponseBodyData( void* self, 
+      HTTPRequestHandle hRequest, u8 *pBodyDataBuffer, u32 unBufferSize );
+
+#endif /* VG_STEAM_HTTP_H */
diff --git a/src/vg/vg_steam_networking.h b/src/vg/vg_steam_networking.h
new file mode 100644 (file)
index 0000000..494e846
--- /dev/null
@@ -0,0 +1,521 @@
+#ifndef VG_STEAM_NETWORKING_H
+#define VG_STEAM_NETWORKING_H
+
+#include "vg_steam.h"
+
+#ifdef VALVE_CALLBACK_PACK_SMALL
+ #pragma pack(push,4)
+#else
+ #pragma pack(push,8)
+#endif
+
+typedef enum ESteamNetworkingConfigScope ESteamNetworkingConfigScope;
+enum ESteamNetworkingConfigScope
+{
+       k_ESteamNetworkingConfig_Global = 1,
+       k_ESteamNetworkingConfig_SocketsInterface = 2,
+       k_ESteamNetworkingConfig_ListenSocket = 3,
+       k_ESteamNetworkingConfig_Connection = 4,
+       k_ESteamNetworkingConfigScope__Force32Bit = 0x7fffffff
+};
+
+typedef enum ESteamNetworkingConfigDataType ESteamNetworkingConfigDataType;
+enum ESteamNetworkingConfigDataType
+{
+       k_ESteamNetworkingConfig_Int32 = 1,
+       k_ESteamNetworkingConfig_Int64 = 2,
+       k_ESteamNetworkingConfig_Float = 3,
+       k_ESteamNetworkingConfig_String = 4,
+       k_ESteamNetworkingConfig_Ptr = 5,
+
+       k_ESteamNetworkingConfigDataType__Force32Bit = 0x7fffffff
+};
+
+typedef enum ESteamNetworkingConfigValue ESteamNetworkingConfigValue;
+enum ESteamNetworkingConfigValue
+{
+       k_ESteamNetworkingConfig_Invalid = 0,
+       k_ESteamNetworkingConfig_TimeoutInitial = 24,
+       k_ESteamNetworkingConfig_TimeoutConnected = 25,
+       k_ESteamNetworkingConfig_SendBufferSize = 9,
+       k_ESteamNetworkingConfig_ConnectionUserData = 40,
+       k_ESteamNetworkingConfig_SendRateMin = 10,
+       k_ESteamNetworkingConfig_SendRateMax = 11,
+       k_ESteamNetworkingConfig_NagleTime = 12,
+       k_ESteamNetworkingConfig_IP_AllowWithoutAuth = 23,
+       k_ESteamNetworkingConfig_MTU_PacketSize = 32,
+       k_ESteamNetworkingConfig_MTU_DataSize = 33,
+       k_ESteamNetworkingConfig_Unencrypted = 34,
+       k_ESteamNetworkingConfig_SymmetricConnect = 37,
+       k_ESteamNetworkingConfig_LocalVirtualPort = 38,
+       k_ESteamNetworkingConfig_DualWifi_Enable = 39,
+       k_ESteamNetworkingConfig_EnableDiagnosticsUI = 46,
+       k_ESteamNetworkingConfig_FakePacketLoss_Send = 2,
+       k_ESteamNetworkingConfig_FakePacketLoss_Recv = 3,
+       k_ESteamNetworkingConfig_FakePacketLag_Send = 4,
+       k_ESteamNetworkingConfig_FakePacketLag_Recv = 5,
+       k_ESteamNetworkingConfig_FakePacketReorder_Send = 6,
+       k_ESteamNetworkingConfig_FakePacketReorder_Recv = 7,
+       k_ESteamNetworkingConfig_FakePacketReorder_Time = 8,
+       k_ESteamNetworkingConfig_FakePacketDup_Send = 26,
+       k_ESteamNetworkingConfig_FakePacketDup_Recv = 27,
+       k_ESteamNetworkingConfig_FakePacketDup_TimeMax = 28,
+       k_ESteamNetworkingConfig_PacketTraceMaxBytes = 41,
+       k_ESteamNetworkingConfig_FakeRateLimit_Send_Rate = 42,
+       k_ESteamNetworkingConfig_FakeRateLimit_Send_Burst = 43,
+       k_ESteamNetworkingConfig_FakeRateLimit_Recv_Rate = 44,
+       k_ESteamNetworkingConfig_FakeRateLimit_Recv_Burst = 45,
+       k_ESteamNetworkingConfig_Callback_ConnectionStatusChanged = 201,
+       k_ESteamNetworkingConfig_Callback_AuthStatusChanged = 202,
+       k_ESteamNetworkingConfig_Callback_RelayNetworkStatusChanged = 203,
+       k_ESteamNetworkingConfig_Callback_MessagesSessionRequest = 204,
+       k_ESteamNetworkingConfig_Callback_MessagesSessionFailed = 205,
+       k_ESteamNetworkingConfig_Callback_CreateConnectionSignaling = 206,
+       k_ESteamNetworkingConfig_Callback_FakeIPResult = 207,
+       k_ESteamNetworkingConfig_P2P_STUN_ServerList = 103,
+       k_ESteamNetworkingConfig_P2P_Transport_ICE_Enable = 104,
+       k_ESteamNetworkingConfig_P2P_Transport_ICE_Penalty = 105,
+       k_ESteamNetworkingConfig_P2P_Transport_SDR_Penalty = 106,
+       k_ESteamNetworkingConfig_SDRClient_ConsecutitivePingTimeoutsFailInitial = 19,
+       k_ESteamNetworkingConfig_SDRClient_ConsecutitivePingTimeoutsFail = 20,
+       k_ESteamNetworkingConfig_SDRClient_MinPingsBeforePingAccurate = 21,
+       k_ESteamNetworkingConfig_SDRClient_SingleSocket = 22,
+       k_ESteamNetworkingConfig_SDRClient_ForceRelayCluster = 29,
+       k_ESteamNetworkingConfig_SDRClient_DebugTicketAddress = 30,
+       k_ESteamNetworkingConfig_SDRClient_ForceProxyAddr = 31,
+       k_ESteamNetworkingConfig_SDRClient_FakeClusterPing = 36,
+       k_ESteamNetworkingConfig_LogLevel_AckRTT = 13,
+       k_ESteamNetworkingConfig_LogLevel_PacketDecode = 14,
+       k_ESteamNetworkingConfig_LogLevel_Message = 15,
+       k_ESteamNetworkingConfig_LogLevel_PacketGaps = 16,
+       k_ESteamNetworkingConfig_LogLevel_P2PRendezvous = 17,
+       k_ESteamNetworkingConfig_LogLevel_SDRRelayPings = 18,
+       k_ESteamNetworkingConfig_DELETED_EnumerateDevVars = 35,
+       k_ESteamNetworkingConfigValue__Force32Bit = 0x7fffffff
+};
+
+
+typedef enum ESteamNetworkingConnectionState ESteamNetworkingConnectionState;
+enum ESteamNetworkingConnectionState
+{
+       k_ESteamNetworkingConnectionState_None = 0,
+       k_ESteamNetworkingConnectionState_Connecting = 1,
+       k_ESteamNetworkingConnectionState_FindingRoute = 2,
+       k_ESteamNetworkingConnectionState_Connected = 3,
+       k_ESteamNetworkingConnectionState_ClosedByPeer = 4,
+       k_ESteamNetworkingConnectionState_ProblemDetectedLocally = 5,
+       k_ESteamNetworkingConnectionState_FinWait = -1,
+       k_ESteamNetworkingConnectionState_Linger = -2, 
+       k_ESteamNetworkingConnectionState_Dead = -3,
+       k_ESteamNetworkingConnectionState__Force32Bit = 0x7fffffff
+};
+
+typedef enum ESteamNetConnectionEnd ESteamNetConnectionEnd;
+enum ESteamNetConnectionEnd
+{
+       k_ESteamNetConnectionEnd_Invalid = 0,
+       k_ESteamNetConnectionEnd_App_Min = 1000,
+   k_ESteamNetConnectionEnd_App_Generic = k_ESteamNetConnectionEnd_App_Min,
+       k_ESteamNetConnectionEnd_App_Max = 1999,
+       k_ESteamNetConnectionEnd_AppException_Min = 2000,
+   k_ESteamNetConnectionEnd_AppException_Generic = 
+      k_ESteamNetConnectionEnd_AppException_Min,
+       k_ESteamNetConnectionEnd_AppException_Max = 2999,
+       k_ESteamNetConnectionEnd_Local_Min = 3000,
+               k_ESteamNetConnectionEnd_Local_OfflineMode = 3001,
+               k_ESteamNetConnectionEnd_Local_ManyRelayConnectivity = 3002,
+               k_ESteamNetConnectionEnd_Local_HostedServerPrimaryRelay = 3003,
+               k_ESteamNetConnectionEnd_Local_NetworkConfig = 3004,
+               k_ESteamNetConnectionEnd_Local_Rights = 3005,
+               k_ESteamNetConnectionEnd_Local_P2P_ICE_NoPublicAddresses = 3006,
+
+       k_ESteamNetConnectionEnd_Local_Max = 3999,
+       k_ESteamNetConnectionEnd_Remote_Min = 4000,
+               k_ESteamNetConnectionEnd_Remote_Timeout = 4001,
+               k_ESteamNetConnectionEnd_Remote_BadCrypt = 4002,
+               k_ESteamNetConnectionEnd_Remote_BadCert = 4003,
+               k_ESteamNetConnectionEnd_Remote_BadProtocolVersion = 4006,
+               k_ESteamNetConnectionEnd_Remote_P2P_ICE_NoPublicAddresses = 4007,
+
+       k_ESteamNetConnectionEnd_Remote_Max = 4999,
+
+       k_ESteamNetConnectionEnd_Misc_Min = 5000,
+               k_ESteamNetConnectionEnd_Misc_Generic = 5001,
+               k_ESteamNetConnectionEnd_Misc_InternalError = 5002,
+               k_ESteamNetConnectionEnd_Misc_Timeout = 5003,
+               k_ESteamNetConnectionEnd_Misc_SteamConnectivity = 5005,
+               k_ESteamNetConnectionEnd_Misc_NoRelaySessionsToClient = 5006,
+               k_ESteamNetConnectionEnd_Misc_P2P_Rendezvous = 5008,
+               k_ESteamNetConnectionEnd_Misc_P2P_NAT_Firewall = 5009,
+               k_ESteamNetConnectionEnd_Misc_PeerSentNoConnection = 5010,
+
+       k_ESteamNetConnectionEnd_Misc_Max = 5999,
+       k_ESteamNetConnectionEnd__Force32Bit = 0x7fffffff
+};
+
+typedef enum ESteamNetworkingIdentityType ESteamNetworkingIdentityType;
+enum ESteamNetworkingIdentityType
+{
+       k_ESteamNetworkingIdentityType_Invalid = 0,
+       k_ESteamNetworkingIdentityType_SteamID = 16,
+       k_ESteamNetworkingIdentityType_IPAddress = 1,
+       k_ESteamNetworkingIdentityType_GenericString = 2,
+       k_ESteamNetworkingIdentityType_GenericBytes = 3,
+       k_ESteamNetworkingIdentityType_UnknownType = 4,
+       k_ESteamNetworkingIdentityType__Force32bit = 0x7fffffff,
+};
+
+typedef enum ESteamNetworkingAvailability ESteamNetworkingAvailability;
+enum ESteamNetworkingAvailability
+{
+       k_ESteamNetworkingAvailability_CannotTry = -102,
+       k_ESteamNetworkingAvailability_Failed = -101,
+       k_ESteamNetworkingAvailability_Previously = -100,
+       k_ESteamNetworkingAvailability_Retrying = -10,
+       k_ESteamNetworkingAvailability_NeverTried = 1,
+       k_ESteamNetworkingAvailability_Waiting = 2,
+       k_ESteamNetworkingAvailability_Attempting = 3,
+       k_ESteamNetworkingAvailability_Current = 100,
+       k_ESteamNetworkingAvailability_Unknown = 0,
+       k_ESteamNetworkingAvailability__Force32bit = 0x7fffffff,
+};
+
+/* Handle used to identify a connection to a remote host. */
+typedef u32 HSteamNetConnection;
+HSteamNetConnection const k_HSteamNetConnection_Invalid = 0;
+
+/* 
+ * Handle used to identify a "listen socket".  Unlike traditional
+ * Berkeley sockets, a listen socket and a connection are two
+ * different abstractions.
+ */
+typedef u32 HSteamListenSocket;
+HSteamListenSocket const k_HSteamListenSocket_Invalid = 0;
+
+typedef u32 SteamNetworkingPOPID;
+
+#define k_cchSteamNetworkingMaxConnectionCloseReason 128
+#define k_cchSteamNetworkingMaxConnectionDescription 128
+#define k_cchSteamNetworkingMaxConnectionAppName 32
+
+#pragma pack(push,1)
+/* Store an IP and port. IPv6 is always used; IPv4 is represented using
+ * "IPv4-mapped" addresses: IPv4 aa.bb.cc.dd => IPv6 ::ffff:aabb:ccdd
+ * (RFC 4291 section 2.5.5.2.)
+ */
+typedef struct SteamNetworkingIPAddr SteamNetworkingIPAddr;
+struct SteamNetworkingIPAddr
+{
+       union
+       {
+               u8 m_ipv6[ 16 ];
+
+      /* RFC4038, section 4.2 */
+      struct IPv4MappedAddress 
+      {
+         u64 m_8zeros;
+         u16 m_0000;
+         u16 m_ffff;
+         u8  m_ip[ 4 ]; /* NOTE: As bytes, i.e. network byte order */
+      }
+      m_ipv4;
+       };
+
+       u16 m_port; // Host byte order
+};
+
+typedef struct SteamNetworkingIdentity SteamNetworkingIdentity;
+struct SteamNetworkingIdentity
+{
+       ESteamNetworkingIdentityType m_eType;
+
+       int m_cbSize;
+       union 
+   {
+               u64 m_steamID64;
+               char m_szGenericString[ 32 ];
+               u8 m_genericBytes[ 32 ];
+               char m_szUnknownRawString[ 128 ];
+               SteamNetworkingIPAddr m_ip;
+               u32 m_reserved[ 32 ];
+       };
+};
+
+#pragma pack(pop)
+
+/* 
+ * "Fake IPs" are assigned to hosts, to make it easier to interface with
+ * older code that assumed all hosts will have an IPv4 address
+ */
+typedef enum ESteamNetworkingFakeIPType ESteamNetworkingFakeIPType;
+enum ESteamNetworkingFakeIPType
+{
+       k_ESteamNetworkingFakeIPType_Invalid, 
+       k_ESteamNetworkingFakeIPType_NotFake,
+       k_ESteamNetworkingFakeIPType_GlobalIPv4,
+       k_ESteamNetworkingFakeIPType_LocalIPv4,
+       k_ESteamNetworkingFakeIPType__Force32Bit = 0x7fffffff
+};
+
+/* Set everything to zero. E.g. [::]:0 */
+void SteamAPI_SteamNetworkingIPAddr_Clear( SteamNetworkingIPAddr* self );
+
+/* Returns true if the IP is ::0. (Doesn't check port.) */
+int  SteamAPI_SteamNetworkingIPAddr_IsIPv6AllZeros( 
+      SteamNetworkingIPAddr* self );
+
+/* 
+ * 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
+ */
+void SteamAPI_SteamNetworkingIPAddr_SetIPv6( SteamNetworkingIPAddr* self, 
+      u8 *ipv6, u16 nPort );
+
+/* Sets to IPv4 mapped address.  IP and port are in host byte order. */
+void SteamAPI_SteamNetworkingIPAddr_SetIPv4( SteamNetworkingIPAddr* self, 
+      u32 nIP, u16 nPort );
+
+/* Return true if IP is mapped IPv4 */
+int SteamAPI_SteamNetworkingIPAddr_IsIPv4( SteamNetworkingIPAddr* self );
+
+/* 
+ * Returns IP in host byte order (e.g. aa.bb.cc.dd as 0xaabbccdd).
+ * Returns 0 if IP is not mapped IPv4.
+ */
+u32 SteamAPI_SteamNetworkingIPAddr_GetIPv4( SteamNetworkingIPAddr* self );
+
+/* Set to the IPv6 localhost address ::1, and the specified port. */
+void SteamAPI_SteamNetworkingIPAddr_SetIPv6LocalHost( 
+                                    SteamNetworkingIPAddr* self, u16 nPort );
+
+/* 
+ * Return true if this identity is localhost.  
+ * (Either IPv6 ::1, or IPv4 127.0.0.1)
+ */
+int SteamAPI_SteamNetworkingIPAddr_IsLocalHost( SteamNetworkingIPAddr* self );
+
+/* 
+ * Print to a string, with or without the port. Mapped IPv4 addresses are 
+ * printed as dotted decimal (12.34.56.78), otherwise this will print the 
+ * canonical form according to RFC5952. If you include the port, IPv6 will be 
+ * surrounded by brackets, e.g. [::1:2]:80. Your buffer should be at least 
+ * k_cchMaxString bytes to avoid truncation
+ *
+ * See also SteamNetworkingIdentityRender
+ */
+void SteamAPI_SteamNetworkingIPAddr_ToString( SteamNetworkingIPAddr* self, 
+      char *buf, u32 cbBuf, int bWithPort );
+
+/* 
+ * Parse an IP address and optional port. If a port is not present, it is set 
+ * to 0.
+ * (This means that you cannot tell if a zero port was explicitly specified.)
+ */
+int SteamAPI_SteamNetworkingIPAddr_ParseString( SteamNetworkingIPAddr* self, 
+      const char *pszStr );
+
+/* See if two addresses are identical */
+int SteamAPI_SteamNetworkingIPAddr_IsEqualTo( SteamNetworkingIPAddr* self, 
+      SteamNetworkingIPAddr *x );
+
+/* 
+ * Classify address as FakeIP.  This function never returns
+ * k_ESteamNetworkingFakeIPType_Invalid.
+ */
+ESteamNetworkingFakeIPType SteamAPI_SteamNetworkingIPAddr_GetFakeIPType( 
+      SteamNetworkingIPAddr* self );
+
+/* Return true if we are a FakeIP */
+int SteamAPI_SteamNetworkingIPAddr_IsFakeIP( SteamNetworkingIPAddr* self );
+
+
+/* Describe the state of a connection. */
+typedef struct SteamNetConnectionInfo_t SteamNetConnectionInfo_t;
+struct SteamNetConnectionInfo_t
+{
+       SteamNetworkingIdentity m_identityRemote;
+
+       /* Arbitrary user data set by the local application code */
+       i64 m_nUserData;
+
+       /* Handle to listen socket this was connected on, or 
+    * k_HSteamListenSocket_Invalid if we initiated the connection */
+       HSteamListenSocket m_hListenSocket;
+
+       /* Remote address.  Might be all 0's if we don't know it, or if this is N/A.
+    * (E.g. Basically everything except direct UDP connection.) */
+       SteamNetworkingIPAddr m_addrRemote;
+       u16 m__pad1;
+
+       /* What data center is the remote host in?  (0 if we don't know.) */
+       SteamNetworkingPOPID m_idPOPRemote;
+
+       /* What relay are we using to communicate with the remote host? 
+    * (0 if not applicable.) */
+       SteamNetworkingPOPID m_idPOPRelay;
+
+       /* High level state of the connection */
+       ESteamNetworkingConnectionState m_eState;
+
+       /* Basic cause of the connection termination or problem.
+    * See ESteamNetConnectionEnd for the values used */
+       int m_eEndReason;
+
+       /* 
+    * Human-readable, but non-localized explanation for connection
+    * termination or problem.  This is intended for debugging /
+        * diagnostic purposes only, not to display to users.  It might
+        * have some details specific to the issue.
+    */
+       char m_szEndDebug[ 128 ];
+
+       /* 
+    * Debug description.  This includes the internal connection ID,
+    * connection type (and peer information), and any name
+        * given to the connection by the app.  This string is used in various
+        * internal logging messages.
+        * 
+        * Note that the connection ID *usually* matches the HSteamNetConnection
+        * handle, but in certain cases with symmetric connections it might not.
+    */
+       char m_szConnectionDescription[ 128 ];
+
+       /* 
+    * Misc flags.  Bitmask of k_nSteamNetworkConnectionInfoFlags_Xxxx
+    */
+       int m_nFlags;
+
+       /* 
+    * Internal stuff, room to change API easily
+    */
+       u32 reserved[63];
+};
+
+/* 
+ * In a few places we need to set configuration options on listen sockets and 
+ * connections, and have them take effect *before* the listen socket or 
+ * connection really starts doing anything. Creating the object and then setting
+ * the options "immediately" after creation doesn't work completely, because 
+ * network packets could be received between the time the object is created and
+ * when the options are applied. To set options at creation time in a reliable 
+ * way, they must be passed to the creation function. This structure is used to 
+ * pass those options.
+ *
+ * For the meaning of these fields, see ISteamNetworkingUtils::SetConfigValue.
+ * Basically when the object is created, we just iterate over the list of 
+ * options and call ISteamNetworkingUtils::SetConfigValueStruct, where the scope
+ * arguments are supplied by the object being created.
+ */
+typedef struct SteamNetworkingConfigValue_t SteamNetworkingConfigValue_t;
+struct SteamNetworkingConfigValue_t
+{
+       /* Which option is being set */
+       ESteamNetworkingConfigValue m_eValue;
+
+       /// Which field below did you fill in?
+       ESteamNetworkingConfigDataType m_eDataType;
+
+       /// Option value
+       union
+       {
+               i32 m_int32;
+               i64 m_int64;
+               float m_float;
+               const char *m_string; // Points to your '\0'-terminated buffer
+               void *m_ptr;
+       } m_val;
+};
+
+void SteamAPI_SteamNetworkingConfigValue_t_SetInt32( 
+      SteamNetworkingConfigValue_t* self, 
+      ESteamNetworkingConfigValue eVal, i32 data );
+
+void SteamAPI_SteamNetworkingConfigValue_t_SetInt64( 
+      SteamNetworkingConfigValue_t* self, 
+      ESteamNetworkingConfigValue eVal, i64 data );
+
+void SteamAPI_SteamNetworkingConfigValue_t_SetFloat( 
+      SteamNetworkingConfigValue_t* self, 
+      ESteamNetworkingConfigValue eVal, float data );
+
+void SteamAPI_SteamNetworkingConfigValue_t_SetPtr( 
+      SteamNetworkingConfigValue_t* self, 
+      ESteamNetworkingConfigValue eVal, void *data );
+
+void SteamAPI_SteamNetworkingConfigValue_t_SetString( 
+      SteamNetworkingConfigValue_t* self, ESteamNetworkingConfigValue eVal, 
+      const char * data );
+
+/*
+ * Handle used to identify a poll group, used to query many
+ * connections at once efficiently.
+ */
+typedef u32 HSteamNetPollGroup;
+HSteamNetPollGroup const k_HSteamNetPollGroup_Invalid = 0;
+
+void *SteamAPI_SteamGameServerNetworkingSockets_SteamAPI_v012(void);
+void *SteamAPI_SteamGameServerNetworkingSockets_SteamAPI(void) 
+{ 
+   return SteamAPI_SteamGameServerNetworkingSockets_SteamAPI_v012(); 
+}
+
+
+void *SteamAPI_SteamNetworkingSockets_SteamAPI_v012();
+void *SteamAPI_SteamNetworkingSockets_SteamAPI() 
+{ 
+   return SteamAPI_SteamNetworkingSockets_SteamAPI_v012(); 
+}
+
+HSteamListenSocket SteamAPI_ISteamNetworkingSockets_CreateListenSocketIP( 
+      void *self, SteamNetworkingIPAddr *localAddress, int nOptions, 
+      SteamNetworkingConfigValue_t *pOptions );
+
+HSteamNetConnection SteamAPI_ISteamNetworkingSockets_ConnectByIPAddress( 
+      void *self, 
+      SteamNetworkingIPAddr *address, int nOptions, 
+      SteamNetworkingConfigValue_t *pOptions );
+
+int SteamAPI_ISteamNetworkingSockets_CloseConnection( 
+      void *self, HSteamNetConnection hPeer, int nReason, const char *pszDebug, 
+      int bEnableLinger );
+
+int SteamAPI_ISteamNetworkingSockets_CloseListenSocket( 
+      void *self, HSteamListenSocket hSocket );
+
+/*
+ * Callbacks
+ */
+
+enum { k_iSteamNetConnectionStatusChangedCallBack = 
+         k_iSteamNetworkingSocketsCallbacks + 1 };
+
+typedef struct SteamNetConnectionStatusChangedCallback_t
+               SteamNetConnectionStatusChangedCallback_t;
+struct SteamNetConnectionStatusChangedCallback_t
+{ 
+       /// Connection handle
+       HSteamNetConnection m_hConn;
+
+       /// Full connection info
+       SteamNetConnectionInfo_t m_info;
+
+       /// Previous state.  (Current state is in m_info.m_eState)
+       ESteamNetworkingConnectionState m_eOldState;
+};
+
+enum { k_iSteamNetAuthenticationStatus = 
+         k_iSteamNetworkingSocketsCallbacks + 2 };
+
+typedef struct SteamNetAuthenticationStatus_t SteamNetAuthenticationStatus_t;
+struct SteamNetAuthenticationStatus_t
+{ 
+       /// Status
+       ESteamNetworkingAvailability m_eAvail;
+
+       /// Non-localized English language status.  For diagnostic/debugging
+       /// purposes only.
+       char m_debugMsg[ 256 ];
+};
+
+#pragma pack(pop)
+#endif /* VG_STEAM_NETWORKING_H */