-
Notifications
You must be signed in to change notification settings - Fork 117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow watching replays while in queue #2945
Conversation
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## develop #2945 +/- ##
=============================================
+ Coverage 64.58% 64.72% +0.14%
- Complexity 4886 4894 +8
=============================================
Files 556 556
Lines 20193 20187 -6
Branches 1080 1077 -3
=============================================
+ Hits 13042 13067 +25
+ Misses 6532 6498 -34
- Partials 619 622 +3
... and 2 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
e09c28b
to
a99ff28
Compare
Seems to be working now. Still needs tests |
There are more places where you can have issues:
(1) and (3) can be a problem when you were watching a replay from a different featured mod. (2) can be a problem where one game is writing to it (because you're closing it, for example) while the next game is trying to read it (because you're starting it). Are these taken into account? |
No, can you elaborate how to take these into account? |
For (1) and (2) the solution would be to delay starting the ladder instance until we're sure that the replay instance has no remaining file handles lingering anywhere. We kill the process, wait a second or two and then launch the game to join ladder. I assume this already happens to some degree. (3) is more difficult, if I'm not mistaken then the files are updated as you join the queue. This includes the executable. Updating the executable would therefore always fail when it needs to be changed: either when you start the queue while in a replay or when you start the replay while in a queue. To overcome this you'd need to not just separate the game data files, but also separate the executable. This is not limited to watching replays of different featured mods, it can also happen between game versions (the few days after a release) |
I see there was a misunderstanding. The executable is copied over to a separate directory as well. So 3) shouldn't be an issue. Killing the replay before starting the match seems like a good idea. |
I thought with game files you were referring to just the files in the |
I think the pref file might still be a concern though. Would that be a problem if a replay is open when the game starts? |
Ideally people don't fiddle with their pref file when they watch a replay anyway, but I understand that this is not always the case. Shouldn't this be addressed by terminating the replay before starting the ladder match? |
I didn't think you wanted to terminate the replay |
I didn't originally think of that and it's not implemented yet, but it sounds like the best solution. We circumvent these file issues, it frees up system resources and prevents that people miss that the game is starting because they are in the replay |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still needs some changes so people can actually queue with one or more replays started.
Also I don't love the passing of the useReplaysFolder parameter but also not sure how to make it better at the moment.
src/main/java/com/faforever/client/fa/ForgedAllianceService.java
Outdated
Show resolved
Hide resolved
src/main/java/com/faforever/client/patch/GameBinariesUpdateTaskImpl.java
Outdated
Show resolved
Hide resolved
I realized that tracking when a replay is started separately from when an online game is started leads to complicated situations when we still want to make e.g. allowing to join a queue while a replay is running dependend on the preference from the settings. |
Yes I was wondering as well if we should just always have the split folders. Then they could be truly separated in the code. |
Sounds good. Why is the patch to the game prefs needed? Do we still need to do this then? |
Yes the patch to the game prefs is to allow multiple instances of the game to run at once. And with the situation where people are already in a game the first game instance has a lock on the files so no other instance should be able to touch them. And that is the instance with the actual game they will play so has priority. When starting a game with a replay started the replay would have the lock which might not have the settings the player wants for the game itself which is the issue. |
When we remove the game.prefs edit from the settings we have to check and edit automatically. Where would be a good place for this check? |
f248651
to
7497829
Compare
.thenCompose(gameLaunchResponse -> downloadMapIfNecessary(gameLaunchResponse.getMapName()).thenCompose(aVoid -> { | ||
// We need to kill the replay to free the lock on the game.prefs | ||
if (isReplayRunning()) { | ||
gameKilled = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be gameKilled should it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from my understanding gameKilled prevents the error message to pop up when the game - in this case the replay - terminates with non-zero exit code. This is what we want. Once the game starts gameKilled gets set to false again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But to me then this should be some other variable. As it is right now this just seems a little confusing since most of the other processes between game and replay are separated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you want to have this variable renamed to something like faKilled or a second one introduced?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A second one introduced would probably be better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a second variable, you can have a look but I am not really convinced that this is a good way to handle it. I think it would be more straightforward to have one variable that is used for games and replays (and named accordingly).
2e408b4
to
d77d9e5
Compare
if (exitCode != 0 && !(gameKilled || replayKilled)) { | ||
if (exitCode == -1073741515) { | ||
notificationService.addImmediateWarnNotification("game.crash.notInitialized"); | ||
} else { | ||
notificationService.addNotification(new ImmediateNotification(i18n.get("errorTitle"), i18n.get("game.crash", exitCode, logFile.map(Path::toString) | ||
.orElse("")), WARN, List.of(new Action(i18n.get("game.open.log"), event -> platformService.reveal(logFile.orElse(operatingSystem.getLoggingDirectory()))), new DismissAction(i18n)))); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main thing with breaking apart the gameKilled and replayKilled was so that replays would not interfere with this notification for games that crashed.
We store game files for replay watching separately if the related option is enabled. This prevents the problems that would occur when the game gets launched with the wrong game version once a match is found.
I also deleted the canUpdate method that always returned true.