mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 08:23:45 +00:00
feat(multiplayer): enforce allocated initial connect policy
This commit is contained in:
@@ -35,17 +35,25 @@ extends Node
|
||||
signal match_starting(arena_path: String, match_index: int)
|
||||
|
||||
const POLL_INTERVAL_MS := 250
|
||||
const ALLOCATED_WAIT := "WAIT"
|
||||
const ALLOCATED_READY := "READY"
|
||||
const ALLOCATED_CANCEL := "CANCEL"
|
||||
const ALLOCATED_START_WITH_BOTS := "START_WITH_BOTS"
|
||||
|
||||
var min_players := 1
|
||||
var start_countdown_seconds := 5.0
|
||||
var max_matches := 0 # 0 = run forever
|
||||
var rotation_mode := "sequential"
|
||||
var allocated_mode := false
|
||||
var allocated_playlist := ""
|
||||
var allocated_roster_size := 0
|
||||
|
||||
var matches_completed := 0
|
||||
var _countdown_started_ms := -1
|
||||
var _match_active := false
|
||||
var _next_poll_ms := 0
|
||||
var _shutting_down := false
|
||||
var _allocated_connect_started_ms := -1
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
@@ -58,7 +66,54 @@ func _process(_delta: float) -> void:
|
||||
if _match_active:
|
||||
_poll_match_end()
|
||||
else:
|
||||
if allocated_mode:
|
||||
_poll_allocated_match_start(now)
|
||||
else:
|
||||
_poll_match_start(now)
|
||||
|
||||
|
||||
func _poll_allocated_match_start(now: int) -> void:
|
||||
if _allocated_connect_started_ms < 0:
|
||||
_allocated_connect_started_ms = now
|
||||
var connected := MatchNet.roster.size()
|
||||
var has_team_zero := false
|
||||
var has_team_one := false
|
||||
for info: MatchNet.PlayerInfo in MatchNet.roster.values():
|
||||
has_team_zero = has_team_zero or info.team == 0
|
||||
has_team_one = has_team_one or info.team == 1
|
||||
var action := allocated_initial_connect_action(allocated_playlist, now - _allocated_connect_started_ms, connected, allocated_roster_size, has_team_zero, has_team_one)
|
||||
if action == ALLOCATED_READY:
|
||||
_poll_match_start(now)
|
||||
return
|
||||
if action == ALLOCATED_CANCEL:
|
||||
var reason := "ranked_initial_connect_timeout" if allocated_playlist == "ranked" else "casual_initial_connect_ineligible"
|
||||
_cancel_allocated_no_show(reason, connected)
|
||||
return
|
||||
if action == ALLOCATED_START_WITH_BOTS:
|
||||
NetworkedMatch.server_bot_fill_override = true
|
||||
_poll_match_start(now)
|
||||
|
||||
|
||||
static func allocated_initial_connect_action(playlist: String, elapsed_ms: int, connected: int, expected: int, has_team_zero: bool, has_team_one: bool) -> String:
|
||||
if elapsed_ms < 0 or connected < 0 or expected < 1:
|
||||
return ALLOCATED_CANCEL
|
||||
if connected >= expected:
|
||||
return ALLOCATED_READY
|
||||
if playlist == "ranked":
|
||||
return ALLOCATED_CANCEL if elapsed_ms >= 30000 else ALLOCATED_WAIT
|
||||
if playlist == "casual":
|
||||
if elapsed_ms < 60000:
|
||||
return ALLOCATED_WAIT
|
||||
return ALLOCATED_START_WITH_BOTS if connected >= 2 and has_team_zero and has_team_one else ALLOCATED_CANCEL
|
||||
return ALLOCATED_CANCEL
|
||||
|
||||
func _cancel_allocated_no_show(reason: String, connected: int) -> void:
|
||||
if _shutting_down:
|
||||
return
|
||||
_shutting_down = true
|
||||
ServerLog.info("initial_connect_cancelled", {"reason": reason, "connected": connected, "expected": allocated_roster_size})
|
||||
NetworkManager.shutdown()
|
||||
get_tree().quit(0)
|
||||
|
||||
|
||||
# A match is over when the match scene is gone. NetworkedMatch returns both
|
||||
|
||||
Reference in New Issue
Block a user