void LevelLoader::loadMenuData() { // Retrieve the main (root) object JSONObject root = getTopLevelJSONObject(); JSONObject gameData = root[L"general_game_data"]->AsObject(); // Locate the menu background filename. if (gameData.find(L"menu_background_file") != gameData.end() && gameData[L"menu_background_file"]->IsString()) { m_menuData.m_menuBackgroundFile = wStringToString(gameData[L"menu_background_file"]->AsString()); } // For brevity, remaining checks on JSON types are skipped. // Locate the menu font file. JSONObject globalSettings = gameData[L"global_settings"]->AsObject(); m_menuData.m_menuFontFile = wStringToString(globalSettings[L"font_file"]->AsString()); // Drill down into the various menu items. JSONObject menuItems = gameData[L"menu_items"]->AsObject(); JSONObject item = menuItems[L"play"]->AsObject(); m_menuData.m_menuItemPlay.m_size = item[L"size"]->AsNumber(); m_menuData.m_menuItemPlay.m_text = wStringToString(item[L"text"]->AsString()); m_menuData.m_menuItemPlay.m_x = item[L"x"]->AsNumber(); m_menuData.m_menuItemPlay.m_y = item[L"y"]->AsNumber(); item = menuItems[L"exit"]->AsObject(); m_menuData.m_menuItemExit.m_size = item[L"size"]->AsNumber(); m_menuData.m_menuItemExit.m_text = wStringToString(item[L"text"]->AsString()); m_menuData.m_menuItemExit.m_x = item[L"x"]->AsNumber(); m_menuData.m_menuItemExit.m_y = item[L"y"]->AsNumber(); item = menuItems[L"continue"]->AsObject(); m_menuData.m_menuItemContinue.m_size = item[L"size"]->AsNumber(); m_menuData.m_menuItemContinue.m_text = wStringToString(item[L"text"]->AsString()); m_menuData.m_menuItemContinue.m_x = item[L"x"]->AsNumber(); m_menuData.m_menuItemContinue.m_y = item[L"y"]->AsNumber(); }
// Fill a map with parameters to be reported for a breakpoint stop. static StopReasonMap breakPointStopReasonParameters(PDEBUG_BREAKPOINT b) { typedef StopReasonMap::value_type StopReasonMapValue; StopReasonMap rc; ULONG uId = 0; if (FAILED(b->GetId(&uId))) return rc; rc.insert(StopReasonMapValue(std::string("breakpointId"), toString(uId))); const std::pair<ULONG64, ULONG> memoryRange = breakPointMemoryRange(b); if (!memoryRange.first) return rc; rc.insert(StopReasonMapValue(std::string("breakpointAddress"), toString(memoryRange.first))); // Report the memory for data breakpoints allowing for watching for changed bits // on the client side. if (!memoryRange.second) return rc; // Try to grab a IDataSpace from somewhere to get the memory if (CIDebugClient *client = ExtensionContext::instance().hookedClient()) { IInterfacePointer<CIDebugDataSpaces> dataSpaces(client); if (dataSpaces) { const std::wstring memoryHex = memoryToHexW(dataSpaces.data(), memoryRange.first, memoryRange.second); if (!memoryHex.empty()) rc.insert(StopReasonMapValue("memory", wStringToString(memoryHex))); } // dataSpaces } // client return rc; }
static inline ExtensionContext::StopReasonMap exceptionParameters(const EXCEPTION_RECORD64 &e, unsigned firstChance) { typedef ExtensionContext::StopReasonMap StopReasonMap; typedef ExtensionContext::StopReasonMap::value_type StopReasonMapValue; // Fill exception record StopReasonMap parameters; parameters.insert(StopReasonMapValue(std::string("firstChance"), toString(firstChance))); parameters.insert(StopReasonMapValue(std::string("exceptionAddress"), toString(e.ExceptionAddress))); parameters.insert(StopReasonMapValue(std::string("exceptionCode"), toString(e.ExceptionCode))); parameters.insert(StopReasonMapValue(std::string("exceptionFlags"), toString(e.ExceptionFlags))); // Hard code some parameters (used for access violations) if (e.NumberParameters >= 1) parameters.insert(StopReasonMapValue(std::string("exceptionInformation0"), toString(e.ExceptionInformation[0]))); if (e.NumberParameters >= 2) parameters.insert(StopReasonMapValue(std::string("exceptionInformation1"), toString(e.ExceptionInformation[1]))); // Add top stack frame if possible StackFrame frame; std::string errorMessage; // If it is a C++ exception, get frame #2 (first outside MSVC runtime) const unsigned frameNumber = e.ExceptionCode == winExceptionCppException ? 2 : 0; if (getFrame(frameNumber, &frame, &errorMessage)) { if (!frame.fullPathName.empty()) { parameters.insert(StopReasonMapValue(std::string("exceptionFile"), wStringToString(frame.fullPathName))); parameters.insert(StopReasonMapValue(std::string("exceptionLine"), toString(frame.line))); } if (!frame.function.empty()) parameters.insert(StopReasonMapValue(std::string("exceptionFunction"), wStringToString(frame.function))); } // getCurrentFrame return parameters; }
std::string widgetAt(const SymbolGroupValueContext &ctx, int x, int y, std::string *errorMessage) { typedef SymbolGroupValue::SymbolList SymbolList; // First, resolve symbol since there are ambiguities. Take the first one which is the // overload for (int,int) and call by address instead off name to overcome that. const QtInfo &qtInfo = QtInfo::get(ctx); const std::string func = qtInfo.prependQtModule("QApplication::widgetAt", qtInfo.version >= 5 ? QtInfo::Widgets : QtInfo::Gui); const SymbolList symbols = SymbolGroupValue::resolveSymbol(func.c_str(), ctx, errorMessage); if (symbols.empty()) return std::string(); // Not a gui application, likely std::ostringstream callStr; callStr << std::showbase << std::hex << symbols.front().second << std::noshowbase << std::dec << '(' << x << ',' << y << ')'; std::wstring wOutput; if (!ExtensionContext::instance().call(callStr.str(), &wOutput, errorMessage)) return std::string(); // Returns: ".call returns\nclass QWidget * 0x00000000`022bf100\nbla...". // Chop lines in front and after 'class ...' and convert first line. const std::wstring::size_type classPos = wOutput.find(L"class "); if (classPos == std::wstring::npos) { *errorMessage = msgWidgetParseError(wOutput); return std::string(); } wOutput.erase(0, classPos + 6); const std::wstring::size_type nlPos = wOutput.find(L'\n'); if (nlPos != std::wstring::npos) wOutput.erase(nlPos, wOutput.size() - nlPos); const std::string::size_type addressPos = wOutput.find(L" * 0x"); if (addressPos == std::string::npos) { *errorMessage = msgWidgetParseError(wOutput); return std::string(); } // "QWidget * 0x00000000`022bf100" -> "QWidget:0x00000000022bf100" wOutput.replace(addressPos, 3, L":"); const std::string::size_type sepPos = wOutput.find(L'`'); if (sepPos != std::string::npos) wOutput.erase(sepPos, 1); return wStringToString(wOutput); }
void LevelLoader::loadLevel1Data() { // Retrieve the main (root) object JSONObject root = getTopLevelJSONObject(); JSONObject gameData = root[L"general_game_data"]->AsObject(); // Load the time to place towers field and related text settings. JSONObject globalSettings = gameData[L"global_settings"]->AsObject(); m_gameData.m_placeTowersText = wStringToString(globalSettings[L"place_towers_text"]->AsString()); m_gameData.m_placeTowersTextSize = globalSettings[L"place_towers_text_size"]->AsNumber(); m_gameData.m_fontFile = wStringToString(globalSettings[L"font_file"]->AsString()); m_gameData.m_placeTowersTextX = globalSettings[L"place_towers_text_x"]->AsNumber(); m_gameData.m_placeTowersTextY = globalSettings[L"place_towers_text_y"]->AsNumber(); // Load game lose text. m_gameData.m_gameLoseText = wStringToString(globalSettings[L"game_lose_text"]->AsString()); // Load the particle system texture file. m_gameData.m_particlesTextureFile = wStringToString(globalSettings[L"particles_texture_file"]->AsString()); // Load the go button filename. m_gameData.m_goButtonFile = wStringToString(globalSettings[L"go_button_file"]->AsString()); m_gameData.m_goButtonWidth = globalSettings[L"go_button_width"]->AsNumber(); m_gameData.m_goButtonHeight = globalSettings[L"go_button_height"]->AsNumber(); // Load the x,y position for the go button. JSONObject goButtonPos = globalSettings[L"go_button_position"]->AsObject(); m_gameData.m_goButtonX = goButtonPos[L"x"]->AsNumber(); m_gameData.m_goButtonY = goButtonPos[L"y"]->AsNumber(); // Load the tower points background. m_gameData.m_towerPointsFile = wStringToString(globalSettings[L"tower_points_file"]->AsString()); // Load the tower points. m_gameData.m_towerPoints = globalSettings[L"tower_points"]->AsNumber(); // Load a value giving the honey level for the hive. m_gameData.m_honeyLevel = globalSettings[L"honey_level"]->AsNumber(); // Load the honey hive base. m_gameData.m_honeyHiveFile = wStringToString(globalSettings[L"honey_hive_file"]->AsString()); m_gameData.m_honeyHiveWidth = globalSettings[L"honey_hive_width"]->AsNumber(); m_gameData.m_honeyHiveRows = globalSettings[L"honey_hive_rows"]->AsNumber(); m_gameData.m_honeyHiveCols = globalSettings[L"honey_hive_cols"]->AsNumber(); m_gameData.m_honeyHiveFrames = globalSettings[L"honey_hive_frames"]->AsNumber(); JSONObject honeyHive = globalSettings[L"honey_hive_position"]->AsObject(); m_gameData.m_honeyHiveX = honeyHive[L"x"]->AsNumber(); m_gameData.m_honeyHiveY = honeyHive[L"y"]->AsNumber(); // Load the tower file JSONObject tower = globalSettings[L"tower"]->AsObject(); // Load the tower base image filename m_gameData.m_towerBaseFile = wStringToString(tower[L"tower_base_file"]->AsString()); // Tower width m_gameData.m_towerWidth = tower[L"tower_width"]->AsNumber(); // Tower height m_gameData.m_towerHeight = tower[L"tower_height"]->AsNumber(); m_gameData.m_towerFile = wStringToString(tower[L"tower_file"]->AsString()); m_gameData.m_numberOfTowers = tower[L"max_num_towers"]->AsNumber(); m_gameData.m_firingDelay = tower[L"firing_delay"]->AsNumber(); m_gameData.m_towerRotationSpeed = tower[L"tower_rotation_speed"]->AsNumber(); JSONObject towerRotationOrigin = tower[L"tower_rotation_origin"]->AsObject(); m_gameData.m_towerRotationOriginX = towerRotationOrigin[L"x"]->AsNumber(); m_gameData.m_towerRotationOriginY = towerRotationOrigin[L"y"]->AsNumber(); // Load some sfx files JSONObject sfx = globalSettings[L"sfx"]->AsObject(); m_gameData.m_mouseOverTowerBaseFile = wStringToString(sfx[L"mouse_over_tower_base"]->AsString()); m_gameData.m_towerPlacedFile = wStringToString(sfx[L"tower_placed"]->AsString()); m_gameData.m_towerFiringFile = wStringToString(sfx[L"tower_firing"]->AsString()); m_gameData.m_bumbleBeesFile = wStringToString(sfx[L"bumble_bees"]->AsString()); // Load the projectile related data JSONObject projectile = globalSettings[L"projectile"]->AsObject(); m_gameData.m_projectileFile = wStringToString(projectile[L"projectile_file"]->AsString()); JSONObject projectileCentre = projectile[L"projectile_centre"]->AsObject(); m_gameData.m_projectileCentreX = projectileCentre[L"x"]->AsNumber(); m_gameData.m_projectileCentreY = projectileCentre[L"y"]->AsNumber(); m_gameData.m_maxProjectiles = projectile[L"max_num_projectiles"]->AsNumber(); m_gameData.m_timeToLive = projectile[L"time_to_live"]->AsNumber(); m_gameData.m_velocity = projectile[L"velocity"]->AsNumber(); // Load the background image filename for level 1 JSONObject level1 = gameData[L"level1"]->AsObject(); m_gameData.m_level1BackgroundFile = wStringToString(level1[L"level1_background_file"]->AsString()); // Load the tower base positions from an array. JSONArray towerBaseArray = level1[L"tower_bases"]->AsArray(); m_gameData.m_numberOfTowerBases = towerBaseArray.size(); for (unsigned int i = 0; i < towerBaseArray.size(); i++) { // Each tower base position is a JSON Object. JSONObject towerBasePos = towerBaseArray[i]->AsObject(); m_gameData.m_towerBaseX[i] = towerBasePos[L"x"]->AsNumber(); m_gameData.m_towerBaseY[i] = towerBasePos[L"y"]->AsNumber(); } }
void LevelLoader::loadAIData() { // Retrieve the main (root) object JSONObject root = getTopLevelJSONObject(); JSONObject aiGameData = root[L"ai_game_data"]->AsObject(); // Load the ai game data for level 1. JSONObject level1 = aiGameData[L"level1"]->AsObject(); JSONObject ai = level1[L"ai"]->AsObject(); // Load the number of AI paths. m_gameData.m_aiPaths = ai[L"ai_paths"]->AsNumber(); // Load the number of little bears. m_gameData.m_maxNumLittleBears = ai[L"max_num_little_bears"]->AsNumber(); // Load the number of bears for the different paths. m_gameData.m_littleBearsPath1 = ai[L"little_bears_path1"]->AsNumber(); m_gameData.m_littleBearsPath2 = ai[L"little_bears_path2"]->AsNumber(); m_gameData.m_littleBearsPath3 = ai[L"little_bears_path3"]->AsNumber(); // Load the damage capability of the little bear ai. m_gameData.m_littleBearDamage = ai[L"little_bear_damage"]->AsNumber(); // Load the spawn interval. m_gameData.m_littleBearSpawnInterval = ai[L"little_bear_spawn_interval"]->AsNumber(); // Load the scaling factor. m_gameData.m_littleBearScale = ai[L"little_bear_scale"]->AsNumber(); // Load the velocity. m_gameData.m_littleBearVelocity = ai[L"little_bear_velocity"]->AsNumber(); // Load the starting position for path 1. JSONObject startPosition = ai[L"little_bear_start_position_path1"]->AsObject(); m_gameData.m_littleBearStartXPath1 = startPosition[L"x"]->AsNumber(); m_gameData.m_littleBearStartYPath1 = startPosition[L"y"]->AsNumber(); // Load the starting position for path 2. startPosition = ai[L"little_bear_start_position_path2"]->AsObject(); m_gameData.m_littleBearStartXPath2 = startPosition[L"x"]->AsNumber(); m_gameData.m_littleBearStartYPath2 = startPosition[L"y"]->AsNumber(); // Load the starting position for path 3. startPosition = ai[L"little_bear_start_position_path3"]->AsObject(); m_gameData.m_littleBearStartXPath3 = startPosition[L"x"]->AsNumber(); m_gameData.m_littleBearStartYPath3 = startPosition[L"y"]->AsNumber(); // Load the spritesheet (walking) data. JSONObject littleBearWalkingSpriteSheet = ai[L"little_bear_walking_spritesheet"]->AsObject(); m_gameData.m_littleBearWalkingRows = littleBearWalkingSpriteSheet[L"rows"]->AsNumber(); m_gameData.m_littleBearWalkingCols = littleBearWalkingSpriteSheet[L"columns"]->AsNumber(); m_gameData.m_littleBearWalkingWidth = littleBearWalkingSpriteSheet[L"width"]->AsNumber(); m_gameData.m_littleBearWalkingHeight = littleBearWalkingSpriteSheet[L"height"]->AsNumber(); // Load the spritesheet (waving) data. JSONObject littleBearWavingSpriteSheet = ai[L"little_bear_waving_spritesheet"]->AsObject(); m_gameData.m_littleBearWavingRows = littleBearWavingSpriteSheet[L"rows"]->AsNumber(); m_gameData.m_littleBearWavingCols = littleBearWavingSpriteSheet[L"columns"]->AsNumber(); m_gameData.m_littleBearWavingWidth = littleBearWavingSpriteSheet[L"width"]->AsNumber(); m_gameData.m_littleBearWavingHeight = littleBearWavingSpriteSheet[L"height"]->AsNumber(); // Load the image for the little bear walking. m_gameData.m_littleBearWalkingFile = wStringToString(ai[L"little_bear_walking_file"]->AsString()); // Load the image for the little bear waving. m_gameData.m_littleBearWavingFile = wStringToString(ai[L"little_bear_waving_file"]->AsString()); // Load AI waypoints for each of the three paths. int index = 0; loadAIWaypoints(ai, L"little_bear_waypoints_1", index, m_gameData.m_littleBearStartXPath1, m_gameData.m_littleBearStartYPath1); index = m_gameData.m_littleBearsPath1; loadAIWaypoints(ai, L"little_bear_waypoints_2", index, m_gameData.m_littleBearStartXPath2, m_gameData.m_littleBearStartYPath2); index = m_gameData.m_littleBearsPath1 + m_gameData.m_littleBearsPath2; loadAIWaypoints(ai, L"little_bear_waypoints_3", index, m_gameData.m_littleBearStartXPath3, m_gameData.m_littleBearStartYPath3); m_gameData.m_beesSwarmingFile = wStringToString(ai[L"bees_swarming_file"]->AsString()); JSONObject beesSwarmingSpriteSheet = ai[L"bees_swarming_spritesheet"]->AsObject(); m_gameData.m_beesSwarmingRows = beesSwarmingSpriteSheet[L"rows"]->AsNumber(); m_gameData.m_beesSwarmingWidth = beesSwarmingSpriteSheet[L"width"]->AsNumber(); m_gameData.m_beesSwarmingHeight = beesSwarmingSpriteSheet[L"height"]->AsNumber(); m_gameData.m_beesSwarmingOnScreenTime = beesSwarmingSpriteSheet[L"on_screen_time"]->AsNumber(); }
static inline std::string msgWidgetParseError(std::wstring wo) { replace(wo, L'\n', L';'); return "Output parse error :" + wStringToString(wo); }