mirror of
https://github.com/quackerd/bdeh.git
synced 2024-11-22 03:06:45 +00:00
Initial commit.
Co-authored-by: Haoyu Gu <guhaoyu2005@gmail.com>
This commit is contained in:
parent
37459062f0
commit
18aa9191d1
289
protobuf/OakProfile.proto
Normal file
289
protobuf/OakProfile.proto
Normal 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
302
protobuf/OakSave.proto
Normal 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
47
protobuf/OakShared.proto
Normal 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
150
py/bdeh.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user