1
0
mirror of https://github.com/quackerd/bdeh.git synced 2024-11-21 18:56:46 +00:00

Initial commit.

Co-authored-by: Haoyu Gu <guhaoyu2005@gmail.com>
This commit is contained in:
quackerd 2020-04-11 00:33:08 -04:00
parent 37459062f0
commit 18aa9191d1
4 changed files with 788 additions and 0 deletions

289
protobuf/OakProfile.proto Normal file
View File

@ -0,0 +1,289 @@
package OakSave;
import "OakShared.proto";
message PlayerInputBinding_Button {
optional string rebind_data_path = 1;
repeated string key_names = 2;
}
message PlayerInputBinding_Axis_Key {
optional string key_name = 1;
optional Vec3 scale_3d = 2;
}
message PlayerInputBinding_Axis {
optional string rebind_data_path = 1;
repeated PlayerInputBinding_Axis_Key keys = 2;
}
message PlayerInputBinding_Category {
optional string category_data_path = 1;
optional string context_data_path = 2;
repeated PlayerInputBinding_Button button_bindings = 3;
repeated PlayerInputBinding_Axis axis_bindings = 4;
}
message PlayerInputBindings {
repeated PlayerInputBinding_Category categories = 1;
}
message OakProfileLastInventoryFilterInfo {
optional string slot_type_id = 1;
optional int32 last_filter_index = 2;
}
message OakProfileMenuTutorialInfo {
repeated string seen_tutorials = 1;
optional bool tutorials_disabled = 2;
optional bool tutorials_allowed_in_non_game_modes = 3;
}
message OakFriendEncounterData {
optional uint32 num_encounters = 1;
optional int64 time_last_encounter = 2;
}
message OakMailItem {
optional uint32 mail_item_type = 1;
optional string sender_display_name = 2;
optional string subject = 3;
optional string body = 4;
optional string gear_serial_number = 5;
optional string mail_guid = 6;
optional int64 date_sent = 7;
optional int64 expiration_date = 8;
optional string from_player_id = 9;
optional bool has_been_read = 10;
}
message GearSoldByFriendData {
optional string gear_serial_number = 1;
optional int32 player_class_identifier_hash = 2;
optional string friend_net_id = 3;
}
message OakCustomizationSaveGameData {
optional bool is_new = 1;
optional string customization_asset_path = 2;
}
message OakInventoryCustomizationPartInfo {
optional uint32 customization_part_hash = 1;
optional bool is_new = 2;
}
message GuardianRankRewardSaveGameData {
optional int32 num_tokens = 1;
optional string reward_data_path = 2;
}
message GuardianRankProfileData {
optional int32 available_tokens = 1;
repeated GuardianRankRewardSaveGameData rank_rewards = 2;
optional int32 guardian_rank = 3;
optional int32 guardian_experience = 4;
optional int32 guardian_reward_random_seed = 5;
optional int64 new_guardian_experience = 6;
}
message CrewQuartersDecorationItemSaveGameData {
optional bool is_new = 1;
optional string decoration_item_asset_path = 2;
}
message CrewQuartersRoomItemSaveGameData {
optional bool is_new = 1;
optional string room_item_asset_path = 2;
}
message RecentlyMetPlayer {
optional string shift_player_id = 1;
optional string first_party_player_id = 2;
optional bool show_shift_player_entry = 3;
}
message Profile {
message FriendEncountersEntry {
optional string key = 1;
optional OakFriendEncounterData value = 2;
}
optional bool enable_aim_assist = 1;
optional bool gamepad_invert_look = 2;
optional bool gamepad_invert_turn = 3;
optional bool gamepad_invert_move = 4;
optional bool gamepad_invert_strafe = 5;
optional bool enable_vibration = 6;
optional bool invert_mouse_pitch = 7;
optional bool enable_mouse_smoothing = 8;
optional float mouse_scale = 9;
optional bool show_damage_numbers = 10;
optional bool show_damage_number_icons = 11;
optional bool enable_training_messages = 12;
optional bool show_text_chat = 13;
optional bool center_crosshair = 14;
optional bool toggle_sprint = 15;
optional bool toggle_crouch = 16;
optional bool censor_content = 17;
optional float music_volume = 18;
optional float sound_effects_volume = 19;
optional float vo_volume = 20;
optional float voice_volume = 21;
optional bool enable_optional_vo = 22;
optional bool push_to_talk = 23;
optional bool enable_controller_audio = 24;
optional float speaker_angle_front = 25;
optional float speaker_angle_side = 26;
optional float speaker_angle_back = 27;
optional uint32 speaker_setup = 28;
optional bool mute_audio_on_focus_loss = 29;
optional bool hide_strict_nat_help_dialog = 34;
optional PlayerInputBindings player_input_bindings = 35;
repeated uint32 news_hashes = 36;
optional uint32 last_used_savegame_id = 37;
optional int32 gamepad_hip_sensitivity_level = 38;
optional int32 gamepad_zoomed_sensitivity_level = 39;
optional int32 gamepad_vehicle_sensitivity_level = 40;
optional float gamepad_movement_dead_zone_x = 41;
optional float gamepad_movement_dead_zone_y = 42;
optional float gamepad_look_dead_zone_inner_x = 43;
optional float gamepad_look_dead_zone_outer_x = 44;
optional float gamepad_look_dead_zone_inner_y = 45;
optional float gamepad_look_dead_zone_outer_y = 46;
optional float gamepad_vehicle_movement_dead_zone_x = 47;
optional float gamepad_vehicle_movement_dead_zone_y = 48;
optional float gamepad_vehicle_look_dead_zone_inner_x = 49;
optional float gamepad_vehicle_look_dead_zone_outer_x = 50;
optional float gamepad_vehicle_look_dead_zone_inner_y = 51;
optional float gamepad_vehicle_look_dead_zone_outer_y = 52;
optional float gamepad_left_dead_zone_inner = 53;
optional float gamepad_left_dead_zone_outer = 54;
optional float gamepad_right_dead_zone_inner = 55;
optional float gamepad_right_dead_zone_outer = 56;
optional float gamepad_look_axial_dead_zone_scale = 57;
optional float gamepad_move_axial_dead_zone_scale = 58;
optional bool gamepad_use_advanced_hip_aim_settings = 59;
optional bool gamepad_use_advanced_zoomed_aim_settings = 60;
optional bool gamepad_use_advanced_vehicle_aim_settings = 61;
optional float gamepad_hip_yaw_rate = 62;
optional float gamepad_hip_pitch_rate = 63;
optional float gamepad_hip_extra_yaw = 64;
optional float gamepad_hip_extra_pitch = 65;
optional float gamepad_hip_ramp_up_time = 66;
optional float gamepad_hip_ramp_up_delay = 67;
optional float gamepad_zoomed_yaw_rate = 68;
optional float gamepad_zoomed_pitch_rate = 69;
optional float gamepad_zoomed_extra_yaw = 70;
optional float gamepad_zoomed_extra_pitch = 71;
optional float gamepad_zoomed_ramp_up_time = 72;
optional float gamepad_zoomed_ramp_up_delay = 73;
optional float gamepad_vehicle_yaw_rate = 74;
optional float gamepad_vehicle_pitch_rate = 75;
optional float gamepad_vehicle_extra_yaw = 76;
optional float gamepad_vehicle_extra_pitch = 77;
optional float gamepad_vehicle_ramp_up_time = 78;
optional float gamepad_vehicle_ramp_up_delay = 79;
optional bool ironsight_aim_assist = 80;
optional uint32 walking_joystick_scheme = 81;
optional uint32 driving_joystick_scheme = 82;
optional float mouse_ads_scale = 83;
optional float mouse_vehicle_scale = 84;
optional bool mouse_ironsight_aim_assist = 85;
optional uint32 vehicle_input_mode = 86;
optional bool weapon_aim_toggle = 87;
optional bool mantle_requires_button = 88;
optional bool fixed_minimap_rotation = 89;
optional bool map_invert_pitch = 90;
optional bool map_invert_yaw = 91;
optional uint32 difficulty = 92;
optional bool swap_dual_wield_controls = 93;
optional float base_fov = 94;
optional uint32 crosshair_neutral_color_frame = 95;
optional uint32 crosshair_enemy_color_frame = 96;
optional uint32 crosshair_ally_color_frame = 97;
optional bool enable_subtitles = 98;
optional bool enable_closed_captions = 99;
optional string last_status_menu_page = 100;
repeated OakProfileLastInventoryFilterInfo inventory_screen_last_filter = 101;
optional OakProfileMenuTutorialInfo tutorial_info = 102;
optional uint32 default_network_type = 103;
optional uint32 default_invite_type = 104;
optional string matchmaking_region = 105;
optional uint32 streaming_service = 106;
optional int32 max_cached_friend_events = 107;
optional int32 max_cached_friend_statuses = 108;
repeated string friend_events = 109;
repeated string friend_statuses = 110;
optional int64 last_whisper_fetch_events_time = 111;
optional int64 last_whisper_fetch_statuses_time = 112;
optional uint32 desired_crossplay_state = 113;
repeated FriendEncountersEntry friend_encounters = 133;
optional int32 max_friend_encounter_size = 134;
repeated GameStatSaveGameData profile_stats_data = 135;
repeated InventoryCategorySaveData bank_inventory_category_list = 136;
repeated bytes bank_inventory_list = 137;
repeated bytes lost_loot_inventory_list = 138;
repeated OakMailItem npc_mail_items = 139;
repeated string mail_guids = 140;
repeated string unread_mail_guids = 141;
repeated GearSoldByFriendData gear_sold_by_friends = 142;
repeated OakSDUSaveGameData profile_sdu_list = 143;
repeated OakCustomizationSaveGameData unlocked_customizations = 144;
repeated OakInventoryCustomizationPartInfo unlocked_inventory_customization_parts = 145;
optional GuardianRankProfileData guardian_rank = 146;
repeated CrewQuartersDecorationItemSaveGameData unlocked_crew_quarters_decorations = 147;
repeated CrewQuartersRoomItemSaveGameData unlocked_crew_quarters_rooms = 148;
optional bool enable_mouse_acceleration = 150;
optional bool enable_gamepad_input = 151;
optional bool use_classic_gamepad_input = 152;
optional float master_volume = 153;
optional uint32 monitor_display_type = 154;
optional uint32 graphics_mode = 155;
optional uint32 frame_rate_limit = 156;
optional float base_vehicle_fov = 157;
optional uint32 graphics_quality = 158;
optional uint32 anisotropic_filtering = 159;
optional uint32 shadow_quality = 160;
optional uint32 display_performance_stats = 161;
optional uint32 texture_detail = 162;
optional uint32 draw_distance = 163;
optional uint32 clutter = 164;
optional uint32 tessellation = 165;
optional uint32 foliage = 166;
optional bool foliage_shadows = 167;
optional bool planar_reflections = 168;
optional uint32 volumetric_fog = 169;
optional uint32 screen_space_reflections = 170;
optional uint32 character_texture_detail = 171;
optional uint32 character_detail = 172;
optional uint32 ambient_occlusion_quality = 173;
optional bool object_motion_blur = 174;
optional bool lens_flare = 175;
optional bool combat_number_long_format = 176;
optional bool show_minimap_legendaries = 177;
optional bool use_player_callouts = 178;
optional uint32 friend_event_notification_lifetime = 179;
optional uint32 friend_event_notification_frequency = 180;
optional uint32 trade_request_reception_type = 181;
optional float head_bob_scale = 182;
optional bool has_seen_first_boot = 184;
optional float subs_cc_size = 189;
optional float cc_subs_background_opacity = 190;
optional uint32 walking_button_scheme = 191;
optional uint32 driving_button_scheme = 192;
optional uint32 glyph_mode = 193;
optional bool use_MPH = 194;
repeated RegisteredDownloadableEntitlements registered_downloadable_entitlements = 195;
repeated string seen_news_items = 196;
optional bool auto_centering_enabled = 197;
optional bool increased_chance_for_subscribers = 198;
optional bool rare_chest_event_enabled = 199;
optional bool badass_event_enabled = 200;
optional bool pinata_event_enabled = 201;
optional int32 min_time_between_badass_events = 202;
optional float hud_scale_multiplier = 203;
optional bool disable_spatial_audio = 204;
optional int32 total_playtime_seconds = 205;
optional bool moxxis_drink_event_enabled = 206;
optional int32 moxxis_drink_event_bits_product_id = 207;
repeated ChallengeSaveGameData challenge_data = 208;
repeated int32 CitizenScienceLevelProgression = 209;
optional bool disable_event_content = 211;
optional uint32 desired_friend_sync_state = 212;
optional bool needs_shift_first_boot = 213;
repeated RecentlyMetPlayer recently_met_players = 214;
optional int32 CitizenScienceActiveBoosterIndex = 215;
optional float CitizenScienceActiveBoosterRemainingTime = 216;
optional float CitizenScienceActiveBoosterTotalTime = 217;
optional int32 StreamerPrimaryActiveBoosterIndex = 218;
optional float StreamerPrimaryActiveBoosterRemainingTime = 219;
optional float StreamerPrimaryActiveBoosterTotalTime = 220;
optional int32 StreamerSecondaryActiveBoosterIndex = 221;
optional float StreamerSecondaryActiveBoosterRemainingTime = 222;
optional float StreamerSecondaryActiveBoosterTotalTime = 223;
optional int32 StreamerBoosterTier = 224;
optional int32 CitizenScienceCSBucksAmount = 226;
optional bool bCitizenScienceHasSeenIntroVideo = 227;
optional bool bCitizenScienceTutorialDone = 228;
}

302
protobuf/OakSave.proto Normal file
View File

@ -0,0 +1,302 @@
syntax = "proto2";
package OakSave;
import "OakShared.proto";
message PlayerClassSaveGameData {
optional string player_class_path = 1;
optional uint32 dlc_package_id = 2;
}
message ResourcePoolSavegameData {
optional float amount = 1;
optional string resource_path = 2;
}
message RegionSaveGameData {
optional int32 game_stage = 1;
optional int32 play_through_idx = 2;
optional string region_path = 3;
optional uint32 dlc_package_id = 4;
}
message InventoryBalanceStateInitializationData {
optional int32 game_stage = 1;
optional string inventory_data = 2;
optional string inventory_balance_data = 3;
optional string manufacturer_data = 4;
repeated string part_list = 5;
repeated string generic_part_list = 6;
optional bytes additional_data = 7;
repeated string customization_part_list = 8;
}
message OakInventoryItemSaveGameData {
optional bytes item_serial_number = 1;
optional int32 pickup_order_index = 2;
optional int32 flags = 3;
optional string weapon_skin_path = 4;
optional InventoryBalanceStateInitializationData development_save_data = 5;
}
message EquippedInventorySaveGameData {
optional int32 inventory_list_index = 1;
optional bool enabled = 2;
optional string slot_data_path = 3;
optional string trinket_data_path = 4;
}
message OakAbilityTreeItemSaveGameData {
optional string item_asset_path = 1;
optional int32 points = 2;
optional int32 max_points = 3;
optional int32 tree_identifier = 4;
}
message OakAbilitySlotSaveGameData {
optional string ability_class_path = 1;
optional string slot_asset_path = 2;
}
message OakActionAbilityAugmentSaveGameData {
optional string action_ability_class_path = 1;
optional string slot_asset_path = 2;
optional string augment_asset_path = 3;
}
message OakActionAbilityAugmentConfigurationSaveGameData {
optional string ability_class_path = 1;
optional string augment_asset_path = 2;
optional string mod_slot_asset_path = 3;
optional string mod_asset_path = 4;
}
message OakPlayerAbilitySaveGameData {
optional int32 ability_points = 1;
repeated OakAbilityTreeItemSaveGameData tree_item_list = 2;
repeated OakAbilitySlotSaveGameData ability_slot_list = 3;
repeated OakActionAbilityAugmentSaveGameData augment_slot_list = 4;
repeated OakActionAbilityAugmentConfigurationSaveGameData augment_configuration_list = 5;
optional int32 tree_grade = 6;
}
message MissionStatusPlayerSaveGameData {
enum MissionState {
MS_NotStarted = 0;
MS_Active = 1;
MS_Complete = 2;
MS_Failed = 3;
MS_Unknown = 4;
}
optional MissionState status = 1;
optional bool has_been_viewed_in_log = 2;
repeated int32 objectives_progress = 3;
optional string mission_class_path = 4;
optional string active_objective_set_path = 5;
optional uint32 dlc_package_id = 6;
optional bool kickoff_played = 7;
optional uint32 league_instance = 8;
}
message MissionPlaythroughSaveGameData {
repeated MissionStatusPlayerSaveGameData mission_list = 1;
optional string tracked_mission_class_path = 2;
}
message ActiveFastTravelSaveData {
optional string active_travel_station_name = 1;
optional bool blacklisted = 2;
}
message PlaythroughActiveFastTravelSaveData {
repeated ActiveFastTravelSaveData active_travel_stations = 1;
}
message DiscoveredAreaInfo {
optional string discovered_area_name = 1;
optional uint32 discovered_playthroughs = 2;
}
message DiscoveredLevelInfo {
optional string discovered_level_name = 1;
optional uint32 discovered_playthroughs = 3;
repeated DiscoveredAreaInfo discovered_area_info = 4;
}
message DiscoveredPlanetInfo {
optional string discovered_planet = 1;
optional bool is_new_planet = 2;
}
message DiscoverySaveData {
repeated DiscoveredLevelInfo discovered_level_info = 1;
}
message VehicleUnlockedSaveGameData {
optional string asset_path = 1;
optional bool just_unlocked = 2;
}
message OakCARMenuVehicleConfigSaveData {
optional string loadout_save_name = 1;
optional string body_asset_path = 2;
optional string wheel_asset_path = 3;
optional string armor_asset_path = 4;
optional string core_mod_asset_path = 5;
optional string gunner_weapon_asset_path = 6;
optional string driver_weapon_asset_path = 7;
optional string ornament_asset_path = 8;
optional string material_decal_asset_path = 9;
optional string material_asset_path = 10;
optional int32 color_index_1 = 11;
optional int32 color_index_2 = 12;
optional int32 color_index_3 = 13;
}
message CustomPlayerColorSaveGameData {
optional string color_parameter = 1;
optional Vec3 applied_color = 2;
optional Vec3 split_color = 3;
optional bool use_default_color = 4;
optional bool use_default_split_color = 5;
}
message GuardianRankSaveGameData {
optional int32 guardian_rank = 1;
optional int32 guardian_experience = 2;
}
message GuardianRankRewardCharacterSaveGameData {
optional int32 num_tokens = 1;
optional bool is_enabled = 2;
optional string reward_data_path = 3;
}
message GuardianRankPerkCharacterSaveGameData {
optional bool is_enabled = 1;
optional string perk_data_path = 2;
}
message GuardianRankCharacterSaveGameData {
optional int32 guardian_available_tokens = 1;
optional int32 guardian_rank = 2;
optional int32 guardian_experience = 3;
repeated GuardianRankRewardCharacterSaveGameData rank_rewards = 4;
repeated GuardianRankPerkCharacterSaveGameData rank_perks = 5;
optional int32 guardian_reward_random_seed = 6;
optional int64 new_guardian_experience = 7;
optional bool is_rank_system_enabled = 8;
}
message CrewQuartersDecorationSaveData {
optional int32 decoration_index = 1;
optional string decoration_data_path = 2;
}
message CrewQuartersSaveData {
optional int32 preferred_room_assignment = 1;
repeated CrewQuartersDecorationSaveData decorations = 2;
optional string room_data_path = 3;
}
message CrewQuartersGunRackItemSaveData {
optional bytes encrypted_serial_number = 1;
optional string slot_asset_path = 2;
optional InventoryBalanceStateInitializationData development_save_data = 3;
}
message CrewQuartersGunRackSaveData {
repeated CrewQuartersGunRackItemSaveData rack_save_data = 1;
}
message EchoLogSaveGameData {
optional bool has_been_seen_in_log = 1;
optional string echo_log_path = 2;
}
message MapIDData {
optional uint32 zone_name_id = 1;
optional uint32 map_name_id = 2;
}
message GameStateSaveData {
optional MapIDData last_traveled_map_id = 1;
optional int32 mayhem_level = 2;
}
message ChallengeCategoryProgressSaveData {
optional bytes category_progress = 1;
}
message OakPlayerCharacterAugmentSaveGameData {
optional string slot_asset_path = 1;
optional string augment_asset_path = 2;
}
message OakPlayerCharacterSlotSaveGameData {
repeated OakPlayerCharacterAugmentSaveGameData augment_slot_list = 1;
}
message UITrackingSaveGameData {
optional bool has_seen_skill_menu_unlock = 1;
optional bool has_seen_guardian_rank_menu_unlock = 2;
optional bool has_seen_echo_boot_ammo_bar = 3;
optional bool has_seen_echo_boot_shield_bar = 4;
optional bool has_seen_echo_boot_grenades = 5;
optional int32 highest_thvm_breadcrumb_seen = 6;
repeated string inventory_slot_unlocks_seen = 7;
optional int32 saved_spin_offset = 8;
}
message PlanetCycleInfo {
optional string planet_name = 1;
optional float cycle_length = 2;
optional float last_cached_time = 3;
}
message TimeOfDaySaveGameData {
repeated PlanetCycleInfo planet_cycle_info = 1;
optional string planet_cycle = 2;
}
message LevelPersistence_Actor_SaveGameData {
optional string actor_name = 1;
optional int32 timer_remaining = 2;
}
message LevelPersistence_Level_SaveGameData {
optional string level_name = 1;
repeated LevelPersistence_Actor_SaveGameData saved_actors = 2;
}
message GbxZoneMapFODSavedLevelData {
optional string level_name = 1;
optional uint32 fod_texture_size = 2;
optional uint32 num_chunks = 3;
optional float discovery_percentage = 4;
optional uint32 data_state = 5;
optional uint32 data_revision = 6;
optional bytes fod_data = 7;
}
message GbxZoneMapFODSaveGameData {
repeated GbxZoneMapFODSavedLevelData level_data = 1;
}
message Character {
message NicknameMappingsEntry {
optional string key = 1;
optional string value = 2;
}
optional uint32 save_game_id = 1;
optional int64 last_save_timestamp = 2;
optional uint32 time_played_seconds = 3;
optional PlayerClassSaveGameData player_class_data = 4;
repeated ResourcePoolSavegameData resource_pools = 5;
repeated RegionSaveGameData saved_regions = 6;
optional int32 experience_points = 7;
repeated GameStatSaveGameData game_stats_data = 8;
repeated InventoryCategorySaveData inventory_category_list = 9;
repeated OakInventoryItemSaveGameData inventory_items = 10;
repeated EquippedInventorySaveGameData equipped_inventory_list = 11;
repeated int32 active_weapon_list = 12;
optional OakPlayerAbilitySaveGameData ability_data = 13;
optional int32 last_play_through_index = 14;
optional int32 playthroughs_completed = 15;
optional bool show_new_playthrough_notification = 16;
repeated MissionPlaythroughSaveGameData mission_playthroughs_data = 17;
repeated string active_travel_stations = 21;
optional DiscoverySaveData discovery_data = 22;
optional string last_active_travel_station = 23;
repeated VehicleUnlockedSaveGameData vehicles_unlocked_data = 24;
repeated string vehicle_parts_unlocked = 25;
repeated OakCARMenuVehicleConfigSaveData vehicle_loadouts = 26;
optional int32 vehicle_last_loadout_index = 27;
repeated ChallengeSaveGameData challenge_data = 28;
repeated OakSDUSaveGameData sdu_list = 29;
repeated string selected_customizations = 30;
repeated int32 equipped_emote_customizations = 31;
repeated CustomPlayerColorSaveGameData selected_color_customizations = 32;
optional GuardianRankSaveGameData guardian_rank = 33;
optional CrewQuartersSaveData crew_quarters_room = 34;
optional CrewQuartersGunRackSaveData crew_quarters_gun_rack = 35;
repeated EchoLogSaveGameData unlocked_echo_logs = 36;
optional bool has_played_special_echo_log_insert_already = 37;
repeated NicknameMappingsEntry nickname_mappings = 38;
optional MapIDData last_traveled_map_id = 39;
optional ChallengeCategoryProgressSaveData challenge_category_completion_pcts = 40;
optional OakPlayerCharacterSlotSaveGameData character_slot_save_game_data = 41;
optional UITrackingSaveGameData ui_tracking_save_game_data = 42;
optional string preferred_character_name = 43;
optional int32 name_character_limit = 44;
optional uint32 preferred_group_mode = 45;
optional TimeOfDaySaveGameData time_of_day_save_game_data = 46;
repeated LevelPersistence_Level_SaveGameData level_persistence_data = 47;
optional uint32 accumulated_level_persistence_reset_timer_seconds = 48;
optional uint32 mayhem_level = 49;
optional GbxZoneMapFODSaveGameData gbx_zone_map_fod_save_game_data = 50;
repeated ActiveFastTravelSaveData active_or_blacklisted_travel_stations = 51;
repeated string last_active_travel_station_for_playthrough = 52;
repeated GameStateSaveData game_state_save_data_for_playthrough = 53;
repeated RegisteredDownloadableEntitlements registered_downloadable_entitlements = 54;
repeated PlaythroughActiveFastTravelSaveData active_travel_stations_for_playthrough = 55;
optional string save_game_guid = 56;
optional GuardianRankCharacterSaveGameData guardian_rank_character_data = 57;
optional bool optional_objective_reward_fixup_applied = 58;
optional bool vehicle_part_rewards_fixup_applied = 59;
}

47
protobuf/OakShared.proto Normal file
View File

@ -0,0 +1,47 @@
syntax = "proto2";
package OakSave;
message Vec3 {
optional float x = 1;
optional float y = 2;
optional float z = 3;
}
message GameStatSaveGameData {
optional int32 stat_value = 1;
optional string stat_path = 2;
}
message InventoryCategorySaveData {
optional uint32 base_category_definition_hash = 1;
optional int32 quantity = 2;
}
message OakSDUSaveGameData {
optional int32 sdu_level = 1;
optional string sdu_data_path = 2;
}
message RegisteredDownloadableEntitlement {
optional int32 id = 1;
optional uint32 consumed = 2;
optional bool registered = 3;
optional bool seen = 4;
}
message RegisteredDownloadableEntitlements {
optional string entitlement_source_asset_path = 1;
repeated int64 entitlement_ids = 2;
repeated RegisteredDownloadableEntitlement entitlements = 3;
}
message ChallengeStatSaveGameData {
optional int32 current_stat_value = 1;
optional string challenge_stat_path = 2;
}
message OakChallengeRewardSaveGameData {
optional bool challenge_reward_claimed = 1;
}
message ChallengeSaveGameData {
optional int32 completed_count = 1;
optional bool is_active = 2;
optional bool currently_completed = 3;
optional int32 completed_progress_level = 4;
optional int32 progress_counter = 5;
repeated ChallengeStatSaveGameData stat_instance_state = 6;
optional string challenge_class_path = 7;
repeated OakChallengeRewardSaveGameData challenge_reward_info = 8;
}

150
py/bdeh.py Normal file
View File

@ -0,0 +1,150 @@
import os
import sys
import OakSave_pb2
dk1 = bytearray([0x71, 0x34, 0x36, 0xB3, 0x56, 0x63, 0x25, 0x5F, 0xEA, 0xE2, 0x83, 0x73, 0xF4, 0x98, 0xB8, 0x18, 0x2E, 0xE5, 0x42, 0x2E, 0x50, 0xA2, 0x0F, 0x49, 0x87, 0x24, 0xE6, 0x65, 0x9A, 0xF0, 0x7C, 0xD7])
dk2 = bytearray([0x7C, 0x07, 0x69, 0x83, 0x31, 0x7E, 0x0C, 0x82, 0x5F, 0x2E, 0x36, 0x7F, 0x76, 0xB4, 0xA2, 0x71, 0x38, 0x2B, 0x6E, 0x87, 0x39, 0x05, 0x02, 0xC6, 0xCD, 0xD8, 0xB1, 0xCC, 0xA1, 0x33, 0xF9, 0xB6])
def write_u32_le(sc : bytearray, offset : int, val: int):
sc[offset] = val & 0xFF
sc[offset + 1] = (val >> 8) & 0xFF
sc[offset + 2] = (val >> 16) & 0xFF
sc[offset + 3] = (val >> 24) & 0xFF
def read_u32_le(sc : bytearray, offset : int):
ret = sc[offset]
ret |= sc[offset + 1] << 8
ret |= sc[offset + 2] << 16
ret |= sc[offset + 3] << 24
return ret
def find_save_core_offset(sc : bytearray):
#core offset is always "OakSaveGame\0" + 4 bytes (<- this is the payload size)
sc_str = "OakSaveGame"
ret = -1
for offset in range(0, len(sc) - len(sc_str)):
match = True
for i in range(0, len(sc_str)):
if sc[offset + i] != ord(sc_str[i]):
match = False
break
if match:
ret = offset
break
if ret == -1:
print("Cannot locate core offset")
exit(-1)
# skip the OakSaveGame string
ret = ret + len(sc_str) + 1
core_sz = read_u32_le(sc, ret)
return ret, core_sz
def usage():
print("Usage: python bdeh.py <save file>")
def decrypt(src : bytearray):
offset = len(src) - 1
while offset >= 0:
k1 = 0
if offset >= 0x20:
k1 = src[offset - 0x20]
else:
k1 = dk1[offset]
k2 = offset
k2 = k2 % 0x20
k2 = dk2[k2]
k2 = k2 ^ k1
src[offset] = int(src[offset]) ^ k2
offset = offset - 1
return src
def encrypt(src : bytearray):
offset = 0
while offset < len(src):
if offset >= 0x20:
k1 = src[offset - 0x20]
else:
k1 = dk1[offset]
k2 = offset
k2 = k2 % 0x20
k2 = dk2[k2]
k2 = k2 ^ k1
src[offset] = int(src[offset]) ^ k2
offset = offset + 1
return src
def editor(save_obj):
return
def main():
if len(sys.argv) != 2:
usage()
exit()
print("Reading " + sys.argv[1])
with open(sys.argv[1], "rb") as f:
savfile = f.read()
core_offset, core_sz = find_save_core_offset(savfile)
if core_offset + core_sz + 4 != len(savfile):
print("Incorrect file size!")
exit(1)
print("Save file loaded - size: " + hex(len(savfile)) + " core offset: " + hex(core_offset) + " core size: " + hex(core_sz))
# copy the payload
payload = bytearray(core_sz)
for i in range(0, core_sz):
payload[i] = savfile[core_offset + 4 + i]
# copy the header
header = bytearray(core_offset)
for i in range(0, core_offset):
header[i] = savfile[i]
# garbage collect the savfile buffer
savfile = None
# decrypt the payload
payload = decrypt(payload)
# deserialize the payload
save_obj = OakSave_pb2.Character()
save_obj.ParseFromString(payload)
# editor loop
editor(save_obj)
# serialize the payload
payload_ro = save_obj.SerializeToString()
payload = bytearray(len(payload_ro))
for i in range(0, len(payload_ro)):
payload[i] = payload_ro[i]
# encrypt the payload
payload = encrypt(payload)
# build the full save
full_save = bytearray(core_offset + 4 + len(payload))
for i in range(0, core_offset):
full_save[i] = header[i]
write_u32_le(full_save, core_offset, len(payload))
for i in range(0, len(payload)):
full_save[core_offset + 4 + i] = payload[i]
# Write
with open(sys.argv[1] + ".bdeh", "wb") as f:
f.write(full_save)
main()