private void ArchiveBattle(SpringBattle battle, string path) { if (!string.IsNullOrEmpty(battle.GlacierArchiveID)) { Trace.TraceWarning("Unable to archive battle {0} : already archived", battle.SpringBattleID); return; } if (string.IsNullOrEmpty(battle.ReplayFileName)) { Trace.TraceWarning("Unable to archive battle {0} : no file name in DB", battle.SpringBattleID); return; } using (var fs = File.OpenRead(path)) { var result = StoreArchive(fs, $"Spring battle {battle.SpringBattleID}"); if (!string.IsNullOrEmpty(result.ArchiveId) && (result.HttpStatusCode == HttpStatusCode.OK || result.HttpStatusCode == HttpStatusCode.Accepted || result.HttpStatusCode == HttpStatusCode.Created)) { battle.GlacierArchiveID = result.ArchiveId; Trace.TraceInformation("Spring battle {0} archived as {1}", battle.SpringBattleID, result.ArchiveId); } else { throw new Exception("Invalid glacier upload: " + result.HttpStatusCode); } } }
private static void ProcessElos(Spring.SpringBattleContext result, ZkLobbyServer.ZkLobbyServer server, ZkDataContext db, SpringBattle sb) { bool noElo = result.OutputExtras.Any(x => x?.StartsWith("noElo", true, System.Globalization.CultureInfo.CurrentCulture) == true); Dictionary<int, int> orgLevels = sb.SpringBattlePlayers.Select(x => x.Account).ToDictionary(x => x.AccountID, x => x.Level); sb.CalculateAllElo(noElo); foreach (var u in sb.SpringBattlePlayers.Where(x => !x.IsSpectator)) u.Account.CheckLevelUp(); db.SaveChanges(); try { foreach (Account a in sb.SpringBattlePlayers.Where(x => !x.IsSpectator).Select(x => x.Account)) server.PublishAccountUpdate(a); } catch (Exception ex) { Trace.TraceError("error updating extension data: {0}", ex); } foreach (Account account in sb.SpringBattlePlayers.Select(x => x.Account)) { if (account.Level > orgLevels[account.AccountID]) { try { string message = string.Format("Congratulations {0}! You just leveled up to level {1}. {3}/Users/Detail/{2}", account.Name, account.Level, account.AccountID, GlobalConst.BaseSiteUrl); //text.AppendLine(message); server.GhostPm(account.Name, message); } catch (Exception ex) { Trace.TraceError("Error sending level up lobby message: {0}", ex); } } } }
/// <summary> /// Updates shadow influence and new owners /// </summary> /// <param name="db"></param> /// <param name="sb">optional spring batle that caused this change (for event logging)</param> public static void SetPlanetOwners(ZkDataContext db = null, SpringBattle sb = null) { if (db == null) db = new ZkDataContext(); Galaxy gal = db.Galaxies.Single(x => x.IsDefault); foreach (Planet planet in gal.Planets) { if (planet.OwnerAccountID != null) foreach (var ps in planet.PlanetStructures.Where(x => x.OwnerAccountID == null)) { ps.OwnerAccountID = planet.OwnerAccountID; ps.IsActive = false; ps.ActivatedOnTurn = null; } PlanetFaction best = planet.PlanetFactions.OrderByDescending(x => x.Influence).FirstOrDefault(); Faction newFaction = planet.Faction; Account newAccount = planet.Account; if (best == null || best.Influence < GlobalConst.InfluenceToCapturePlanet) { // planet not capture if (planet.Faction != null) { var curFacInfluence = planet.PlanetFactions.Where(x => x.FactionID == planet.OwnerFactionID).Select(x => x.Influence).FirstOrDefault(); if (curFacInfluence <= GlobalConst.InfluenceToLosePlanet) { // owners have too small influence, planet belong to nobody newFaction = null; newAccount = null; } } } else { if (best.Faction != planet.Faction) { newFaction = best.Faction; // best attacker without planets Account candidate = planet.AccountPlanets.Where( x => x.Account.FactionID == newFaction.FactionID && x.AttackPoints > 0 && !x.Account.Planets.Any()).OrderByDescending( x => x.AttackPoints).Select(x => x.Account).FirstOrDefault(); if (candidate == null) { // best attacker candidate = planet.AccountPlanets.Where(x => x.Account.FactionID == newFaction.FactionID && x.AttackPoints > 0).OrderByDescending( x => x.AttackPoints).ThenBy(x => x.Account.Planets.Count()).Select(x => x.Account).FirstOrDefault(); } // best player without planets if (candidate == null) { candidate = newFaction.Accounts.Where(x => !x.Planets.Any()).OrderByDescending(x => x.AccountPlanets.Sum(y => y.AttackPoints)). FirstOrDefault(); } // best with planets if (candidate == null) { candidate = newFaction.Accounts.OrderByDescending(x => x.AccountPlanets.Sum(y => y.AttackPoints)). FirstOrDefault(); } newAccount = candidate; } } // change has occured if (newFaction != planet.Faction) { // disable structures foreach (PlanetStructure structure in planet.PlanetStructures.Where(x => x.StructureType.OwnerChangeDisablesThis)) { structure.IsActive = false; structure.ActivatedOnTurn = null; structure.Account = newAccount; } // delete structures being lost on planet change foreach (PlanetStructure structure in planet.PlanetStructures.Where(structure => structure.StructureType.OwnerChangeDeletesThis).ToList()) db.PlanetStructures.DeleteOnSubmit(structure); // reset attack points memory foreach (AccountPlanet acp in planet.AccountPlanets) acp.AttackPoints = 0; if (newFaction == null) { Account account = planet.Account; Clan clan = null; if (account != null) { clan = planet.Account != null ? planet.Account.Clan : null; } db.Events.InsertOnSubmit(Global.CreateEvent("{0} planet {1} owned by {2} {3} was abandoned. {4}", planet.Faction, planet, account, clan, sb)); if (account != null) { Global.Server.GhostPm(planet.Account.Name, string.Format( "Warning, you just lost planet {0}!! {2}/PlanetWars/Planet/{1}", planet.Name, planet.PlanetID, GlobalConst.BaseSiteUrl)); } } else { // new real owner // log messages if (planet.OwnerAccountID == null) // no previous owner { db.Events.InsertOnSubmit(Global.CreateEvent("{0} has claimed planet {1} for {2} {3}. {4}", newAccount, planet, newFaction, newAccount.Clan, sb)); Global.Server.GhostPm(newAccount.Name, string.Format( "Congratulations, you now own planet {0}!! {2}/PlanetWars/Planet/{1}", planet.Name, planet.PlanetID, GlobalConst.BaseSiteUrl)); } else { db.Events.InsertOnSubmit(Global.CreateEvent("{0} of {1} {2} has captured planet {3} from {4} of {5} {6}. {7}", newAccount, newFaction, newAccount.Clan, planet, planet.Account, planet.Faction, planet.Account.Clan, sb)); Global.Server.GhostPm(newAccount.Name, string.Format( "Congratulations, you now own planet {0}!! {2}/PlanetWars/Planet/{1}", planet.Name, planet.PlanetID, GlobalConst.BaseSiteUrl)); Global.Server.GhostPm(planet.Account.Name, string.Format( "Warning, you just lost planet {0}!! {2}/PlanetWars/Planet/{1}", planet.Name, planet.PlanetID, GlobalConst.BaseSiteUrl)); } } planet.Faction = newFaction; planet.Account = newAccount; } ReturnPeacefulDropshipsHome(db, planet); } db.SaveChanges(); }
/// <summary> /// Process planet wars turn /// </summary> /// <param name="mapName"></param> /// <param name="extraData"></param> /// <param name="db"></param> /// <param name="winNum">0 = attacker wins, 1 = defender wins</param> /// <param name="players"></param> /// <param name="text"></param> /// <param name="sb"></param> public static void EndTurn(string mapName, List<string> extraData, ZkDataContext db, int? winNum, List<Account> players, StringBuilder text, SpringBattle sb, List<Account> attackers) { if (extraData == null) extraData = new List<string>(); Galaxy gal = db.Galaxies.Single(x => x.IsDefault); Planet planet = gal.Planets.Single(x => x.Resource.InternalName == mapName); text.AppendFormat("Battle on {1}/PlanetWars/Planet/{0} has ended\n", planet.PlanetID, GlobalConst.BaseSiteUrl); Faction attacker = attackers.Where(x => x.Faction != null).Select(x => x.Faction).First(); var defenders = players.Where(x => x.FactionID != attacker.FactionID && x.FactionID != null).ToList(); bool isAttackerWinner; bool wasAttackerCcDestroyed = false; bool wasDefenderCcDestroyed = false; if (winNum != null) { if (winNum == 0) isAttackerWinner = true; else isAttackerWinner = false; wasAttackerCcDestroyed = extraData.Any(x => x.StartsWith("hqkilled,0")); wasDefenderCcDestroyed = extraData.Any(x => x.StartsWith("hqkilled,1")); } else { text.AppendFormat("No winner on this battle!"); Trace.TraceError("PW battle without a winner {0}", sb != null ? sb.SpringBattleID : (int?)null); return; } int dropshipsSent = (planet.PlanetFactions.Where(x => x.Faction == attacker).Sum(x => (int?)x.Dropships) ?? 0); bool isLinked = planet.CanDropshipsAttack(attacker); string influenceReport = ""; // distribute influence // save influence gains // give influence to main attackers double planetDropshipDefs = (planet.PlanetStructures.Where(x => x.IsActive).Sum(x => x.StructureType.EffectDropshipDefense) ?? 0); double planetIpDefs = (planet.PlanetStructures.Where(x => x.IsActive).Sum(x => x.StructureType.EffectReduceBattleInfluenceGain) ?? 0); double baseInfluence = GlobalConst.BaseInfluencePerBattle; double influence = baseInfluence; double effectiveShips = Math.Max(0, (dropshipsSent - planetDropshipDefs)); double shipBonus = effectiveShips*GlobalConst.InfluencePerShip; double defenseBonus = -planetIpDefs; double techBonus = attacker.GetFactionUnlocks().Count() * GlobalConst.InfluencePerTech; double ipMultiplier = 1; string ipReason; if (!isAttackerWinner) { if (wasDefenderCcDestroyed) { ipMultiplier = 0.2; ipReason = "from losing but killing defender's CC"; } else { ipMultiplier = 0; ipReason = "from losing horribly"; } } else { if (wasAttackerCcDestroyed) { ipReason = "from losing own CC"; ipMultiplier = 0.5; } else { ipReason = "from winning flawlessly"; } } if (!isLinked && effectiveShips < GlobalConst.DropshipsForFullWarpIPGain) { var newMult = effectiveShips/GlobalConst.DropshipsForFullWarpIPGain; ipMultiplier *= newMult ; ipReason = ipReason + string.Format(" and reduced to {0}% because only {1} of {2} ships needed for warp attack got past defenses", (int)(newMult*100.0), (int)effectiveShips, GlobalConst.DropshipsForFullWarpIPGain); } influence = (influence + shipBonus + techBonus) * ipMultiplier + defenseBonus; if (influence < 0) influence = 0; influence = Math.Floor(influence * 100) / 100; // main winner influence PlanetFaction entry = planet.PlanetFactions.FirstOrDefault(x => x.Faction == attacker); if (entry == null) { entry = new PlanetFaction { Faction = attacker, Planet = planet, }; planet.PlanetFactions.Add(entry); } entry.Influence += influence; // clamping of influence // gained over 100, sole owner if (entry.Influence >= 100) { entry.Influence = 100; foreach (var pf in planet.PlanetFactions.Where(x => x.Faction != attacker)) pf.Influence = 0; } else { var sumOthers = planet.PlanetFactions.Where(x => x.Faction != attacker).Sum(x => (double?)x.Influence) ?? 0; if (sumOthers + entry.Influence > 100) { var excess = sumOthers + entry.Influence - 100; foreach (var pf in planet.PlanetFactions.Where(x => x.Faction != attacker)) pf.Influence -= pf.Influence / sumOthers * excess; } } try { influenceReport = String.Format("{0} gained {1} influence ({2}% {3} of {4}{5}{6}{7})", attacker.Shortcut, influence, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", techBonus > 0 ? " +" + techBonus + " from techs" : "", shipBonus > 0 ? " +" + shipBonus + " from dropships" : "", defenseBonus != 0 ? " -" + -defenseBonus + " from defenses" : ""); } catch (Exception ex) { Trace.TraceError(ex.ToString()); } // distribute metal var attackersTotalMetal = Math.Floor(GlobalConst.PlanetWarsAttackerMetal); var defendersTotalMetal = Math.Floor(GlobalConst.PlanetWarsDefenderMetal); var attackerMetal = Math.Floor(attackersTotalMetal / attackers.Count); var defenderMetal = Math.Floor(defendersTotalMetal / defenders.Count); foreach (Account w in attackers) { w.ProduceMetal(attackerMetal); var ev = Global.CreateEvent("{0} gained {1} metal from battle {2}", w, attackerMetal, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } foreach (Account w in defenders) { w.ProduceMetal(defenderMetal); var ev = Global.CreateEvent("{0} gained {1} metal from battle {2}", w, defenderMetal, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } // remove dropships foreach (var pf in planet.PlanetFactions.Where(x => x.Faction == attacker)) pf.Dropships = 0; // add attack points foreach (Account acc in players) { int ap = acc.Faction == attacker ? GlobalConst.AttackPointsForVictory : GlobalConst.AttackPointsForDefeat; if (acc.Faction != null) { AccountPlanet apentry = planet.AccountPlanets.SingleOrDefault(x => x.AccountID == acc.AccountID); if (apentry == null) { apentry = new AccountPlanet { AccountID = acc.AccountID, PlanetID = planet.PlanetID }; db.AccountPlanets.InsertOnSubmit(apentry); } apentry.AttackPoints += ap; } acc.PwAttackPoints += ap; } // paranoia! try { var mainEvent = Global.CreateEvent("{0} attacked {1} {2} in {3} and {4}. {5}", attacker, planet.Faction, planet, sb, isAttackerWinner ? "won. " : "lost. ", influenceReport ); db.Events.InsertOnSubmit(mainEvent); text.AppendLine(mainEvent.PlainText); } catch (Exception ex) { Trace.TraceError(ex.ToString()); } // destroy pw structures killed ingame if (!isAttackerWinner) { var handled = new List<string>(); foreach (string line in extraData.Where(x => x.StartsWith("structurekilled"))) { string[] data = line.Substring(16).Split(','); string unitName = data[0]; if (handled.Contains(unitName)) continue; handled.Add(unitName); foreach (PlanetStructure s in planet.PlanetStructures.Where(x => x.StructureType.IngameUnitName == unitName)) { if (s.StructureType.IsIngameDestructible) { s.IsActive = false; s.ActivatedOnTurn = gal.Turn + (int)(s.StructureType.TurnsToActivate * (GlobalConst.StructureIngameDisableTimeMult - 1)); var ev = Global.CreateEvent("{0} has been disabled on {1} planet {2}. {3}", s.StructureType.Name, planet.Faction, planet, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } } } } else { // attacker won disable all foreach (var s in planet.PlanetStructures.Where(x => x.StructureType.IsIngameDestructible)) { s.IsActive = false; s.ActivatedOnTurn = gal.Turn + (int)(s.StructureType.TurnsToActivate * (GlobalConst.StructureIngameDisableTimeMult - 1)); } // destroy structures by battle (usually defenses) foreach (PlanetStructure s in planet.PlanetStructures.Where(x => x.StructureType.BattleDeletesThis).ToList()) planet.PlanetStructures.Remove(s); var ev = Global.CreateEvent("All structures have been disabled on {0} planet {1}. {2}", planet.Faction, planet, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } db.SaveChanges(); gal.DecayInfluence(); gal.SpreadInfluence(); // process faction energies foreach (var fac in db.Factions.Where(x => !x.IsDeleted)) fac.ProcessEnergy(gal.Turn); // process production gal.ProcessProduction(); // process treaties foreach (var tr in db.FactionTreaties.Where(x => x.TreatyState == TreatyState.Accepted || x.TreatyState == TreatyState.Suspended)) { if (tr.ProcessTrade(false)) { tr.TreatyState = TreatyState.Accepted; if (tr.TurnsTotal != null) { tr.TurnsRemaining--; if (tr.TurnsRemaining <= 0) { tr.TreatyState = TreatyState.Invalid; db.FactionTreaties.DeleteOnSubmit(tr); } } } else tr.TreatyState = TreatyState.Suspended; } // burn extra energy foreach (var fac in db.Factions.Where(x => !x.IsDeleted)) fac.ConvertExcessEnergyToMetal(); int? oldOwner = planet.OwnerAccountID; gal.Turn++; db.SaveChanges(); db = new ZkDataContext(); // is this needed - attempt to fix setplanetownersbeing buggy PlanetwarsController.SetPlanetOwners(db, sb); gal = db.Galaxies.Single(x => x.IsDefault); planet = gal.Planets.Single(x => x.Resource.InternalName == mapName); if (planet.OwnerAccountID != oldOwner && planet.OwnerAccountID != null) { text.AppendFormat("Congratulations!! Planet {0} was conquered by {1} !! {3}/PlanetWars/Planet/{2}\n", planet.Name, planet.Account.Name, planet.PlanetID, GlobalConst.BaseSiteUrl); } try { // store history foreach (Planet p in gal.Planets) { db.PlanetOwnerHistories.InsertOnSubmit(new PlanetOwnerHistory { PlanetID = p.PlanetID, OwnerAccountID = p.OwnerAccountID, OwnerClanID = p.OwnerAccountID != null ? p.Account.ClanID : null, OwnerFactionID = p.OwnerFactionID, Turn = gal.Turn }); } db.SubmitChanges(); } catch (Exception ex) { Trace.TraceError(ex.ToString()); text.AppendLine("error saving history: " + ex); } //rotate map if (GlobalConst.RotatePWMaps) { db = new ZkDataContext(); gal = db.Galaxies.Single(x => x.IsDefault); planet = gal.Planets.Single(x => x.Resource.InternalName == mapName); var mapList = db.Resources.Where(x => x.MapPlanetWarsIcon != null && x.Planets.Where(p => p.GalaxyID == gal.GalaxyID).Count() == 0 && x.FeaturedOrder != null && x.ResourceID != planet.MapResourceID && x.MapWaterLevel == planet.Resource.MapWaterLevel).ToList(); if (mapList.Count > 0) { int r = new Random().Next(mapList.Count); int resourceID = mapList[r].ResourceID; Resource newMap = db.Resources.Single(x => x.ResourceID == resourceID); text.AppendLine(String.Format("Map cycler - {0} maps found, selected map {1} to replace map {2}", mapList.Count, newMap.InternalName, planet.Resource.InternalName)); planet.Resource = newMap; gal.IsDirty = true; } else { text.AppendLine("Map cycler - no maps found"); } db.SaveChanges(); } }
public static MvcHtmlString PrintBattle(this HtmlHelper helper, SpringBattle battle, bool? isVictory = null) { var url = Global.UrlHelper(); var icon = ""; if (isVictory == true) icon = "battlewon.png"; else if (isVictory == null) icon = "spec.png"; else icon = "battlelost.png"; icon = string.Format("<img src='/img/battles/{0}' class='vcenter' />", icon); if (battle.IsMission) icon += " <img src='/img/battles/mission.png' alt='Mission' class='vcenter' />"; if (battle.HasBots) icon += " <img src='/img/battles/robot.png' alt='Bots' class='vcenter' />"; if (battle.BattleType == "Multiplayer") icon += " <img src='/img/battles/multiplayer.png' alt='Multiplayer' class='vcenter' />"; else if (battle.BattleType == "Singleplayer") icon += " <img src='/img/battles/singleplayer.png' alt='Singleplayer' class='vcenter' />"; return new MvcHtmlString(string.Format("<span><a href='{0}'>{4} B{1}</a> {2} on {3}</span>", url.Action("Detail", "Battles", new { id = battle.SpringBattleID }), battle.SpringBattleID, battle.PlayerCount, PrintMap(helper, battle.ResourceByMapResourceID.InternalName), icon)); }
public static string SubmitSpringBattleResult(BattleContext context, string password, BattleResult result, List<BattlePlayerResult> players, List<string> extraData) { try { Account acc = AuthServiceClient.VerifyAccountPlain(context.AutohostName, password); if (acc == null) throw new Exception("Account name or password not valid"); AutohostMode mode = context.GetMode(); var db = new ZkDataContext(); if (extraData == null) extraData = new List<string>(); var sb = new SpringBattle { HostAccountID = acc.AccountID, Duration = result.Duration, EngineGameID = result.EngineBattleID, MapResourceID = db.Resources.Single(x => x.InternalName == result.Map).ResourceID, ModResourceID = db.Resources.Single(x => x.InternalName == result.Mod).ResourceID, HasBots = result.IsBots, IsMission = result.IsMission, PlayerCount = players.Count(x => !x.IsSpectator), StartTime = result.StartTime, Title = result.Title, ReplayFileName = result.ReplayName, EngineVersion = result.EngineVersion, }; db.SpringBattles.InsertOnSubmit(sb); foreach (BattlePlayerResult p in players) { sb.SpringBattlePlayers.Add(new SpringBattlePlayer { AccountID = db.Accounts.First(x => x.AccountID == p.LobbyID).AccountID, AllyNumber = p.AllyNumber, CommanderType = p.CommanderType, IsInVictoryTeam = p.IsVictoryTeam, IsSpectator = p.IsSpectator, LoseTime = p.LoseTime }); } db.SubmitChanges(); // awards foreach (string line in extraData.Where(x => x.StartsWith("award"))) { string[] partsSpace = line.Substring(6).Split(new[] { ' ' }, 3); string name = partsSpace[0]; string awardType = partsSpace[1]; string awardText = partsSpace[2]; SpringBattlePlayer player = sb.SpringBattlePlayers.FirstOrDefault(x => x.Account.Name == name); if (player != null) { db.AccountBattleAwards.InsertOnSubmit(new AccountBattleAward { AccountID = player.AccountID, SpringBattleID = sb.SpringBattleID, AwardKey = awardType, AwardDescription = awardText }); } } var text = new StringBuilder(); bool isPlanetwars = false; if (mode == AutohostMode.Planetwars && sb.SpringBattlePlayers.Count(x => !x.IsSpectator) >= 2 && sb.Duration >= GlobalConst.MinDurationForPlanetwars) { // test that factions are not intermingled (each faction only has one ally number) - if they are it wasnt actually PW balanced if ( sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.Account.Faction != null) .GroupBy(x => x.Account.Faction) .All(grp => grp.Select(x => x.AllyNumber).Distinct().Count() < 2)) { isPlanetwars = true; List<int> winnerTeams = sb.SpringBattlePlayers.Where(x => x.IsInVictoryTeam && !x.IsSpectator).Select(x => x.AllyNumber).Distinct().ToList(); int? winNum = null; if (winnerTeams.Count == 1) { winNum = winnerTeams[0]; if (winNum > 1) { winNum = null; text.AppendLine("ERROR: Invalid winner"); } } PlanetWarsTurnHandler.EndTurn(result.Map, extraData, db, winNum, sb.SpringBattlePlayers.Where(x => !x.IsSpectator).Select(x => x.Account).ToList(), text, sb, sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.AllyNumber == 0).Select(x => x.Account).ToList()); Global.PlanetWarsMatchMaker.RemoveFromRunningBattles(context.AutohostName); } else { text.AppendLine("Battle wasn't PlanetWars balanced, it counts as a normal team game only"); } } bool noElo = (extraData.FirstOrDefault(x => x.StartsWith("noElo", true, System.Globalization.CultureInfo.CurrentCulture)) != null); try { db.SubmitChanges(); } catch (System.Data.Linq.DuplicateKeyException ex) { Trace.TraceError(ex.ToString()); } Dictionary<int, int> orgLevels = sb.SpringBattlePlayers.Select(x => x.Account).ToDictionary(x => x.AccountID, x => x.Level); sb.CalculateAllElo(noElo, isPlanetwars); foreach (var u in sb.SpringBattlePlayers.Where(x => !x.IsSpectator)) u.Account.CheckLevelUp(); db.SubmitAndMergeChanges(); try { foreach (Account a in sb.SpringBattlePlayers.Where(x => !x.IsSpectator).Select(x => x.Account)) Global.Server.PublishAccountUpdate(a); } catch (Exception ex) { Trace.TraceError("error updating extension data: {0}", ex); } foreach (Account account in sb.SpringBattlePlayers.Select(x => x.Account)) { if (account.Level > orgLevels[account.AccountID]) { try { string message = string.Format("Congratulations {0}! You just leveled up to level {1}. {3}/Users/Detail/{2}", account.Name, account.Level, account.AccountID, GlobalConst.BaseSiteUrl); //text.AppendLine(message); Global.Server.GhostPm(account.Name, message); } catch (Exception ex) { Trace.TraceError("Error sending level up lobby message: {0}", ex); } } } text.AppendLine(string.Format("BATTLE DETAILS AND REPLAY ----> {1}/Battles/Detail/{0} <-----", sb.SpringBattleID, GlobalConst.BaseSiteUrl)); /* // create debriefing room, join players there and output message string channelName = "B" + sb.SpringBattleID; var joinplayers = new List<string>(); joinplayers.AddRange(context.Players.Select(x => x.Name)); // add those who were there at start joinplayers.AddRange(sb.SpringBattlePlayers.Select(x => x.Account.Name)); // add those who played Battle bat = Global.Server.Battles.Values.FirstOrDefault(x => x.Founder.Name == context.AutohostName); // add those in lobby atm var conf = context.GetConfig(); if (bat != null && (conf == null || conf.MinToJuggle == null)) // if not qm room do not join those who are in battle { List<string> inbatPlayers = bat.Users.Keys.ToList(); joinplayers.RemoveAll(x => inbatPlayers.Contains(x)); } foreach (string jp in joinplayers.Distinct().Where(x => x != context.AutohostName)) tas.ForceJoinChannel(jp, channelName); tas.JoinChannel(channelName); // join nightwatch and say it tas.Say(SayPlace.Channel, channelName, text.ToString(), true); tas.LeaveChannel(channelName);*/ //text.Append(string.Format("Debriefing in #{0} - zk://chat/channel/{0} ", channelName)); return text.ToString(); } catch (Exception ex) { Trace.TraceError(ex.ToString()); return ex.ToString(); } }
private static void ProcessPlanetWars(Spring.SpringBattleContext result, ZkLobbyServer.ZkLobbyServer server, SpringBattle sb, ZkDataContext db, StringBuilder text) { if (result.LobbyStartContext.Mode != AutohostMode.Planetwars || sb.PlayerCount < 2 || sb.Duration >= GlobalConst.MinDurationForPlanetwars) return; List<int> winnerTeams = sb.SpringBattlePlayers.Where(x => x.IsInVictoryTeam && !x.IsSpectator).Select(x => x.AllyNumber).Distinct().ToList(); int? winNum = null; if (winnerTeams.Count == 1) { winNum = winnerTeams[0]; if (winNum > 1) winNum = null; } PlanetWarsTurnHandler.EndTurn(result.LobbyStartContext.Map, result.OutputExtras, db, winNum, sb.SpringBattlePlayers.Where(x => !x.IsSpectator).Select(x => x.Account).ToList(), text, sb, sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.AllyNumber == 0).Select(x => x.Account).ToList(), server.PlanetWarsEventCreator); // TODO HACK Global.PlanetWarsMatchMaker.RemoveFromRunningBattles(context.AutohostName); }
private static void ProcessExtras(List<string> extras, SpringBattle sb, ZkDataContext db) { // awards foreach (string line in extras.Where(x => x?.StartsWith("award") == true)) { string[] partsSpace = line.Substring(6).Split(new[] { ' ' }, 3); string name = partsSpace[0]; string awardType = partsSpace[1]; string awardText = partsSpace[2]; // prevent hax: tourney cups and event coins are never given automatically if (awardType != null && (awardType == "gold" || awardType == "silver" || awardType == "bronze")) continue; if (awardType != null && (awardType == "goldcoin" || awardType == "silvercoin" || awardType == "bronzecoin")) continue; SpringBattlePlayer player = sb.SpringBattlePlayers.FirstOrDefault(x => x.Account?.Name == name); if (player != null) { db.AccountBattleAwards.InsertOnSubmit(new AccountBattleAward { AccountID = player.AccountID, SpringBattleID = sb.SpringBattleID, AwardKey = awardType, AwardDescription = awardText }); } } // chatlogs foreach (string line in extras.Where(x => x?.StartsWith("CHATLOG") == true)) { string[] partsSpace = line.Substring(8).Split(new[] { ' ' }, 2); string name = partsSpace[0]; string chatlog = partsSpace[1]; SpringBattlePlayer player = sb.SpringBattlePlayers.FirstOrDefault(x => x.Account?.Name == name); if (player != null) { db.LobbyChatHistories.InsertOnSubmit(new LobbyChatHistory { IsEmote = false, SayPlace = SayPlace.Game, User = name, Ring = false, Target = "B" + sb.SpringBattleID, Text = chatlog, Time = DateTime.UtcNow }); } } }
private static SpringBattle SaveSpringBattle(Spring.SpringBattleContext result, ZkDataContext db) { var sb = new SpringBattle { HostAccountID = Account.AccountByName(db, result.LobbyStartContext.FounderName)?.AccountID, Mode = result.LobbyStartContext.Mode, Duration = result.Duration, EngineGameID = result.EngineBattleID, MapResourceID = db.Resources.Single(x => x.InternalName == result.LobbyStartContext.Map).ResourceID, ModResourceID = db.Resources.Single(x => x.InternalName == result.LobbyStartContext.Mod).ResourceID, HasBots = result.LobbyStartContext.Bots.Any(), IsMission = result.LobbyStartContext.IsMission, PlayerCount = result.ActualPlayers.Count(x => !x.IsSpectator), StartTime = result.StartTime, Title = result.LobbyStartContext.Title, ReplayFileName = result.ReplayName, EngineVersion = result.LobbyStartContext.EngineVersion, IsMatchMaker = result.LobbyStartContext.IsMatchMakerGame }; db.SpringBattles.InsertOnSubmit(sb); foreach (BattlePlayerResult p in result.ActualPlayers) { var account = Account.AccountByName(db, p.Name); if (account != null) { sb.SpringBattlePlayers.Add(new SpringBattlePlayer { Account = account, AccountID = account.AccountID, AllyNumber = p.AllyNumber, IsInVictoryTeam = p.IsVictoryTeam, IsSpectator = p.IsSpectator, LoseTime = p.LoseTime }); } } db.SaveChanges(); return db.SpringBattles.FirstOrDefault(x => x.SpringBattleID == sb.SpringBattleID); // reselect from db to get proper lazy proxies }
private static void ProcessElos(SpringBattleContext result, ZkLobbyServer.ZkLobbyServer server, ZkDataContext db, SpringBattle sb) { bool noElo = result.OutputExtras.Any(x => x?.StartsWith("noElo", true, System.Globalization.CultureInfo.CurrentCulture) == true); sb.CalculateAllElo(noElo); foreach (var u in sb.SpringBattlePlayers.Where(x => !x.IsSpectator)) u.Account.CheckLevelUp(); db.SaveChanges(); try { foreach (Account a in sb.SpringBattlePlayers.Where(x => !x.IsSpectator).Select(x => x.Account)) server.PublishAccountUpdate(a); } catch (Exception ex) { Trace.TraceError("error updating extension data: {0}", ex); } }