public ActionResult BombPlanet(int planetID, int count, bool?useWarp) { var db = new ZkDataContext(); Account acc = db.Accounts.Single(x => x.AccountID == Global.AccountID); if (acc.Faction == null) { return(Content("Join some faction first")); } Planet planet = db.Planets.Single(x => x.PlanetID == planetID); bool accessible = (useWarp == true) ? planet.CanBombersWarp(acc.Faction) : planet.CanBombersAttack(acc.Faction); if (!accessible) { return(Content("You cannot attack here")); } if (Global.Server.GetPlanetBattles(planet).Any(x => x.IsInGame)) { return(Content("Battle in progress on the planet, cannot bomb planet")); } bool selfbomb = acc.FactionID == planet.OwnerFactionID; if (count < 0) { count = 0; } double avail = Math.Min(count, acc.GetBombersAvailable()); if (useWarp == true) { avail = Math.Min(acc.GetWarpAvailable(), avail); } var capa = acc.GetBomberCapacity(); if (avail > capa) { return(Content("Too many bombers - the fleet limit is " + capa)); } if (avail > 0) { double defense = planet.PlanetStructures.Where(x => x.IsActive).Sum(x => x.StructureType.EffectBomberDefense) ?? 0; double effective = avail; if (!selfbomb) { effective = effective - defense; } if (effective <= 0) { return(Content("Enemy defenses completely block your ships")); } acc.SpendBombers(avail); if (useWarp == true) { acc.SpendWarps(avail); } var r = new Random(); double strucKillChance = !selfbomb ? effective * GlobalConst.BomberKillStructureChance : 0; int strucKillCount = (int)Math.Floor(strucKillChance + r.NextDouble()); double ipKillChance = effective * GlobalConst.BomberKillIpChance; int ipKillCount = (int)Math.Floor(ipKillChance + r.NextDouble()); List <PlanetStructure> structs = planet.PlanetStructures.Where(x => x.StructureType.IsBomberDestructible).ToList(); var bombed = new List <StructureType>(); while (structs.Count > 0 && strucKillCount > 0) { strucKillCount--; PlanetStructure s = structs[r.Next(structs.Count)]; bombed.Add(s.StructureType); structs.Remove(s); db.PlanetStructures.DeleteOnSubmit(s); } double ipKillAmmount = ipKillCount * GlobalConst.BomberKillIpAmount; if (ipKillAmmount > 0) { var influenceDecayMin = planet.PlanetStructures.Where(x => x.IsActive && x.StructureType.EffectPreventInfluenceDecayBelow != null).Select(x => x.StructureType.EffectPreventInfluenceDecayBelow).OrderByDescending(x => x).FirstOrDefault() ?? 0; foreach (PlanetFaction pf in planet.PlanetFactions.Where(x => x.FactionID != acc.FactionID)) { pf.Influence -= ipKillAmmount; if (pf.Influence < 0) { pf.Influence = 0; } // prevent bombing below influence decaymin for owner - set by active structures if (pf.FactionID == planet.OwnerFactionID && pf.Influence < influenceDecayMin) { pf.Influence = influenceDecayMin; } } } var args = new List <object> { acc, acc.Faction, !selfbomb ? planet.Faction : null, planet, avail, defense, useWarp == true ? "They attacked by warp. " : "", ipKillAmmount }; args.AddRange(bombed); string str; if (selfbomb) { str = "{0} of {1} bombed own planet {3} using {4} bombers against {5} defenses. {6}Ground armies lost {7} influence"; } else { str = "{0} of {1} bombed {2} planet {3} using {4} bombers against {5} defenses. {6}Ground armies lost {7} influence"; } if (bombed.Count > 1) { str += " and "; int counter = 8; foreach (var b in bombed) { str += "{" + counter + "}" + ", "; counter++; } str += " were destroyed."; } else if (bombed.Count == 1) { str += " and {8} was destroyed."; } else { str += "."; } db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent(str, args.ToArray())); } db.SaveChanges(); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator()); return(RedirectToAction("Planet", new { id = planetID })); }
private static SpringBattle SaveSpringBattle(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 = Path.GetFileName(result.ReplayName), EngineVersion = result.LobbyStartContext.EngineVersion, IsMatchMaker = result.LobbyStartContext.IsMatchMakerGame, ApplicableRatings = 0, }; db.SpringBattles.InsertOnSubmit(sb); // store players 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 }); } } // store bots var victoryAllyID = result.ActualPlayers.Where(x => x.IsVictoryTeam).Select(x => (int?)x.AllyNumber).FirstOrDefault() ?? -1; if (victoryAllyID == -1) { victoryAllyID = (result.ActualPlayers.Min(x => (int?)x.AllyNumber) ?? -1) + 1; // no player won, its likely to be next lowes team (stupid hack needed) } foreach (var bot in result.LobbyStartContext.Bots) { sb.SpringBattleBots.Add(new SpringBattleBot() { AllyNumber = bot.AllyID, BotAI = bot.BotAI, BotName = bot.BotName, IsInVictoryTeam = bot.AllyID == victoryAllyID }); } db.SaveChanges(); return(db.SpringBattles.FirstOrDefault(x => x.SpringBattleID == sb.SpringBattleID)); // reselect from db to get proper lazy proxies }
public async Task Process(SetAccountRelation rel) { if (!IsLoggedIn) { return; } if (string.IsNullOrEmpty(rel.TargetName) && string.IsNullOrEmpty(rel.SteamID)) { return; } using (var db = new ZkDataContext()) { ulong steamId = 0; var srcAccount = db.Accounts.Find(User.AccountID); ulong.TryParse(rel.SteamID, out steamId); var trgtAccount = Account.AccountByName(db, rel.TargetName) ?? db.Accounts.FirstOrDefault(x => x.SteamID == steamId); if (trgtAccount == null) { if (!string.IsNullOrEmpty(rel.TargetName)) { await Respond("No such account found"); // only warn if name is set and not just steam id } return; } var friendAdded = false; var entry = srcAccount.RelalationsByOwner.FirstOrDefault(x => x.TargetAccountID == trgtAccount.AccountID); if ((rel.Relation == Relation.None) && (entry != null)) { db.AccountRelations.Remove(entry); } if (rel.Relation != Relation.None) { if (entry == null) { if (rel.Relation == Relation.Friend) { friendAdded = true; } entry = new AccountRelation() { Owner = srcAccount, Target = trgtAccount, Relation = rel.Relation }; srcAccount.RelalationsByOwner.Add(entry); } else { entry.Relation = rel.Relation; } } db.SaveChanges(); ConnectedUser targetConnectedUser; if (server.ConnectedUsers.TryGetValue(trgtAccount.Name, out targetConnectedUser)) { targetConnectedUser.LoadFriendsIgnores(); // update partner's mutual lists if (friendAdded) // friend added, sync new friend to me (user, battle and channels) { await server.TwoWaySyncUsers(Name, new List <string>() { targetConnectedUser.Name }); foreach (var chan in server.Channels.Values.Where( x => (x != null) && x.Users.ContainsKey(Name) && x.Users.ContainsKey(targetConnectedUser.Name))) { await SendCommand(new ChannelUserAdded() { ChannelName = chan.Name, UserName = targetConnectedUser.Name }); } } } LoadFriendsIgnores(); await SendCommand(new FriendList() { Friends = FriendEntries.ToList() }); await SendCommand(new IgnoreList() { Ignores = Ignores.ToList() }); } }
public ActionResult VotePost(int forumPostID, int delta) { var db = new ZkDataContext(); var myAcc = Global.Account; var penalty = Punishment.GetActivePunishment(Global.AccountID, Request.UserHostAddress, 0, null, x => x.BanForum); if (penalty != null) { return(Content(string.Format("You cannot vote while banned from forum!\nExpires: {0} UTC\nReason: {1}", penalty.BanExpires, penalty.Reason))); } if (myAcc.Level < GlobalConst.MinLevelForForumVote) { return(Content(string.Format("You cannot vote until you are level {0} or higher", GlobalConst.MinLevelForForumVote))); } if ((Global.Account.ForumTotalUpvotes - Global.Account.ForumTotalDownvotes) < GlobalConst.MinNetKarmaToVote) { return(Content("Your net karma is too low to vote")); } if (delta > 1) { delta = 1; } else if (delta < -1) { delta = -1; } var post = db.ForumPosts.First(x => x.ForumPostID == forumPostID); var author = post.Account; if (author.AccountID == Global.AccountID) { return(Content("Cannot vote for your own posts")); } if (myAcc.VotesAvailable <= 0) { return(Content("Out of votes")); } var existingVote = db.AccountForumVotes.SingleOrDefault(x => x.ForumPostID == forumPostID && x.AccountID == Global.AccountID); if (existingVote != null) // clear existing vote { var oldDelta = existingVote.Vote; // reverse vote effects if (oldDelta > 0) { author.ForumTotalUpvotes = author.ForumTotalUpvotes - oldDelta; post.Upvotes = post.Upvotes - oldDelta; } else if (oldDelta < 0) { author.ForumTotalDownvotes = author.ForumTotalDownvotes + oldDelta; post.Downvotes = post.Downvotes + oldDelta; } db.AccountForumVotes.DeleteOnSubmit(existingVote); } if (delta > 0) { author.ForumTotalUpvotes = author.ForumTotalUpvotes + delta; post.Upvotes = post.Upvotes + delta; } else if (delta < 0) { author.ForumTotalDownvotes = author.ForumTotalDownvotes - delta; post.Downvotes = post.Downvotes - delta; } if (delta != 0) { var voteEntry = new AccountForumVote { AccountID = Global.AccountID, ForumPostID = forumPostID, Vote = delta }; db.AccountForumVotes.InsertOnSubmit(voteEntry); myAcc.VotesAvailable--; } db.SaveChanges(); return(RedirectToAction("Thread", new { id = post.ForumThreadID, postID = forumPostID })); }
/// <summary> /// Process planet wars turn /// </summary> /// <param name="mapName"></param> /// <param name="extraData"></param> /// <param name="db"></param> /// <param name="winnerSide">0 = first team wins, 1 = second team wins</param> /// <param name="players"></param> /// <param name="text"></param> /// <param name="sb"></param> /// public static void ResolveBattleOutcome(string mapName, List <string> extraData, ZkDataContext db, int?winnerSide, List <Account> players, List <Account> firstSidePlayers, StringBuilder text, SpringBattle sb, IPlanetwarsEventCreator eventCreator, ZkLobbyServer.ZkLobbyServer server) { 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); var hqStructure = db.StructureTypes.FirstOrDefault(x => x.EffectDisconnectedMetalMalus != null || x.EffectDistanceMetalBonusMax != null); text.AppendFormat("Battle on {1}/PlanetWars/Planet/{0} has ended\n", planet.PlanetID, GlobalConst.BaseSiteUrl); bool firstFactionWon; bool wasFirstCcDestroyed = false; bool wasSecondCcDestroyed = false; if (winnerSide != null) { if (winnerSide == 0) { firstFactionWon = true; } else { firstFactionWon = false; } wasFirstCcDestroyed = extraData.Any(x => x.StartsWith("hqkilled,0")); wasSecondCcDestroyed = 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; } Faction firstFaction = firstSidePlayers.Where(x => x.Faction != null).Select(x => x.Faction).First(); var secondSidePlayers = players.Where(x => x.FactionID != firstFaction.FactionID && x.FactionID != null).ToList(); Faction secondFaction = null; if (secondSidePlayers.Any()) { secondFaction = secondSidePlayers.Where(x => x.Faction != null).Select(x => x.Faction).First(); } Faction winningFaction; Faction losingFaction; bool ccDestroyed = false; if (firstFactionWon) { winningFaction = firstFaction; losingFaction = secondFaction; ccDestroyed = wasFirstCcDestroyed; } else { winningFaction = secondFaction; losingFaction = firstFaction; ccDestroyed = wasSecondCcDestroyed; } if (winningFaction == null) { text.AppendFormat("Winning team had no players!"); Trace.TraceError("PW battle where the winner had no players!", sb != null ? sb.SpringBattleID : (int?)null); return; } double baseInfluence = GlobalConst.BaseInfluencePerBattle; double influenceChange = baseInfluence; double loserInfluence = 0; double ipMultiplier = 1; string influenceReport = ""; string ipReason; bool reducedEnemyInfluence = false; bool flippedDominance = false; bool planetConquered = false; if (ccDestroyed) { ipMultiplier = GlobalConst.PlanetWarsLostCcMultiplier; ipReason = "due to winning but losing Command Centre"; } else { ipReason = "due to winning flawlessly"; } influenceChange = (influenceChange) * ipMultiplier; if (influenceChange < 0) { influenceChange = 0; } influenceChange = Math.Floor(influenceChange * 100) / 100; PlanetFaction entry = planet.PlanetFactions.FirstOrDefault(); if (entry == null) { entry = new PlanetFaction { Faction = winningFaction, Planet = planet, }; planet.PlanetFactions.Add(entry); } // if non-winner currently dominates planet if (entry.Faction != winningFaction) { loserInfluence = entry.Influence; // if win is insufficient to change this if (loserInfluence >= influenceChange) { reducedEnemyInfluence = true; entry.Influence -= influenceChange; } else // flip dominance { flippedDominance = true; planet.PlanetFactions.Remove(entry); entry = new PlanetFaction { Faction = winningFaction, Planet = planet, }; planet.PlanetFactions.Add(entry); entry.Influence += (influenceChange - loserInfluence); if (entry.Influence >= GlobalConst.PlanetWarsMaximumIP) { entry.Influence = GlobalConst.PlanetWarsMaximumIP; planetConquered = true; } } } else // increase winner's existing dominance { if (entry.Influence < GlobalConst.PlanetWarsMaximumIP) { entry.Influence += influenceChange; if (entry.Influence >= GlobalConst.PlanetWarsMaximumIP) { entry.Influence = GlobalConst.PlanetWarsMaximumIP; planetConquered = true; } } } string contestReport = ""; int newContested = 0; if (planetConquered) { foreach (Link link in planet.LinksByPlanetID1.Union(planet.LinksByPlanetID2).ToList()) { Planet otherPlanet = link.PlanetID1 == planet.PlanetID ? link.PlanetByPlanetID2 : link.PlanetByPlanetID1; PlanetFaction otherPlanetFaction = otherPlanet.PlanetFactions.FirstOrDefault(); if (otherPlanetFaction.Faction != winningFaction && otherPlanetFaction.Influence > GlobalConst.BreakthroughInfluence) { otherPlanetFaction.Influence = GlobalConst.BreakthroughInfluence; if (newContested > 0) { contestReport += ", "; } contestReport += otherPlanet.Name; newContested++; } } } if (newContested > 0) { contestReport = "Adjacent planets now contested: " + contestReport + "."; } // Check all planets to see if they are contested by a single faction string controlReport = ""; int newControlled = 0; foreach (Planet p1 in gal.Planets) { List <Faction> l = GetContestingFactions(p1); if (l.Count() == 1) { Faction f = l.FirstOrDefault(); // this faction should be made dominant if it is not already PlanetFaction cEntry = p1.PlanetFactions.FirstOrDefault(); if (cEntry.Faction != f) { p1.PlanetFactions.Remove(cEntry); cEntry = new PlanetFaction { Faction = f, Planet = p1, Influence = 0 }; p1.PlanetFactions.Add(cEntry); } if (cEntry.Influence != GlobalConst.PlanetWarsMaximumIP) { cEntry.Influence = GlobalConst.PlanetWarsMaximumIP; if (newControlled > 0) { controlReport += ", "; } controlReport += p1.Name; newControlled++; } } } if (newControlled > 0) { controlReport = "Planets automatically controlled: " + controlReport + "."; } // Update actual *control* of all planets PlanetWarsTurnHandler.SetPlanetOwners(eventCreator, db, sb); try { if (planetConquered) { influenceReport = String.Format("{0} conquered the planet, gained {1} influence ({2}% {3} of {4})", winningFaction.Shortcut, influenceChange, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base"); } else { if (reducedEnemyInfluence) { influenceReport = String.Format("{0} reduced influence of {1} by {2} ({3}% {4} of {5}); {6} has {7} influence remaining on {8}", winningFaction.Shortcut, (losingFaction == null) ? "opposing faction" : losingFaction.Shortcut, influenceChange, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", entry.Faction, entry.Influence, entry.Planet); } else { if (flippedDominance) { influenceReport = String.Format("{0} took dominance from {1} and gained {2} influence ({3}% {4} of {5}); {6} now has {7} influence on {8}", winningFaction.Shortcut, (losingFaction == null) ? "opposing faction" : losingFaction.Shortcut, influenceChange, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", entry.Faction, entry.Influence, entry.Planet); } else { influenceReport = String.Format("{0} gained {1} influence ({2}% {3} of {4}); {5} now has {6} influence on {7} ", winningFaction.Shortcut, influenceChange, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", entry.Faction, entry.Influence, entry.Planet); } } } } catch (Exception ex) { Trace.TraceError(ex.ToString()); } // paranoia! try { var mainEvent = eventCreator.CreateEvent("{0} defeated {1} on {2} in {3}. {4}. {5} {6}", winningFaction, (losingFaction == null) ? "opposing faction" : losingFaction.Shortcut, planet, (sb == null) ? "no battle" : string.Format("B{0}", sb.SpringBattleID), influenceReport, contestReport, controlReport ); db.Events.InsertOnSubmit(mainEvent); text.AppendLine(mainEvent.PlainText); } catch (Exception ex) { Trace.TraceError(ex.ToString()); } db.SaveChanges(); /*gal.Turn++; * db.SaveChanges(); * * db = new ZkDataContext(); // is this needed - attempt to fix setplanetownersbeing buggy * SetPlanetOwners(eventCreator, db, sb != null ? db.SpringBattles.Find(sb.SpringBattleID) : null); * gal = db.Galaxies.Single(x => x.IsDefault);*/ }
public async Task <LoginCheckerResponse> DoLogin(Login login, string ip) { await semaphore.WaitAsync(); try { var userID = login.UserID; var lobbyVersion = login.LobbyVersion; using (var db = new ZkDataContext()) { if (!VerifyIp(ip)) { return(new LoginCheckerResponse(LoginResponse.Code.BannedTooManyConnectionAttempts)); } SteamWebApi.PlayerInfo info = null; if (!string.IsNullOrEmpty(login.SteamAuthToken)) { info = await server.SteamWebApi.VerifyAndGetAccountInformation(login.SteamAuthToken); if (info == null) { LogIpFailure(ip); return(new LoginCheckerResponse(LoginResponse.Code.InvalidSteamToken)); } } Account accBySteamID = null; Account accByLogin = null; if (info != null) { accBySteamID = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.SteamID == info.steamid); } if (!string.IsNullOrEmpty(login.Name)) { var loginToUpper = login.Name.ToUpper(); accByLogin = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name == login.Name) ?? db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name.ToUpper() == loginToUpper); } if (accBySteamID == null) { if (accByLogin == null) { LogIpFailure(ip); if (!string.IsNullOrEmpty(login.Name)) { return(new LoginCheckerResponse(LoginResponse.Code.InvalidName)); } else { return(new LoginCheckerResponse(LoginResponse.Code.SteamNotLinkedAndLoginMissing)); } } if (string.IsNullOrEmpty(login.PasswordHash) || !accByLogin.VerifyPassword(login.PasswordHash)) { LogIpFailure(ip); return(new LoginCheckerResponse(LoginResponse.Code.InvalidPassword)); } } var acc = accBySteamID ?? accByLogin; var ret = new LoginCheckerResponse(LoginResponse.Code.Ok); ret.LoginResponse.Name = acc.Name; var user = ret.User; acc.Country = ResolveCountry(ip); if ((acc.Country == null) || string.IsNullOrEmpty(acc.Country)) { acc.Country = "??"; } acc.LobbyVersion = lobbyVersion; acc.LastLogin = DateTime.UtcNow; if (info != null) { if (db.Accounts.Any(x => x.SteamID == info.steamid && x.Name != acc.Name)) { LogIpFailure(ip); return(new LoginCheckerResponse(LoginResponse.Code.SteamLinkedToDifferentAccount)); } acc.SteamID = info.steamid; acc.SteamName = info.personaname; } user.LobbyVersion = login.LobbyVersion; user.IpAddress = ip; UpdateUserFromAccount(user, acc); LogIP(db, acc, ip); LogUserID(db, acc, userID); db.SaveChanges(); ret.LoginResponse.SessionToken = Guid.NewGuid().ToString(); // create session token var banPenalty = Punishment.GetActivePunishment(acc.AccountID, ip, userID, x => x.BanLobby); if (banPenalty != null) { return (BlockLogin( $"Banned until {banPenalty.BanExpires} (match to {banPenalty.AccountByAccountID.Name}), reason: {banPenalty.Reason}", acc, ip, userID)); } if (!acc.HasVpnException && GlobalConst.VpnCheckEnabled) { if (HasVpn(ip, acc, db)) { return(BlockLogin("Connection using proxy or VPN is not allowed! (You can ask for exception)", acc, ip, userID)); } } return(ret); } } finally { semaphore.Release(); } }
public ActionResult SubmitPost( int?threadID, int?categoryID, int?resourceID, int?missionID, int?springBattleID, int?clanID, int?planetID, string text, string title, string wikiKey, int?forumPostID, bool?isMinorEdit) { if (threadID == null && missionID == null && resourceID == null && springBattleID == null && clanID == null && planetID == null && forumPostID == null && string.IsNullOrWhiteSpace(title)) { return(Content("Cannot post new thread with blank title")); } if (string.IsNullOrWhiteSpace(text)) { return(Content("Please type some text :)")); } var penalty = Punishment.GetActivePunishment(Global.AccountID, Request.UserHostAddress, 0, null, x => x.BanForum); if (penalty != null) { return (Content( string.Format("You cannot post while banned from forum!\nExpires: {0} UTC\nReason: {1}", penalty.BanExpires, penalty.Reason))); } var db = new ZkDataContext(); using (var scope = new TransactionScope()) { var thread = db.ForumThreads.SingleOrDefault(x => x.ForumThreadID == threadID); var category = thread?.ForumCategory; if (category == null && categoryID != null) { category = db.ForumCategories.FirstOrDefault(x => x.ForumCategoryID == categoryID); } string currentTitle = null; // update title if (thread != null && !string.IsNullOrEmpty(title)) { currentTitle = thread.Title; thread.Title = title; thread.WikiKey = wikiKey; } if (thread != null && planetID != null) { var planet = db.Planets.Single(x => x.PlanetID == planetID); thread.Title = "Planet " + planet.Name; } if (thread != null && clanID != null) { var clan = db.Clans.Single(x => x.ClanID == clanID); thread.Title = "Clan " + clan.ClanName; } if (thread != null && missionID != null) { var mission = db.Missions.Single(x => x.MissionID == missionID); thread.Title = "Mission " + mission.Name; } if (thread != null && resourceID != null) { var map = db.Resources.Single(x => x.ResourceID == resourceID); thread.Title = "Map " + map.InternalName; } if (threadID == null && category != null) // new thread { if (category.IsLocked) { return(Content("Thread is locked")); } if (category.ForumMode == ForumMode.Wiki) { if (string.IsNullOrEmpty(wikiKey) || !Account.IsValidLobbyName(wikiKey)) { return(Content("You need to set a valid wiki key")); } if (db.ForumThreads.Any(y => y.WikiKey == wikiKey)) { return(Content("This wiki key already exists")); } } if (string.IsNullOrEmpty(title)) { return(Content("Title cannot be empty")); } thread = new ForumThread(); thread.CreatedAccountID = Global.AccountID; thread.Title = title; thread.WikiKey = wikiKey; thread.ForumCategoryID = category.ForumCategoryID; db.ForumThreads.InsertOnSubmit(thread); } if (thread == null && resourceID != null) // non existing thread, we posted new post on map { var res = db.Resources.Single(x => x.ResourceID == resourceID); if (res.ForumThread != null) { return(Content("Double post")); } thread = new ForumThread { Title = "Map " + res.InternalName, CreatedAccountID = Global.AccountID, LastPostAccountID = Global.AccountID }; thread.ForumCategory = db.ForumCategories.FirstOrDefault(x => x.ForumMode == ForumMode.Maps); res.ForumThread = thread; db.ForumThreads.InsertOnSubmit(thread); } if (thread == null && springBattleID != null) // non existing thread, we posted new post on battle { var bat = db.SpringBattles.Single(x => x.SpringBattleID == springBattleID); if (bat.ForumThread != null) { return(Content("Double post")); } thread = new ForumThread { Title = bat.FullTitle, CreatedAccountID = Global.AccountID, LastPostAccountID = Global.AccountID }; thread.ForumCategory = db.ForumCategories.FirstOrDefault(x => x.ForumMode == ForumMode.SpringBattles); bat.ForumThread = thread; db.ForumThreads.InsertOnSubmit(thread); } if (thread == null && clanID != null) { var clan = db.Clans.Single(x => x.ClanID == clanID); if (clan.ForumThread != null) { return(Content("Double post")); } thread = new ForumThread { Title = "Clan " + clan.ClanName, CreatedAccountID = Global.AccountID, LastPostAccountID = Global.AccountID }; thread.ForumCategory = db.ForumCategories.FirstOrDefault(x => x.ForumMode == ForumMode.Clans); clan.ForumThread = thread; thread.Clan = clan; db.ForumThreads.InsertOnSubmit(thread); } if (thread == null && planetID != null) { var planet = db.Planets.Single(x => x.PlanetID == planetID); if (planet.ForumThread != null) { return(Content("Double post")); } thread = new ForumThread { Title = "Planet " + planet.Name, CreatedAccountID = Global.AccountID, LastPostAccountID = Global.AccountID }; thread.ForumCategory = db.ForumCategories.FirstOrDefault(x => x.ForumMode == ForumMode.Planets); planet.ForumThread = thread; db.ForumThreads.InsertOnSubmit(thread); } if (thread == null) { return(Content("Thread not found")); } if (thread.IsLocked && Global.Account.AdminLevel < AdminLevel.Moderator) { return(Content("Thread is locked")); } if (thread.RestrictedClanID != null && thread.RestrictedClanID != Global.Account.ClanID) { return(Content("Cannot post in this clan")); } var lastPost = thread.ForumPosts.OrderByDescending(x => x.ForumPostID).FirstOrDefault(); int?gotoPostId = null; //double post preventer if (lastPost == null || lastPost.AuthorAccountID != Global.AccountID || lastPost.Text != text || (!string.IsNullOrEmpty(title) && title != currentTitle)) { if (forumPostID != null) { var post = thread.ForumPosts.Single(x => x.ForumPostID == forumPostID); if (!post.CanEdit(Global.Account)) { throw new ApplicationException("Not authorized to edit the post"); } post.ForumPostEdits.Add( new ForumPostEdit { EditorAccountID = Global.AccountID, EditTime = DateTime.UtcNow, OriginalText = post.Text, NewText = text }); post.Text = text; } else { var p = new ForumPost { AuthorAccountID = Global.AccountID, Text = text, Created = DateTime.UtcNow }; thread.ForumPosts.Add(p); db.SaveChanges(); gotoPostId = p.ForumPostID; } if (isMinorEdit != true) { thread.LastPost = DateTime.UtcNow; thread.LastPostAccountID = Global.AccountID; } thread.PostCount = thread.ForumPosts.Count(); thread.UpdateLastRead(Global.AccountID, true, thread.LastPost); db.SaveChanges(); } scope.Complete(); if (missionID.HasValue) { return(RedirectToAction("Detail", "Missions", new { id = missionID })); } if (resourceID.HasValue) { return(RedirectToAction("Detail", "Maps", new { id = resourceID })); } if (springBattleID.HasValue) { return(RedirectToAction("Detail", "Battles", new { id = springBattleID })); } if (clanID.HasValue) { return(RedirectToAction("Detail", "Clans", new { id = clanID })); } if (planetID.HasValue) { return(RedirectToAction("Planet", "Planetwars", new { id = planetID })); } if (forumPostID.HasValue) { return(RedirectToAction("Thread", "Forum", new { id = thread.ForumThreadID, postID = forumPostID })); } return(RedirectToAction("Thread", "Forum", new { id = thread.ForumThreadID, postID = gotoPostId })); } }
public async Task<RegisterResponse> DoRegister(Register register, string ip) { if (!Account.IsValidLobbyName(register.Name)) return new RegisterResponse(RegisterResponse.Code.NameHasInvalidCharacters); if (server.ConnectedUsers.ContainsKey(register.Name)) return new RegisterResponse(RegisterResponse.Code.AlreadyConnected); if (string.IsNullOrEmpty(register.PasswordHash) && string.IsNullOrEmpty(register.SteamAuthToken)) return new RegisterResponse(RegisterResponse.Code.MissingBothPasswordAndToken); if (!VerifyIp(ip)) return new RegisterResponse(RegisterResponse.Code.BannedTooManyAttempts); var banPenalty = Punishment.GetActivePunishment(null, ip, register.UserID, register.InstallID, x => x.BanLobby); if (banPenalty != null) return new RegisterResponse(RegisterResponse.Code.Banned) {BanReason = banPenalty.Reason}; SteamWebApi.PlayerInfo info = null; if (!string.IsNullOrEmpty(register.SteamAuthToken)) { info = await server.SteamWebApi.VerifyAndGetAccountInformation(register.SteamAuthToken); if (info == null) return new RegisterResponse(RegisterResponse.Code.InvalidSteamToken); } using (var db = new ZkDataContext()) { var registerName = register.Name.ToUpper(); var existingByName = db.Accounts.FirstOrDefault(x => x.Name.ToUpper() == registerName); if (existingByName != null) { if (info != null && existingByName.SteamID == info.steamid) return new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisSteamToken); if (info == null && !string.IsNullOrEmpty(register.PasswordHash) && existingByName.VerifyPassword(register.PasswordHash)) return new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisPassword); return new RegisterResponse(RegisterResponse.Code.NameAlreadyTaken); } var acc = new Account() { Name = register.Name }; acc.SetPasswordHashed(register.PasswordHash); acc.SetName(register.Name); acc.SetAvatar(); acc.Email = register.Email; if (info != null) { var existingBySteam = db.Accounts.FirstOrDefault(x => x.SteamID == info.steamid); if (existingBySteam != null) return new RegisterResponse(RegisterResponse.Code.SteamAlreadyRegistered); acc.SteamID = info.steamid; acc.SteamName = info.personaname; } else if (string.IsNullOrEmpty(register.PasswordHash)) { return new RegisterResponse(RegisterResponse.Code.InvalidPassword); } LogIP(db, acc, ip); LogUserID(db, acc, register.UserID, register.InstallID); db.Accounts.Add(acc); db.SaveChanges(); var smurfs = acc.GetSmurfs().Where(a => a.PunishmentsByAccountID.Any(x => x.BanExpires > DateTime.UtcNow)); if (smurfs.Any()) { await server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("Smurf Alert! {0} might be a smurf of {1}. Check https://zero-k.info/Users/AdminUserDetail/{2}", acc.Name, smurfs.OrderByDescending(x => x.Level).First().Name, acc.AccountID)); } } return new RegisterResponse(RegisterResponse.Code.Ok); }
//private //Runs in O(N log(N)) for all players private void UpdateRankings(IEnumerable <Player> players) { try { Dictionary <int, float> oldRatings = new Dictionary <int, float>(); //check for ladder elo updates using (var db = new ZkDataContext()) { var battleIDs = pendingDebriefings.Keys.ToList(); var lastBattlePlayers = db.SpringBattlePlayers.Where(p => battleIDs.Contains(p.SpringBattleID) && !p.IsSpectator).Include(x => x.Account).ToList(); oldRatings = lastBattlePlayers.ToDictionary(p => p.AccountID, p => playerRatings[p.AccountID].LadderElo); lastBattlePlayers.ForEach(p => playerRatings[p.AccountID].LadderElo = Ranks.UpdateLadderRating(p.Account, category, this.players[p.AccountID].avgElo + RatingOffset, p.IsInVictoryTeam, !p.IsInVictoryTeam, db)); } //update ladders int currentDay = RatingSystems.ConvertDateToDays(DateTime.UtcNow); int playerCount = 0; using (var db = new ZkDataContext()) { foreach (var p in players) { if (p.days.Count == 0) { Trace.TraceError("WHR " + category + " has invalid player " + p.id + " with no days(games)"); continue; } float elo = p.days.Last().GetElo() + RatingOffset; float lastNaturalRatingVar = p.avgEloVar * GlobalConst.EloToNaturalRatingMultiplierSquared; var lastDay = p.days.Last(); float ladderElo; if (playerRatings.ContainsKey(p.id)) { ladderElo = playerRatings[p.id].LadderElo; } else { ladderElo = (float?)db.AccountRatings.Where(x => x.AccountID == p.id && x.RatingCategory == category).FirstOrDefault()?.LadderElo ?? DefaultRating.LadderElo; } playerRatings[p.id] = new PlayerRating(int.MaxValue, 1, elo, lastNaturalRatingVar, GlobalConst.NaturalRatingVariancePerDay(lastDay.totalWeight), lastDay.day, currentDay, ladderElo, !float.IsNaN(p.avgElo)); float rating = -playerRatings[p.id].LadderElo + 0.001f * (float)rand.NextDouble(); if (playerKeys.ContainsKey(p.id)) { sortedPlayers.Remove(playerKeys[p.id]); } playerKeys[p.id] = rating; sortedPlayers[rating] = p.id; if (playerRatings[p.id].Ranked) { playerCount++; } } } this.activePlayers = playerCount; int rank = 0; List <int> newTopPlayers = new List <int>(); int matched = 0; List <float> newPercentileBrackets = new List <float>(); newPercentileBrackets.Add(playerRatings[sortedPlayers.First().Value].LadderElo + 420); float percentile; float[] percentilesRev = Ranks.Percentiles.Reverse().ToArray(); foreach (var pair in sortedPlayers) { if (playerRatings[pair.Value].Ranked) { newTopPlayers.Add(pair.Value); if (rank == matched && rank < topPlayers.Count && topPlayers[rank] == pair.Value) { matched++; } rank++; percentile = (float)rank / activePlayers; if (newPercentileBrackets.Count <= Ranks.Percentiles.Length && percentile > percentilesRev[newPercentileBrackets.Count - 1]) { newPercentileBrackets.Add(playerRatings[pair.Value].LadderElo); } playerRatings[pair.Value].ApplyLadderUpdate(rank, percentile, currentDay, true); } else if (playerRatings[pair.Value].Rank < int.MaxValue) { playerRatings[pair.Value].ApplyLadderUpdate(int.MaxValue, 1, currentDay, false); } } newPercentileBrackets.Add(newPercentileBrackets.Last() - 420); PercentileBrackets = newPercentileBrackets.Select(x => x).Reverse().ToArray(); topPlayers = newTopPlayers; laddersCache = new List <Account>(); Trace.TraceInformation("WHR " + category + " Ladders updated with " + topPlayers.Count + "/" + this.players.Count + " entries. Brackets are now: " + string.Join(", ", PercentileBrackets)); var playerIds = players.Select(x => x.id).ToList(); if (playerIds.Count() < 100) { SaveToDB(playerIds); } else { SaveToDB(); } //check for rank updates if (pendingDebriefings.Any()) { List <int> playersWithRatingChange = new List <int>(); Dictionary <int, int> oldRanks = new Dictionary <int, int>(); Dictionary <int, Account> updatedRanks = new Dictionary <int, Account>(); Dictionary <int, Account> involvedAccounts = new Dictionary <int, Account>(); Trace.TraceInformation("WHR Filling in Debriefings for Battles: " + pendingDebriefings.Keys.Select(x => "B" + x).StringJoin()); using (var db = new ZkDataContext()) { var battleIDs = pendingDebriefings.Keys.ToList(); var lastBattlePlayers = db.SpringBattlePlayers.Where(p => battleIDs.Contains(p.SpringBattleID) && !p.IsSpectator).Include(x => x.Account).ToList(); involvedAccounts = lastBattlePlayers.ToDictionary(p => p.AccountID, p => p.Account); Trace.TraceInformation("WHR Debriefing players: " + involvedAccounts.Values.Select(x => x.Name).StringJoin()); oldRanks = lastBattlePlayers.ToDictionary(p => p.AccountID, p => p.Account.Rank); updatedRanks = lastBattlePlayers.Where(p => Ranks.UpdateRank(p.Account, p.IsInVictoryTeam, !p.IsInVictoryTeam, db)).Select(x => x.Account).ToDictionary(p => p.AccountID, p => p); updatedRanks.Values.ForEach(p => db.Entry(p).State = EntityState.Modified); playersWithRatingChange = lastBattlePlayers.Select(x => x.AccountID).ToList(); lastBattlePlayers.Where(p => playerOldRatings.ContainsKey(RatingSystems.GetRatingId(p.AccountID)) && !p.EloChange.HasValue).ForEach(p => { //p.EloChange = playerRatings[RatingSystems.GetRatingId(p.AccountID)].RealElo - playerOldRatings[RatingSystems.GetRatingId(p.AccountID)].RealElo; p.EloChange = playerRatings[p.AccountID].LadderElo - oldRatings[p.AccountID]; }); db.SpringBattlePlayers.Where(p => battleIDs.Contains(p.SpringBattleID) && !p.IsSpectator).ToList().ForEach(x => playerOldRatings[RatingSystems.GetRatingId(x.AccountID)] = playerRatings[RatingSystems.GetRatingId(x.AccountID)]); db.SaveChanges(); } //Publish new results only after saving new stats to db. pendingDebriefings.ForEach(pair => { pair.Value.partialDebriefing.DebriefingUsers.Values.ForEach(user => { try { user.EloChange = playerRatings[user.AccountID].LadderElo - oldRatings[user.AccountID]; user.IsRankup = updatedRanks.ContainsKey(user.AccountID) && oldRanks[user.AccountID] < updatedRanks[user.AccountID].Rank; user.IsRankdown = updatedRanks.ContainsKey(user.AccountID) && oldRanks[user.AccountID] > updatedRanks[user.AccountID].Rank; var prog = Ranks.GetRankProgress(involvedAccounts[user.AccountID], this); if (prog == null) { Trace.TraceWarning("User " + user.AccountID + " is wrongfully unranked"); } user.NextRankElo = prog.RankCeilElo; user.PrevRankElo = prog.RankFloorElo; user.NewElo = prog.CurrentElo; } catch (Exception ex) { Trace.TraceError("Unable to complete debriefing for user " + user.AccountID + ": " + ex); } }); pair.Value.partialDebriefing.RatingCategory = category.ToString(); pair.Value.debriefingConsumer.Invoke(pair.Value.partialDebriefing); }); RatingsUpdated(this, new RatingUpdate() { affectedPlayers = playersWithRatingChange }); pendingDebriefings.Clear(); } //check for topX updates GetTopPlayers(GlobalConst.LadderSize); foreach (var listener in topPlayersUpdateListeners) { if (matched < listener.Value) { listener.Key.TopPlayersUpdated(GetTopPlayers(listener.Value)); } } } catch (Exception ex) { string dbg = "WHR " + category + ": Failed to update rankings " + ex + "\nPlayers: "; foreach (var p in players) { dbg += p.id + " (" + p.days.Count + " days), "; } Trace.TraceError(dbg); } }
public ActionResult SubmitCreate(Clan clan, HttpPostedFileBase image, HttpPostedFileBase bgimage, bool noFaction = false) { //using (var scope = new TransactionScope()) //{ ZkDataContext db = new ZkDataContext(); bool created = clan.ClanID == 0; // existing clan vs creation var acc = db.Accounts.Single(x => x.AccountID == Global.AccountID); //return Content(noFaction ? "true":"false"); if (noFaction) { clan.FactionID = null; } Faction new_faction = db.Factions.SingleOrDefault(x => x.FactionID == clan.FactionID); if ((new_faction != null) && new_faction.IsDeleted) { return(Content("Cannot create clans in deleted factions")); } if (string.IsNullOrEmpty(clan.ClanName) || string.IsNullOrEmpty(clan.Shortcut)) { return(Content("Name and shortcut cannot be empty!")); } if (!ZkData.Clan.IsShortcutValid(clan.Shortcut)) { return(Content("Shortcut must have at least 1 characters and contain only numbers and letters")); } if (created && (image == null || image.ContentLength == 0)) { return(Content("A clan image is required")); } Clan orgClan = null; if (!created) { if (!Global.IsModerator && (!Global.Account.HasClanRight(x => x.RightEditTexts) || clan.ClanID != Global.Account.ClanID)) { return(Content("Unauthorized")); } // check if our name or shortcut conflicts with existing clans var existingClans = db.Clans.Where(x => ((SqlFunctions.PatIndex(clan.Shortcut, x.Shortcut) > 0 || SqlFunctions.PatIndex(clan.ClanName, x.ClanName) > 0) && x.ClanID != clan.ClanID)); if (existingClans.Count() > 0) { if (existingClans.Any(x => !x.IsDeleted)) { return(Content("Clan with this shortcut or name already exists")); } } orgClan = db.Clans.Single(x => x.ClanID == clan.ClanID); string orgImageUrl = Server.MapPath(orgClan.GetImageUrl()); string orgBGImageUrl = Server.MapPath(orgClan.GetBGImageUrl()); string orgShortcut = orgClan.Shortcut; string newImageUrl = Server.MapPath(clan.GetImageUrl()); string newBGImageUrl = Server.MapPath(clan.GetBGImageUrl()); if (Global.IsModerator && (!Global.Account.HasClanRight(x => x.RightEditTexts) || clan.ClanID != Global.Account.ClanID)) { Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("{0} edited clan {1} {2}", Global.Account.Name, orgClan.ClanName, Url.Action("Detail", "Clans", new { id = clan.ClanID }, "http"))); if (orgClan.ClanName != clan.ClanName) { Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("{0} => {1}", orgClan.ClanName, clan.ClanName)); } } orgClan.ClanName = clan.ClanName; orgClan.Shortcut = clan.Shortcut; orgClan.Description = clan.Description; orgClan.SecretTopic = clan.SecretTopic; orgClan.Password = clan.Password; bool shortcutChanged = orgShortcut != clan.Shortcut; if (image != null && image.ContentLength > 0) { var im = Image.FromStream(image.InputStream); if (im.Width != 64 || im.Height != 64) { im = im.GetResized(64, 64, InterpolationMode.HighQualityBicubic); } im.Save(newImageUrl); } else if (shortcutChanged) { //if (System.IO.File.Exists(newImageUrl)) System.IO.File.Delete(newImageUrl); //System.IO.File.Move(orgImageUrl, newImageUrl); try { //var im = Image.FromFile(orgImageUrl); //im.Save(newImageUrl); System.IO.File.Copy(orgImageUrl, newImageUrl, true); } catch (System.IO.FileNotFoundException fnfex) // shouldn't happen but hey { return(Content("A clan image is required")); } } if (bgimage != null && bgimage.ContentLength > 0) { var im = Image.FromStream(bgimage.InputStream); im.Save(newBGImageUrl); } else if (shortcutChanged) { //if (System.IO.File.Exists(newBGImageUrl)) System.IO.File.Delete(newBGImageUrl); //System.IO.File.Move(orgBGImageUrl, newBGImageUrl); try { //var im = Image.FromFile(orgBGImageUrl); //im.Save(newBGImageUrl); System.IO.File.Copy(orgBGImageUrl, newBGImageUrl, true); } catch (System.IO.FileNotFoundException fnfex) { // there wasn't an original background image, do nothing } } if (clan.FactionID != orgClan.FactionID) { // set factions of members Faction oldFaction = orgClan.Faction; orgClan.FactionID = clan.FactionID; foreach (Account member in orgClan.Accounts) { if (member.FactionID != clan.FactionID && member.FactionID != null) { FactionsController.PerformLeaveFaction(member.AccountID, true, db); } member.FactionID = clan.FactionID; } db.SaveChanges(); if (clan.FactionID != null) { db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("Clan {0} moved to faction {1}", orgClan, orgClan.Faction)); } else { db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("Clan {0} left faction {1}", orgClan, oldFaction)); } } db.SaveChanges(); } else { if (Global.Clan != null) { return(Content("You already have a clan")); } // should just change their faction for them? if (Global.FactionID != 0 && Global.FactionID != clan.FactionID) { return(Content("Clan must belong to same faction you are in")); } // check if our name or shortcut conflicts with existing clans // if so, allow us to create a new clan over it if it's a deleted clan, else block action var existingClans = db.Clans.Where(x => ((SqlFunctions.PatIndex(clan.Shortcut, x.Shortcut) > 0 || SqlFunctions.PatIndex(clan.ClanName, x.ClanName) > 0) && x.ClanID != clan.ClanID)); if (existingClans.Count() > 0) { if (existingClans.Any(x => !x.IsDeleted)) { return(Content("Clan with this shortcut or name already exists")); } Clan deadClan = existingClans.First(); Clan inputClan = clan; clan = deadClan; if (noFaction) { clan.FactionID = null; } clan.IsDeleted = false; clan.ClanName = inputClan.ClanName; clan.Password = inputClan.Password; clan.Description = inputClan.Description; clan.SecretTopic = inputClan.SecretTopic; } else { db.Clans.InsertOnSubmit(clan); } db.SaveChanges(); acc.ClanID = clan.ClanID; // we created a new clan, set self as founder and rights AddClanLeader(acc.AccountID, clan.ClanID, db); db.SaveChanges(); if (image != null && image.ContentLength > 0) { var im = Image.FromStream(image.InputStream); if (im.Width != 64 || im.Height != 64) { im = im.GetResized(64, 64, InterpolationMode.HighQualityBicubic); } im.Save(Server.MapPath(clan.GetImageUrl())); } if (bgimage != null && bgimage.ContentLength > 0) { var im = Image.FromStream(bgimage.InputStream); im.Save(Server.MapPath(clan.GetBGImageUrl())); } db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("New clan {0} formed by {1}", clan, acc)); db.SaveChanges(); } Global.Server.PublishAccountUpdate(acc); //scope.Complete(); Global.Server.ChannelManager.AddClanChannel(clan);; Global.Server.SetTopic(clan.GetClanChannel(), clan.SecretTopic, Global.Account.Name); //} return(RedirectToAction("Detail", new { id = clan.ClanID })); }
/// <summary> /// Go to home page; also updates news read dates /// </summary> public ActionResult Index() { var db = new ZkDataContext(); var result = new IndexResult() { Spotlight = SpotlightHandler.GetRandom(), Top10Players = RatingSystems.GetRatingSystem(RatingCategory.MatchMaking).GetTopPlayers(10), WikiRecentChanges = MediaWikiRecentChanges.LoadRecentChanges() }; result.LobbyStats = MemCache.GetCached("lobby_stats", GetCurrentLobbyStats, 60 * 2); result.News = db.News.Where(x => x.Created < DateTime.UtcNow).OrderByDescending(x => x.Created); if (Global.Account != null) { result.Headlines = db.News.Where( x => x.Created <DateTime.UtcNow && x.HeadlineUntil != null && x.HeadlineUntil> DateTime.UtcNow && !x.ForumThread.ForumThreadLastReads.Any(y => y.AccountID == Global.AccountID && y.LastRead != null)). OrderByDescending(x => x.Created).ToList(); if (result.Headlines.Any()) { foreach (var h in result.Headlines) { h.ForumThread.UpdateLastRead(Global.AccountID, false); } db.SaveChanges(); } } else { result.Headlines = new List <News>(); } var accessibleThreads = db.ForumThreads.Where(x => x.RestrictedClanID == null || x.RestrictedClanID == Global.ClanID); accessibleThreads = accessibleThreads.Where(x => x.ForumCategory.ForumMode != ForumMode.Archive); if (!Global.IsAccountAuthorized) { result.NewThreads = accessibleThreads.OrderByDescending(x => x.LastPost).Take(10).Select(x => new NewThreadEntry() { ForumThread = x }); } else { result.NewThreads = (from t in accessibleThreads let read = t.ForumThreadLastReads.FirstOrDefault(x => x.AccountID == Global.AccountID) let readForum = t.ForumCategory.ForumLastReads.FirstOrDefault(x => x.AccountID == Global.AccountID) where (read == null || t.LastPost > read.LastRead) && (readForum == null || t.LastPost > readForum.LastRead) orderby t.LastPost descending select new NewThreadEntry { ForumThread = t, WasRead = read != null, WasWritten = read != null && read.LastPosted != null }). Take(10); } return(View("HomeIndex", result)); }
private void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs) { try { timer.Stop(); // auto change PW mode based on time if (MiscVar.PlanetWarsNextModeTime != null && MiscVar.PlanetWarsNextModeTime < DateTime.UtcNow && MiscVar.PlanetWarsNextMode != null) { MiscVar.PlanetWarsMode = MiscVar.PlanetWarsNextMode ?? PlanetWarsModes.AllOffline; MiscVar.PlanetWarsNextMode = null; MiscVar.PlanetWarsNextModeTime = null; using (var db = new ZkDataContext()) { db.Events.Add(server.PlanetWarsEventCreator.CreateEvent("PlanetWars changed status to {0}", MiscVar.PlanetWarsMode.Description())); db.SaveChanges(); } } if (MiscVar.PlanetWarsMode != lastPlanetWarsMode) { server.Broadcast(GeneratePwStatus()); UpdateLobby(); lastPlanetWarsMode = MiscVar.PlanetWarsMode; } if (MiscVar.PlanetWarsMode != PlanetWarsModes.Running) { return; } // Some sort of battle timer // PlanetWarsTurnHandler.UpdateEconomy(new ZkDataContext(), server.PlanetWarsEventCreator); if (Challenge == null) { // attack timer if (DateTime.UtcNow > GetAttackDeadline()) { AttackerSideCounter++; ResetAttackOptions(); } } else { // accept timer if (DateTime.UtcNow > GetAcceptDeadline()) { if ((Challenge.Defenders.Count >= Challenge.Attackers.Count - 1) && (Challenge.Defenders.Count > 0)) { AcceptChallenge(); } else { RecordPlanetwarsLoss(Challenge); AttackerSideCounter++; ResetAttackOptions(); } } } } catch (Exception ex) { Trace.TraceError("PlanetWars timer error: {0}", ex); } finally { timer.Start(); } }
private ActionResult ChangePlanetMap(int planetID, int structureTypeID, int targetID, int?newMapID) { var db = new ZkDataContext(); PlanetStructure structure = db.PlanetStructures.FirstOrDefault(x => x.PlanetID == planetID && x.StructureTypeID == structureTypeID); Planet source = db.Planets.FirstOrDefault(x => x.PlanetID == planetID); Planet target = db.Planets.FirstOrDefault(x => x.PlanetID == targetID); Galaxy gal = db.Galaxies.FirstOrDefault(x => x.GalaxyID == source.GalaxyID); if (newMapID == null) { List <Resource> mapList = db.Resources.Where( x => x.MapPlanetWarsIcon != null && x.Planets.Where(p => p.GalaxyID == gal.GalaxyID).Count() == 0 && x.MapSupportLevel >= MapSupportLevel.Featured && x.ResourceID != source.MapResourceID).ToList(); if (mapList.Count > 0) { int r = new Random().Next(mapList.Count); newMapID = mapList[r].ResourceID; } } if (newMapID != null) { Resource newMap = db.Resources.Single(x => x.ResourceID == newMapID); target.Resource = newMap; gal.IsDirty = true; string word = ""; if (target.Faction == source.Faction) { if (target.TeamSize < GlobalConst.PlanetWarsMaxTeamsize) { target.TeamSize++; } word = "terraformed"; } else { word = "nanodegraded"; if (target.TeamSize > 1) { target.TeamSize--; } } db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("{0} {1} has been {6} by {2} from {3} {4}. New team size is {5} vs {5}", target.Faction, target, structure.StructureType, source.Faction, source, target.TeamSize, word)); } else { return (Content(string.Format("Terraform attempt on {0} {1} using {2} from {3} {4} has failed - no valid maps", target.Faction, target, structure.StructureType, source.Faction, source))); } db.SaveChanges(); return(null); }
public ActionResult SendDropships(int planetID, int count, bool?useWarp) { var db = new ZkDataContext(); Account acc = db.Accounts.Single(x => x.AccountID == Global.AccountID); if (acc.Faction == null) { return(Content("Join a faction first")); } Planet planet = db.Planets.SingleOrDefault(x => x.PlanetID == planetID); int there = planet.PlanetFactions.Where(x => x.FactionID == acc.FactionID).Sum(x => (int?)x.Dropships) ?? 0; bool accessible = useWarp == true?planet.CanDropshipsWarp(acc.Faction) : planet.CanDropshipsAttack(acc.Faction); if (!accessible) { return(Content(string.Format("That planet cannot be attacked"))); } if (Global.Server.GetPlanetBattles(planet).Any(x => x.IsInGame)) { return(Content("Battle in progress on the planet, cannot send ships")); } int cnt = Math.Max(count, 0); int capa = acc.GetDropshipCapacity(); if (cnt + there > capa) { return(Content("Too many dropships on planet - the fleet limit is " + capa)); } cnt = Math.Min(cnt, (int)acc.GetDropshipsAvailable()); if (useWarp == true) { cnt = Math.Min(cnt, (int)acc.GetWarpAvailable()); } if (cnt > 0) { acc.SpendDropships(cnt); if (useWarp == true) { acc.SpendWarps(cnt); if (cnt < GlobalConst.DropshipsForFullWarpIPGain) { return(Content($"You must send at least {GlobalConst.DropshipsForFullWarpIPGain} dropships when warping")); } } if (planet.Account != null) { Global.Server.GhostPm(planet.Account.Name, string.Format( "Warning: long range scanners detected fleet of {0} ships inbound to your planet {1} {3}/Planetwars/Planet/{2}", cnt, planet.Name, planet.PlanetID, GlobalConst.BaseSiteUrl)); } PlanetFaction pac = planet.PlanetFactions.SingleOrDefault(x => x.FactionID == acc.FactionID); if (pac == null) { pac = new PlanetFaction { FactionID = Global.FactionID, PlanetID = planetID }; db.PlanetFactions.InsertOnSubmit(pac); } pac.Dropships += cnt; pac.DropshipsLastAdded = DateTime.UtcNow; if (cnt > 0) { db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("{0} sends {1} {2} dropships to {3} {4} {5}", acc, cnt, acc.Faction, planet.Faction, planet, useWarp == true ? "using warp drives" : "")); } db.SaveChanges(); } return(RedirectToAction("Planet", new { id = planetID })); }
public async Task <ActionResult> Punish(int accountID, string reason, bool banMute, bool banVotes, bool banCommanders, bool banSite, bool banLobby, bool banSpecChat, bool banForum, bool messageOnly, string banIP, long?banUserID, string installID, double banHours) { ZkDataContext db = new ZkDataContext(); Account acc = db.Accounts.SingleOrDefault(x => x.AccountID == accountID); if (acc == null) { return(Content("Invalid accountID")); } if (banHours > MaxBanHours) { banHours = MaxBanHours; // todo show some notification } Punishment punishment = new Punishment { Time = DateTime.UtcNow, Reason = reason, BanMute = banMute, BanVotes = banVotes, BanCommanders = banCommanders, BanSite = banSite, BanLobby = banLobby, BanExpires = DateTime.UtcNow.AddHours(banHours), BanUnlocks = false, BanSpecChat = banSpecChat, MessageOnly = messageOnly, BanIP = banIP, BanForum = banForum, DeleteXP = false, DeleteInfluence = false, CreatedAccountID = Global.AccountID, InstallID = installID, UserID = banUserID }; acc.PunishmentsByAccountID.Add(punishment); db.SaveChanges(); // notify lobby of changes and post log message try { string pmAction = ""; bool activePenalty = banLobby || banMute || banForum || banSpecChat || banVotes || banCommanders || banSite; if (messageOnly && !activePenalty) { await Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("Message sent to {0} {1} ", acc.Name, Url.Action("Detail", "Users", new { id = acc.AccountID }, "http"))); await Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format(" - message: {0} ", reason)); await Global.Server.GhostPm(acc.Name, string.Format("A moderator has sent you a message: {0}", reason)); } else { await Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("New penalty for {0} {1} ", acc.Name, Url.Action("Detail", "Users", new { id = acc.AccountID }, "http"))); await Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format(" - reason: {0} ", reason)); await Global.Server.GhostPm(acc.Name, string.Format("Your account has received moderator action, reason: {0}", reason)); if (banLobby == true) { await Global.Server.KickFromServer(Global.Account.Name, acc.Name, reason); pmAction += "Lobby banned, "; } if (banMute == true) { await Global.Server.PublishAccountUpdate(acc); pmAction += "Muted, "; } if (banForum == true) { pmAction += "Forum banned, "; } if (banSpecChat == true) { pmAction += "Spectator all-chat muted, "; } if (banVotes == true) { pmAction += "Vote powers restricted, "; } if (banCommanders == true) { pmAction += "Custom commanders restricted, "; } if (banSite == true) { pmAction += "Site banned, "; } if (activePenalty) { pmAction = pmAction.Substring(0, Math.Max(0, pmAction.Length - 2)); // removes trailing comma and space await Global.Server.GhostPm(acc.Name, string.Format("Action taken: {0}", pmAction)); await Global.Server.GhostPm(acc.Name, string.Format("Total duration: {0} hours", banHours)); await Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format(" - duration: {0}h ", banHours)); await Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format(" - penalty type: {0}", pmAction)); } else { await Global.Server.GhostPm(acc.Name, "Action taken: Warning"); await Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, " - penalty type: Warning"); } } } catch (Exception ex) { Trace.TraceError(ex.ToString()); await Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, ex.ToString()); } return(RedirectToAction("Detail", new { id = accountID })); }
/* * public static void Test1v1Elo() * { * var db = new ZkDataContext(); * Dictionary<Account, EloEntry> PlayerElo = new Dictionary<Account, EloEntry>(); * * int cnt = 0; * foreach (var sb in db.SpringBattles.Where(x => !x.IsMission && !x.HasBots && x.PlayerCount == 2).OrderBy(x => x.SpringBattleID)) * { * cnt++; * * double winnerElo = 0; * double loserElo = 0; * * var losers = sb.SpringBattlePlayers.Where(x => !x.IsSpectator && !x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList(); * var winners = sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList(); * * if (losers.Count != 1 || winners.Count != 1) * { * continue; * } * * foreach (var r in winners) * { * EloEntry el; * if (!PlayerElo.TryGetValue(r.Account, out el)) el = new EloEntry(); * winnerElo += el.Elo; * } * foreach (var r in losers) * { * EloEntry el; * if (!PlayerElo.TryGetValue(r.Account, out el)) el = new EloEntry(); * loserElo += el.Elo; * } * * winnerElo = winnerElo / winners.Count; * loserElo = loserElo / losers.Count; * * var eWin = 1 / (1 + Math.Pow(10, (loserElo - winnerElo) / 400)); * var eLose = 1 / (1 + Math.Pow(10, (winnerElo - loserElo) / 400)); * * var sumCount = losers.Count + winners.Count; * var scoreWin = Math.Sqrt(sumCount / 2.0) * 32 * (1 - eWin); * var scoreLose = Math.Sqrt(sumCount / 2.0) * 32 * (0 - eLose); * * foreach (var r in winners) * { * var change = (float)(scoreWin); * EloEntry elo; * if (!PlayerElo.TryGetValue(r.Account, out elo)) * { * elo = new EloEntry(); * PlayerElo[r.Account] = elo; * } * elo.Elo += change; * elo.Cnt++; * } * * foreach (var r in losers) * { * var change = (float)(scoreLose); * EloEntry elo; * if (!PlayerElo.TryGetValue(r.Account, out elo)) * { * elo = new EloEntry(); * PlayerElo[r.Account] = elo; * } * elo.Elo += change; * elo.Cnt++; * } * } * * * Console.WriteLine("Total battles: {0}", cnt); * Console.WriteLine("Name;1v1Elo;TeamElo;1v1Played;TeamPlayed"); * foreach (var entry in PlayerElo.Where(x => x.Value.Cnt > 40).OrderByDescending(x => x.Value.Elo)) * { * Console.WriteLine("{0};{1:f0};{2:f0};{3};{4}", entry.Key.Name, entry.Value.Elo, entry.Key.EffectiveElo, entry.Value.Cnt, entry.Key.SpringBattlePlayers.Count(x => !x.IsSpectator && x.SpringBattle.PlayerCount > 2)); * } * * }*/ /* * public static void TestPrediction() * { * var db = new ZkDataContext(); * var cnt = 0; * var winPro = 0; * var winLessNub = 0; * var winMoreVaried = 0; * var winPredicted = 0; * * * foreach (var sb in db.SpringBattles.Where(x => !x.IsMission && !x.HasBots && x.IsEloProcessed && x.PlayerCount >= 8 && !x.Events.Any()).OrderByDescending(x => x.SpringBattleID)) * { * * var losers = sb.SpringBattlePlayers.Where(x => !x.IsSpectator && !x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList(); * var winners = sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.IsInVictoryTeam).Select(x => new { Player = x, x.Account }).ToList(); * * if (losers.Count == 0 || winners.Count == 0 || losers.Count == winners.Count) continue; * * if (winners.Select(x => x.Account.EffectiveElo).Max() > losers.Select(x => x.Account.EffectiveElo).Max()) winPro++; * if (winners.Select(x => x.Account.EffectiveElo).Min() > losers.Select(x => x.Account.EffectiveElo).Min()) winLessNub++; * * if (winners.Select(x => x.Account.EffectiveElo).StdDev() > losers.Select(x => x.Account.EffectiveElo).StdDev()) winMoreVaried++; * * var winnerElo = winners.Select(x => x.Account.EffectiveElo).Average(); * var loserElo = losers.Select(x => x.Account.EffectiveElo).Average(); * * var eWin = 1 / (1 + Math.Pow(10, (loserElo - winnerElo) / 400)); * var eLose = 1 / (1 + Math.Pow(10, (winnerElo - loserElo) / 400)); * * if (eWin > eLose) winPredicted++; * * * cnt++; * if (cnt == 200) break; * } * * Console.WriteLine("prwin: {0}, lessnubwin: {1}, morevaried: {2}, count: {3}, predicted:{4}", winPro, winLessNub, winMoreVaried, cnt, winPredicted); * } * * static void RecalculateBattleElo() * { * using (var db = new ZkDataContext()) * { * foreach (var b in db.SpringBattles.Where(x => !x.IsEloProcessed).ToList()) * { * Console.WriteLine(b.SpringBattleID); * b.CalculateAllElo(); * } * db.SaveChanges(); * } * } * * static void ImportSpringiePlayers() * { * var db = new ZkDataContext(); * foreach (var line in File.ReadLines("springie.csv").AsParallel()) * { * var m = Regex.Match(line, "\"[0-9]+\";\"([^\"]+)\";\"[0-9]+\";\"[0-9]+\";\"([^\"]+)\";\"([^\"]+)\""); * if (m.Success) * { * string name = m.Groups[1].Value; * double elo = double.Parse(m.Groups[2].Value, CultureInfo.InvariantCulture); * double w = double.Parse(m.Groups[3].Value, CultureInfo.InvariantCulture); * if (elo != 1500 || w != 1) * { * foreach (var a in db.Accounts.Where(x => x.Name == name)) * { * a.Elo = (float)elo; * a.EloWeight = (float)w; * } * Console.WriteLine(name); * } * } * } * db.SaveChanges(); * }*/ static void FixMaps() { try { var db = new ZkDataContext(); foreach (var r in db.Resources.Where(x => x.LastChange == null)) { r.LastChange = DateTime.UtcNow; } db.SaveChanges(); return; foreach (var resource in db.Resources.Where(x => x.TypeID == ResourceType.Map))//&&x.MapSizeSquared == null)) { var file = String.Format("{0}/{1}.metadata.xml.gz", GlobalConst.SiteDiskPath + @"\Resources", resource.InternalName.EscapePath()); var map = (Map) new XmlSerializer(typeof(Map)).Deserialize(new MemoryStream(File.ReadAllBytes(file).Decompress())); resource.MapWidth = map.Size.Width / 512; resource.MapHeight = map.Size.Height / 512; if (string.IsNullOrEmpty(resource.AuthorName)) { if (!string.IsNullOrEmpty(map.Author)) { resource.AuthorName = map.Author; } else { Console.WriteLine("regex test"); var m = Regex.Match(map.Description, "by ([\\w]+)", RegexOptions.IgnoreCase); if (m.Success) { resource.AuthorName = m.Groups[1].Value; } } } Console.WriteLine("author: " + resource.AuthorName); if (resource.MapIsSpecial == null) { resource.MapIsSpecial = map.ExtractorRadius > 120 || map.MaxWind > 40; } resource.MapSizeSquared = (map.Size.Width / 512) * (map.Size.Height / 512); resource.MapSizeRatio = (float)map.Size.Width / map.Size.Height; var minimap = String.Format("{0}/{1}.minimap.jpg", GlobalConst.SiteDiskPath + @"\Resources", resource.InternalName.EscapePath()); using (var im = Image.FromFile(minimap)) { int w, h; if (resource.MapSizeRatio > 1) { w = 96; h = (int)(w / resource.MapSizeRatio); } else { h = 96; w = (int)(h * resource.MapSizeRatio); } using (var correctMinimap = new Bitmap(w, h, PixelFormat.Format24bppRgb)) { using (var graphics = Graphics.FromImage(correctMinimap)) { graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.DrawImage(im, 0, 0, w, h); } var jgpEncoder = ImageCodecInfo.GetImageEncoders().First(x => x.FormatID == ImageFormat.Jpeg.Guid); var encoderParams = new EncoderParameters(1); encoderParams.Param[0] = new EncoderParameter(Encoder.Quality, 100L); var target = String.Format("{0}/{1}.thumbnail.jpg", GlobalConst.SiteDiskPath + @"\Resources", resource.InternalName.EscapePath()); correctMinimap.Save(target, jgpEncoder, encoderParams); } } Console.WriteLine(string.Format("{0}", resource.InternalName)); } db.SaveChanges(); } catch (Exception ex) { Console.WriteLine(ex); } }
public async Task <RegisterResponse> DoRegister(Register register, string ip) { if (!Account.IsValidLobbyName(register.Name)) { return(new RegisterResponse(RegisterResponse.Code.NameHasInvalidCharacters)); } if (server.ConnectedUsers.ContainsKey(register.Name)) { return(new RegisterResponse(RegisterResponse.Code.AlreadyConnected)); } if (string.IsNullOrEmpty(register.PasswordHash) && string.IsNullOrEmpty(register.SteamAuthToken)) { return(new RegisterResponse(RegisterResponse.Code.MissingBothPasswordAndToken)); } if (!VerifyIp(ip)) { return(new RegisterResponse(RegisterResponse.Code.BannedTooManyAttempts)); } var banPenalty = Punishment.GetActivePunishment(null, ip, register.UserID, x => x.BanLobby); if (banPenalty != null) { return new RegisterResponse(RegisterResponse.Code.Banned) { BanReason = banPenalty.Reason } } ; SteamWebApi.PlayerInfo info = null; if (!string.IsNullOrEmpty(register.SteamAuthToken)) { info = await server.SteamWebApi.VerifyAndGetAccountInformation(register.SteamAuthToken); if (info == null) { return(new RegisterResponse(RegisterResponse.Code.InvalidSteamToken)); } } using (var db = new ZkDataContext()) { var registerName = register.Name.ToUpper(); var existingByName = db.Accounts.FirstOrDefault(x => x.Name.ToUpper() == registerName); if (existingByName != null) { if (info != null && existingByName.SteamID == info.steamid) { return(new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisSteamToken)); } if (info == null && !string.IsNullOrEmpty(register.PasswordHash) && existingByName.VerifyPassword(register.PasswordHash)) { return(new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisPassword)); } return(new RegisterResponse(RegisterResponse.Code.NameAlreadyTaken)); } var acc = new Account() { Name = register.Name }; acc.SetPasswordHashed(register.PasswordHash); acc.SetName(register.Name); acc.SetAvatar(); acc.Email = register.Email; if (info != null) { var existingBySteam = db.Accounts.FirstOrDefault(x => x.SteamID == info.steamid); if (existingBySteam != null) { return(new RegisterResponse(RegisterResponse.Code.SteamAlreadyRegistered)); } acc.SteamID = info.steamid; acc.SteamName = info.personaname; } else if (string.IsNullOrEmpty(register.PasswordHash)) { return(new RegisterResponse(RegisterResponse.Code.InvalidPassword)); } LogIP(db, acc, ip); LogUserID(db, acc, register.UserID); db.Accounts.Add(acc); db.SaveChanges(); } return(new RegisterResponse(RegisterResponse.Code.Ok)); }
public void UpdateRatings() { if (!RatingSystems.Initialized) { return; } if (latestBattle == null) { //Trace.TraceInformation("WHR " + category +": No battles to evaluate"); return; } lock (updateLock) { Action updateAction = null; if (lastUpdate == null) { updateAction = (() => { Trace.TraceInformation("Initializing WHR " + category + " ratings for " + battlesRegistered + " battles, this will take some time.. From B" + firstBattle?.SpringBattleID + " to B" + latestBattle?.SpringBattleID); runIterations(75); UpdateRankings(players.Values); playerOldRatings = new Dictionary <int, PlayerRating>(playerRatings); }); } else if (DateTime.UtcNow.Subtract(lastUpdateTime).TotalHours >= GlobalConst.LadderUpdatePeriod) { updateAction = (() => { Trace.TraceInformation("Updating all WHR " + category + " ratings"); runIterations(1); UpdateRankings(players.Values); }); lastUpdateTime = DateTime.UtcNow; } else if (!latestBattle.Equals(lastUpdate)) { updateAction = (() => { Trace.TraceInformation("Updating WHR " + category + " ratings for last Battle: " + latestBattle.SpringBattleID); IEnumerable <Player> players = latestBattle.SpringBattlePlayers.Where(p => !p.IsSpectator).Select(p => getPlayerById(RatingSystems.GetRatingId(p.AccountID))); players.ForEach(p => p.runOneNewtonIteration()); players.ForEach(p => p.updateUncertainty()); UpdateRankings(players); }); } else { //Trace.TraceInformation("No WHR " + category +" ratings to update"); return; } var lastUpdateEx = lastUpdate; Task.Factory.StartNew(() => { try { lock (updateLockInternal) { DateTime start = DateTime.Now; updateAction.Invoke(); Trace.TraceInformation("WHR " + category + " Ratings updated in " + DateTime.Now.Subtract(start).TotalSeconds + " seconds, " + (GC.GetTotalMemory(false) / (1 << 20)) + "MiB total memory allocated"); IEnumerable <Account> updatedRanks = new List <Account>(); using (var db = new ZkDataContext()) { var lastBattlePlayers = db.SpringBattlePlayers.Where(p => p.SpringBattleID == latestBattle.SpringBattleID && !p.IsSpectator).Include(x => x.Account).ToList(); if (latestBattle.GetRatingCategory() == category && lastBattleRanked) { lastBattleRanked = false; lastBattlePlayers.Where(p => playerOldRatings.ContainsKey(RatingSystems.GetRatingId(p.AccountID)) && !p.EloChange.HasValue).ForEach(p => { p.EloChange = playerRatings[RatingSystems.GetRatingId(p.AccountID)].RealElo - playerOldRatings[RatingSystems.GetRatingId(p.AccountID)].RealElo; }); updatedRanks = lastBattlePlayers.Where(p => Ranks.UpdateRank(p.Account, p.IsInVictoryTeam, !p.IsInVictoryTeam, db)).Select(x => x.Account).ToList(); updatedRanks.ForEach(p => db.Entry(p).State = EntityState.Modified); } db.SpringBattlePlayers.Where(p => p.SpringBattleID == latestBattle.SpringBattleID && !p.IsSpectator).ToList().ForEach(x => playerOldRatings[RatingSystems.GetRatingId(x.AccountID)] = playerRatings[RatingSystems.GetRatingId(x.AccountID)]); db.SaveChanges(); } RatingsUpdated(this, new RatingUpdate() { affectedPlayers = updatedRanks.Select(p => RatingSystems.GetRatingId(p.AccountID)) }); } } catch (Exception ex) { Trace.TraceError("Thread error while updating WHR " + category + " " + ex); } }, CancellationToken.None, TaskCreationOptions.None, PriorityScheduler.BelowNormal); lastUpdate = latestBattle; } }
//private //Runs in O(N log(N)) for all players private void UpdateRankings(IEnumerable <Player> players) { try { int currentDay = RatingSystems.ConvertDateToDays(DateTime.UtcNow); foreach (var p in players) { if (p.days.Count == 0) { Trace.TraceError("WHR " + category + " has invalid player " + p.id + " with no days(games)"); continue; } float elo = p.days.Last().getElo() + RatingOffset; float lastUncertainty = p.days.Last().uncertainty * 100; int lastDay = p.days.Last().day; playerRatings[p.id] = new PlayerRating(int.MaxValue, 1, elo, lastUncertainty, lastDay, currentDay); float rating = -playerRatings[p.id].Elo + 0.001f * (float)rand.NextDouble(); if (playerKeys.ContainsKey(p.id)) { sortedPlayers.Remove(playerKeys[p.id]); } playerKeys[p.id] = rating; sortedPlayers[rating] = p.id; } float[] playerUncertainties = new float[playerRatings.Count]; int index = 0; float DynamicMaxUncertainty = GlobalConst.MinimumDynamicMaxLadderUncertainty; int maxAge = GlobalConst.LadderActivityDays; foreach (var pair in playerRatings) { if (currentDay - pair.Value.LastGameDate > maxAge) { playerUncertainties[index++] = 9999 + index; //don't use infinity because i'm doing shady floating point things } else { playerUncertainties[index++] = (float)pair.Value.Uncertainty; } } Array.Sort(playerUncertainties); DynamicMaxUncertainty = Math.Max(DynamicMaxUncertainty, playerUncertainties[Math.Min(playerUncertainties.Length, GlobalConst.LadderSize) - 1] + 0.01f); int activePlayers = Math.Max(1, ~Array.BinarySearch(playerUncertainties, DynamicMaxUncertainty)); int rank = 0; List <int> newTopPlayers = new List <int>(); int matched = 0; List <float> newPercentileBrackets = new List <float>(); newPercentileBrackets.Add(3000); float percentile; float[] percentilesRev = Ranks.Percentiles.Reverse().ToArray(); foreach (var pair in sortedPlayers) { if (playerRatings[pair.Value].Uncertainty <= DynamicMaxUncertainty && currentDay - playerRatings[pair.Value].LastGameDate <= maxAge) { newTopPlayers.Add(pair.Value); if (rank == matched && rank < topPlayers.Count && topPlayers[rank] == pair.Value) { matched++; } rank++; percentile = (float)rank / activePlayers; if (newPercentileBrackets.Count <= Ranks.Percentiles.Length && percentile > percentilesRev[newPercentileBrackets.Count - 1]) { newPercentileBrackets.Add(playerRatings[pair.Value].Elo); } playerRatings[pair.Value].ApplyLadderUpdate(rank, percentile, currentDay); } else if (playerRatings[pair.Value].Rank < int.MaxValue) { playerRatings[pair.Value].ApplyLadderUpdate(int.MaxValue, 1, currentDay); } } this.activePlayers = rank; newPercentileBrackets.Add(0); PercentileBrackets = newPercentileBrackets.Select(x => x).Reverse().ToArray(); topPlayers = newTopPlayers; laddersCache = new List <Account>(); Trace.TraceInformation("WHR " + category + " Ladders updated with " + topPlayers.Count + "/" + this.players.Count + " entries, max uncertainty selected: " + DynamicMaxUncertainty + " brackets are now: " + string.Join(", ", PercentileBrackets)); var playerIds = players.Select(x => x.id).ToList(); if (playerIds.Count() < 100) { SaveToDB(playerIds); } else { SaveToDB(); } //check for rank updates using (var db = new ZkDataContext()) { var lastBattlePlayers = db.SpringBattlePlayers.Where(p => p.SpringBattleID == latestBattle.SpringBattleID && !p.IsSpectator).Include(x => x.Account).ToList(); if (latestBattle.GetRatingCategory() == category && lastBattleRanked) { lastBattleRanked = false; lastBattlePlayers.Where(p => playerOldRatings.ContainsKey(RatingSystems.GetRatingId(p.AccountID)) && !p.EloChange.HasValue).ForEach(p => { p.EloChange = playerRatings[RatingSystems.GetRatingId(p.AccountID)].RealElo - playerOldRatings[RatingSystems.GetRatingId(p.AccountID)].RealElo; }); var updatedRanks = lastBattlePlayers.Where(p => Ranks.UpdateRank(p.Account, p.IsInVictoryTeam, !p.IsInVictoryTeam, db)).Select(x => x.Account).ToList(); updatedRanks.ForEach(p => db.Entry(p).State = EntityState.Modified); RatingsUpdated(this, new RatingUpdate() { affectedPlayers = lastBattlePlayers.Select(x => x.AccountID) }); } db.SpringBattlePlayers.Where(p => p.SpringBattleID == latestBattle.SpringBattleID && !p.IsSpectator).ToList().ForEach(x => playerOldRatings[RatingSystems.GetRatingId(x.AccountID)] = playerRatings[RatingSystems.GetRatingId(x.AccountID)]); db.SaveChanges(); } //check for topX updates GetTopPlayers(GlobalConst.LadderSize); foreach (var listener in topPlayersUpdateListeners) { if (matched < listener.Value) { listener.Key.TopPlayersUpdated(GetTopPlayers(listener.Value)); } } } catch (Exception ex) { string dbg = "WHR " + category + ": Failed to update rankings " + ex + "\nPlayers: "; foreach (var p in players) { dbg += p.id + " (" + p.days.Count + " days), "; } Trace.TraceError(dbg); } }
/// <summary> /// Create or modify a PlanetWars <see cref="FactionTreaty"/> /// </summary> /// <param name="factionTreatyID">Existing <see cref="FactionTreaty"/> ID, if modifying one</param> /// <param name="turns">How long the treaty lasts</param> /// <param name="acceptingFactionID"></param> /// <param name="effectTypeID"><see cref="TreatyEffect"/> to add or remove, if applicable</param> /// <param name="effectValue"></param> /// <param name="planetID">Specifies the <see cref="Planet"/> for planet-based effects</param> /// <param name="isReverse"></param> /// <param name="note">Diplomatic note readable by both parties, to better communicate their intentions</param> /// <param name="add">If not null or empty, add the specified <see cref="TreatyEffect"/></param> /// <param name="delete">Delete the specified <see cref="TreatyEffect"/>?</param> /// <param name="propose">If not null or empty, this is a newly proposed treaty</param> /// <returns></returns> public ActionResult ModifyTreaty(int factionTreatyID, int?turns, int?acceptingFactionID, int?effectTypeID, double?effectValue, int?planetID, bool?isReverse, string note, string add, int?delete, string propose) { if (!Global.Account.HasFactionRight(x => x.RightDiplomacy)) { return(Content("Not a diplomat!")); } FactionTreaty treaty; // submit, store treaty in db var db = new ZkDataContext(); if (factionTreatyID > 0) { treaty = db.FactionTreaties.Single(x => x.FactionTreatyID == factionTreatyID); if (treaty.TreatyState != TreatyState.Invalid) { return(Content("Treaty already in progress!")); } } else { treaty = new FactionTreaty(); db.FactionTreaties.InsertOnSubmit(treaty); treaty.FactionByAcceptingFactionID = db.Factions.Single(x => x.FactionID == acceptingFactionID); } treaty.AccountByProposingAccountID = db.Accounts.Find(Global.AccountID); treaty.FactionByProposingFactionID = db.Factions.Single(x => x.FactionID == Global.FactionID); treaty.TurnsRemaining = turns; treaty.TurnsTotal = turns; treaty.TreatyNote = note; if (!string.IsNullOrEmpty(add)) { TreatyEffectType effectType = db.TreatyEffectTypes.Single(x => x.EffectTypeID == effectTypeID); var effect = new TreatyEffect { FactionByGivingFactionID = isReverse == true ? treaty.FactionByAcceptingFactionID : treaty.FactionByProposingFactionID, FactionByReceivingFactionID = isReverse == true ? treaty.FactionByProposingFactionID : treaty.FactionByAcceptingFactionID, TreatyEffectType = effectType, FactionTreaty = treaty }; if (effectType.HasValue) { if (effectType.MinValue.HasValue && effectValue < effectType.MinValue.Value) { effectValue = effectType.MinValue; } if (effectType.MaxValue.HasValue && effectValue > effectType.MaxValue.Value) { effectValue = effectType.MaxValue; } } if (effectType.HasValue) { effect.Value = effectValue; } if (effectType.IsPlanetBased) { effect.PlanetID = planetID.Value; } db.TreatyEffects.InsertOnSubmit(effect); } if (delete != null) { db.TreatyEffects.DeleteOnSubmit(db.TreatyEffects.Single(x => x.TreatyEffectID == delete)); } db.SaveChanges(); if (!string.IsNullOrEmpty(propose)) { treaty.TreatyState = TreatyState.Proposed; db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("{0} proposes a new treaty between {1} and {2} - {3}", treaty.AccountByProposingAccountID, treaty.FactionByProposingFactionID, treaty.FactionByAcceptingFactionID, treaty)); db.SaveChanges(); return(RedirectToAction("Detail", new { id = treaty.ProposingFactionID })); } return(View("FactionTreatyDefinition", db.FactionTreaties.Find(treaty.FactionTreatyID))); }
/// <summary> /// Go to a specific <see cref="ForumThread" /> /// </summary> /// <param name="lastPost">Go to last post</param> /// <param name="lastSeen">UNUSED</param> /// <param name="postID">A specific <see cref="ForumPost" /> ID to go to</param> /// <returns></returns> public ActionResult Thread(int?id, int?postID) { if (id == null) { if (postID == null) { return(RedirectToAction("Index")); } else { return(RedirectToAction("Post", new { id = postID })); } } var db = new ZkDataContext(); var t = db.ForumThreads.FirstOrDefault(x => x.ForumThreadID == id); // TODO - indicate thread has been deleted if (t == null) { return(RedirectToAction("Index")); } var cat = t.ForumCategory; if (cat != null) { if (cat.ForumMode == ForumMode.Missions && t.Missions.Any()) { return(RedirectToAction("Detail", "Missions", new { id = t.Missions.First().MissionID })); } if (cat.ForumMode == ForumMode.Maps && t.Resources.Any()) { return(RedirectToAction("Detail", "Maps", new { id = t.Resources.First().ResourceID })); } if (cat.ForumMode == ForumMode.SpringBattles && t.SpringBattles.Any()) { return(RedirectToAction("Detail", "Battles", new { id = t.SpringBattles.First().SpringBattleID })); } if (cat.ForumMode == ForumMode.Clans && t.Clan != null) { return(RedirectToAction("Detail", "Clans", new { id = t.RestrictedClanID })); } if (cat.ForumMode == ForumMode.Planets && t.Planets.Any()) { return(RedirectToAction("Planet", "Planetwars", new { id = t.Planets.First().PlanetID })); } } var res = new ThreadResult(); res.GoToPost = postID ?? t.UpdateLastRead(Global.AccountID, false); db.SaveChanges(); res.Path = cat?.GetPath() ?? new List <ForumCategory>(); res.CurrentThread = t; return(View(res)); }
public LoginResponse Login(User user, Login login, Client client) { string ip = client.RemoteEndpointIP; long userID = login.UserID; string lobbyVersion = login.LobbyVersion; using (var db = new ZkDataContext()) { Account acc = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name == login.Name); if (acc == null) { return new LoginResponse { ResultCode = LoginResponse.Code.InvalidName } } ; if (!acc.VerifyPassword(login.PasswordHash)) { return new LoginResponse { ResultCode = LoginResponse.Code.InvalidPassword } } ; if (state.Clients.ContainsKey(login.Name)) { return new LoginResponse { ResultCode = LoginResponse.Code.AlreadyConnected } } ; acc.Country = ResolveCountry(ip); acc.LobbyVersion = lobbyVersion; acc.LastLogin = DateTime.UtcNow; user.ClientType = login.ClientType; user.LobbyVersion = login.LobbyVersion; UpdateUserFromAccount(user, acc); LogIP(db, acc, ip); LogUserID(db, acc, userID); db.SaveChanges(); var banMute = Punishment.GetActivePunishment(acc.AccountID, ip, userID, x => x.BanMute, db); if (banMute != null) { user.BanMute = true; } Punishment banPenalty = Punishment.GetActivePunishment(acc.AccountID, ip, userID, x => x.BanLobby, db); if (banPenalty != null) { return (BlockLogin( string.Format("Banned until {0} (match to {1}), reason: {2}", banPenalty.BanExpires, banPenalty.AccountByAccountID.Name, banPenalty.Reason), acc, ip, userID)); } Account accAnteep = db.Accounts.FirstOrDefault(x => x.AccountID == 4490); if (accAnteep != null) { if (accAnteep.AccountUserIDs.Any(y => y.UserID == userID)) { Talk(String.Format("Suspected Anteep smurf: {0} (ID match {1}) {2}", acc.Name, userID, string.Format("{1}/Users/Detail/{0}", acc.AccountID, GlobalConst.BaseSiteUrl))); } if (userID > 0 && userID < 1000) { Talk(String.Format("Suspected Anteep smurf: {0} (too short userID {1}) {2}", acc.Name, userID, string.Format("{1}/Users/Detail/{0}", acc.AccountID, GlobalConst.BaseSiteUrl))); } if (accAnteep.AccountIPs.Any(y => y.IP == ip)) { Talk(String.Format("Suspected Anteep smurf: {0} (IP match {1}) {2}", acc.Name, ip, string.Format("{1}/Users/Detail/{0}", acc.AccountID, GlobalConst.BaseSiteUrl))); } } if (!acc.HasVpnException && GlobalConst.VpnCheckEnabled) { // check user IP against http://dnsbl.tornevall.org // does not catch all smurfs // mostly false positives, do not use string reversedIP = string.Join(".", ip.Split('.').Reverse().ToArray()); try { IPAddress[] resolved = Dns.GetHostEntry(string.Format("{0}.dnsbl.tornevall.org", reversedIP)).AddressList; if (resolved.Length > 0) { Talk(String.Format("User {0} {3} has IP {1} on dnsbl.tornevall.org ({2} result/s)", acc.Name, ip, resolved.Length, string.Format("{1}/Users/Detail/{0}", acc.AccountID, GlobalConst.BaseSiteUrl))); } } catch (SocketException sockEx) { // not in database, do nothing } } try { if (!acc.HasVpnException) { for (int i = 0; i <= 1; i++) { var whois = new Whois(); Dictionary <string, string> data = whois.QueryByIp(ip, i == 1); if (!data.ContainsKey("netname")) { data["netname"] = "UNKNOWN NETNAME"; } if (!data.ContainsKey("org-name")) { data["org-name"] = "UNKNOWN ORG"; } if (!data.ContainsKey("abuse-mailbox")) { data["abuse-mailbox"] = "no mailbox"; } if (!data.ContainsKey("notify")) { data["notify"] = "no notify address"; } if (!data.ContainsKey("role")) { data["role"] = "UNKNOWN ROLE"; } if (!data.ContainsKey("descr")) { data["descr"] = "no description"; } if (!data.ContainsKey("remarks")) { data["remarks"] = "no remarks"; } List <string> blockedCompanies = db.BlockedCompanies.Select(x => x.CompanyName.ToLower()).ToList(); List <string> blockedHosts = db.BlockedHosts.Select(x => x.HostName).ToList(); /*if (acc.Country == "MY") * { * client.Say(SayPlace.User, "KingRaptor", String.Format("USER {0}\nnetname: {1}\norgname: {2}\ndescr: {3}\nabuse-mailbox: {4}", * acc.Name, data["netname"], data["org-name"], data["descr"], data["abuse-mailbox"]), false); * }*/ bool blockedHost = blockedHosts.Any(x => data["abuse-mailbox"].Contains(x)) || (blockedHosts.Any(x => data["notify"].Contains(x))); foreach (string company in blockedCompanies) { if (data["netname"].ToLower().Contains(company) || data["org-name"].ToLower().Contains(company) || data["descr"].ToLower().Contains(company) || data["role"].ToLower().Contains(company) || data["remarks"].ToLower().Contains(company)) { blockedHost = true; break; } } string hostname = Dns.GetHostEntry(ip).HostName; if (blockedHosts.Any(hostname.Contains)) { blockedHost = true; } if (blockedHost) { return(BlockLogin("Connection using proxy or VPN is not allowed! (You can ask for exception)", acc, ip, userID)); } } } } catch (SocketException sockEx) {} catch (Exception ex) { Trace.TraceError("VPN check error: {0}", ex); } if (state.Clients.TryAdd(login.Name, client)) { return new LoginResponse { ResultCode = LoginResponse.Code.Ok } } ; else { return new LoginResponse() { ResultCode = LoginResponse.Code.AlreadyConnected } }; } } string ResolveCountry(string ip) { if (IsLanIP(ip)) { return("CZ"); } else { try { return(geoIP.Country(ip).Country.IsoCode); } catch (Exception ex) { Trace.TraceWarning("{0} Unable to resolve country", this); return("??"); } } } LoginResponse BlockLogin(string reason, Account acc, string ip, long user_id) { Talk(string.Format("Login denied for {0} IP:{1} ID:{2} reason: {3}", acc.Name, ip, user_id, reason)); return(new LoginResponse { Reason = reason, ResultCode = LoginResponse.Code.Banned }); }
public static void EndTurn(string mapName, List <string> extraData, ZkDataContext db, int?winNum, List <Account> players, StringBuilder text, SpringBattle sb, List <Account> attackers, IPlanetwarsEventCreator eventCreator, ZkLobbyServer.ZkLobbyServer server) { 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); var hqStructure = db.StructureTypes.FirstOrDefault(x => x.EffectDisconnectedMetalMalus != null || x.EffectDistanceMetalBonusMax != null); 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; } var evacuatedStructureTypeIDs = GetEvacuatedStructureTypes(extraData, db); string influenceReport = ""; // distribute influence // save influence gains // give influence to main attackers double planetIpDefs = planet.GetEffectiveIpDefense(); double baseInfluence = GlobalConst.BaseInfluencePerBattle; double influenceChange = baseInfluence; double loserInfluence = 0; Faction loserFaction = attacker; // TODO make this less awful bool reducedEnemyInfluence = false; bool flippedDominance = false; bool planetConquered = false; double shipBonus = planet.GetEffectiveShipIpBonus(attacker); double defenseBonus = -planetIpDefs; double techBonus = attacker.GetFactionUnlocks().Count() * GlobalConst.InfluencePerTech; double ipMultiplier = 1; string ipReason; if (!isAttackerWinner) { if (wasDefenderCcDestroyed) { ipMultiplier = GlobalConst.PlanetWarsDefenderWinKillCcMultiplier; ipReason = "from losing but killing defender's CC"; } else { ipMultiplier = 0; ipReason = "from losing horribly"; } } else { if (wasAttackerCcDestroyed) { ipReason = "from losing own CC"; ipMultiplier = GlobalConst.PlanetWarsAttackerWinLoseCcMultiplier; } else { ipReason = "from winning flawlessly"; } } influenceChange = (influenceChange + shipBonus + techBonus + defenseBonus) * ipMultiplier; if (influenceChange < 0) { influenceChange = 0; } influenceChange = Math.Floor(influenceChange * 100) / 100; // main winner influence // PlanetFaction entry = planet.PlanetFactions.FirstOrDefault(x => x.Faction == attacker); PlanetFaction entry = planet.PlanetFactions.FirstOrDefault(); if (entry == null) { entry = new PlanetFaction { Faction = attacker, Planet = planet, }; planet.PlanetFactions.Add(entry); } // if non-winner currently dominates planet if (entry.Faction != attacker) { loserFaction = entry.Faction; loserInfluence = entry.Influence; // if win is insufficient to change this if (loserInfluence >= influenceChange) { reducedEnemyInfluence = true; entry.Influence -= influenceChange; } else // flip dominance { flippedDominance = true; planet.PlanetFactions.Remove(entry); entry = new PlanetFaction { Faction = attacker, Planet = planet, }; planet.PlanetFactions.Add(entry); entry.Influence += (influenceChange - loserInfluence); if (entry.Influence >= GlobalConst.PlanetWarsMaximumIP) { entry.Influence = GlobalConst.PlanetWarsMaximumIP; planetConquered = true; } } } else // increase winner's existing dominance { if (entry.Influence < GlobalConst.PlanetWarsMaximumIP) { entry.Influence += influenceChange; if (entry.Influence >= GlobalConst.PlanetWarsMaximumIP) { entry.Influence = GlobalConst.PlanetWarsMaximumIP; planetConquered = true; } } } // TODO remove dependence on attacker if (planetConquered) { // Contest Adjacent Planets // GlobalConst.PlanetWarsBreakthroughIP } // Check all planets to see if they are contested by a single faction try { if (reducedEnemyInfluence) { influenceReport = String.Format("{0} reduced influence of {1} by {2} ({3}% {4} of {5}{6}{7}{8})", attacker.Shortcut, loserFaction.Shortcut, influenceChange, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", techBonus > 0 ? " +" + techBonus + " from techs" : "", shipBonus > 0 ? " +" + shipBonus + " from dropships" : "", defenseBonus != 0 ? " -" + -defenseBonus + " from defenses" : ""); } else { if (flippedDominance) { influenceReport = String.Format("{0} took dominance from {1} and gained {2} influence ({3}% {4} of {5}{6}{7}{8})", attacker.Shortcut, loserFaction.Shortcut, influenceChange - loserInfluence, (int)(ipMultiplier * 100.0), ipReason, baseInfluence + " base", techBonus > 0 ? " +" + techBonus + " from techs" : "", shipBonus > 0 ? " +" + shipBonus + " from dropships" : "", defenseBonus != 0 ? " -" + -defenseBonus + " from defenses" : ""); } else { influenceReport = String.Format("{0} gained {1} influence ({2}% {3} of {4}{5}{6}{7})", attacker.Shortcut, influenceChange, (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 = CalculateFactionMetalGain(planet, hqStructure, attacker, GlobalConst.PlanetWarsAttackerMetal, eventCreator, db, text, sb); var attackerMetal = Math.Floor(attackersTotalMetal / attackers.Count); foreach (Account w in attackers) { w.ProduceMetal(attackerMetal); var ev = eventCreator.CreateEvent("{0} gained {1} metal from battle {2}", w, attackerMetal, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } var defendersTotalMetal = planet.OwnerFactionID == null?Math.Floor(GlobalConst.PlanetWarsDefenderMetal) : CalculateFactionMetalGain(planet, hqStructure, planet.Faction, GlobalConst.PlanetWarsDefenderMetal, eventCreator, db, text, sb); if (defenders.Count > 0) { var defenderMetal = Math.Floor(defendersTotalMetal / defenders.Count); foreach (Account w in defenders) { w.ProduceMetal(defenderMetal); var ev = eventCreator.CreateEvent("{0} gained {1} metal from battle {2}", w, defenderMetal, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } } else { // planet had no defenders, give metal to owner's faction if (planet.OwnerFactionID != null) { planet.Faction.ProduceMetal(defendersTotalMetal); var ev = eventCreator.CreateEvent("{0} gained {1} metal from battle {2}", planet.Faction, defendersTotalMetal, sb); db.Events.InsertOnSubmit(ev); } } // remove attacker's dropships foreach (var pf in planet.PlanetFactions.Where(x => x.Faction == attacker)) { pf.Dropships = 0; } // remove dropships staying for too long (return to faction pool) foreach (var pf in planet.PlanetFactions.Where(x => x.Faction != attacker && x.Dropships > 0 && x.DropshipsLastAdded != null)) { if (DateTime.UtcNow.Subtract(pf.DropshipsLastAdded.Value).TotalMinutes > GlobalConst.PlanetWarsDropshipsStayForMinutes) { pf.Faction.ProduceDropships(pf.Dropships); 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 = eventCreator.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", StringComparison.InvariantCulture))) { 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.ReactivateAfterDestruction(); var ev = eventCreator.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 but evacuated foreach (var s in planet.PlanetStructures.Where(x => x.StructureType.IsIngameDestructible)) { if (evacuatedStructureTypeIDs.Contains(s.StructureTypeID)) { var evSaved = eventCreator.CreateEvent("{0} structure {1} on planet {2} has been saved by evacuation. {3}", planet.Faction, s.StructureType, planet, sb); db.Events.InsertOnSubmit(evSaved); text.AppendLine(evSaved.PlainText); } else { s.ReactivateAfterDestruction(); } } // destroy structures by battle (usually defenses) foreach (PlanetStructure s in planet.PlanetStructures.Where(x => x.StructureType.BattleDeletesThis).ToList()) { if (evacuatedStructureTypeIDs.Contains(s.StructureTypeID)) { var evSaved = eventCreator.CreateEvent("{0} structure {1} on planet {2} has been saved by evacuation. {3}", planet.Faction, s.StructureType, planet, sb); db.Events.InsertOnSubmit(evSaved); text.AppendLine(evSaved.PlainText); } else { planet.PlanetStructures.Remove(s); } } var ev = eventCreator.CreateEvent("All non-evacuated structures have been disabled on {0} planet {1}. {2}", planet.Faction, planet, sb); db.Events.InsertOnSubmit(ev); text.AppendLine(ev.PlainText); } db.SaveChanges(); // no longer used? //gal.DecayInfluence(); //gal.SpreadInfluence(); // process faction energies foreach (var fac in db.Factions.Where(x => !x.IsDeleted)) { fac.ProcessEnergy(gal.Turn); } // process production (incl. victory points) gal.ProcessProduction(); db.SaveChanges(); var vpFacs = db.Factions.Where(x => x.VictoryPoints > 0); if (vpFacs.Count() > 1) { foreach (var fac in vpFacs) { fac.VictoryPoints -= Math.Min(fac.VictoryPoints, GlobalConst.VictoryPointDecay); } } // delete one time activated structures gal.DeleteOneTimeActivated(eventCreator, db); db.SaveChanges(); // process treaties foreach (var tr in db.FactionTreaties.Where(x => x.TreatyState == TreatyState.Accepted || x.TreatyState == TreatyState.Suspended)) { var failedTradeFaction = tr.ProcessTrade(false); if (failedTradeFaction == null) { tr.TreatyState = TreatyState.Accepted; if (tr.TurnsTotal != null) { tr.TurnsRemaining--; if (tr.TurnsRemaining <= 0) // treaty expired { tr.TreatyState = TreatyState.Ended; tr.FactionByAcceptingFactionID.ProduceMetal(tr.AcceptingFactionGuarantee ?? 0); tr.FactionByProposingFactionID.ProduceMetal(tr.ProposingFactionGuarantee ?? 0); } } } else { // failed to perform trade if (tr.TreatyUnableToTradeMode == TreatyUnableToTradeMode.Suspend) { tr.TreatyState = TreatyState.Suspended; } else { // forced cancel tr.CancelTreaty(failedTradeFaction); db.Events.InsertOnSubmit(server.PlanetWarsEventCreator.CreateEvent("Treaty {0} between {1} and {2} cancelled by {3} because it failed to trade", tr, tr.FactionByProposingFactionID, tr.FactionByAcceptingFactionID, failedTradeFaction)); } } } // 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 SetPlanetOwners(eventCreator, db, sb != null ? db.SpringBattles.Find(sb.SpringBattleID) : null); gal = db.Galaxies.Single(x => x.IsDefault); var winByVictoryPoints = db.Factions.FirstOrDefault(x => !x.IsDeleted && x.VictoryPoints >= GlobalConst.PlanetWarsVictoryPointsToWin); if (winByVictoryPoints != null) { WinGame(db, gal, winByVictoryPoints, eventCreator.CreateEvent("CONGRATULATIONS!! {0} has won the PlanetWars by getting enough victory points!", winByVictoryPoints)); db.SaveChanges(); } 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); } server.PublishUserProfilePlanetwarsPlayers(); try { // store history foreach (Planet p in gal.Planets) { var hist = db.PlanetOwnerHistories.FirstOrDefault(x => x.PlanetID == p.PlanetID && x.Turn == gal.Turn); if (hist == null) { hist = new PlanetOwnerHistory() { PlanetID = p.PlanetID, Turn = gal.Turn }; db.PlanetOwnerHistories.Add(hist); } hist.OwnerAccountID = p.OwnerAccountID; hist.OwnerClanID = p.OwnerAccountID != null ? p.Account.ClanID : null; hist.OwnerFactionID = p.OwnerFactionID; } db.SaveChanges(); } 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.MapSupportLevel >= MapSupportLevel.Featured && 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 ActionResult CommanderProfile(int profileNumber, string name, int?chassis, string deleteCommander) { if (profileNumber < 1 || profileNumber > GlobalConst.CommanderProfileCount) { return(Content("WTF! get lost")); } var db = new ZkDataContext(); using (var scope = new TransactionScope()) { var unlocks = GetUserUnlockCountsListIncludingFree(db); Commander comm = db.Commanders.SingleOrDefault(x => x.ProfileNumber == profileNumber && x.AccountID == Global.AccountID); if (comm != null) { if (!string.IsNullOrEmpty(deleteCommander)) // delete commander { db.Commanders.DeleteOnSubmit(comm); db.SaveChanges(); scope.Complete(); return(GetCommanderProfileView(profileNumber)); } } else { comm = new Commander() { AccountID = Global.AccountID, ProfileNumber = profileNumber }; db.Commanders.InsertOnSubmit(comm); } if (comm.Unlock == null) { var chassisUnlock = unlocks.FirstOrDefault(x => x.Unlock.UnlockID == chassis); if ((chassis == null || chassisUnlock == null)) { return(GetCommanderProfileView(profileNumber)); } else { comm.ChassisUnlockID = chassis.Value; comm.Unlock = chassisUnlock.Unlock; } } if (!string.IsNullOrEmpty(name)) { if (name.Length > GlobalConst.MaxCommanderNameLength) { name = name.Substring(0, GlobalConst.MaxCommanderNameLength); } name = Regex.Replace(name, @"[^\u0020-\u007E]", string.Empty); // remove unicode stuff comm.Name = name; } // process modules foreach (var key in Request.Form.AllKeys.Where(x => !string.IsNullOrEmpty(x))) { var m = Regex.Match(key, "m([0-9]+)"); if (m.Success) { var slotId = int.Parse(m.Groups[1].Value); int unlockId; int.TryParse(Request.Form[key], out unlockId); if (unlockId > 0) { CommanderSlot slot = db.CommanderSlots.SingleOrDefault(x => x.CommanderSlotID == slotId); if (slot == null) { return(Content("WTF get lost!")); } Unlock unlock = db.Unlocks.SingleOrDefault(x => x.UnlockID == unlockId); if (unlock == null) { return(Content("WTF get lost!")); } if (!unlocks.Any(x => x.Unlock.UnlockID == unlock.UnlockID)) { return(Content("WTF get lost!")); } if (slot.MorphLevel < unlock.MorphLevel || !IsUnlockValidForSlot(unlock, slot)) { return(Content(string.Format("WTF cannot use {0} in slot {1}", unlock.Name, slot.CommanderSlotID))); } if (!string.IsNullOrEmpty(unlock.LimitForChassis)) { var validChassis = unlock.LimitForChassis.Split(','); if (!validChassis.Contains(comm.Unlock.Code)) { return(Content(string.Format("{0} cannot be used in commander {1}", unlock.Name, comm.Unlock.Name))); } } if (!IsPrerequisiteUnlockPresent(comm, unlock)) { return(Content(string.Format("{0} missing prerequisite module", unlock.Name))); } var comSlot = comm.CommanderModules.SingleOrDefault(x => x.SlotID == slotId); if (comSlot == null) { comSlot = new CommanderModule() { SlotID = slotId }; comm.CommanderModules.Add(comSlot); } comSlot.ModuleUnlockID = unlockId; } else { var oldModule = comm.CommanderModules.FirstOrDefault(x => x.SlotID == slotId); if (oldModule != null) { comm.CommanderModules.Remove(oldModule); } } } } // process decorations foreach (var key in Request.Form.AllKeys.Where(x => !string.IsNullOrEmpty(x))) { var d = Regex.Match(key, "d([0-9]+)"); if (d.Success) { var slotId = int.Parse(d.Groups[1].Value); int unlockId; int.TryParse(Request.Form[key], out unlockId); if (unlockId > 0) { CommanderDecorationSlot decSlot = db.CommanderDecorationSlots.SingleOrDefault(x => x.CommanderDecorationSlotID == slotId); if (decSlot == null) { return(Content("WTF get lost!")); } Unlock unlock = db.Unlocks.SingleOrDefault(x => x.UnlockID == unlockId && x.UnlockType == UnlockTypes.Decoration); if (unlock == null) { return(Content("WTF get lost!")); } if (!unlocks.Any(x => x.Unlock.UnlockID == unlock.UnlockID)) { return(Content("WTF get lost!")); } if (!string.IsNullOrEmpty(unlock.LimitForChassis)) { var validChassis = unlock.LimitForChassis.Split(','); if (!validChassis.Contains(comm.Unlock.Code)) { return(Content(string.Format("{0} cannot be used in commander {1}", unlock.Name, comm.Unlock.Name))); } } var comSlot = comm.CommanderDecorations.SingleOrDefault(x => x.SlotID == slotId); if (comSlot == null) { comSlot = new CommanderDecoration() { SlotID = slotId }; comm.CommanderDecorations.Add(comSlot); } comSlot.DecorationUnlockID = unlockId; } else { var oldDecoration = comm.CommanderDecorations.FirstOrDefault(x => x.SlotID == slotId); if (oldDecoration != null) { comm.CommanderDecorations.Remove(oldDecoration); } } } } // remove a module/decoration if ordered to foreach (var toDel in Request.Form.AllKeys.Where(x => !string.IsNullOrEmpty(x))) { var m = Regex.Match(toDel, "deleteSlot([0-9]+)"); if (m.Success) { var slotId = int.Parse(m.Groups[1].Value); comm.CommanderModules.Remove(comm.CommanderModules.SingleOrDefault(x => x.SlotID == slotId)); } var d = Regex.Match(toDel, "deleteDecorationSlot([0-9]+)"); if (d.Success) { var decSlotId = int.Parse(d.Groups[1].Value); comm.CommanderDecorations.Remove(comm.CommanderDecorations.SingleOrDefault(x => x.SlotID == decSlotId)); } } // cleanup invalid modules? db.SaveChanges(); foreach (var unlock in comm.CommanderModules.GroupBy(x => x.Unlock)) { if (unlock.Key == null) { continue; } var owned = unlocks.Where(x => x.Unlock.UnlockID == unlock.Key.UnlockID).Sum(x => (int?)x.Count) ?? 0; if (owned < unlock.Count()) { var toRemove = unlock.Count() - owned; foreach (var m in unlock.OrderByDescending(x => x.SlotID)) { db.CommanderModules.DeleteOnSubmit(m); //comm.CommanderModules.Remove(m); toRemove--; if (toRemove <= 0) { break; } } } } db.SaveChanges(); scope.Complete(); } return(GetCommanderProfileView(profileNumber)); }
//stores replay, springbattle, processes rating and xp, returns whether battle ended normally public static bool SubmitSpringBattleResult(SpringBattleContext result, ZkLobbyServer.ZkLobbyServer server, Action <BattleDebriefing> consumer) { var ret = new BattleDebriefing(); try { bool isValidGame = true; if (!result.GameEndedOk) { ret.Message = "Game didn't end properly"; isValidGame = false; } if (result.IsCheating) { ret.Message = "Cheats were enabled during this game"; isValidGame = false; } var db = new ZkDataContext(); var text = new StringBuilder(); var sb = SaveSpringBattle(result, db); if (isValidGame) { StoreAwards(result.OutputExtras, sb, db); } StoreLogs(result.OutputExtras, sb, db); if (result.LobbyStartContext.Mode == AutohostMode.Planetwars) { ProcessPlanetWars(result, server, sb, db, text); } Dictionary <int, int> orgLevels = sb.SpringBattlePlayers.Select(x => x.Account).ToDictionary(x => x.AccountID, x => x.Level); //fill in applicable ratings bool noElo = !isValidGame || result.LobbyStartContext.ModOptions.Any(x => x.Key.ToLower() == "noelo" && x.Value != "0" && x.Value != "false"); if (!noElo) { RatingSystems.FillApplicableRatings(sb, result); } if (isValidGame) { ProcessXP(result, server, db, sb); } ret.Url = string.Format("{1}/Battles/Detail/{0}", sb.SpringBattleID, GlobalConst.BaseSiteUrl); ret.ServerBattleID = sb.SpringBattleID; server.GhostSay( new Say() { Text = string.Format("BATTLE DETAILS AND REPLAY ----> {0} <-----", ret.Url), IsEmote = true, Place = SayPlace.Battle, User = GlobalConst.NightwatchName }, result.LobbyStartContext.BattleID); foreach (var p in sb.SpringBattlePlayers.Where(x => !x.IsSpectator)) { ret.DebriefingUsers[p.Account.Name] = new BattleDebriefing.DebriefingUser() { AccountID = p.AccountID, LoseTime = p.LoseTime ?? -1, AllyNumber = p.AllyNumber, IsInVictoryTeam = p.IsInVictoryTeam, EloChange = 0, IsRankdown = false, IsRankup = false, NewElo = -1, NextRankElo = -1, PrevRankElo = -1, NewRank = p.Account.Rank, XpChange = p.XpChange ?? 0, NewXp = p.Account.Xp, NextLevelXp = Account.GetXpForLevel(p.Account.Level + 1), PrevLevelXp = Account.GetXpForLevel(p.Account.Level), IsLevelUp = orgLevels[p.AccountID] < p.Account.Level, Awards = sb.AccountBattleAwards.Where(x => x.AccountID == p.AccountID).Select(x => new BattleDebriefing.DebriefingAward() { Value = x.Value, Key = x.AwardKey, Description = x.AwardDescription }).ToList() }; } //send to rating if (!noElo) { RatingSystems.ProcessResult(sb, result, new PendingDebriefing() { debriefingConsumer = consumer, partialDebriefing = ret, battle = sb, }); } Trace.TraceInformation("Battle ended: Server exited for B" + sb.SpringBattleID); db.SaveChanges(); return(true); } catch (Exception ex) { var data = JsonConvert.SerializeObject(result); Trace.TraceError($"{ex}\nData:\n{data}"); ret.Message = "Error processing game result: " + ex.Message; return(false); } }
public static void StartGalaxy(int galaxyID, params int[] startingPlanets) { using (var db = new ZkDataContext()) { var facs = db.Factions.Where(x => !x.IsDeleted).ToList(); if (startingPlanets == null || startingPlanets.Length < facs.Count) { startingPlanets = db.Planets.Where(x => x.GalaxyID == galaxyID && x.PlanetStructures.Any(y => y.StructureType.OwnerChangeWinsGame == true)) .OrderBy(x => x.Y) .ThenBy(x => x.Y) .Select(x => x.PlanetID) .ToArray(); } for (int i = 0; i < facs.Count; i++) { var pid = startingPlanets[i]; var planet = db.Planets.First(x => x.PlanetID == pid); var faction = facs[i]; planet.PlanetFactions.Add(new PlanetFaction() { Faction = faction, Influence = 100 }); planet.Faction = faction; } db.SaveChanges(); /*foreach (Account acc in db.Accounts) * { * double elo = acc.Elo; * if (acc.Elo1v1 > elo) elo = acc.Elo1v1; * acc.EloPw = elo; * } * System.Console.WriteLine("PW Elo set"); * foreach (Faction fac in db.Factions) * { * var accounts = fac.Accounts.Where(x=> x.Planets.Count > 0).ToList(); * foreach (Account acc in accounts) * { * acc.ProduceDropships(1); * } * fac.ProduceDropships(5); * } * System.Console.WriteLine("Dropships ready"); */ var gal = db.Galaxies.Single(x => x.GalaxyID == galaxyID); foreach (Planet planet in gal.Planets) { if (planet.Faction != null) { foreach (PlanetStructure s in planet.PlanetStructures) { //s.ActivatedOnTurn = 0; s.IsActive = true; } } else { foreach (PlanetStructure s in planet.PlanetStructures.Where(x => x.StructureType.OwnerChangeWinsGame != true)) { s.IsActive = false; s.ActivatedOnTurn = null; } } } System.Console.WriteLine("Structure activation set"); gal.Turn = 0; gal.Started = DateTime.UtcNow; db.SaveChanges(); } }
public ActionResult Punish(int accountID, string reason, bool deleteXP, bool deleteInfluence, bool banMute, bool banCommanders, bool banSite, bool banLobby, bool banUnlocks, bool banSpecChat, bool banForum, bool setRightsToZero, string banIP, long?banUserID, double banHours) { ZkDataContext db = new ZkDataContext(); Account acc = db.Accounts.SingleOrDefault(x => x.AccountID == accountID); if (acc == null) { return(Content("Invalid accountID")); } if (banHours > MaxBanHours) { banHours = MaxBanHours; // todo show some notification } Punishment punishment = new Punishment { Time = DateTime.UtcNow, Reason = reason, BanMute = banMute, BanCommanders = banCommanders, BanSite = banSite, BanLobby = banLobby, BanExpires = DateTime.UtcNow.AddHours(banHours), BanUnlocks = banUnlocks, BanSpecChat = banSpecChat, BanIP = banIP, BanForum = banForum, DeleteXP = deleteXP, DeleteInfluence = deleteInfluence, CreatedAccountID = Global.AccountID, UserID = banUserID }; acc.PunishmentsByAccountID.Add(punishment); db.SaveChanges(); // notify lobby of changes and post log message try { if (banLobby == true) { Global.Server.KickFromServer(Global.Account.Name, acc.Name, reason); } if (banMute == true) { Global.Server.PublishAccountUpdate(acc); } Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("New penalty for {0} {1} ", acc.Name, Url.Action("Detail", "Users", new { id = acc.AccountID }, "http"))); Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("Reason: {0} ", reason)); Global.Server.GhostPm(acc.Name, string.Format("Your account has received moderator action: {0}", reason)); } catch (Exception ex) { Trace.TraceError(ex.ToString()); Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, ex.ToString()); } return(RedirectToAction("Detail", new { id = accountID })); }
static void GenerateStructures(int galaxyID) { var rand = new Random(); var db = new ZkDataContext(); var gal = db.Galaxies.Single(x => x.GalaxyID == galaxyID); var names = Resources.names.Lines().ToList(); var wormhole = 16; var wormhole2 = 19; var mine = 1; var mine2 = 3; var mine3 = 4; var warp = 10; var chicken = 20; var dfac = 6; var ddepot = 7; int artefact = 9; int militia = 594; /* * 567 Jumpjet/Specialist Plant * 568 Screamer * 569 Athena * 570 Heavy Tank Factory * 571 Airplane Plant * 572 Krow * 573 Bantha * 574 Jugglenaut * 575 Detriment * 576 Singularity Reactor * 577 Annihilator * 578 Doomsday Machine * 579 Behemoth * 580 Starlight * 581 Big Bertha * 582 Goliath * 583 Licho * 584 Reef * 585 Scythe * 586 Panther * 587 Black Dawn * 588 Dominatrix * 589 Newton * 590 Shield Bot Factory * 591 Silencer * 592 Disco Rave Party*/ List <int> bannedStructures = new List <int>() { }; // { 568, 577, 578, 584, 585, 586, 588, 589, 571, 590 }; var structs = db.StructureTypes.Where(x => x.Unlock != null && !bannedStructures.Contains(x.StructureTypeID)); List <Tuple <int, int> > costs = new List <Tuple <int, int> >(); foreach (var s in structs) { costs.Add(Tuple.Create((int)(5000 / s.Cost), s.StructureTypeID)); // probabality is relative to 1200-cost } var sumCosts = costs.Sum(x => x.Item1); foreach (var p in gal.Planets) { p.PlanetStructures.Clear(); //p.Name = names[rand.Next(names.Count)]; //names.Remove(p.Name); //if (rand.Next(50) == 0 ) p.AddStruct(wormhole2); //else //if (rand.Next(10)<8) p.AddStruct(wormhole); //p.AddStruct(militia); //if (rand.Next(30) ==0) p.AddStruct(mine3); //else if (rand.Next(20)==0) p.AddStruct(mine2); //else //if (rand.Next(20) ==0) p.AddStruct(mine); //if (rand.Next(20) == 0) p.AddStruct(dfac); //if (rand.Next(20) == 0) p.AddStruct(ddepot); //if (rand.Next(20) == 0) p.AddStruct(warp); if (p.Resource.MapIsChickens == true) { p.AddStruct(chicken); } // tech structures /*if (rand.Next(8) ==0) * { * * var probe = rand.Next(sumCosts); * foreach (var s in costs) * { * probe -= s.Item1; * if (probe <= 0) * { * p.AddStruct(s.Item2); * break; * } * } * }*/ } // artefacts //foreach (var p in gal.Planets.Where(x => x.Resource.MapIsChickens!=true && !x.Resource.MapIsFfa != true && x.Resource.MapIs1v1 != true).Shuffle().Take(5)) p.AddStruct(artefact); // jump gates //foreach (var p in gal.Planets.Shuffle().Take(6)) p.AddStruct(warp); db.SaveChanges(); db.SaveChanges(); }
public void SaveGalaxy(int galaxyNumber) { // using (var scope = new TransactionScope()) { try { var db = new ZkDataContext(); var gal = db.Galaxies.SingleOrDefault(x => x.GalaxyID == galaxyNumber); if (gal == null || galaxyNumber == 0) { gal = new Galaxy(); db.Galaxies.InsertOnSubmit(gal); } else if (gal.Started != null) { MessageBox.Show("This galaxy is running, cannot edit it!"); return; } else { db.Links.DeleteAllOnSubmit(gal.Links); db.Planets.DeleteAllOnSubmit(gal.Planets); } gal.IsDirty = true; db.SaveChanges(); galaxyNumber = gal.GalaxyID; var maps = Maps.Shuffle(); var cnt = 0; foreach (var d in PlanetDrawings) { var memPlanet = d.Planet; var p = new Planet(); db.Planets.Add(p); p.Name = memPlanet.Name; p.GalaxyID = galaxyNumber; p.OwnerAccountID = memPlanet.OwnerAccountID; p.X = (float)(Canvas.GetLeft(d) / imageSource.Width); p.Y = (float)(Canvas.GetTop(d) / imageSource.Height); if (memPlanet.MapResourceID == null) { p.MapResourceID = maps[cnt].ResourceID; cnt++; cnt = cnt % maps.Count; } else { p.MapResourceID = memPlanet.MapResourceID; } p.PlanetStructures.Clear(); p.PlanetStructures.AddRange(memPlanet.PlanetStructures.Select(x => new PlanetStructure() { StructureTypeID = x.StructureTypeID })); } db.SaveChanges(); var linkList = LinkDrawings.Select( d => new Link() { GalaxyID = galaxyNumber, PlanetID1 = db.Planets.Single(x => x.GalaxyID == galaxyNumber && x.Name == d.Planet1.Planet.Name).PlanetID, PlanetID2 = db.Planets.Single(x => x.GalaxyID == galaxyNumber && x.Name == d.Planet2.Planet.Name).PlanetID }); db.Links.InsertAllOnSubmit(linkList); db.SaveChanges(); // scope.Complete(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } MessageBox.Show("Exported!"); } }
public static ReturnValue RegisterResource(int apiVersion, string springVersion, string md5, int length, ResourceType resourceType, string archiveName, string internalName, byte[] serializedData, List <string> dependencies, byte[] minimap, byte[] metalMap, byte[] heightMap, byte[] torrentData) { if (md5 == null) { throw new ArgumentNullException("md5"); } if (archiveName == null) { throw new ArgumentNullException("archiveName"); } if (internalName == null) { throw new ArgumentNullException("internalName"); } if (serializedData == null) { throw new ArgumentNullException("serializedData"); } if (torrentData == null) { throw new ArgumentNullException("torrentData"); } if (PlasmaServerApiVersion > apiVersion) { throw new Exception("Obsolete PlasmaServer Client"); } if (dependencies == null) { dependencies = new List <string>(); } var db = new ZkDataContext(); var contentFile = db.ResourceContentFiles.FirstOrDefault(x => x.Md5 == md5); if (contentFile != null) { // content file already stored if (contentFile.Resource.InternalName != internalName) { return(ReturnValue.Md5AlreadyExistsWithDifferentName); } // new spring version we add its hash StoreMetadata(md5, contentFile.Resource, serializedData, torrentData, minimap, metalMap, heightMap); db.SaveChanges(); return(ReturnValue.Ok); } var resource = db.Resources.Where(x => x.InternalName == internalName).SingleOrDefault(); if (resource == null) { resource = new Resource { InternalName = internalName, TypeID = resourceType }; db.Resources.Add(resource); StoreMetadata(md5, resource, serializedData, torrentData, minimap, metalMap, heightMap); } if (!resource.ResourceDependencies.Select(x => x.NeedsInternalName).Except(dependencies).Any()) { // new dependencies are superset foreach (var depend in dependencies) { // add missing dependencies var s = depend; if (!resource.ResourceDependencies.Any(x => x.NeedsInternalName == s)) { resource.ResourceDependencies.Add(new ResourceDependency { NeedsInternalName = depend }); } } } if (resource.ResourceContentFiles.Any(x => x.Length == length && x.Md5 != md5)) { return(ReturnValue.Md5AlreadyExistsWithDifferentName); // add proper message - file exists with different md5 and same size - cant register cant detect mirrors } var newContentFile = new ResourceContentFile { FileName = archiveName, Length = length, Md5 = md5, Resource = resource }; resource.ResourceContentFiles.Add(newContentFile); ResourceLinkProvider.UpdateLinks(newContentFile); File.WriteAllBytes(GetTorrentPath(internalName, md5), torrentData); // add new torrent file db.SaveChanges(); return(ReturnValue.Ok); }