mirror of
https://github.com/zebrajr/SamRewritten.git
synced 2025-12-06 12:19:51 +01:00
commit
1091c4daa5
24
README.MD
24
README.MD
|
|
@ -49,12 +49,26 @@ Run SamRewritten by opening the corresponding desktop entry, or by using the `sa
|
||||||
|
|
||||||
# Command line options
|
# Command line options
|
||||||
|
|
||||||
I know you linux geeks love to use command line options.
|
I know you linux geeks love to use command line options! SamRewritten has a few, let us know if you want to see more!
|
||||||
We have big ambitions for SamRewritten, and I believe many of them are related to these command-line options, so stay put, because that list will be growing soon!
|
|
||||||
|
|
||||||
* -a \<appid\>
|
```
|
||||||
* Prevents the window from showing and sets your status to "In Game"
|
Usage:
|
||||||
* `./bin/launch.sh -a 10` will idle Counter Strike
|
samrewritten [AppId] [OPTION...]
|
||||||
|
|
||||||
|
--apps Get the list of your owned apps.
|
||||||
|
-h, --help Show CLI help.
|
||||||
|
-a, --app arg Set which AppId you want to use. Same as using positional
|
||||||
|
'AppId'
|
||||||
|
-i, --idle Set your Steam profile as 'ingame'. Ctrl+c to stop.
|
||||||
|
--ls Display stats (TODO) and achievements for selected app.
|
||||||
|
--sort arg Sort option for --ls. You can leave empty or set to
|
||||||
|
'unlock_rate'
|
||||||
|
--unlock arg Unlock achievements for an AppId. Separate achievement
|
||||||
|
names by a comma.
|
||||||
|
--lock arg Lock achievements for an AppId. Separate achievement
|
||||||
|
names by a comma.
|
||||||
|
--launch Actually just launch the app.
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,46 +1,192 @@
|
||||||
#include "cli_funcs.h"
|
#include "cli_funcs.h"
|
||||||
#include "../controller/MySteam.h"
|
#include "../controller/MySteam.h"
|
||||||
#include "../globals.h"
|
#include "../globals.h"
|
||||||
|
#include "../common/cxxopts.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
void handle_sigint_cli(int signum) {
|
void handle_sigint_cli(int signum)
|
||||||
|
{
|
||||||
std::cout << "Quitting cli idling" << std::endl;
|
std::cout << "Quitting cli idling" << std::endl;
|
||||||
g_steam->quit_game();
|
g_steam->quit_game();
|
||||||
exit(0);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void idle_app(std::string appid) {
|
void idle_app(AppId_t appid)
|
||||||
|
{
|
||||||
std::cout << "Idling from command line " << appid << std::endl;
|
std::cout << "Idling from command line " << appid << std::endl;
|
||||||
AppId_t realid = strtoul(appid.c_str(), NULL, 10);
|
g_steam->launch_app(appid);
|
||||||
g_steam->launch_game(realid);
|
|
||||||
signal(SIGINT, handle_sigint_cli);
|
signal(SIGINT, handle_sigint_cli);
|
||||||
|
|
||||||
|
// Wait for ctrl+c, so we can kill both processes, otherwise
|
||||||
|
// GUI process will exit while game process still goes on
|
||||||
|
for(;;) {
|
||||||
|
sleep(10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compareByUnlockRateDesc(const Achievement_t &a, const Achievement_t &b)
|
||||||
|
{
|
||||||
|
return a.global_achieved_rate > b.global_achieved_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool go_cli_mode(int argc, char* argv[]) {
|
bool go_cli_mode(int argc, char* argv[]) {
|
||||||
bool cli = false;
|
cxxopts::Options options(argv[0], "Steam Achievements Manager");
|
||||||
int opt;
|
|
||||||
while((opt = getopt(argc, argv, ":a:")) != -1)
|
options
|
||||||
{
|
.positional_help("[AppId]")
|
||||||
switch(opt)
|
.show_positional_help()
|
||||||
{
|
.add_options()
|
||||||
case 'a':
|
("apps", "Get the list of your owned apps.")
|
||||||
const std::string appid = std::string(optarg);
|
("h,help", "Show CLI help.")
|
||||||
idle_app(appid);
|
("a,app", "Set which AppId you want to use. Same as using positional 'AppId'", cxxopts::value<AppId_t>())
|
||||||
cli = true;
|
("i,idle", "Set your Steam profile as 'ingame'. Ctrl+c to stop.")
|
||||||
break;
|
("ls", "Display stats (TODO) and achievements for selected app.")
|
||||||
}
|
("sort", "Sort option for --ls. You can leave empty or set to 'unlock_rate'", cxxopts::value<std::string>())
|
||||||
}
|
("unlock", "Unlock achievements for an AppId. Separate achievement names by a comma.", cxxopts::value<std::vector<std::string>>())
|
||||||
|
("lock", "Lock achievements for an AppId. Separate achievement names by a comma.", cxxopts::value<std::vector<std::string>>())
|
||||||
|
("launch", "Actually just launch the app.");
|
||||||
|
|
||||||
// If cli, wait for ctrl+c, so we can kill both processes, otherwise
|
|
||||||
// GUI process will exit while game process still goes on
|
options.parse_positional({"app"});
|
||||||
if ( cli ) {
|
|
||||||
for(;;) {
|
auto result = options.parse(argc, argv);
|
||||||
sleep(10000);
|
bool cli = false;
|
||||||
|
AppId_t app = 0;
|
||||||
|
|
||||||
|
if (result.count("help"))
|
||||||
|
{
|
||||||
|
std::cout << options.help() << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("app") > 0)
|
||||||
|
{
|
||||||
|
cli = true;
|
||||||
|
app = result["app"].as<AppId_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("apps") > 0)
|
||||||
|
{
|
||||||
|
cli = true;
|
||||||
|
|
||||||
|
g_steam->refresh_owned_apps();
|
||||||
|
auto apps = g_steam->get_subscribed_apps();
|
||||||
|
|
||||||
|
std::cout << "AppId \t App Name" << std::endl;
|
||||||
|
for ( Game_t& it : apps )
|
||||||
|
{
|
||||||
|
std::cout << it.app_id << "\t " << it.app_name << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.count("idle") > 0)
|
||||||
|
{
|
||||||
|
cli = true;
|
||||||
|
if (app == 0)
|
||||||
|
{
|
||||||
|
std::cout << "Please provide an AppId argument before idling." << std::endl;
|
||||||
|
return cli;
|
||||||
|
}
|
||||||
|
|
||||||
|
idle_app(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("ls") > 0) {
|
||||||
|
cli = true;
|
||||||
|
if (app == 0)
|
||||||
|
{
|
||||||
|
std::cout << "Please provide an AppId argument before listing stats." << std::endl;
|
||||||
|
return cli;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_steam->launch_app(app);
|
||||||
|
g_steam->refresh_achievements();
|
||||||
|
auto achievements = g_steam->get_achievements();
|
||||||
|
g_steam->quit_game();
|
||||||
|
|
||||||
|
if (result.count("sort") > 0)
|
||||||
|
{
|
||||||
|
const std::string sort = result["sort"].as<std::string>();
|
||||||
|
|
||||||
|
if (sort == "unlock_rate")
|
||||||
|
{
|
||||||
|
std::sort(achievements.begin(), achievements.end(), compareByUnlockRateDesc);
|
||||||
|
std::cout << "Sorted by global unlock rate\n" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/haarcuba/cpp-text-table -> worth? nah but best I've found
|
||||||
|
std::cout << "API Name \t\tName \t\tDescription \t\tUnlock rate \t\tUnlocked" << std::endl;
|
||||||
|
std::cout << "--------------------------------------------------------------" << std::endl;
|
||||||
|
for ( Achievement_t& it : achievements )
|
||||||
|
{
|
||||||
|
std::cout
|
||||||
|
<< it.id << " \t"
|
||||||
|
<< it.name << " \t"
|
||||||
|
<< it.desc << " \t"
|
||||||
|
<< it.global_achieved_rate << "% \t"
|
||||||
|
<< (it.achieved ? "✔️" : "❌") << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("unlock") > 0)
|
||||||
|
{
|
||||||
|
if (app == 0)
|
||||||
|
{
|
||||||
|
std::cout << "Please provide an AppId argument before unlocking achievements." << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli = true;
|
||||||
|
const std::vector<std::string> ids = result["unlock"].as<std::vector<std::string>>();
|
||||||
|
|
||||||
|
for ( std::string it : ids )
|
||||||
|
{
|
||||||
|
g_steam->add_modification_ach(it, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_steam->launch_app(app);
|
||||||
|
g_steam->commit_changes();
|
||||||
|
g_steam->quit_game();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("lock") > 0)
|
||||||
|
{
|
||||||
|
if (app == 0)
|
||||||
|
{
|
||||||
|
std::cout << "Please provide an AppId argument before relocking achievements." << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cli = true;
|
||||||
|
const std::vector<std::string> ids = result["lock"].as<std::vector<std::string>>();
|
||||||
|
|
||||||
|
for ( std::string it : ids )
|
||||||
|
{
|
||||||
|
g_steam->add_modification_ach(it, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_steam->launch_app(app);
|
||||||
|
g_steam->commit_changes();
|
||||||
|
g_steam->quit_game();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.count("launch") > 0)
|
||||||
|
{
|
||||||
|
if (app == 0)
|
||||||
|
{
|
||||||
|
std::cout << "Please provide an AppId argument before launching the app." << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Launching app with Steam. Make sure you have xdg-open installed." << std::endl;
|
||||||
|
system(("xdg-open steam://run/" + std::to_string(app)).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return cli;
|
return cli;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2214
src/common/cxxopts.hpp
Normal file
2214
src/common/cxxopts.hpp
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -65,7 +65,7 @@ MySteam::get_instance() {
|
||||||
* Fakes a new game being launched. Keeps running in the background until quit_game is called.
|
* Fakes a new game being launched. Keeps running in the background until quit_game is called.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
MySteam::launch_game(AppId_t appID) {
|
MySteam::launch_app(AppId_t appID) {
|
||||||
// Print an error if a game is already launched
|
// Print an error if a game is already launched
|
||||||
// allow multiple games at the same time in the future via new window launching
|
// allow multiple games at the same time in the future via new window launching
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ MySteam::launch_game(AppId_t appID) {
|
||||||
m_app_id = appID;
|
m_app_id = appID;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// => launch_game
|
// => launch_app
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,10 @@ public:
|
||||||
* given appId. Returns false if this process failed to launch.
|
* given appId. Returns false if this process failed to launch.
|
||||||
* The process may start successfully but fail during execution.
|
* The process may start successfully but fail during execution.
|
||||||
*/
|
*/
|
||||||
bool launch_game(AppId_t appId);
|
bool launch_app(AppId_t appId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the process started with the above method launch_game.
|
* Stops the process started with the above method launch_app.
|
||||||
* Returns true if a process was successfully stopped.
|
* Returns true if a process was successfully stopped.
|
||||||
*/
|
*/
|
||||||
bool quit_game();
|
bool quit_game();
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ MainPickerWindow::on_game_row_activated(Gtk::ListBoxRow* row) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_to_achievement_page();
|
switch_to_achievement_page();
|
||||||
g_steam->launch_game(appid);
|
g_steam->launch_app(appid);
|
||||||
m_async_loader.populate_achievements();
|
m_async_loader.populate_achievements();
|
||||||
}
|
}
|
||||||
// => on_game_row_activated
|
// => on_game_row_activated
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user