Add support for Android devices (proper commit...)

This commit is contained in:
zoffline
2018-10-26 21:22:41 -04:00
parent 121bb976ec
commit 2eb0c38164
2 changed files with 62 additions and 18 deletions
+25
View File
@@ -100,6 +100,31 @@ to generate your own certificates and do the same.
</details>
<details><summary>Android (requires a rooted device)</summary>
* Install Zwift on the device
* Append the contents of ``ssl/cert-zwift-com.pem`` to ``/data/data/com.zwift.zwiftgame/dataES/cacerts.pem`` on the device
* Note: this file will only exist after the first run of Zwift since it's downloaded after the initial install
* Simple approach to achieve this if your device doesn't have a text editor:
* ``adb push ssl/cert-zwift-com.pem /data/data/com.zwift.zwiftgame/dataES/``
* In ``adb shell``: ``cd /data/data/com.zwift.zwiftgame/dataES/``
* In ``adb shell``: ``cat cert-zwift-com.pem >> cacerts.pem``
* However you do it, ensure the permissions and ownership of the file remains the same.
* Modify the device's /etc/hosts file
* Append this line: ``<zoffline ip> us-or-rly101.zwift.com secure.zwift.com cdn.zwift.com``
<br />(Where ``<zoffline ip>`` is the ip address of the machine running zoffline. If
it's running on the same machine as Zwift, use ``127.0.0.1`` as the ip.)
* If no text editor on the device, recommend:
* ``adb pull /etc/hosts``
* (modify on PC)
* ``adb push hosts /etc/hosts``
* Start Zwift and sign in using any email/password
Why: We need to redirect Zwift to use zoffline and convince Zwift to
accept zoffline's self signed certificates for Zwift's domain names. Feel free
to generate your own certificates and do the same.
</details>
#### Enabling/Disabling zoffline
+37 -18
View File
@@ -24,7 +24,8 @@ import protobuf.profile_pb2 as profile_pb2
import protobuf.segment_result_pb2 as segment_result_pb2
import protobuf.world_pb2 as world_pb2
app = Flask(__name__)
# Android uses https for cdn
app = Flask(__name__, static_folder='cdn/gameassets', static_url_path='/gameassets')
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
STORAGE_DIR = "%s/storage" % SCRIPT_DIR
@@ -337,29 +338,47 @@ def api_profiles_goals_id(player_id, goal_id):
return '', 200
def relay_worlds_generic(world_id=None):
# Android client also requests a JSON version
if request.headers['Accept'] == 'application/json':
world = { 'currentDateTime': int(time.time()),
'currentWorldTime': int(time.time())*1000,
'friendsInWorld': [],
'mapId': 1,
'name': 'Public Watopia',
'playerCount': 0,
'worldId': 1
}
if world_id:
world['mapId'] = world_id
return jsonify(world)
else:
return jsonify([ world ])
else: # protobuf request
worlds = world_pb2.Worlds()
world = worlds.worlds.add()
world.id = 1
world.name = 'Public Watopia'
world.f3 = 1
# Windows client crashes if playerCount is 0
world.f5 = 1 # playerCount
world.world_time = int(time.time())*1000
world.real_time = int(time.time())
if world_id:
world.id = world_id
return worlds.SerializeToString()
else:
return world.SerializeToString()
@app.route('/relay/worlds', methods=['GET'])
def relay_worlds():
worlds = world_pb2.Worlds()
world = worlds.worlds.add()
world.id = 1
world.name = 'Public Watopia'
world.f3 = 1
world.f5 = 1
world.world_time = int(time.time())*1000
world.real_time = int(time.time())
return worlds.SerializeToString(), 200
return relay_worlds_generic()
@app.route('/relay/worlds/<int:world_id>', methods=['GET'])
def relay_worlds_id(world_id):
# XXX: Will need to keep MapSchedule.xml up to date
return jsonify({ 'currentDateTime': int(time.time()),
'currentWorldTime': int(time.time())*1000,
'friendsInWorld': [ ],
'mapId': world_id,
'name': 'Public Watopia',
'playerCount': 0,
'worldId': 1 })
return relay_worlds_generic(world_id)
@app.route('/relay/worlds/<int:world_id>/join', methods=['POST'])