diff --git a/protobuf/Makefile b/protobuf/Makefile index 096fa546..17348c85 100644 --- a/protobuf/Makefile +++ b/protobuf/Makefile @@ -14,6 +14,7 @@ all: protoc --python_out=. variants.proto protoc --python_out=. playback.proto protoc --python_out=. route-result.proto + protoc --python_out=. user_storage.proto clean: rm -f *_pb2.py *_pb2.pyc diff --git a/protobuf/make.bat b/protobuf/make.bat index 0111465a..bc911001 100644 --- a/protobuf/make.bat +++ b/protobuf/make.bat @@ -14,5 +14,6 @@ protoc --python_out=. events.proto protoc --python_out=. variants.proto protoc --python_out=. playback.proto protoc --python_out=. route-result.proto +protoc --python_out=. user_storage.proto pause \ No newline at end of file diff --git a/protobuf/user_storage.proto b/protobuf/user_storage.proto new file mode 100644 index 00000000..6675c57f --- /dev/null +++ b/protobuf/user_storage.proto @@ -0,0 +1,18 @@ +syntax = "proto2"; + +message UserStorage { + optional GameSettings game_settings = 2; +} + +message GameSettings { + optional Attributes f22 = 22; +} + +message Attributes { + optional float f2 = 2; + optional int32 f3 = 3; + optional int32 f4 = 4; + optional int32 f5 = 5; + optional int32 f6 = 6; + optional int32 f7 = 7; +} diff --git a/protobuf/user_storage_pb2.py b/protobuf/user_storage_pb2.py new file mode 100644 index 00000000..22e6d5b4 --- /dev/null +++ b/protobuf/user_storage_pb2.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: user_storage.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12user_storage.proto\"3\n\x0bUserStorage\x12$\n\rgame_settings\x18\x02 \x01(\x0b\x32\r.GameSettings\"(\n\x0cGameSettings\x12\x18\n\x03\x66\x32\x32\x18\x16 \x01(\x0b\x32\x0b.Attributes\"T\n\nAttributes\x12\n\n\x02\x66\x32\x18\x02 \x01(\x02\x12\n\n\x02\x66\x33\x18\x03 \x01(\x05\x12\n\n\x02\x66\x34\x18\x04 \x01(\x05\x12\n\n\x02\x66\x35\x18\x05 \x01(\x05\x12\n\n\x02\x66\x36\x18\x06 \x01(\x05\x12\n\n\x02\x66\x37\x18\x07 \x01(\x05') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'user_storage_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _USERSTORAGE._serialized_start=22 + _USERSTORAGE._serialized_end=73 + _GAMESETTINGS._serialized_start=75 + _GAMESETTINGS._serialized_end=115 + _ATTRIBUTES._serialized_start=117 + _ATTRIBUTES._serialized_end=201 +# @@protoc_insertion_point(module_scope) diff --git a/zwift_offline.py b/zwift_offline.py index 9a12d5dd..16faad05 100644 --- a/zwift_offline.py +++ b/zwift_offline.py @@ -56,6 +56,7 @@ import events_pb2 import variants_pb2 import playback_pb2 +import user_storage_pb2 import online_sync logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO")) @@ -1313,7 +1314,6 @@ def api_clubs_club_my_clubs_summary(): @app.route('/api/game-asset-patching-service/manifest', methods=['GET']) @app.route('/api/race-results', methods=['POST']) @app.route('/api/workout/progress', methods=['POST']) -@app.route('/api/player-profile/user-game-storage/attributes', methods=['GET', 'POST']) # will load from prefs.xml def api_proto_empty(): return '', 200 @@ -3656,6 +3656,31 @@ def api_power_curve_best(option): return power_curves.SerializeToString(), 200 +@app.route('/api/player-profile/user-game-storage/attributes', methods=['GET', 'POST']) +@jwt_to_session_cookie +@login_required +def api_player_profile_user_game_storage_attributes(): + user_storage = user_storage_pb2.UserStorage() + user_storage_file = os.path.join(STORAGE_DIR, str(current_user.player_id), 'user_storage.bin') + if os.path.isfile(user_storage_file): + with open(user_storage_file, 'rb') as f: + user_storage.ParseFromString(f.read()) + if request.method == 'POST': + new = user_storage_pb2.UserStorage() + new.ParseFromString(request.stream.read()) + user_storage.MergeFrom(new) + with open(user_storage_file, 'wb') as f: + f.write(user_storage.SerializeToString()) + return '', 202 + ret = user_storage_pb2.UserStorage() + n = int(request.args.get('n')) + if n in user_storage.game_settings.DESCRIPTOR.fields_by_number: + field = user_storage.game_settings.DESCRIPTOR.fields_by_number[n].name + if user_storage.game_settings.HasField(field): + getattr(ret.game_settings, field).CopyFrom(getattr(user_storage.game_settings, field)) + return ret.SerializeToString(), 200 + + @app.teardown_request def teardown_request(exception): db.session.close()