diff --git a/CMakeLists.txt b/CMakeLists.txt index c734cb6..24b7a79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ elseif(NOT SSXTOOLS_LINKER) set(SSXTOOLS_LINKER "bfd") endif() +include(FetchContent) ssxtools_set_alternate_linker() add_executable(swsf_scramble diff --git a/src/main.cpp b/src/main.cpp index 73115f6..446e981 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,14 +1,12 @@ -#include #include #include #include -#include #include #include namespace asio = boost::asio; // nvm doesnt work lol :) -//using asio::experimental::concurrent_channel; +// using asio::experimental::concurrent_channel; template std::string RandomString(std::uint32_t length, TRandomAlgo& rng) { @@ -65,49 +63,69 @@ bool NextCode(std::string& buffer, size_t start) { return false; } -void ThreadFunction(char prefix) { - for(std::uint32_t i = 2; i < code_length; ++i) { - std::string test_buffer(i, 'a'); - test_buffer[0] = prefix; +// see https://bisqwit.iki.fi/jutut/kuvat/programming_examples/cpp_thread_tutorial/ver05.cc +namespace { + unsigned ln = 1; - // test all possible combinations - while(true) { - std::cout << std::format("trying code \"{}\"...\r", test_buffer); - if(SwsfScramble(test_buffer) == code_hash) { - std::cerr << std::format("match: {}", test_buffer); + auto Color(int n, const std::string& s) { + return "\33[38;5;" + std::to_string(n) + 'm' + s + "\33[m"; + } + + auto Line(int l) { + int m = l - ln; + ln = l; + return "\r" + (m < 0 ? "\33[" + std::to_string(-m) + 'A' : std::string(m, '\n')); + } + + std::mutex print_lock; + +} // namespace + +struct BruteThreadState { + BruteThreadState(unsigned line) : line(line) {} + + void DisplayProgress(const std::string& code) { + std::lock_guard lk(print_lock); + std::cout << Line(line) << std::format("Thread {:2}: Trying code {}", line, Color(140, code)) << std::flush; + } + + void BruteForce(char prefix) { + for(std::uint32_t i = 2; i < code_length; ++i) { + std::string test_buffer(i, 'a'); + test_buffer[0] = prefix; + + // test all possible combinations + while(true) { + // std::cout << std::format("trying code \"{}\"...\r", test_buffer); + DisplayProgress(test_buffer); + + if(SwsfScramble(test_buffer) == code_hash) { + std::cerr << std::format("match: {}\n", test_buffer); + } + + if(!NextCode(test_buffer, 1)) + break; } - - if(!NextCode(test_buffer, 1)) - break; } } -#if 0 - std::string test_buffer(code_length, 'a'); - test_buffer[0] = prefix; + private: + unsigned line; +}; - while(true) { - std::cout << std::format("trying code \"{}\"...\r", test_buffer); - if(SwsfScramble(test_buffer) == code_hash) { - std::cerr << std::format("match: {}", test_buffer); - } - - if(!NextCode(test_buffer, 1)) - return; - } -#endif -} int main() { asio::io_context ioc; asio::thread_pool pool(26); - // Channel - // ChannelType channel(ioc); + auto line = 0u; // post onto the thread pool for(int i = 0; i < 26; ++i) - asio::post(pool, [i]() { ThreadFunction('a' + i); }); + asio::post(pool, [i, l = line++]() { + BruteThreadState state(l); + state.BruteForce('a' + i); + }); pool.join(); return 0;