#include "HttpServer.hpp" #include #include #include #include const char* src_debugger_js = R"( var app = angular.module('debugApp', []); app.controller('DebugCtrl', function($scope,$http) { $scope.threads = []; $scope.running = true; $scope.breakpoint = {}; $scope.refresh = function() { var promise = $http.get('/state') .success(function(data, status, headers, config) { $scope.running = data.status == 'running'; $scope.threads = data.threads; $scope.breakpoint = data.breakpoint; }); }; $scope.interrupt = function() { var promise = $http.get('/interrupt') .success(function(data, status, headers, config) { $scope.refresh(); }); } $scope.step = function() { var promise = $http.get('/step') .success(function(data, status, headers, config) { $scope.refresh(); }); } $scope.continue = function() { var promise = $http.get('/continue') .success(function(data, status, headers, config) { $scope.refresh(); }); } $scope.refresh(); }); )"; const char* src_page = R"(

OpenRW Debugger

Game is running
{{ breakpoint.program_counter }} {{ breakpoint.thread }}

Threads

  • {{thread.name}} ({{thread.address}})

    program counter: {{thread.program_counter}}
    wake counter: {{thread.wake_counter}} ms

    Return Stack

    1. Address {{return_address}}

    Disassembly

    {{ call.address }} {{call.function }} ( {{param.value}}, )
    1. Address {{return_address}}
)"; HttpServer::HttpServer(RWGame* game, GameWorld* world) : game(game), world(world), paused(false), lastBreakpoint(nullptr) {} void HttpServer::run() { listener.listen(8091); std::cout << "STARTING HTTP SERVER" << std::endl; while ( game->getWindow().isOpen() ) { sf::TcpSocket client; if (listener.accept(client) == sf::Socket::Done) { std::cout << "New connection from " << client.getRemoteAddress() << ":" << client.getRemotePort() << std::endl; char buf[1024]; size_t received; client.receive(buf, 1023, received); buf[received] = '\0'; std::cout << "Got " << received << " bytes: " << buf << std::endl; try { std::regex regex_http_first_line("(\\w+)\\s+(/.*?)\\s+HTTP/\\d+.\\d+"); std::cmatch regex_match; std::regex_search(buf, regex_match, regex_http_first_line); if (regex_match.size() == 3) { std::string http_method = regex_match.str(1); std::string http_path = regex_match.str(2); std::string response = dispatch(http_method, http_path); client.send(response.c_str(), response.size()); } } catch(std::regex_error er) { std::cerr << er.what() << " " << er.code() << std::endl; } client.disconnect(); } } listener.close(); } void HttpServer::handleBreakpoint(const SCMBreakpoint &bp) { lastBreakpoint = &bp; paused = true; while( paused ) { // Do nothing } } std::string thread_stack(SCMThread& th) { std::stringstream ss; for(unsigned int i = 0; i < th.stackDepth; ++i) { bool last = (th.stackDepth == i+1); ss << th.calls[i] << (last ? "" : ","); } return ss.str(); } #include