From 623a8245257bcfb7939d15b96736f76f3515258f Mon Sep 17 00:00:00 2001 From: Michael Sondergaard Date: Wed, 26 Nov 2014 01:18:33 +0100 Subject: [PATCH] Send version info to server, use init files --- src/client/_clientwindow.py | 15 +++++++++----- src/config/production.py | 1 + src/fa/game_version.py | 3 +++ src/fa/play.py | 37 ++++++++++++++++++++++++----------- src/fa/process.py | 2 +- src/fa/updater.py | 1 + src/games/_gameswidget.py | 1 + tests/fa/conftest.py | 20 +++++++++++++++++++ tests/fa/test_play.py | 39 ++++++++++++++++++++++++++++++++----- 9 files changed, 97 insertions(+), 22 deletions(-) create mode 100644 tests/fa/conftest.py diff --git a/src/client/_clientwindow.py b/src/client/_clientwindow.py index 0da644f62..a57deeb52 100644 --- a/src/client/_clientwindow.py +++ b/src/client/_clientwindow.py @@ -49,6 +49,8 @@ import random import notificatation_system as ns +from fa.game_version import GameVersion + try: from profile import playerstats except: @@ -1775,17 +1777,20 @@ def process(self, action, stream): except: logger.error("Error dispatching JSON: " + action, exc_info=sys.exc_info()) - - + def serialize(self, obj): + if isinstance(obj, GameVersion): + return obj.to_dict() + else: + return GameVersion.serialize_kids(obj) # # JSON Protocol v2 Implementation below here # def send(self, message): - data = json.dumps(message) - if message["command"] == "hello" : + data = json.dumps(message, default=self.serialize) + if message["command"] == "hello": logger.info("Outgoing JSON Message: login.") - else : + else: logger.info("Outgoing JSON Message: " + data) self.writeToServer(data) diff --git a/src/config/production.py b/src/config/production.py index 0919ac336..79ac8e9de 100644 --- a/src/config/production.py +++ b/src/config/production.py @@ -24,6 +24,7 @@ "ENGINE_PATH": join(join(APPDATA_DIR, "repo"), "binary-patch"), "MODS_PATH": join(join(APPDATA_DIR, "repo"), "mods"), "MAPS_PATH": join(join(APPDATA_DIR, "repo"), "maps"), + "WRITE_GAME_LOG": False }, 'PROXY': { 'HOST': 'proxy.faforever.com', diff --git a/src/fa/game_version.py b/src/fa/game_version.py index ea989a51a..a87ac4ec9 100644 --- a/src/fa/game_version.py +++ b/src/fa/game_version.py @@ -155,6 +155,9 @@ def serialize_kids(obj): def to_json(self): return json.dumps(self._versions, default=self.serialize_kids) + def to_dict(self): + return self._versions + @staticmethod def from_default_version(result): return GameVersion.from_dict(result) diff --git a/src/fa/play.py b/src/fa/play.py index 11b46e154..4b79fd6d6 100644 --- a/src/fa/play.py +++ b/src/fa/play.py @@ -16,6 +16,9 @@ # GNU General Public License for more details. #------------------------------------------------------------------------------- from fa import mods +from fa.init_file import InitFile +from fa.path import getGameFolderFA +from fa.game_version import GameVersion from .process import instance @@ -29,11 +32,11 @@ from PyQt4 import QtCore -settings = QtCore.QSettings("ForgedAllianceForever", "FA Lobby") - from . import DEFAULT_WRITE_GAME_LOG from . import DEFAULT_RECORD_REPLAY +from config import Settings + def build_argument_list(game_info, port, arguments=None): """ @@ -46,19 +49,18 @@ def build_argument_list(game_info, port, arguments=None): raise ValueError("Custom init scripts no longer supported.") #log file - if settings.value("fa.write_game_log", DEFAULT_WRITE_GAME_LOG, type=bool): - arguments.append("/log") - arguments.append('"' + util.LOG_FILE_GAME + '"') + if Settings.get('WRITE_GAME_LOG', 'FA'): + arguments.append(("log", util.LOG_FILE_GAME)) #live replay - arguments.append('/savereplay') - arguments.append('"gpgnet://localhost/' + str(game_info['uid']) + "/" + str(game_info['recorder']) + '.SCFAreplay"') + arguments.append(('savereplay', + '"gpgnet://localhost/' + str(game_info['uid']) + "/" + str(game_info['recorder']) + '.SCFAreplay"')) #disable bug reporter - arguments.append('/nobugreport') + arguments.append(('nobugreport', None)) #gpg server emulation - arguments.append('/gpgnet 127.0.0.1:' + str(port)) + arguments.append(('gpgnet', '127.0.0.1:' + str(port))) return arguments @@ -67,6 +69,19 @@ def run(game_info, port, arguments=None): """ Launches Forged Alliance with the given arguments """ - logger.info("Play received arguments: %s" % arguments) arguments = build_argument_list(game_info, port, arguments) - return instance.run(game_info, arguments) + init_file = InitFile() + logger.info("Launching with game_info %r" % game_info) + game_version = game_info['version'] + + init_file.mount(os.path.join(getGameFolderFA(), 'gamedata'), '/') + init_file.mount(game_version.main_mod.path, '/') + + init_path = os.path.join(Settings.get('BIN', 'FA'), 'init_%s.lua' % game_version.main_mod.name) + f = file(init_path, 'w') + f.write(init_file.to_lua()) + f.close() + + arguments.append(('init', init_path)) + + return instance.run(game_version, arguments, False, init_file) diff --git a/src/fa/process.py b/src/fa/process.py index b21858ce9..427dcca63 100644 --- a/src/fa/process.py +++ b/src/fa/process.py @@ -54,7 +54,7 @@ def run(self, info, arguments, detach=False, init_file=None): """ #prepare actual command for launching executable = os.path.join(config.Settings.get('bin_dir', 'fa'), "ForgedAllianceForever.exe") - command = '"' + executable + '" ' + " ".join(arguments) + command = '"' + executable + '" ' + " ".join(map(lambda (k, v): '/%s %s' % (k, v), arguments)) logger.info("Running FA with info: " + str(info)) logger.info("Running FA via command: " + command) diff --git a/src/fa/updater.py b/src/fa/updater.py index 23bbf0b68..0973c93c9 100644 --- a/src/fa/updater.py +++ b/src/fa/updater.py @@ -29,6 +29,7 @@ @author thygrrr """ import os + import time import shutil from types import FloatType, IntType, ListType diff --git a/src/games/_gameswidget.py b/src/games/_gameswidget.py index d5eec019a..75f8d2875 100644 --- a/src/games/_gameswidget.py +++ b/src/games/_gameswidget.py @@ -669,6 +669,7 @@ def launch_game(): self.client.send(dict(command="game_host", access="password" if self.ispassworded else "public", password=self.gamepassword, + version=version, mod=item.mod, title=self.gamename, mapname=self.gamemap, diff --git a/tests/fa/conftest.py b/tests/fa/conftest.py new file mode 100644 index 000000000..34f801c08 --- /dev/null +++ b/tests/fa/conftest.py @@ -0,0 +1,20 @@ +__author__ = 'Sheeo' + +import os +import pytest + +from fa.game_version import GameVersion +from fa.mod import Mod +from git import Version + +from config import Settings + + +FAF_PATH = os.path.join(Settings.get('MODS_PATH', 'FA'), 'faf') + +@pytest.fixture(scope='function') +def game_version(): + return GameVersion(Version('binary-patch', 'master', None, 'a41659780460fd8829fce87b479beaa8ac78e474'), + Mod('faf', FAF_PATH, Version('faf', '3634', None, 'ed052486a19f7adc1adb3f65451af1a7081d2339')), + [], + '') diff --git a/tests/fa/test_play.py b/tests/fa/test_play.py index b4657f410..410ce8ccb 100644 --- a/tests/fa/test_play.py +++ b/tests/fa/test_play.py @@ -1,21 +1,50 @@ +from fa.init_file import InitFile + __author__ = 'Sheeo' from flexmock import flexmock process_mock = flexmock() +settings_mock = flexmock() import fa import fa.play fa.play.instance = process_mock +fa.play.Settings = settings_mock + + +def test_launches_process_with_given_arguments(game_version, tmpdir): + game_info = { + 'uid': 0, + 'recorder': 'Sheeo', + 'version': game_version + } + expected_args = [('some-arg', 'test')] + + def validate_args(game_info, args, detach, init_file): + for k, v in expected_args: + assert k in dict(args).keys() + assert dict(args)[k] == v + return True + + settings_mock.should_receive('get').with_args('WRITE_GAME_LOG', 'FA').and_return(False) + settings_mock.should_receive('get').with_args('BIN', 'FA').and_return(str(tmpdir)) + process_mock.should_receive('run').replace_with(validate_args) + assert fa.run(game_info, 0, expected_args) -def test_launches_process_with_given_arguments(): +def test_constructs_and_uses_init_file_from_game_version(game_version, tmpdir): game_info = { 'uid': 0, - 'recorder': 'Sheeo' + 'recorder': 'Sheeo', + 'version': game_version } - args = ['/some-arg', 'test'] - process_mock.should_receive('run').with_args(game_info, args).and_return(True).once() - assert fa.run(game_info, 0, args) + settings_mock.should_receive('get').with_args('WRITE_GAME_LOG', 'FA').and_return(False) + settings_mock.should_receive('get').with_args('BIN', 'FA').and_return(str(tmpdir)) + def validate_args(game_info, args, detach, init_file): + assert dict(args)['init'] == str(tmpdir.join('init_%s.lua' % game_version.main_mod.name)) + return True + process_mock.should_receive('run').replace_with(validate_args).once() + assert fa.run(game_info, 0)