Compare commits
	
		
			3 Commits
		
	
	
		
			c633c96ad7
			...
			d11b690708
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d11b690708 | |||
| 8dbb226251 | |||
| 870ec7345b | 
@@ -34,4 +34,4 @@ TODO: Generate this.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## COPYRIGHT
 | 
					## COPYRIGHT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Copyright © 2017-2019 Nicholas O'Connor. Provided under the terms of the MIT license: https://opensource.org/licenses/MIT
 | 
					Copyright © 2017-2025 Nicole O'Connor. Provided under the terms of the MIT license: https://opensource.org/licenses/MIT
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/* This file contains string definitions for ANSI color sequences
 | 
					/* This file contains string definitions for ANSI color sequences
 | 
				
			||||||
 * it was written by Nicole O'Connor and is available  to all 
 | 
					 * it was written by Nicole O'Connor and is available to all 
 | 
				
			||||||
 * under the MIT license.
 | 
					 * under the MIT license.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Usage:
 | 
					 * Usage:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,12 @@ namespace cellar {
 | 
				
			|||||||
            bottle_labelled,
 | 
					            bottle_labelled,
 | 
				
			||||||
            bottle_symlink
 | 
					            bottle_symlink
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * Bottles are the internal name for WINE prefixes. In addition to standard WINE contents,
 | 
				
			||||||
 | 
					         * bottles contain a configuration file managed by cellar, which labels the bottle as well
 | 
				
			||||||
 | 
					         * as providing configuration settings.
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
        class Bottle {
 | 
					        class Bottle {
 | 
				
			||||||
            public:
 | 
					            public:
 | 
				
			||||||
                // public members
 | 
					                // public members
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,10 @@ using namespace cellar::bottles;
 | 
				
			|||||||
using CommandFunction = cellar::commands::CommandFunction;
 | 
					using CommandFunction = cellar::commands::CommandFunction;
 | 
				
			||||||
using json = nlohmann::json;
 | 
					using json = nlohmann::json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Construct an empty bottle object.
 | 
				
			||||||
 | 
					 * This empty bottle object can then be used to help create new ones.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
Bottle::Bottle() {
 | 
					Bottle::Bottle() {
 | 
				
			||||||
    // define a null bottle
 | 
					    // define a null bottle
 | 
				
			||||||
    // strings handle themselves
 | 
					    // strings handle themselves
 | 
				
			||||||
@@ -31,6 +35,11 @@ Bottle::Bottle() {
 | 
				
			|||||||
    type = bottle_anonymous;
 | 
					    type = bottle_anonymous;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Construct a bottle object from at a given path.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @param patharg The path to load a bottle from.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
Bottle::Bottle(string patharg) {
 | 
					Bottle::Bottle(string patharg) {
 | 
				
			||||||
    output::statement("loading bottle from " + patharg, true);
 | 
					    output::statement("loading bottle from " + patharg, true);
 | 
				
			||||||
    config = json({});
 | 
					    config = json({});
 | 
				
			||||||
@@ -58,6 +67,14 @@ Bottle::Bottle(string patharg) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Lists all bottles cellar manages or is otherwise aware of.
 | 
				
			||||||
 | 
					 * This includes bottles managed by other tools like Steam or Lutris,
 | 
				
			||||||
 | 
					 * assuming support for those tools is compiled into cellar. (Steam
 | 
				
			||||||
 | 
					 * support is present; Lutris support is planned for the future.)
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @return map<string, Bottle> All bottles. Bottles managed by other tools have prefixed keys, e.g. Steam bottles use "steam:"
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
map<string, Bottle> cellar::bottles::get_bottles() {
 | 
					map<string, Bottle> cellar::bottles::get_bottles() {
 | 
				
			||||||
	map<string, Bottle> result;
 | 
						map<string, Bottle> result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -80,6 +97,19 @@ map<string, Bottle> cellar::bottles::get_bottles() {
 | 
				
			|||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Takes an input that refers to a bottle and returns a path to that bottle.
 | 
				
			||||||
 | 
					 * This input can be any of the following:
 | 
				
			||||||
 | 
					 *  * A bottle name as managed by cellar
 | 
				
			||||||
 | 
					 *  * A prefixed bottle name, in the format `<tool>:<identifier>`. (e.g. `steam:78000`)
 | 
				
			||||||
 | 
					 *  * An absolute or relative path, in which case it is returned with no modification.
 | 
				
			||||||
 | 
					 *  * A path relative to (and starting with ~). cellar will throw a warning in verbose mode,
 | 
				
			||||||
 | 
					 *    since usually the shell expands this for us, but will do a naive replacement on its own
 | 
				
			||||||
 | 
					 *    and try to prevent confused users.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @param bottlechoice Input, usually referring to a specific bottle known to cellar.
 | 
				
			||||||
 | 
					 * @return string Path to referenced bottle.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
string cellar::bottles::resolve_bottle(string bottlechoice) {
 | 
					string cellar::bottles::resolve_bottle(string bottlechoice) {
 | 
				
			||||||
    string result;
 | 
					    string result;
 | 
				
			||||||
    if (bottlechoice.substr(0,1) == "/" || bottlechoice.substr(0,1) == ".") { // absolute or relative path
 | 
					    if (bottlechoice.substr(0,1) == "/" || bottlechoice.substr(0,1) == ".") { // absolute or relative path
 | 
				
			||||||
@@ -107,6 +137,9 @@ string cellar::bottles::resolve_bottle(string bottlechoice) {
 | 
				
			|||||||
    return result;
 | 
					    return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Prints bottles. Used as a command in CLI.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
void cellar::bottles::print_bottles(int argc, vector<string> argv) {
 | 
					void cellar::bottles::print_bottles(int argc, vector<string> argv) {
 | 
				
			||||||
    map<string, Bottle> bottles = get_bottles();
 | 
					    map<string, Bottle> bottles = get_bottles();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
core
 | 
					core
 | 
				
			||||||
config
 | 
					config
 | 
				
			||||||
bottles
 | 
					bottles
 | 
				
			||||||
launch
 | 
					launch
 | 
				
			||||||
steam
 | 
					 | 
				
			||||||
@@ -11,6 +11,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using namespace tyti; //vdf
 | 
					using namespace tyti; //vdf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Returns all app bottles managed by Steam.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @return std::map<std::string, cellar::bottles::Bottle> Steam managed bottles. Keys are "steam:<appid>".
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
std::map<std::string, cellar::bottles::Bottle> cellar::steam::get_app_bottles() {
 | 
					std::map<std::string, cellar::bottles::Bottle> cellar::steam::get_app_bottles() {
 | 
				
			||||||
    std::map<std::string, cellar::bottles::Bottle> result;
 | 
					    std::map<std::string, cellar::bottles::Bottle> result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +0,0 @@
 | 
				
			|||||||
steamtest test_command Test Steam related thing.
 | 
					 | 
				
			||||||
@@ -12,17 +12,23 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
using namespace tyti;
 | 
					using namespace tyti;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @brief Reads Steam library settings and returns a list of Steam library paths.
 | 
				
			||||||
 | 
					 * Returns an empty vector if it can't read ~/.steam/root/config/libraryfolders.vdf.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * @return std::vector<std::string> Steam library paths.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
std::vector<std::string> cellar::steam::find_steam_libraries() {
 | 
					std::vector<std::string> cellar::steam::find_steam_libraries() {
 | 
				
			||||||
    std::stringstream sstr_steam_library_config;
 | 
					    std::stringstream sstr_steam_library_config;
 | 
				
			||||||
    sstr_steam_library_config << std::getenv("HOME");
 | 
					    sstr_steam_library_config << std::getenv("HOME");
 | 
				
			||||||
    sstr_steam_library_config << "/.steam/root/config/libraryfolders.vdf";
 | 
					    sstr_steam_library_config << "/.steam/root/config/libraryfolders.vdf";
 | 
				
			||||||
    std::string str_steam_library_config = sstr_steam_library_config.str();
 | 
					    std::string str_steam_library_config = sstr_steam_library_config.str();
 | 
				
			||||||
 | 
					    std::vector<std::string> result = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::ifstream fd_steam_library_config(str_steam_library_config);
 | 
					    std::ifstream fd_steam_library_config(str_steam_library_config);
 | 
				
			||||||
 | 
					    if (fd_steam_library_config.fail()) { return result; } // return empty if something went wrong (should cover most problems)
 | 
				
			||||||
    auto hnd_steam_library_config = vdf::read(fd_steam_library_config);
 | 
					    auto hnd_steam_library_config = vdf::read(fd_steam_library_config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::vector<std::string> result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (auto hnd_library_def : hnd_steam_library_config.childs) {
 | 
					    for (auto hnd_library_def : hnd_steam_library_config.childs) {
 | 
				
			||||||
        std::string str_index = hnd_library_def.first;
 | 
					        std::string str_index = hnd_library_def.first;
 | 
				
			||||||
        auto hnd_library = hnd_library_def.second;
 | 
					        auto hnd_library = hnd_library_def.second;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,49 +0,0 @@
 | 
				
			|||||||
#include <cstdlib>
 | 
					 | 
				
			||||||
#include <filesystem>
 | 
					 | 
				
			||||||
#include <format>
 | 
					 | 
				
			||||||
#include <fstream>
 | 
					 | 
				
			||||||
#include <sstream>
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "vdf_parser.hpp"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "bottles.hpp"
 | 
					 | 
				
			||||||
#include "output.hpp"
 | 
					 | 
				
			||||||
#include "steam.hpp"
 | 
					 | 
				
			||||||
#include "internal/steam.hpp"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace tyti; // vdf
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void cellar::steam::test_command(int argc, std::vector<std::string> argv) {
 | 
					 | 
				
			||||||
    for (std::string str_path_library : cellar::steam::find_steam_libraries()) {
 | 
					 | 
				
			||||||
        output::statement(str_path_library);
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        std::filesystem::path pth_library(str_path_library);
 | 
					 | 
				
			||||||
        std::filesystem::path pth_steam_cellar = pth_library / "steamapps/compatdata";
 | 
					 | 
				
			||||||
        for (auto const& itm_appid : std::filesystem::directory_iterator(pth_steam_cellar)) {
 | 
					 | 
				
			||||||
            auto pth_appid = itm_appid.path();
 | 
					 | 
				
			||||||
            if (std::filesystem::is_directory(pth_appid / "pfx") && ! std::filesystem::is_empty(pth_appid / "pfx")) {
 | 
					 | 
				
			||||||
                //                            \/ string-to-unsigned-long
 | 
					 | 
				
			||||||
                std::string str_appid = pth_appid.filename().string(); // should become, e.g. 1124300
 | 
					 | 
				
			||||||
                auto pth_appmanifest = pth_library / ("steamapps/appmanifest_" + str_appid + ".acf");
 | 
					 | 
				
			||||||
                if (! std::filesystem::exists(pth_appmanifest) ) { continue; }
 | 
					 | 
				
			||||||
                std::string str_gamename = "";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                std::ifstream fd_appmanifest(pth_appmanifest);
 | 
					 | 
				
			||||||
                auto hnd_appmanifest = vdf::read(fd_appmanifest);
 | 
					 | 
				
			||||||
                for (auto hnd_appmanifest_def : hnd_appmanifest.attribs) {
 | 
					 | 
				
			||||||
                    std::string str_index = hnd_appmanifest_def.first;
 | 
					 | 
				
			||||||
                    std::string str_value = hnd_appmanifest_def.second;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (str_index == "name") {
 | 
					 | 
				
			||||||
                        str_gamename = str_value;
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                output::warning("Steam App #" + str_appid + " (" + str_gamename + ")");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user