#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;
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 )
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) )
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);
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];
/* 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];
--- /dev/null
+#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 */
--- /dev/null
+#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 */
--- /dev/null
+#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 */
--- /dev/null
+#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 */