Ryan Stecker avatar Ryan Stecker committed 937c043

Config files are the best.

Comments (0)

Files changed (8)

steam_api/ConfigReader.cpp

+#include "StdAfx.h"
+#include "ConfigReader.h"
+
+ConfigReader::ConfigReader( const char *fileName )
+{
+#ifdef WIN32
+	strcpy_s( m_FileName, 260, fileName );
+#else
+	strlcpy( m_FileName, fileName, 260 );
+#endif
+}
+
+bool ConfigReader::GetConfigString( const char *configName, char *configValue, uint32 outSize )
+{
+	// boost? heh, no.
+
+	if ( !configName || !configValue || !outSize )
+		return false;
+
+#ifdef WIN32
+	DWORD numWritten = GetPrivateProfileString( "SteamAPI", configName, NULL, configValue, outSize, m_FileName );
+
+	if ( !numWritten )
+		return false;
+
+#else
+	// todo: implement me!
+#endif
+
+	return true;
+}
+
+bool ConfigReader::GetConfigInt( const char *configName, int *configValue )
+{
+	if ( !configName || !configValue )
+		return false;
+
+#ifdef WIN32
+	uint32 ret = GetPrivateProfileInt( "SteamAPI", configName, -1, m_FileName );
+
+	if ( ret == -1 )
+		return false;
+
+	*configValue = ret;
+
+#else
+	// todo: implement me!
+#endif
+
+	return true;
+}
+
+bool ConfigReader::FileExists()
+{
+	std::ifstream fileStream( m_FileName );
+	bool exists = fileStream.good();
+
+	fileStream.close();
+
+	return exists;
+}

steam_api/ConfigReader.h

+#pragma once
+
+/* example config
+
+[SteamAPI]
+SteamClient = SteamClient008
+SteamUtils = SteamUtils003
+
+*/
+
+class ConfigReader
+{
+
+public:
+	ConfigReader( const char *fileName );
+
+
+	bool GetConfigString( const char *configName, char *configValue, uint32 outSize );
+	bool GetConfigInt( const char *configName, int *configValue );
+
+	bool FileExists();
+
+
+private:
+	char m_FileName[ 260 ];
+
+};

steam_api/interfaces.cpp

 #include "stdafx.h"
 #include "interfaces.h"
 
+
+ISteamClient *steamClient = NULL; // this is exposed
+ISteamUser *steamUser = NULL;
+ISteamUtils *steamUtils = NULL; // etc..
+
+/*
 DEFINE_CURRENT_VERSION( STEAMUSER,					012, ISteamUser,				SteamUser) 
 DEFINE_CURRENT_VERSION( STEAMFRIENDS,				004, ISteamFriends,				SteamFriends)
 DEFINE_CURRENT_VERSION( STEAMUTILS,					004, ISteamUtils,				SteamUtils)
 DEFINE_CURRENT_VERSION( STEAMAPPS,					003, ISteamApps,				SteamApps)
 DEFINE_CURRENT_VERSION( STEAMNETWORKING,			003, ISteamNetworking,			SteamNetworking)
 DEFINE_CURRENT_VERSION( STEAMMATCHMAKINGSERVERS,	002, ISteamMatchmakingServers,	SteamMatchmakingServers)
-DEFINE_CURRENT_VERSION( STEAMREMOTESTORAGE,			002, ISteamRemoteStorage,		SteamRemoteStorage)
+DEFINE_CURRENT_VERSION( STEAMREMOTESTORAGE,			002, ISteamRemoteStorage,		SteamRemoteStorage)*/
 
-
+/*
 bool LoadInterfaces()
 {
 	TRYGET_CURRENT_VERSION_PIPE( STEAMUTILS,			GetISteamUtils )
 	TRYGET_CURRENT_VERSION( STEAMREMOTESTORAGE,			GetISteamRemoteStorage )
 
 	return true;
+}*/
+
+// globals so that GetInterfaces and SteamAPI_InitInternal can access them
+// best to have an array of these, but i'm too tried to fully implement something like that
+char steamClientVer[ 30 ];
+char steamUserVer[ 30 ];
+char steamUtilsVer[ 30 ]; // etc..
+
+bool LoadInterfaces()
+{
+	if ( !internalSteamClient )
+		return false;
+
+	steamUser = internalSteamClient->GetISteamUser( user, pipe, steamUserVer );
+	if ( !steamUser )
+		return false;
+
+	steamUtils = internalSteamClient->GetISteamUtils( pipe, steamUtilsVer );
+	if ( !steamUtils )
+		return false;
+
+	return true;
 }
 
 S_API ISteamClient* STEAM_CALL SteamClient()
 {
-	return (ISteamClient *)steamclient;
+	return steamClient;
+}
+
+S_API ISteamUser* STEAM_CALL SteamUser()
+{
+	return steamUser;
 }

steam_api/interfaces.h

 #pragma once
 
+// move these to interfaces eventually
+extern ISteamClient *steamClient; // this is exposed
+extern ISteamUser *steamUser;
+extern ISteamUtils *steamUtils; // etc..
+
+// globals so that GetInterfaces and SteamAPI_InitInternal can access them
+// best to have an array of these, but i'm too tried to fully implement something like that
+extern char steamClientVer[ 30 ];
+extern char steamUserVer[ 30 ];
+extern char steamUtilsVer[ 30 ]; // etc..
+
 #define EXPORT_CURRENT_VERSION(ICLASS, EXPORT) \
 	S_API ICLASS * STEAM_CALL EXPORT();
 

steam_api/stdafx.h

 #include "steam_api.h"
 
 #include <boost/unordered_map.hpp>
+#include <iostream>
+#include <fstream>
 #include <vector>

steam_api/steam_api.cpp

 #include "stdafx.h"
 #include "interfaces.h"
 
+#include "ConfigReader.h"
+
+
 CSteamAPILoader loader;
 CreateInterfaceFn clientFactory = NULL;
 
-STEAMCLIENT_ICLASS *steamclient = NULL;
+STEAMCLIENT_ICLASS *internalSteamClient = NULL;
 
 HSteamPipe pipe = 0;
 HSteamUser user = 0;
 
-S_API bool STEAM_CALL SteamAPI_Init()
+ConfigReader config( "steam_api.cfg" );
+
+
+#ifndef WIN32
+void OutputDebugString( const char *msg )
 {
-	if(!SteamAPI_InitSafe())
+	printf( "%s", msg ); // there's probably something better to use here
+}
+#endif
+
+
+
+bool SteamAPI_InitInternal( bool safeInit )
+{
+	if ( !config.FileExists() )
+	{
+		OutputDebugString( "[S_API FAIL] SteamAPI_Init() failed; no config file found.\nConfig file names 'steam_api.cfg' is required.\n" );
+		return false;
+	}
+
+	if ( !config.GetConfigString( "SteamCilent", steamClientVer, 30 ) )
+	{
+		OutputDebugString( "[S_API FAIL] SteamAPI_Init() failed; SteamClient version not set.\n" );
+		return false;
+	}
+	// get other interface version strings
+
+
+	clientFactory = loader.Load();
+	if ( clientFactory == NULL )
+	{
+		OutputDebugString( "[S_API FAIL] SteamAPI_Init() failed; unable to locate a running instance of Steam, or a local steamclient.dll.\n" );
+		return false;
+	}
+
+	steamClient = (ISteamClient *)clientFactory( steamClientVer, NULL );
+	if ( !steamClient )
+		return false; // valve's steam_api doesn't spew an error, but we probably should
+
+	internalSteamClient = (STEAMCLIENT_ICLASS *)clientFactory( STEAMCLIENT_IFACE, NULL );
+	if ( !internalSteamClient )
 		return false;
 
-	if(!LoadInterfaces())
+	pipe = internalSteamClient->CreateSteamPipe();
+	if ( !pipe )
 		return false;
 
+	user = internalSteamClient->ConnectToGlobalUser( pipe );
+	if ( !user )
+		return false;
+
+	/* valve's code:
+
+	if ( safe )
+	{
+		pSteamUtils = g_pSteamClient->GetISteamUils( g_hSteamPipe, "SteamUtils003" );
+		if ( !pSteamUtils )
+		{
+			OutputDebugStringA("[S_API FAIL] SteamAPI_Init() failed; no appID found.\nEither launch the game from Steam, or put the file steam_appid.txt containing the correct appID in your game folder.\n");
+			return 0;
+		}
+    }
+
+	apparently this implies that if there is no steam_appid.txt, this interface won't be returned?
+	*/
+	if ( safeInit )
+	{
+		ISteamUtils003 *tempUtils = (ISteamUtils003 *)internalSteamClient->GetISteamUtils( pipe, STEAMUTILS_INTERFACE_VERSION_003 );
+
+		if ( !tempUtils || !tempUtils->GetAppID() )
+		{
+			OutputDebugString("[S_API FAIL] SteamAPI_Init() failed; no appID found.\nEither launch the game from Steam, or put the file steam_appid.txt containing the correct appID in your game folder.\n");
+			return false;
+		}
+	}
+
+	// get other interfaces based on config strings
+	if ( !LoadInterfaces() )
+		return false;
+
+	
+	//Steam_RegisterInterfaceFuncs( loader.GetSteamModule() );
+
 	return true;
 }
 
+S_API bool STEAM_CALL SteamAPI_Init()
+{
+	return SteamAPI_InitInternal( false );
+}
+
 S_API bool STEAM_CALL SteamAPI_InitSafe()
 {
-	clientFactory = loader.Load();
-
-	if(clientFactory == NULL)
-		return false;
-
-	steamclient = (STEAMCLIENT_ICLASS *)clientFactory(STEAMCLIENT_IFACE, NULL);
-
-	if(steamclient == NULL)
-		return false;
-
-	pipe = steamclient->CreateSteamPipe();
-
-	if(pipe == NULL)
-		return false;
-
-	user = steamclient->ConnectToGlobalUser(pipe);
-
-	if(user == NULL)
-		return false;
-
-	return true;
+	return SteamAPI_InitInternal( true );
 }
 
 S_API void SteamAPI_Shutdown()
 {
-	if(user)
+	if( user )
 	{
-		steamclient->ReleaseUser(pipe, user);
+		internalSteamClient->ReleaseUser( pipe, user );
 		user = NULL;
 	}
-	if(pipe)
+
+	if( pipe )
 	{
-		steamclient->ReleaseSteamPipe(pipe);
+		internalSteamClient->ReleaseSteamPipe( pipe );
 		pipe = NULL;
 	}
 }

steam_api/steam_api.h

 extern CSteamAPILoader loader;
 extern CreateInterfaceFn clientFactory;
 
-extern STEAMCLIENT_ICLASS *steamclient;
+extern STEAMCLIENT_ICLASS *internalSteamClient;
 
 extern HSteamUser user;
 extern HSteamPipe pipe;

steam_api/steam_api.vcproj

 			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
 			IntermediateDirectory="$(ConfigurationName)"
 			ConfigurationType="2"
-			CharacterSet="1"
+			CharacterSet="0"
 			>
 			<Tool
 				Name="VCPreBuildEventTool"
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="&quot;../Open Steamworks&quot;;../boost_1_40_0"
+				AdditionalIncludeDirectories="&quot;../Open Steamworks&quot;;../boost_1_40_0;.."
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;STEAM_API_EXPORTS"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
 			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
 			IntermediateDirectory="$(ConfigurationName)"
 			ConfigurationType="2"
-			CharacterSet="1"
+			CharacterSet="0"
 			WholeProgramOptimization="1"
 			>
 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="2"
 				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="&quot;../Open Steamworks&quot;;../boost_1_40_0"
+				AdditionalIncludeDirectories="&quot;../Open Steamworks&quot;;../boost_1_40_0;.."
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;STEAM_API_EXPORTS"
 				RuntimeLibrary="2"
 				EnableFunctionLevelLinking="true"
 				>
 			</File>
 			<File
+				RelativePath=".\ConfigReader.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\dllmain.cpp"
 				>
 				<FileConfiguration
 				>
 			</File>
 			<File
+				RelativePath=".\ConfigReader.h"
+				>
+			</File>
+			<File
 				RelativePath=".\interfaces.h"
 				>
 			</File>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.