Made the Steam class in STK and SSM more compatible. Improve error
handling, and cache frequently used values (e.g. name and id).
This commit is contained in:
parent
eb4989c2ef
commit
de795b766a
@ -1518,11 +1518,10 @@ int main(int argc, char *argv[] )
|
||||
|
||||
Steam *steam = new Steam();
|
||||
bool steam_avail = steam->isSteamAvailable();
|
||||
std::string id = steam->getId();
|
||||
std::string name = steam->getName();
|
||||
std::string id = steam->getSteamID();
|
||||
std::string name = steam->getUserName();
|
||||
int n = steam->saveAvatarAs("test.png");
|
||||
//std::vector<std::string> friends = steam->getFriends();
|
||||
//std::string quit = steam->sendCommand("quit");
|
||||
delete steam;
|
||||
|
||||
CrashReporting::installHandlers();
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
Steam::Steam()
|
||||
{
|
||||
m_steam_available = false;
|
||||
#ifdef WIN32
|
||||
// Based on: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
|
||||
SECURITY_ATTRIBUTES sec_attr;
|
||||
@ -40,47 +41,85 @@ Steam::Steam()
|
||||
if (!CreatePipe(&m_child_stdout_read, &m_child_stdout_write, &sec_attr, 0))
|
||||
{
|
||||
Log::error("Steam", "Error creating StdoutRd CreatePipe");
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the read handle to the pipe for STDOUT is not inherited.
|
||||
|
||||
if (!SetHandleInformation(m_child_stdout_read, HANDLE_FLAG_INHERIT, 0))
|
||||
{
|
||||
Log::error("Steam", "Stdout SetHandleInformation");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a pipe for the child process's STDIN.
|
||||
if (!CreatePipe(&m_child_stdin_read, &m_child_stdin_write, &sec_attr, 0))
|
||||
{
|
||||
Log::error("Steam", "Stdin CreatePipe");
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the write handle to the pipe for STDIN is not inherited.
|
||||
|
||||
if (!SetHandleInformation(m_child_stdin_write, HANDLE_FLAG_INHERIT, 0))
|
||||
{
|
||||
Log::error("Steam", "Stdin SetHandleInformation");
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the child process.
|
||||
|
||||
createChildProcess();
|
||||
if (!createChildProcess())
|
||||
{
|
||||
Log::error("Steam", "Could not start ssm.exe");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
std::string s = sendCommand("init");
|
||||
if (s != "1")
|
||||
{
|
||||
Log::error("Steam", "Could not initialise Steam API.");
|
||||
return;
|
||||
}
|
||||
|
||||
s = sendCommand("name");
|
||||
m_user_name = decodeString(s);
|
||||
if (m_user_name == "")
|
||||
{
|
||||
Log::error("Steam", "Can not get Steam user name.");
|
||||
return;
|
||||
}
|
||||
|
||||
s = sendCommand("id");
|
||||
m_steam_id = decodeString(s);
|
||||
if (m_steam_id== "")
|
||||
{
|
||||
Log::error("Steam", "Can not get Steam id.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_steam_available = true;
|
||||
} // Steam
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Terminates the child processes and shuts down the Steam API.
|
||||
*/
|
||||
Steam::~Steam()
|
||||
{
|
||||
|
||||
std::string s = sendCommand("quit");
|
||||
if (s != "quit")
|
||||
{
|
||||
Log::error("Steam", "Could not shutdown Steam process properly");
|
||||
}
|
||||
} // ~Steam
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
int Steam::createChildProcess()
|
||||
/** Starts ssm.exe as a child process and sets up communication via pipes.
|
||||
* \return True if the child process creation was successful.
|
||||
*/
|
||||
bool Steam::createChildProcess()
|
||||
{
|
||||
#ifdef WIN32
|
||||
TCHAR command_line[] = TEXT("ssm.exe 1");
|
||||
PROCESS_INFORMATION piProcInfo;
|
||||
STARTUPINFO siStartInfo;
|
||||
BOOL bSuccess = FALSE;
|
||||
|
||||
// Set up members of the PROCESS_INFORMATION structure.
|
||||
|
||||
@ -98,7 +137,7 @@ int Steam::createChildProcess()
|
||||
|
||||
// Create the child process.
|
||||
|
||||
bSuccess = CreateProcess(NULL,
|
||||
bool success = CreateProcess(NULL,
|
||||
command_line, // command line
|
||||
NULL, // process security attributes
|
||||
NULL, // primary thread security attributes
|
||||
@ -107,32 +146,31 @@ int Steam::createChildProcess()
|
||||
NULL, // use parent's environment
|
||||
NULL, // use parent's current directory
|
||||
&siStartInfo, // STARTUPINFO pointer
|
||||
&piProcInfo); // receives PROCESS_INFORMATION
|
||||
&piProcInfo) != 0; // receives PROCESS_INFORMATION
|
||||
|
||||
// If an error occurs, exit the application.
|
||||
if (!bSuccess)
|
||||
if (!success)
|
||||
{
|
||||
Log::error("Steam", "CreateProcess");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Close handles to the child process and its primary thread.
|
||||
// Some applications might keep these handles to monitor the status
|
||||
// of the child process, for example.
|
||||
|
||||
CloseHandle(piProcInfo.hProcess);
|
||||
CloseHandle(piProcInfo.hThread);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
} // createChildProcess
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Reads a command from the input pipe.
|
||||
*/
|
||||
std::string Steam::getLine()
|
||||
{
|
||||
#define BUFSIZE 1024
|
||||
CHAR buffer[BUFSIZE];
|
||||
char buffer[BUFSIZE];
|
||||
DWORD bytes_read;
|
||||
// Read from pipe that is the standard output for child process.
|
||||
bool success = ReadFile(m_child_stdout_read, buffer, BUFSIZE-1,
|
||||
@ -147,6 +185,9 @@ std::string Steam::getLine()
|
||||
} // getLine
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sends a command to the SSM via a pipe, and reads the answer.
|
||||
* \return Answer from SSM.
|
||||
*/
|
||||
std::string Steam::sendCommand(const std::string &command)
|
||||
{
|
||||
#ifdef WIN32
|
||||
@ -163,6 +204,12 @@ std::string Steam::sendCommand(const std::string &command)
|
||||
} // sendCommand
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** All answer strings from 'SSM' are in the form: "length string", i.e. the
|
||||
* length of the string, followed by a space and then the actual strings.
|
||||
* This allows for checking on some potential problems (e.g. if a pipe should
|
||||
* only send part of the answer string - todo: handle this problem instead of
|
||||
* ignoring it.
|
||||
*/
|
||||
std::string Steam::decodeString(const std::string &s)
|
||||
{
|
||||
std::vector<std::string> l = StringUtils::split(s, ' ');
|
||||
@ -180,21 +227,21 @@ std::string Steam::decodeString(const std::string &s)
|
||||
/** Returns the steam user name. SSM returns 'N name" where N is
|
||||
* the length of the name.
|
||||
*/
|
||||
std::string Steam::getName()
|
||||
const std::string& Steam::getUserName()
|
||||
{
|
||||
std::string s = sendCommand("name");
|
||||
return decodeString(s);
|
||||
} // getName
|
||||
assert(m_steam_available);
|
||||
return m_user_name;
|
||||
} // getUserName
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns a unique id (string) from steam. SSM returns 'N ID" where N is
|
||||
* the length of the ID.
|
||||
*/
|
||||
std::string Steam::getId()
|
||||
const std::string& Steam::getSteamID()
|
||||
{
|
||||
std::string s = sendCommand("id");
|
||||
return decodeString(s);
|
||||
} // getId
|
||||
assert(m_steam_available);
|
||||
return m_steam_id;
|
||||
} // getSteamID
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Returns a std::vector with the names of all friends. SSM returns a first
|
||||
@ -214,6 +261,10 @@ std::vector<std::string> Steam::getFriends()
|
||||
return result;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Instructs the SSM to save the avatar of the user with the specified
|
||||
* filename. Note that the avatar is always saved in png format (independent
|
||||
* on what is specified as filename).
|
||||
*/
|
||||
int Steam::saveAvatarAs(const std::string filename)
|
||||
{
|
||||
//std::string s = sendCommand(std::string("avatar ")+filename);
|
||||
|
@ -34,6 +34,15 @@
|
||||
class Steam
|
||||
{
|
||||
private:
|
||||
/** True if a connection to steam was made successfully. */
|
||||
bool m_steam_available;
|
||||
|
||||
/** Steam user name. Only defined if m_steam_available. */
|
||||
std::string m_user_name;
|
||||
|
||||
/** Unique steam id. */
|
||||
std::string m_steam_id;
|
||||
|
||||
#ifdef WIN32
|
||||
// Various handles for the window pipes
|
||||
HANDLE m_child_stdin_read;
|
||||
@ -41,24 +50,23 @@ private:
|
||||
HANDLE m_child_stdout_read;
|
||||
HANDLE m_child_stdout_write;
|
||||
|
||||
int createChildProcess();
|
||||
bool createChildProcess();
|
||||
#endif
|
||||
|
||||
bool m_steam_available;
|
||||
std::string decodeString(const std::string &s);
|
||||
std::string sendCommand(const std::string &command);
|
||||
std::string getLine();
|
||||
public:
|
||||
Steam();
|
||||
~Steam();
|
||||
std::string getName();
|
||||
std::string getId();
|
||||
const std::string& getUserName();
|
||||
const std::string& getSteamID();
|
||||
int saveAvatarAs(const std::string filename);
|
||||
std::vector<std::string> getFriends();
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns true if the connection to the Steam API was successful, i.e.
|
||||
* connection to steam worked, and SteamWorks API could be initialised. */
|
||||
bool isSteamAvailable() { return m_steam_available; }
|
||||
bool isSteamAvailable() const { return m_steam_available; }
|
||||
}; // class Steam
|
||||
|
||||
#endif // HEADER_STEAM_HPP
|
||||
|
Loading…
Reference in New Issue
Block a user