internal void TryCreateArenaForPlayersAsync(IMatchMaker match_maker, List <Player> buffer) { if (is_disposing()) { return; } Task.Run(async() => { var attempt = new CreateArenaAttempt(); foreach (var player in buffer) { attempt.PlayerInfo.Add(new ArenaServer.PlayerInfo { AuthToken = GuidOps.ToByteString(Guid.NewGuid()), BasicInfo = player.BasicPlayerInfo() }); } foreach (var arena in hosts) { if (await arena.TryCreateArenaForPlayers(buffer, attempt)) { return; } } match_maker.AddPlayers(buffer); }); }
internal async Task <bool> TryCreateArenaForPlayers(List <Player> buffer, CreateArenaAttempt attempt) { if (is_disposing()) { return(false); } if (channel.State != ChannelState.Ready) { return(false); } if (buffer.Count != attempt.PlayerInfo.Count) { Log.Fatal("Parameter buffer is expected to have same size and attempt.PlayerInfo"); return(false); } if (suggested_arena_instances_left == 0) { return(false); } CreateArenaResult result; try { result = await client.CreateArenaAsync(attempt); if (!result.Success) { return(false); } } catch (RpcException) { Log.Msg(string.Format("Could not speak to arena host with connection string: {0}", connection_str)); try_connect(); return(false); } catch (Exception e) { Log.Exception(e); return(false); } suggested_arena_instances_left = result.FreeArenaCount; var arena = new SingleArena(this, buffer, result); lock (arenas) arenas.Add(arena); for (var i = 0; i < buffer.Count; ++i) { var player = buffer[i]; var info = attempt.PlayerInfo[i]; player.arena = arena; player.arena_state = ArenaState.InArena; var ev = new Event { QueuePopped = new Event_QueuePopped { AuthToken = info.AuthToken, ConnectionStr = result.PublicConnectionStr } }; player.event_stream.Enqueue(ev); } return(true); }
public override async Task <CreateArenaResult> CreateArena(CreateArenaAttempt request, ServerCallContext context) { var result = new CreateArenaResult(); var args = new StringBuilder(); args.Append("-executeMethod SingleArenaServerController.Run "); var private_port = port_allocator.Allocate(); if (!private_port.HasValue) { Log.Warning("Could not allocate a port from the port allocator"); result.Success = false; return(result); } var public_port = port_allocator.Allocate(); if (!public_port.HasValue) { Log.Warning("Could not allocate a port from the port allocator"); result.Success = false; return(result); } args.Append("-private_port="); args.Append(private_port.Value); args.Append(" "); args.Append("-public_port="); args.Append(public_port.Value); args.Append(" "); if (!show_arena_windows) { args.Append("-batchmode -nographics "); } var process = new Process(); process.StartInfo = new ProcessStartInfo { FileName = invoke_unity_file, Arguments = args.ToString() }; if (!processes.AddIfCountIsLessThan(process, max_arena_count)) { result.Success = false; return(result); } process.EnableRaisingEvents = true; process.Exited += on_process_exited; process.Start(); await Task.Delay(process_startup_delay_sec * 1000); if (process.HasExited) { Log.Warning("Could not start arena process properly"); result.Success = false; return(result); } result.FreeArenaCount = max_arena_count - processes.Count(); result.PrivateConnectionStr = self_url + ":" + private_port.Value; result.PublicConnectionStr = self_url + ":" + public_port.Value; return(result); }