Skip to content

Clear sm_nextmap so we don't get stuck in a loop#1545

Merged
peace-maker merged 2 commits intomasterfrom
bug-1429
Jul 3, 2023
Merged

Clear sm_nextmap so we don't get stuck in a loop#1545
peace-maker merged 2 commits intomasterfrom
bug-1429

Conversation

@asherkin
Copy link
Member

This seems to work well, but it requires a change to the nextmap plugin as well as the implementation in core - which will be a pain for users as they almost never update the base plugins on upgrade. If the old plugin is used against a newer core version the sm_nextmap cvar will never get re-populated after map change, so SM will stop controlling the map cycle.

Fixes #1429

@asherkin asherkin marked this pull request as draft July 19, 2021 17:34
@asherkin asherkin force-pushed the bug-1429 branch 3 times, most recently from c055213 to a501ccb Compare July 19, 2021 21:00
@asherkin
Copy link
Member Author

Got two potential solutions for the bug here (in each commit), one on the C++ side that is more generic but a slightly hairy implementation (I think only TF2 can take this path though, other games don't recover from bad map changes), or one purely in the nextmap plugin that listens to the event added for TF2 specifically. The plugin code has a nice advantage of preserving the SM-enforced map cycle, whereas the C++ impl just gives up for a map. I'm really not sure which I prefer.

@asherkin asherkin marked this pull request as ready for review July 19, 2021 21:31
@nosoop
Copy link
Contributor

nosoop commented Jul 20, 2021

I think having a hybrid of both would be best — the changes on the C++ side are necessary since core manages sm_nextmap and there's no guarantee that the plugin will be up to date, let alone actually be installed.

}
}

public void OnChangelevelFailed(Event event, const char[] name, bool dontBroadcast)
Copy link
Contributor

@nosoop nosoop Jul 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this event also fires for failed changelevels mid-round (e.g. sm_map workshop/1); will ideally want to introduce an (optional) dependency in SDKTools and check against GameRules_GetRoundState() == RoundState_GameOver.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this triggering even on a failed mid-round change is probably sane, can you see any problem with that? I guess we'd end up picking the "wrong" next map perhaps (it'd be the one after the one they tried to change to).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The server (well, TF2) forces a map change to advance to the next map in its cycle only during the game over state, so without checking for that, a failed mid-round change would overwrite any existing nextmap even if it would've been okay to use.

Round state may not be the most exact one though; the SDK actually uses g_fGameOver.

@asherkin
Copy link
Member Author

Ah, I hadn't spotted that any other plugins were using SetNextMap - yeah, probably best to take both of these then (they do work well together). The core changes will ensure nothing gets stuck, and the plugin changes will keep it on the right mapcycle if it would have gotten stuck.

@KyleSanderson
Copy link
Member

If the old plugin is used against a newer core version the sm_nextmap cvar will never get re-populated after map change, so SM will stop controlling the map cycle.

This sounds rather undesirable - no?

@nosoop
Copy link
Contributor

nosoop commented Aug 3, 2021

If the old plugin is used against a newer core version the sm_nextmap cvar will never get re-populated after map change, so SM will stop controlling the map cycle.

This sounds rather undesirable - no?

I believe that comment was for the original version of the PR, which (if I remember correctly) blanked out nextmap at the start of every map change. The latest revision for core should be fine with an older version of the plugin; the effect of a failed map change will be one off-cycle map before getting back on track (with an updated plugin, a failed map change will advance to the next available map in the cycle).

@nosoop
Copy link
Contributor

nosoop commented Sep 3, 2021

I've tested the latest commit against TF2 - including running a copy of nextmap.smx from before this change - and it should be fine, aside from the current behavior the plugin where a failed changelevel mid-game unconditionally modifies sm_nextmap (which wouldn't cause a softlock as the game only continues on the current map).

@KyleSanderson
Copy link
Member

I don't like this - I think there's a better approach.

This has messed up my bench for ages (readas: 15 years) - the reason why is we don't do any validation of the level before setting the convar. Things are OK as the engine takes over and ignores case sensitivity which is excellent as levels are delivered using netchannel at a speedy rate speed (usually 30 to 100KB/s). However, the requests that are serviced against sv_downloadurl are still in the wrong case which frequently results in a 404 situation as the requested file does not actually exist on the webserver.

What I think we should do: I think we should resolve the relative path, then verify the file exists, and then set the convar. It's going to result in a "no workshop2" support situation, but we can add support for that situation when it happens (like when workshop shipped previously).

@nosoop
Copy link
Contributor

nosoop commented Jul 23, 2022

Could you clarify? There is no change in that the engine still handles checking the validity of the map and preparing resources here; I don't quite understand where sv_downloadurl ties into this.

newmap will be whatever was stored in sm_nextmap; there's no change in that behavior either, other than it being blanked out between pre-ChangeLevel and the next LevelInit.

@KyleSanderson
Copy link
Member

Yeah, boiling the ocean lead to nothing happening... this is still an improvement, feel free to merge.

@peace-maker
Copy link
Member

Sounds like this should be merged a while ago and nobody pressed da button. Handling failed mid-round mapchanges slightly wrong is better than deadlocking in a map loop and can be addressed later.

@peace-maker peace-maker merged commit f40ae82 into master Jul 3, 2023
@peace-maker peace-maker deleted the bug-1429 branch July 3, 2023 18:48
StarterX4 pushed a commit to StarterX4/sourcemod that referenced this pull request Aug 2, 2023
* Pure C++ solution

* Pure SourcePawn solution
@ambaca
Copy link
Contributor

ambaca commented Dec 14, 2024

I actually liked that forced change map behaviour...

Anyway, this change affected DOD:S game, because it have a bug inside game.
https://forums.alliedmods.net/showpost.php?p=2831497&postcount=4

*edit
Update, made plugin
[DOD:S] Fix ChangeLevel() Spam

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Populated sm_nextmap causes looping on changelevel failures

6 participants