public virtual void ValidateBattleStatus(UserBattleStatus ubs) { if (Mode != AutohostMode.None) { ubs.AllyNumber = 0; } if (!ubs.IsSpectator) { var cnt = Users.Values.Count(x => !x.IsSpectator); var isPresent = Users.ContainsKey(ubs.Name); if (isPresent && (cnt > MaxPlayers)) { ubs.IsSpectator = true; } if (!isPresent && (cnt >= MaxPlayers)) { ubs.IsSpectator = true; } } }
public PlanetWarsServerBattle(ZkLobbyServer server, PlanetWarsMatchMaker.AttackOption option) : base(server, null) { IsMatchMakerBattle = true; ApplicableRating = RatingCategory.Planetwars; EngineVersion = server.Engine; ModName = server.Game; FounderName = "PlanetWars #" + BattleID; Title = "PlanetWars " + BattleID; Mode = AutohostMode.Planetwars; MapName = option.Map; MaxPlayers = option.TeamSize * 2; prototype = option; foreach (var pe in option.Attackers) { Users[pe] = new UserBattleStatus(pe, server.ConnectedUsers.Get(pe)?.User, GenerateClientScriptPassword(pe)) { AllyNumber = 0 } } ; foreach (var pe in option.Defenders) { Users[pe] = new UserBattleStatus(pe, server.ConnectedUsers.Get(pe)?.User, GenerateClientScriptPassword(pe)) { AllyNumber = 1 } } ; if (ModOptions == null) { ModOptions = new Dictionary <string, string>(); } SetCompetitiveModoptions(); ValidateAndFillDetails(); }
public virtual async Task ProcessPlayerJoin(ConnectedUser user, string joinPassword) { if (IsPassworded && (Password != joinPassword)) { await user.Respond("Invalid password"); return; } if (IsKicked(user.Name)) { await KickFromBattle(user.Name, "Banned for five minutes"); return; } if ((user.MyBattle != null) && (user.MyBattle != this)) { await user.Process(new LeaveBattle()); } UserBattleStatus ubs; if (!Users.TryGetValue(user.Name, out ubs)) { ubs = new UserBattleStatus(user.Name, user.User, GenerateClientScriptPassword(user.Name)); Users[user.Name] = ubs; } ValidateBattleStatus(ubs); user.MyBattle = this; await server.TwoWaySyncUsers(user.Name, Users.Keys); // mutually sync user statuses await server.SyncUserToAll(user); await RecalcSpectators(); await user.SendCommand(new JoinBattleSuccess() { BattleID = BattleID, Players = Users.Values.Select(x => x.ToUpdateBattleStatus()).ToList(), Bots = Bots.Values.Select(x => x.ToUpdateBotStatus()).ToList(), Options = ModOptions }); await server.Broadcast(Users.Keys.Where(x => x != user.Name), ubs.ToUpdateBattleStatus()); // send my UBS to others in battle if (spring.IsRunning) { spring.AddUser(ubs.Name, ubs.ScriptPassword, ubs.LobbyUser); var started = DateTime.UtcNow.Subtract(spring.IngameStartTime ?? RunningSince ?? DateTime.UtcNow); started = new TimeSpan((int)started.TotalHours, started.Minutes, started.Seconds); await SayBattle($"THIS GAME IS CURRENTLY IN PROGRESS, PLEASE WAIT UNTIL IT ENDS! Running for {started}", ubs.Name); await SayBattle("If you say !notify, I will message you when the current game ends.", ubs.Name); } try { var ret = PlayerJoinHandler.AutohostPlayerJoined(GetContext(), ubs.LobbyUser.AccountID); if (ret != null) { if (!IsNullOrEmpty(ret.PrivateMessage)) { await SayBattle(ret.PrivateMessage, ubs.Name); } if (!IsNullOrEmpty(ret.PublicMessage)) { await SayBattle(ret.PublicMessage); } } } catch (Exception ex) { Trace.TraceError(ex.ToString()); await SayBattle("ServerManage error: " + ex); } }
void TasClient_BattleUserStatusChanged(object sender, UserBattleStatus ubs) { RefreshBattleUser(ubs.Name); }
public static void Generate(string filename, Battle b, out List <Battle.GrPlayer> players) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; StringBuilder s = new StringBuilder(); s.AppendLine("[GAME]"); s.AppendLine("{"); s.AppendFormat(" Mapname={0};\n", b.Map.Name); s.AppendFormat(" StartMetal={0};\n", b.Details.StartingMetal); s.AppendFormat(" StartEnergy={0};\n", b.Details.StartingEnergy); s.AppendFormat(" MaxUnits={0};\n", b.Details.MaxUnits); s.AppendFormat(" StartPosType={0};\n", (int)b.Details.StartPos); s.AppendFormat(" GameMode={0};\n", (int)b.Details.EndCondition); s.AppendFormat(" GameType={0};\n", b.Mod.ArchiveName); s.AppendFormat(" LimitDGun={0};\n", b.Details.LimitDgun); s.AppendFormat(" DiminishingMMs={0};\n", b.Details.DiminishingMM); s.AppendFormat(" GhostedBuildings={0};\n", b.Details.GhostedBuildings); s.AppendLine(); s.AppendFormat(" HostIP={0};\n", "127.0.0.1"); s.AppendFormat(" HostPort={0};\n", b.HostPort); //s.AppendFormat(" MinSpeed={0};\n", 1); //s.AppendFormat(" MaxSpeed={0};\n", 1); s.AppendLine(); s.AppendFormat(" MyPlayerNum={0};\n", 0); //List<Battle.GrPlayer> players; List <Battle.GrTeam> teams; List <Battle.GrAlly> alliances; b.GroupData(out players, out teams, out alliances); s.AppendLine(); s.AppendFormat(" NumPlayers={0};\n", players.Count); s.AppendFormat(" NumTeams={0};\n", teams.Count); s.AppendFormat(" NumAllyTeams={0};\n", alliances.Count); s.AppendLine(); // PLAYERS for (int i = 0; i < players.Count; ++i) { UserBattleStatus u = players[i].user; s.AppendFormat(" [PLAYER{0}]\n", i); s.AppendLine(" {"); s.AppendFormat(" name={0};\n", u.name); s.AppendFormat(" Spectator={0};\n", u.IsSpectator ? 1 : 0); if (!u.IsSpectator) { s.AppendFormat(" team={0};\n", u.TeamNumber); } s.AppendLine(" }"); } // TEAMS s.AppendLine(); for (int i = 0; i < teams.Count; ++i) { s.AppendFormat(" [TEAM{0}]\n", i); s.AppendLine(" {"); s.AppendFormat(" TeamLeader={0};\n", teams[i].leader); UserBattleStatus u = teams[i].bot ?? players[teams[i].leader].user; s.AppendFormat(" AllyTeam={0};\n", u.AllyNumber); s.AppendFormat(" RGBColor={0:F5} {1:F5} {2:F5};\n", (u.TeamColor & 255) / 255.0, ((u.TeamColor >> 8) & 255) / 255.0, ((u.TeamColor >> 16) & 255) / 255.0); s.AppendFormat(" Side={0};\n", b.Mod.Sides[u.Side]); s.AppendFormat(" Handicap={0};\n", 0); if (teams[i].bot != null) { s.AppendFormat(" AIDLL={0};\n", teams[i].bot.aiLib); } s.AppendLine(" }"); } // ALLYS s.AppendLine(); for (int i = 0; i < alliances.Count; ++i) { s.AppendFormat("[ALLYTEAM{0}]\n", i); s.AppendLine("{"); s.AppendFormat(" NumAllies={0};\n", 0); double left, top, right, bottom; alliances[i].rect.ToFractions(out left, out top, out right, out bottom); s.AppendFormat(" StartRectLeft={0};\n", left); s.AppendFormat(" StartRectTop={0};\n", top); s.AppendFormat(" StartRectRight={0};\n", right); s.AppendFormat(" StartRectBottom={0};\n", bottom); s.AppendLine("}"); } s.AppendLine(); s.AppendFormat(" NumRestrictions={0};\n", b.DisabledUnits.Count); s.AppendLine(" [RESTRICT]"); s.AppendLine(" {"); for (int i = 0; i < b.DisabledUnits.Count; ++i) { s.AppendFormat(" Unit{0}={1};\n", i, b.DisabledUnits[i]); s.AppendFormat(" Limit{0}=0;\n", i); } s.AppendLine(" }"); s.AppendLine(" [modoptions]"); s.AppendLine(" {"); foreach (UnitSync.Option o in b.Mod.Options) { string v = o.Default; if (b.ModOptions.ContainsKey(o.Key)) { v = b.ModOptions[o.Key]; } s.AppendFormat(" {0}={1};\n", o.Key, v); } s.AppendLine(" }"); s.AppendLine("}"); StreamWriter f = File.CreateText(filename); f.Write(s.ToString()); f.Flush(); f.Close(); }
/// <summary> /// singleton, dont use, internal for designer /// </summary> internal BattleBar() { InitializeComponent(); picoChat.ChatBackgroundColor = TextColor.background; //same color as Program.Conf.BgColor picoChat.IRCForeColor = 14; //mirc grey. Unknown use Program.ToolTip.SetText(cbSide, "Choose the faction you wish to play."); client = Program.TasClient; spring = new Spring(Program.SpringPaths); try { // silly way to create speech and voice engines on runtime - needed due to mono crash speech = Activator.CreateInstance(Type.GetType("ZeroKLobby.ChatToSpeech"), spring); if (Program.Conf.EnableVoiceCommands) { voice = Activator.CreateInstance(Type.GetType("ZeroKLobby.VoiceCommand.VoiceCommandEngine"), client, spring); } } catch (Exception ex) { Trace.TraceWarning("Failed to init VoiceCommands:{0}", ex.Message); } spring.SpringExited += (s, e) => { client.ChangeMyUserStatus(isInGame: false); client.ChangeMyBattleStatus(ready: true); if (e.Data) { Program.MainWindow.InvokeFunc(() => { var defaultButton = MessageBoxDefaultButton.Button2; var icon = MessageBoxIcon.None; if ( MessageBox.Show("Do you want me to set Low details?\n(will effect: lups.cfg and springsettings.cfg)\n\nIf you wish to file a bug report, please include a copy of infolog.txt in your game data folder (accessible through Settings).\nUpload it to a text sharing site such as pastebin.com.", "Spring engine has crashed, update your video and audio drivers please!", MessageBoxButtons.YesNo, icon, defaultButton) == DialogResult.Yes) { Program.Conf.UseSafeMode = true; Program.EngineConfigurator.Configure(true, 0); } }); } }; spring.SpringStarted += (s, e) => { client.ChangeMyUserStatus(isInGame: true); }; client.Rang += (s, e) => { MainWindow.Instance.NotifyUser("chat/battle", "Someone demands your attention in battle room!", true, true); AutoRespond(); }; client.BattleJoined += (s, e) => { if (!isVisible) { ManualBattleStarted(); } if (IsHostGameRunning()) { barContainer.btnDetail.Text = "Rejoin"; } else { barContainer.btnDetail.Text = "Start"; } //client.ChangeMyUserStatus(false, false); var battle = client.MyBattle; lastBattleFounder = battle.Founder.Name; if (battle.Founder.Name.StartsWith("PlanetWars")) { ChangeDesiredSpectatorState(false); // TODO pw unpsec hack, remove later } Program.SpringScanner.MetaData.GetModAsync(battle.ModName, (mod) => { if (!Program.CloseOnNext) { Program.MainWindow.InvokeFunc(() => { var previousSide = cbSide.SelectedItem != null ? cbSide.SelectedItem.ToString() : null; cbSide.Items.Clear(); var cnt = 0; foreach (var side in mod.Sides) { cbSide.Items.Add(new SideItem(side, mod.SideIcons[cnt++])); } var pickedItem = cbSide.Items.OfType <SideItem>() .FirstOrDefault(x => x.Side == previousSide); suppressSideChangeEvent = true; cbSide.Visible = mod.Sides.Length > 1; if (cbSide.Visible) { if (pickedItem != null) { cbSide.SelectedItem = pickedItem; } else { cbSide.SelectedIndex = random.Next(cbSide.Items.Count); } } suppressSideChangeEvent = false; }); } }, (ex) => { }, Program.SpringPaths.SpringVersion); Program.Downloader.GetResource(DownloadType.MAP, battle.MapName); Program.Downloader.GetResource(DownloadType.MOD, battle.ModName); engineVersionNeeded = battle.EngineVersion; if (engineVersionNeeded != Program.SpringPaths.SpringVersion) { Program.Downloader.GetAndSwitchEngine(engineVersionNeeded); } else { engineVersionNeeded = null; } if (battle != previousBattle) { previousBattle = battle; if (gameBox.Image != null) { gameBox.Image.Dispose(); } DpiMeasurement.DpiXYMeasurement(this); int scaledIconHeight = DpiMeasurement.ScaleValueY(BattleIcon.Height); int scaledIconWidth = DpiMeasurement.ScaleValueX(BattleIcon.Width); gameBox.Image = new Bitmap(scaledIconWidth, scaledIconHeight); using (var g = Graphics.FromImage(gameBox.Image)) { g.FillRectangle(Brushes.White, 0, 0, scaledIconWidth, scaledIconHeight); var bi = Program.BattleIconManager.GetBattleIcon(battle.BattleID); g.DrawImageUnscaled(bi.Image, 0, 0); } gameBox.Invalidate(); } RefreshTooltip(); }; cbSide.DrawMode = DrawMode.OwnerDrawFixed; cbSide.DrawItem += cbSide_DrawItem; client.MyBattleMapChanged += (s, e) => { if (client.MyBattle != null && !Program.SpringScanner.HasResource(client.MyBattle.MapName)) { client.ChangeMyBattleStatus(syncStatus: SyncStatuses.Unsynced); Program.Downloader.GetResource(DownloadType.MAP, client.MyBattle.MapName); } RefreshTooltip(); }; client.MyBattleHostExited += (s, e) => { barContainer.btnDetail.Text = "Start"; }; client.RequestBattleStatus += (s, e) => { var battle = client.MyBattle; var alliance = Enumerable.Range(0, TasClient.MaxAlliances - 1) .FirstOrDefault(allyTeam => !battle.Users.Any(user => user.AllyNumber == allyTeam)); var team = battle.GetFreeTeamID(client.UserName); /* if (battle) * { * var b = tas.MyBattle; * return hostedMod.MissionSlots.Where(x => x.IsHuman).OrderByDescending(x => x.IsRequired).Where( * x => !b.Users.Any(y => y.AllyNumber == x.AllyID && y.TeamNumber == x.TeamID && !y.IsSpectator)); * * var slot = GetFreeSlots().FirstOrDefault(); * if (slot != null) * { * tas.ForceAlly(u.Name, slot.AllyID); * tas.ForceTeam(u.Name, slot.TeamID); * } * else tas.ForceSpectator(u.Name); * }*/ var status = new UserBattleStatus { AllyNumber = alliance, TeamNumber = team, SyncStatus = HasAllResources() ? SyncStatuses.Synced : SyncStatuses.Unsynced, IsSpectator = desiredSpectatorState, Side = cbSide.SelectedIndex >= 0 ? cbSide.SelectedIndex : 0, TeamColor = Program.Conf.DefaultPlayerColorInt, IsReady = true, }; client.SendMyBattleStatus(status); }; client.MyBattleStarted += (s, e) => { try { barContainer.btnDetail.Text = "Rejoin"; if (client.MyBattleStatus.SyncStatus == SyncStatuses.Synced) { if (Utils.VerifySpringInstalled()) { if (spring.IsRunning) { spring.ExitGame(); } lastScript = spring.StartGame(client, null, null, null, Program.Conf.UseSafeMode, client.MyBattleStatus.IsSpectator?Program.Conf.UseMtEngine:false); //use MT tag when in spectator slot } } } catch (Exception ex) { MessageBox.Show("Error starting spring: " + ex.Message); } RefreshTooltip(); }; client.BattleMyUserStatusChanged += (s, e) => { if (client.MyBattleStatus != null) { barContainer.btnDetail.Enabled = client.MyBattleStatus.SyncStatus == SyncStatuses.Synced; if (client.MyBattleStatus.IsSpectator && radioPlay.Checked) { ChangeGuiSpectatorWithoutEvent(false); // i was spectated } if (!client.MyBattleStatus.IsSpectator && radioSpec.Checked) { ChangeGuiSpectatorWithoutEvent(true); //i was unspectated } } }; client.BattleClosed += (s, e) => { barContainer.btnDetail.Text = "Start"; if (gameBox.Image != null) { gameBox.Image.Dispose(); } gameBox.Image = null; cbSide.Visible = false; RefreshTooltip(); Stop(); }; client.MyBattleEnded += (s, e) => { var t = new Timer(); var tryCount = 0; t.Interval = 1000; t.Tick += (s2, e2) => { tryCount++; if (tryCount > 15) { t.Stop(); } else if (client.IsLoggedIn && client.MyBattle == null) { var bat = client.ExistingBattles.Values.FirstOrDefault(x => x.Founder.Name == lastBattleFounder && !x.IsPassworded); if (bat != null) { ActionHandler.JoinBattle(bat.BattleID, null); t.Stop(); } } }; t.Start(); }; client.ConnectionLost += (s, e) => { if (gameBox.Image != null) { gameBox.Image.Dispose(); } gameBox.Image = null; cbSide.Visible = false; RefreshTooltip(); Stop(); }; timer.Tick += (s, e) => { if (client.IsLoggedIn) { if (WindowsApi.IdleTime.TotalMinutes > Program.Conf.IdleTime) { client.ChangeMyUserStatus(isAway: true); } else { client.ChangeMyUserStatus(isAway: false); } CheckMyBattle(); } }; timer.Interval = 2500; timer.Start(); Program.BattleIconManager.BattleChanged += BattleIconManager_BattleChanged; //picoChat.Font = new Font(Program.Conf.ChatFont.FontFamily, Program.Conf.ChatFont.Size*0.8f); picoChat.ShowHistory = false; picoChat.ShowJoinLeave = false; //picoChat.HideScroll = true; BattleChatControl.BattleLine += (s, e) => picoChat.AddLine(e.Data); picoChat.MouseClick += (s, e) => NavigationControl.Instance.Path = "chat/battle"; }
/// <summary> /// Determines command permissions /// </summary> /// <param name="battle"></param> /// <param name="userName"></param> /// <returns></returns> public virtual RunPermission GetRunPermissions(ServerBattle battle, string userName, out string reason) { reason = ""; if (Access == AccessType.NoCheck) { return(RunPermission.Run); } User user = null; UserBattleStatus ubs = null; if (userName != null) { battle.Users.TryGetValue(userName, out ubs); if (ubs != null) { user = ubs.LobbyUser; } else { ConnectedUser con; battle.server.ConnectedUsers.TryGetValue(userName, out con); user = con?.User; } } var hasAdminRights = user?.IsAdmin == true; var hasElevatedRights = hasAdminRights || userName == battle.FounderName; var s = battle.spring; bool isSpectator = IsSpectator(battle, userName, ubs); bool isAway = user?.IsAway == true; int count = 0; if (s.IsRunning) { count = s.LobbyStartContext.Players.Count(x => !x.IsSpectator); } else { count = battle.Users.Count(x => !x.Value.IsSpectator); } if (Access == AccessType.Admin && hasAdminRights) { return(RunPermission.Run); } else if (Access == AccessType.Admin) { reason = "This command can only be used by moderators."; return(RunPermission.None); } var defPerm = hasElevatedRights ? RunPermission.Run : (isSpectator || isAway ? RunPermission.None : RunPermission.Vote); if (defPerm == RunPermission.None) { reason = "This command can't be executed by spectators. Join the game to use this command."; return(RunPermission.None); } if (defPerm == RunPermission.Vote && count <= 1) { defPerm = RunPermission.Run; } if (Access == AccessType.Anywhere) { return(defPerm); } if (Access == AccessType.Ingame || Access == AccessType.IngameVote) { if (s.IsRunning) { if (Access == AccessType.IngameVote) { return(RunPermission.Vote); } else { return(defPerm); } } else { reason = "This command can only be used while the game is running. Use !start to start the game."; return(RunPermission.None); } } if (Access == AccessType.NotIngameNotAutohost && battle.IsAutohost && !hasAdminRights) { reason = "This command cannot be used on autohosts, either ask a moderator to change the settings or create your own host."; return(RunPermission.None); } if (Access == AccessType.NotIngame || Access == AccessType.NotIngameNotAutohost) { if (!s.IsRunning) { return(defPerm); } else { reason = "This command can only be used outside of the game. Use !exit to abort the game."; return(RunPermission.None); } } //unknown access type return(RunPermission.None); }