public static Faction PerformLeaveFaction(int accountID, bool keepClan = false, ZkDataContext db = null) { if (db == null) { db = new ZkDataContext(); } Account acc = db.Accounts.Single(x => x.AccountID == Global.AccountID); Faction faction = acc.Faction; if (!keepClan && acc.Clan != null) { ClansController.PerformLeaveClan(Global.AccountID); } db.AccountRoles.DeleteAllOnSubmit(acc.AccountRolesByAccountID.Where(x => !keepClan || x.ClanID == null).ToList()); acc.ResetQuotas(); foreach (var ps in acc.PlanetStructures) { ps.OwnerAccountID = null; } foreach (var planet in acc.Planets) { planet.OwnerAccountID = null; } db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("{0} leaves faction {1}", acc, acc.Faction)); db.SaveChanges(); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator(), db); using (var db2 = new ZkDataContext()) { Account acc2 = db2.Accounts.Single(x => x.AccountID == Global.AccountID); acc2.FactionID = null; db2.SaveChanges(); Global.Server.PublishAccountUpdate(acc2); Global.Server.PublishUserProfileUpdate(acc2); PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator(), db2); } return(faction); }
public ActionResult NewPost(int?categoryID, int?threadID, int?forumPostID, string wikiKey) { var res = new NewPostResult(); var db = new ZkDataContext(); var penalty = Punishment.GetActivePunishment(Global.AccountID, Request.UserHostAddress, 0, 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))); } if (threadID.HasValue && threadID > 0) { var clan = db.Clans.FirstOrDefault(x => x.ForumThreadID == threadID); if (clan != null && Global.ClanID != clan.ClanID) { return(Content(string.Format("You are not a member of {0}, you cannot post in their clan thread", clan.ClanName))); } var t = db.ForumThreads.Single(x => x.ForumThreadID == threadID.Value); res.CurrentThread = t; res.LastPosts = res.CurrentThread.ForumPosts.OrderByDescending(x => x.ForumPostID).Take(20); if (!categoryID.HasValue) { categoryID = t.ForumCategoryID; } } if (!categoryID.HasValue) { categoryID = db.ForumCategories.Where(x => !x.IsLocked && x.ForumMode == ForumMode.General).OrderBy(x => x.SortOrder).First().ForumCategoryID; // post in general by default } var category = db.ForumCategories.FirstOrDefault(x => x.ForumCategoryID == categoryID); res.Path = category?.GetPath() ?? new List <ForumCategory>(); res.CurrentCategory = category; if (forumPostID != null) { var post = db.ForumPosts.Single(x => x.ForumPostID == forumPostID); if (!post.CanEdit(Global.Account)) { return(Content("You cannot edit this post")); } res.EditedPost = post; } if (threadID != null) { var thread = res.CurrentThread; res.CanSetTopic = (thread.ForumPosts.Count > 0 && thread.ForumPosts.First().ForumPostID == forumPostID && (category.ForumMode == ForumMode.General || category.ForumMode == ForumMode.Wiki || category.ForumMode == ForumMode.Archive)); } else { res.CanSetTopic = true; } res.WikiKey = wikiKey; return(View(res)); }
/// <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 async Task <LoginCheckerResponse> DoLogin(Login login, string ip, List <ulong> dlc) { var limit = MiscVar.ZklsMaxUsers; if (limit > 0 && server.ConnectedUsers.Count >= limit) { return(new LoginCheckerResponse(LoginResponse.Code.ServerFull)); } 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; acc.VerifyAndAddDlc(dlc); 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 PostNews(News nn, HttpPostedFileBase image) { if (string.IsNullOrEmpty(nn.Title) || string.IsNullOrEmpty(nn.Text)) { return(Content("Empty text!")); } var db = new ZkDataContext(); using (var scope = new TransactionScope()) { News news; if (nn.NewsID == 0) { news = new News(); news.Created = nn.Created; } else { news = db.News.Single(x => x.NewsID == nn.NewsID); } news.AuthorAccountID = Global.AccountID; news.Title = nn.Title; news.Text = nn.Text; Image im = null; if (image != null && image.ContentLength > 0) { im = Image.FromStream(image.InputStream); news.ImageExtension = Path.GetExtension(image.FileName); news.ImageContentType = image.ContentType; news.ImageLength = image.ContentLength; } news.HeadlineUntil = nn.HeadlineUntil; string postText = news.Text; if (nn.NewsID == 0) { var thread = new ForumThread() { Created = news.Created, CreatedAccountID = news.AuthorAccountID, Title = news.Title, ForumCategoryID = db.ForumCategories.Single(x => x.ForumMode == ForumMode.News).ForumCategoryID }; thread.ForumPosts.Add(new ForumPost() { Created = news.Created, Text = postText, AuthorAccountID = news.AuthorAccountID }); db.ForumThreads.InsertOnSubmit(thread); db.SaveChanges(); news.ForumThreadID = thread.ForumThreadID; db.News.InsertOnSubmit(news); } db.SaveChanges(); // add image to the start of the forum post we made // do it down here so it gets the correct news ID if (!String.IsNullOrWhiteSpace(news.ImageRelativeUrl) && news.ForumThread != null) { postText = "[img]" + news.ImageRelativeUrl + "[/img]" + Environment.NewLine + postText; news.ForumThread.ForumPosts.ElementAt(0).Text = postText; db.SaveChanges(); } if (im != null) { im.Save(Server.MapPath(news.ImageRelativeUrl)); Image thumb = im.GetResized(120, (int)Math.Round(120.0 / im.Width * im.Height), InterpolationMode.HighQualityBicubic); thumb.Save(Server.MapPath(news.ThumbRelativeUrl)); } scope.Complete(); } return(Content("Posted!")); }
Account UpdateUser(int lobbyID, string name, User user, string hashedPassword, ZkDataContext db = null) { Account acc = null; if (db == null) { db = new ZkDataContext(); } acc = Account.AccountByLobbyID(db, lobbyID); if (acc == null) { acc = new Account(); db.Accounts.InsertOnSubmit(acc); } acc.LobbyID = lobbyID; acc.Name = name; if (!string.IsNullOrEmpty(hashedPassword)) { acc.Password = hashedPassword; } acc.LastLogin = DateTime.UtcNow; if (user != null) // user was online, we can update his data { acc.IsBot = user.IsBot; acc.IsLobbyAdministrator = user.IsAdmin; acc.Country = user.Country; acc.LobbyTimeRank = user.Rank; } db.SubmitAndMergeChanges(); return(acc); }
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 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) { foreach (PlanetFaction pf in planet.PlanetFactions.Where(x => x.FactionID != acc.FactionID)) { pf.Influence -= ipKillAmmount; if (pf.Influence < 0) { pf.Influence = 0; } } } 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 })); }
public ActionResult Events(int?planetID, int?accountID, int?springBattleID, int?clanID, int?factionID, string filter, int pageSize = 0, int page = 0, bool partial = false) { var db = new ZkDataContext(); if (Request.IsAjaxRequest()) { partial = true; } if (pageSize == 0) { if (!partial) { pageSize = 40; } else { pageSize = 10; } } IQueryable <Event> res = db.Events.AsQueryable(); if (planetID.HasValue) { res = res.Where(x => x.Planets.Any(y => y.PlanetID == planetID)); } if (accountID.HasValue) { res = res.Where(x => x.Accounts.Any(y => y.AccountID == accountID)); } if (clanID.HasValue) { res = res.Where(x => x.Clans.Any(y => y.ClanID == clanID)); } if (springBattleID.HasValue) { res = res.Where(x => x.SpringBattles.Any(y => y.SpringBattleID == springBattleID)); } if (factionID.HasValue) { res = res.Where(x => x.Factions.Any(y => y.FactionID == factionID)); } if (!string.IsNullOrEmpty(filter)) { res = res.Where(x => x.Text.Contains(filter)); } res = res.OrderByDescending(x => x.EventID); var ret = new EventsResult { PageCount = (res.Count() / pageSize) + 1, Page = page, Events = res.Skip(page * pageSize).Take(pageSize), PlanetID = planetID, AccountID = accountID, SpringBattleID = springBattleID, Filter = filter, ClanID = clanID, Partial = partial, PageSize = pageSize }; return(View(ret)); }
public AuthService(TasClient client) { this.client = client; this.client.LoginAccepted += (s, e) => { client.JoinChannel(ModeratorChannel); client.JoinChannel(Top20Channel); using (var db = new ZkDataContext()) foreach (var fac in db.Factions.Where(x => !x.IsDeleted)) { client.JoinChannel(fac.Shortcut); } }; this.client.UserAdded += (s, e) => { if (e.Name == client.UserName) { return; } if (e.SpringieLevel > 2 || e.IsAdmin) { client.ForceJoinChannel(e.Name, ModeratorChannel); } if (topPlayers.IsTop20(e.AccountID)) { client.ForceJoinChannel(e.Name, Top20Channel); } if (e.Clan != null) { client.ForceJoinChannel(e.Name, Clan.GetClanChannel(e.Clan)); } if (e.Faction != null && e.Level >= GlobalConst.FactionChannelMinLevel) { client.ForceJoinChannel(e.Name, e.Faction); } }; // TODO set bot mode //this.client.BattleFound += // (s, e) => { if (e.Data.Founder.IsZkLobbyUser && !e.Data.Founder.IsBot) client.SetBotMode(e.Data.Founder.Name, true); }; this.client.ChannelUserAdded += (sender, args) => { try { var channel = args.Channel.Name; foreach (var u in args.Users) { if (u.Name == client.UserName) { continue; } if (channel == ModeratorChannel) { if (u.SpringieLevel <= 2 && !u.IsAdmin) { client.ForceLeaveChannel(u.Name, ModeratorChannel); } } else if (channel == Top20Channel) { if (!topPlayers.IsTop20(u.AccountID) && u.Name != client.UserName) { client.ForceLeaveChannel(u.Name, Top20Channel); } } else { using (var db = new ZkDataContext()) { var fac = db.Factions.FirstOrDefault(x => x.Shortcut == channel); if (fac != null) { // faction channel var acc = db.Accounts.Find(u.AccountID); if (acc == null || acc.FactionID != fac.FactionID || acc.Level < GlobalConst.FactionChannelMinLevel) { client.ForceLeaveChannel(u.Name, channel); } } } } } } catch (Exception ex) { Trace.TraceError("Error procesisng channel user added: {0}", ex); } }; this.client.ChannelUserRemoved += (sender, args) => { try { var channel = args.Channel.Name; if (channel == ModeratorChannel) { var u = args.User; if (u.SpringieLevel > 2 || u.IsAdmin) { client.ForceJoinChannel(u.Name, ModeratorChannel); } } } catch (Exception ex) { Trace.TraceError("Error procesisng channel user added: {0}", ex); } }; }
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 = db.AccountUnlocks.Where(x => x.AccountID == Global.AccountID); 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.SubmitChanges(); scope.Complete(); return(GetCommanderProfileView(db, profileNumber)); } } else { comm = new Commander() { AccountID = Global.AccountID, ProfileNumber = profileNumber }; db.Commanders.InsertOnSubmit(comm); } if (comm.Unlock == null) { var chassisUnlock = unlocks.FirstOrDefault(x => x.UnlockID == chassis); if ((chassis == null || chassisUnlock == null)) { return(GetCommanderProfileView(db, profileNumber)); } else { comm.ChassisUnlockID = chassis.Value; comm.Unlock = chassisUnlock.Unlock; } } if (!string.IsNullOrEmpty(name)) { if (name.Length > 50) { name = name.Substring(0, 50); } name = Regex.Replace(name, @"[^\u0000-\u007F]", 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.Single(x => x.CommanderSlotID == slotId); Unlock unlock = db.Unlocks.Single(x => x.UnlockID == unlockId); if (!unlocks.Any(x => x.UnlockID == unlock.UnlockID)) { return(Content("WTF get lost!")); } if (slot.MorphLevel < unlock.MorphLevel || slot.UnlockType != unlock.UnlockType) { 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))); } } 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.Single(x => x.CommanderDecorationSlotID == slotId); Unlock unlock = db.Unlocks.Single(x => x.UnlockID == unlockId); if (!unlocks.Any(x => x.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)); } } db.SubmitChanges(); foreach (var unlock in comm.CommanderModules.GroupBy(x => x.Unlock)) { if (unlock.Key == null) { continue; } var owned = unlocks.Where(x => x.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.SubmitChanges(); scope.Complete(); } return(GetCommanderProfileView(db, profileNumber)); }
/// <summary> /// Sets up all the things that Springie needs to know for the battle: how to balance, who to get extra commanders, /// what PlanetWars structures to create, etc. /// </summary> public static LobbyHostingContext GetDedicatedServerStartSetup(LobbyHostingContext context) { var ret = context; try { var mode = context.Mode; var commProfiles = new LuaTable(); var db = new ZkDataContext(); // calculate to whom to send extra comms var accountIDsWithExtraComms = new List <int>(); if (mode == AutohostMode.Planetwars || mode == AutohostMode.GameFFA || mode == AutohostMode.Teams) { var groupedByTeam = context.Players.Where(x => !x.IsSpectator).GroupBy(x => x.AllyID).OrderByDescending(x => x.Count()); var biggest = groupedByTeam.FirstOrDefault(); if (biggest != null) { foreach (var other in groupedByTeam.Skip(1)) { var cnt = biggest.Count() - other.Count(); if (cnt > 0) { foreach (var a in other.Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID)) .OrderByDescending(x => x.Elo * x.EloWeight) .Take(cnt)) { accountIDsWithExtraComms.Add(a.AccountID); } } } } } // write Planetwars details to modoptions (for widget) Faction attacker = null; Faction defender = null; Planet planet = null; if (mode == AutohostMode.Planetwars) { planet = db.Galaxies.First(x => x.IsDefault).Planets.First(x => x.Resource.InternalName == context.Map); attacker = context.Players.Where(x => x.AllyID == 0 && !x.IsSpectator) .Select(x => db.Accounts.First(y => y.AccountID == x.LobbyID)) .Where(x => x.Faction != null) .Select(x => x.Faction) .First(); defender = planet.Faction; if (attacker == defender) { defender = null; } ret.ModOptions["attackingFaction"] = attacker.Shortcut; ret.ModOptions["attackingFactionName"] = attacker.Name; ret.ModOptions["attackingFactionColor"] = attacker.Color; if (defender != null) { ret.ModOptions["defendingFaction"] = defender.Shortcut; ret.ModOptions["defendingFactionName"] = defender.Name; ret.ModOptions["defendingFactionColor"] = defender.Color; } else { ret.ModOptions["defendingFaction"] = "Mercenary"; ret.ModOptions["defendingFactionName"] = "Local militia"; ret.ModOptions["defendingFactionColor"] = "#CCCCCC"; } ret.ModOptions["planet"] = planet.Name; } // write player custom keys (level, elo, is muted, etc.) foreach (var p in context.Players) { var user = db.Accounts.Where(x => x.AccountID == p.LobbyID).Include(x => x.RelalationsByOwner).FirstOrDefault(); if (user != null) { var userParams = new Dictionary <string, string>(); ret.UserParameters[p.Name] = userParams; userParams["LobbyID"] = user.AccountID.ToString(); userParams["CountryCode"] = user.Country; var userBanMuted = Punishment.GetActivePunishment(user.AccountID, null, null, x => x.BanMute) != null; if (userBanMuted) { userParams["muted"] = "1"; } userParams["faction"] = user.Faction != null ? user.Faction.Shortcut : ""; userParams["clan"] = user.Clan != null ? user.Clan.Shortcut : ""; userParams["clanfull"] = user.Clan != null ? user.Clan.ClanName : ""; userParams["level"] = user.Level.ToString(); //userParams["mm_elo"] = Math.Round(user.EffectiveMmElo).ToString(); //userParams["casual_elo"] = Math.Round(user.EffectiveElo).ToString(); userParams["elo"] = Math.Round(RatingSystems.DisableRatingSystems ? user.BestEffectiveElo : user.GetBestRating().Elo).ToString(); userParams["icon"] = user.GetIconName(); userParams["avatar"] = user.Avatar; userParams["badges"] = string.Join(",", user.GetBadges()); userParams["admin"] = user.AdminLevel >= AdminLevel.Moderator ? "1" : "0"; if (p.PartyID.HasValue) { userParams["PartyID"] = p.PartyID.ToString(); } var userSpecChatBlocked = Punishment.GetActivePunishment(user.AccountID, null, null, x => x.BanSpecChat) != null;; userParams["can_spec_chat"] = userSpecChatBlocked ? "0" : "1"; userParams["ignored"] = string.Join(",", user.RelalationsByOwner.Where(x => x.Relation == Relation.Ignore).Select(x => x.Target.Name)); userParams["friends"] = string.Join(",", user.RelalationsByOwner.Where(x => x.Relation == Relation.Friend).Select(x => x.Target.Name)); if (!p.IsSpectator) { // set valid PW structure attackers if (mode == AutohostMode.Planetwars) { userParams["pwRank"] = (user.AccountRolesByAccountID.Where( x => !x.RoleType.IsClanOnly && (x.RoleType.RestrictFactionID == null || x.RoleType.RestrictFactionID == user.FactionID)).OrderBy(x => x.RoleType.DisplayOrder).Select(x => (int?)x.RoleType.DisplayOrder).FirstOrDefault() ?? 999).ToString(); var allied = user.Faction != null && defender != null && user.Faction != defender && defender.HasTreatyRight(user.Faction, x => x.EffectPreventIngamePwStructureDestruction == true, planet); if (!allied && user.Faction != null && (user.Faction == attacker || user.Faction == defender)) { userParams["canAttackPwStructures"] = "1"; } userParams["pwInstructions"] = Convert.ToBase64String(Encoding.UTF8.GetBytes(GetPwInstructions(planet, user, db, attacker))); } if (accountIDsWithExtraComms.Contains(user.AccountID)) { userParams["extracomm"] = "1"; } var commProfileIDs = new LuaTable(); var userCommandersBanned = Punishment.GetActivePunishment(user.AccountID, null, null, x => x.BanCommanders) != null; if (!userCommandersBanned) { // set up commander data foreach (var c in user.Commanders.Where(x => x.Unlock != null && x.ProfileNumber <= GlobalConst.CommanderProfileCount) ) { try { var commProfile = new LuaTable(); if (string.IsNullOrEmpty(c.Name) || c.Name.Any(x => x == '"')) { c.Name = c.CommanderID.ToString(); } commProfiles.Add("c" + c.CommanderID, commProfile); commProfileIDs.Add("c" + c.CommanderID); // process decoration icons var decorations = new LuaTable(); foreach (var d in c.CommanderDecorations.Where(x => x.Unlock != null).OrderBy(x => x.SlotID).Select(x => x.Unlock)) { var iconData = db.CommanderDecorationIcons.FirstOrDefault(x => x.DecorationUnlockID == d.UnlockID); if (iconData != null) { string iconName = null, iconPosition = null; // FIXME: handle avatars and preset/custom icons if (iconData.IconType == (int)DecorationIconTypes.Faction) { iconName = user.Faction != null ? user.Faction.Shortcut : null; } else if (iconData.IconType == (int)DecorationIconTypes.Clan) { iconName = user.Clan != null ? user.Clan.Shortcut : null; } if (iconName != null) { iconPosition = CommanderDecoration.GetIconPosition(d); var entry = new LuaTable(); entry.Add("image", iconName); decorations.Add("icon_" + iconPosition.ToLower(), entry); } } else { decorations.Add(d.Code); } } commProfile["name"] = c.Name.Substring(0, Math.Min(25, c.Name.Length)); commProfile["chassis"] = c.Unlock.Code; commProfile["decorations"] = decorations; var modules = new LuaTable(); commProfile["modules"] = modules; for (var i = 1; i <= GlobalConst.NumCommanderLevels; i++) { var modulesForLevel = new LuaTable(); modules.Add(modulesForLevel); var modulesOrdered = c.CommanderModules.Where(x => x.CommanderSlot.MorphLevel == i).ToList(); var slots = db.CommanderSlots.ToList().Where(x => x.MorphLevel == i && (x.ChassisID == null || (x.ChassisID == c.ChassisUnlockID))).ToList(); slots.Sort(delegate(CommanderSlot x, CommanderSlot y) { UnlockTypes type1 = x.UnlockType; UnlockTypes type2 = x.UnlockType; if (type1 == UnlockTypes.WeaponManualFire || type1 == UnlockTypes.WeaponBoth) { type1 = UnlockTypes.Weapon; } if (type2 == UnlockTypes.WeaponManualFire || type2 == UnlockTypes.WeaponBoth) { type2 = UnlockTypes.Weapon; } int result = type1.CompareTo(type2); if (result == 0) { return(x.CommanderSlotID.CompareTo(y.CommanderSlotID)); } else { return(result); } }); foreach (var slot in slots) { String value = String.Empty; var module = c.CommanderModules.FirstOrDefault(x => x.SlotID == slot.CommanderSlotID); if (module != null) { value = module.Unlock.Code; } modulesForLevel.Add(value); } } } catch (Exception ex) { Trace.TraceError(ex.ToString()); throw new ApplicationException( $"Error processing commander: {c.CommanderID} - {c.Name} of player {user.AccountID} - {user.Name}", ex); } } } else { userParams["jokecomm"] = "1"; } userParams["commanders"] = commProfileIDs.ToBase64String(); } } } ret.ModOptions["commanderTypes"] = commProfiles.ToBase64String(); // set PW structures if (mode == AutohostMode.Planetwars) { var owner = planet.Faction != null ? planet.Faction.Shortcut : ""; var pwStructures = new LuaTable(); foreach ( var s in planet.PlanetStructures.Where(x => x.StructureType != null && !string.IsNullOrEmpty(x.StructureType.IngameUnitName))) { pwStructures.Add(s.StructureType.IngameUnitName, new LuaTable { { "unitname", s.StructureType.IngameUnitName }, { "owner", s.Account?.Name }, { "canBeEvacuated", s.StructureType.IsIngameEvacuable }, { "canBeDestroyed", s.StructureType.IsIngameDestructible }, //{ "isDestroyed", s.IsDestroyed ? true : false }, { "name", $"{owner} {s.StructureType.Name} ({(s.Account != null ? s.Account.Name : "unowned")})" }, { "description", s.StructureType.Description } }); } ret.ModOptions["planetwarsStructures"] = pwStructures.ToBase64String(); } return(ret); } catch (Exception ex) { Trace.TraceError(ex.ToString()); throw; } }
private static List <AwardItem> CalculateAwards(ZkDataContext db) { var monthStart = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); var validAwards = db.SpringBattles.Where( x => (x.StartTime >= monthStart) && (x.HasBots == false) && (x.ResourceByMapResourceID.MapSupportLevel >= MapSupportLevel.Supported) && (x.ResourceByMapResourceID.MapIsSpecial == false)) .SelectMany(x => x.AccountBattleAwards) .GroupBy(x => x.AwardKey); var awardItems = new List <AwardItem>(); foreach (var awardsByType in validAwards) { var awardType = awardsByType.Key; var awardCounts = awardsByType.GroupBy(x => x.Account).Select(x => new { Account = x.Key, Count = x.Count() }).OrderByDescending(x => x.Count); var topCountM = awardCounts.First().Count; var topCollectorsM = new List <Account>(); foreach (var award in awardCounts) { if (award.Count == topCountM) { topCollectorsM.Add(award.Account); } else { break; } } var topScore = 0; string titleName = null; topScore = 0; var fullTitleM = ""; var topActID = 0; var topBattleID = 0; foreach (var award in awardsByType) { if (titleName == null) { titleName = award.AwardDescription.Split(',').First(); } int score; if (int.TryParse(Regex.Replace(award.AwardDescription, @"\D", string.Empty), out score)) { if (score > topScore) { topActID = award.AccountID; topBattleID = award.SpringBattleID; topScore = score; fullTitleM = string.Join(" ", award.AwardDescription.Split(',').Skip(1)); } } } var awardItem = new AwardItem { AwardType = awardType, AwardTitle = titleName, TopScoreHolderM = db.Accounts.SingleOrDefault(x => x.AccountID == topActID), TopScoreDescM = fullTitleM, TopScoreBattlePlayerM = db.SpringBattlePlayers.Include(x => x.SpringBattle) .Include(x => x.SpringBattle.ResourceByMapResourceID) .SingleOrDefault(x => (x.AccountID == topActID) && (x.SpringBattleID == topBattleID)), TopCollectorsM = topCollectorsM, TopCollectorCountM = topCountM }; awardItems.Add(awardItem); } return(awardItems); }
private LadderModel ComputeLadder() { lock (computeLadderLock) { try { var db = new ZkDataContext(); db.Database.CommandTimeout = 600; var awardItems = CalculateAwards(db); var ladderTimeout = DateTime.UtcNow.AddDays(-GlobalConst.LadderActivityDays); // set unused accounts weight to 1 db.Accounts.Where(x => !x.SpringBattlePlayers.Any( y => (y.SpringBattle.StartTime > ladderTimeout) && !y.SpringBattle.IsMatchMaker && !y.IsSpectator)) .Update(acc => new Account() { EloWeight = 1 }); db.Accounts.Where(x => !x.SpringBattlePlayers.Any(y => (y.SpringBattle.StartTime > ladderTimeout) && y.SpringBattle.IsMatchMaker && !y.IsSpectator)).Update(acc => new Account() { EloMmWeight = 1 }); db.SaveChanges(); foreach ( var entry in db.Accounts.Where(x => x.EloWeight > 1) .Select( acc => new { Account = acc, LastGame = acc.SpringBattlePlayers.Where(x => !x.IsSpectator && !x.SpringBattle.IsMatchMaker) .OrderByDescending(x => x.SpringBattleID) .Select(x => x.SpringBattle.StartTime).FirstOrDefault() })) { var days = DateTime.UtcNow.Subtract(entry.LastGame).TotalDays; var decayRatio = ((days - 7) / (GlobalConst.LadderActivityDays - 7)).Clamp(0, 1); entry.Account.EloWeight = Math.Min(entry.Account.EloWeight, Math.Max(1, GlobalConst.EloWeightMax - (GlobalConst.EloWeightMax - 1) * decayRatio)); } db.SaveChanges(); foreach ( var entry in db.Accounts.Where(x => x.EloMmWeight > 1) .Select( acc => new { Account = acc, LastGame = acc.SpringBattlePlayers.Where(x => !x.IsSpectator && x.SpringBattle.IsMatchMaker) .OrderByDescending(x => x.SpringBattleID) .Select(x => x.SpringBattle.StartTime).FirstOrDefault() })) { var days = DateTime.UtcNow.Subtract(entry.LastGame).TotalDays; var decayRatio = ((days - 7) / (GlobalConst.LadderActivityDays - 7)).Clamp(0, 1); entry.Account.EloMmWeight = Math.Min(entry.Account.EloMmWeight, Math.Max(1, GlobalConst.EloWeightMax - (GlobalConst.EloWeightMax - 1) * decayRatio)); } db.SaveChanges(); // recalc competitive ranking var cnt = 0; foreach (var a in db.Accounts.Where( x => x.SpringBattlePlayers.Any( y => (y.SpringBattle.StartTime > ladderTimeout) && y.SpringBattle.IsMatchMaker && !y.IsSpectator)) .OrderByDescending(x => x.EffectiveMmElo) .WithTranslations()) { cnt++; a.CompetitiveRank = cnt; } db.SaveChanges(); cnt = 0; foreach (var a in db.Accounts.Where( x => x.SpringBattlePlayers.Any( y => (y.SpringBattle.StartTime > ladderTimeout) && !y.SpringBattle.IsMatchMaker && !y.IsSpectator)) .OrderByDescending(x => x.EffectiveElo) .WithTranslations()) { cnt++; a.CasualRank = cnt; } db.SaveChanges(); var top50Accounts = db.Accounts.Where( x => x.SpringBattlePlayers.Any( y => (y.SpringBattle.StartTime > ladderTimeout) && y.SpringBattle.IsMatchMaker && !y.IsSpectator)) .Include(x => x.Clan) .Include(x => x.Faction) .OrderByDescending(x => x.EffectiveMmElo) .WithTranslations() .Take(50) .ToList(); var top50Casual = db.Accounts.Where( x => x.SpringBattlePlayers.Any( y => (y.SpringBattle.StartTime > ladderTimeout) && !y.SpringBattle.IsMatchMaker && !y.IsSpectator)) .Include(x => x.Clan) .Include(x => x.Faction) .OrderByDescending(x => x.EffectiveElo) .WithTranslations() .Take(50) .ToList(); return(new LadderModel { AwardItems = awardItems, Top50Accounts = top50Accounts, Top50Casual = top50Casual }); } catch (Exception ex) { Trace.TraceError("Error computing ladder: {0}", ex); return(new LadderModel()); } } }
/// <summary> /// Automatically close old polls /// </summary> public static void AutoClosePolls() { var db = new ZkDataContext(); foreach (var p in db.Polls.Where(x => x.IsHeadline && x.ExpireBy != null && x.ExpireBy < DateTime.UtcNow && x.RoleTypeID != null).ToList()) { var yes = p.PollVotes.Count(x => x.PollOption.OptionText == "Yes"); var no = p.PollVotes.Count(x => x.PollOption.OptionText == "No"); var acc = p.AccountByRoleTargetAccountID; if (yes > no) { if (p.RoleIsRemoval) { var toDelete = db.AccountRoles.Where(x => x.AccountID == acc.AccountID && x.RoleTypeID == p.RoleTypeID); db.AccountRoles.DeleteAllOnSubmit(toDelete); db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("{0} was removed from the {1} role of {2} by a vote - {3} for, {4} against", acc, (object)p.Clan ?? p.Faction, p.RoleType, yes, no)); db.SaveChanges(); Global.Server.GhostPm(acc.Name, string.Format("You were recalled from the function of {0} by a vote", p.RoleType.Name)); } else { if (!acc.AccountRolesByAccountID.Any(x => x.RoleTypeID == p.RoleTypeID)) { Account previous = null; if (p.RoleType.IsOnePersonOnly) { var entries = db.AccountRoles.Where(x => x.RoleTypeID == p.RoleTypeID && (p.RoleType.IsClanOnly ? x.ClanID == p.RestrictClanID : x.FactionID == p.RestrictFactionID)).ToList(); if (entries.Any()) { previous = entries.First().Account; db.AccountRoles.DeleteAllOnSubmit(entries); db.SaveChanges(); } } var entry = new AccountRole() { Account = acc, Inauguration = DateTime.UtcNow, Clan = p.Clan, Faction = p.Faction, RoleType = p.RoleType }; acc.AccountRolesByAccountID.Add(entry); if (previous == null) { db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("{0} was elected for the {1} role of {2} by a vote - {3} for, {4} against", acc, (object)p.Clan ?? p.Faction, p.RoleType, yes, no)); } else { db.Events.InsertOnSubmit(PlanetwarsEventCreator.CreateEvent("{0} was elected for the {1} role of {2} by a vote, replacing {3} - {4} for, {5} against", acc, (object)p.Clan ?? p.Faction, p.RoleType, previous, yes, no)); } Global.Server.GhostPm(acc.Name, string.Format("Congratulations!! You were elected into a function of {0} by a vote", p.RoleType.Name)); } } } p.IsHeadline = false; db.Polls.DeleteOnSubmit(p); } db.SaveChanges(); }
/// <summary> /// Makes an image: galaxy background with planet images drawn on it (cheaper than rendering each planet individually) /// </summary> // FIXME: having issues with bitmap parameters; setting AA factor to 1 as fallback (was 4) public Bitmap GenerateGalaxyImage(int galaxyID, double zoom = 1, double antiAliasingFactor = 1) { zoom *= antiAliasingFactor; using (var db = new ZkDataContext()) { Galaxy gal = db.Galaxies.Single(x => x.GalaxyID == galaxyID); using (Image background = Image.FromFile(Server.MapPath("/img/galaxies/" + gal.ImageName))) { //var im = new Bitmap((int)(background.Width*zoom), (int)(background.Height*zoom)); var im = new Bitmap(background.Width, background.Height); using (Graphics gr = Graphics.FromImage(im)) { gr.DrawImage(background, 0, 0, im.Width, im.Height); /* * using (var pen = new Pen(Color.FromArgb(255, 180, 180, 180), (int)(1*zoom))) * { * foreach (var l in gal.Links) * { * gr.DrawLine(pen, * (int)(l.PlanetByPlanetID1.X*im.Width), * (int)(l.PlanetByPlanetID1.Y*im.Height), * (int)(l.PlanetByPlanetID2.X*im.Width), * (int)(l.PlanetByPlanetID2.Y*im.Height)); * } * }*/ foreach (Planet p in gal.Planets) { string planetIconPath = null; try { planetIconPath = "/img/planets/" + (p.Resource.MapPlanetWarsIcon ?? "1.png"); // backup image is 1.png using (Image pi = Image.FromFile(Server.MapPath(planetIconPath))) { double aspect = pi.Height / (double)pi.Width; var width = (int)(p.Resource.PlanetWarsIconSize * zoom); var height = (int)(width * aspect); gr.DrawImage(pi, (int)(p.X * im.Width) - width / 2, (int)(p.Y * im.Height) - height / 2, width, height); } } catch (Exception ex) { throw new ApplicationException( string.Format("Cannot process planet image {0} for planet {1} map {2}", planetIconPath, p.PlanetID, p.MapResourceID), ex); } } if (antiAliasingFactor == 1) { return(im); } else { zoom /= antiAliasingFactor; return(im.GetResized((int)(background.Width * zoom), (int)(background.Height * zoom), InterpolationMode.HighQualityBicubic)); } } } } }
public AuthService(TasClient client) { this.client = client; /* * this.client.Input += (s, e) => * { * Console.WriteLine(e.Command +" "+ Utils.Glue(e.Args)); * }; * this.client.Output += (s, e) => * { * Console.WriteLine(e.Data.Key + " " +Utils.Glue(e.Data.Value.Select(x=>x.ToString()).ToArray())); * };*/ this.client.LoginAccepted += (s, e) => { requests.Clear(); client.JoinChannel(ModeratorChannel); client.JoinChannel(Top20Channel); using (var db = new ZkDataContext()) foreach (var fac in db.Factions.Where(x => !x.IsDeleted)) { client.JoinChannel(fac.Shortcut); } }; this.client.TestLoginAccepted += (s, e) => { RequestInfo entry; if (requests.TryGetValue(client.MessageID, out entry)) { entry.CorrectName = e.ServerParams[0]; entry.LobbyID = Convert.ToInt32(e.ServerParams[1]); if (client.ExistingUsers.ContainsKey(entry.CorrectName)) { entry.User = client.ExistingUsers[entry.CorrectName]; } entry.WaitHandle.Set(); } requests.TryRemove(client.MessageID, out entry); }; this.client.UserAdded += (s, e) => { using (var db = new ZkDataContext()) { var acc = Account.AccountByLobbyID(db, e.Data.LobbyID); if (acc != null) { this.client.Extensions.PublishAccountData(acc); if (acc.SpringieLevel > 2 || acc.IsZeroKAdmin) { client.ForceJoinChannel(e.Data.Name, ModeratorChannel); } if (topPlayers.IsTop20(e.Data.LobbyID)) { client.ForceJoinChannel(e.Data.Name, Top20Channel); } if (acc.Clan != null) { client.ForceJoinChannel(e.Data.Name, acc.Clan.GetClanChannel(), acc.Clan.Password); } if (acc.Faction != null && acc.Level >= GlobalConst.FactionChannelMinLevel && acc.CanPlayerPlanetWars()) { client.ForceJoinChannel(e.Data.Name, acc.Faction.Shortcut); } } client.RequestUserIP(e.Data.Name); client.RequestUserID(e.Data.Name); } }; this.client.UserIDRecieved += (sender, args) => { Task.Factory.StartNew(() => { try { using (var db = new ZkDataContext()) { var acc = Account.AccountByName(db, args.Name); var penalty = Punishment.GetActivePunishment(acc != null ? acc.AccountID : 0, null, args.ID, x => x.BanLobby, db); if (penalty != null) { client.AdminKickFromLobby(args.Name, string.Format("Banned until {0} (ID match to {1}), reason: {2}", penalty.BanExpires, penalty.AccountByAccountID.Name, penalty.Reason)); } ; if (acc != null && args.ID != 0) { var entry = acc.AccountUserIDS.FirstOrDefault(x => x.UserID == args.ID); if (entry == null) { entry = new AccountUserID { AccountID = acc.AccountID, UserID = args.ID, FirstLogin = DateTime.UtcNow }; db.AccountUserIDS.InsertOnSubmit(entry); } entry.LoginCount++; entry.LastLogin = DateTime.UtcNow; } Account accAnteep = db.Accounts.FirstOrDefault(x => x.AccountID == 4490); bool isAnteepSmurf = accAnteep.AccountUserIDS.Any(x => x.UserID == args.ID); if (isAnteepSmurf) { client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("Suspected Anteep smurf: {0} (ID match {1}) {2}", args.Name, args.ID, acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false); } if (args.ID != 0 && args.ID < 1000) { client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("Suspected Anteep smurf: {0} (too short userID {1}) {2}", args.Name, args.ID, acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false); } db.SubmitChanges(); } } catch (Exception ex) { Trace.TraceError("Error getting user ID: {0}", ex); } }); }; this.client.UserIPRecieved += (sender, args) => { Task.Factory.StartNew(() => { try { Account acc = null; using (var db = new ZkDataContext()) { acc = Account.AccountByName(db, args.Name); var penalty = Punishment.GetActivePunishment(acc != null ? acc.AccountID : 0, args.IP, null, x => x.BanLobby, db); if (penalty != null) { client.AdminKickFromLobby(args.Name, string.Format("Banned until {0} (IP match to {1}), reason: {2}", penalty.BanExpires, penalty.AccountByAccountID.Name, penalty.Reason)); } if (acc != null) { var entry = acc.AccountIPS.FirstOrDefault(x => x.IP == args.IP); if (entry == null) { entry = new AccountIP { AccountID = acc.AccountID, IP = args.IP, FirstLogin = DateTime.UtcNow }; db.AccountIPS.InsertOnSubmit(entry); } entry.LoginCount++; entry.LastLogin = DateTime.UtcNow; } db.SubmitChanges(); } try { if (acc == null || !acc.HasVpnException) { if (GlobalConst.VpnCheckEnabled) { // check user IP against http://dnsbl.tornevall.org // does not catch all smurfs // mostly false positives, do not use var reversedIP = string.Join(".", args.IP.Split('.').Reverse().ToArray()); try { var resolved = Dns.GetHostEntry(string.Format("{0}.dnsbl.tornevall.org", reversedIP)).AddressList; if (resolved.Length > 0) { client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("User {0} {3} has IP {1} on dnsbl.tornevall.org ({2} result/s)", args.Name, args.IP, resolved.Length, acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false); //client.AdminKickFromLobby(args.Name, // "Connection using proxy or VPN is not allowed! (You can ask for exception). See http://dnsbl.tornevall.org/removal.php to get your IP removed from the blacklist."); } } catch (System.Net.Sockets.SocketException sockEx) { // not in database, do nothing } } using (var db = new ZkDataContext()) { Account accAnteep = db.Accounts.FirstOrDefault(x => x.AccountID == 4490); bool isAnteepSmurf = accAnteep.AccountIPS.Any(x => x.IP == args.IP); if (isAnteepSmurf) { client.Say(TasClient.SayPlace.Channel, ModeratorChannel, String.Format("Suspected Anteep smurf: {0} (IP match {1}) {2}", args.Name, args.IP, acc != null ? "http://zero-k.info/Users/Detail/" + acc.AccountID : ""), false); } } using (ZkDataContext db = new ZkDataContext()) { for (int i = 0; i <= 1; i++) { var whois = new Whois(); var data = whois.QueryByIp(args.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"; } var blockedCompanies = db.BlockedCompanies.Select(x => x.CompanyName.ToLower()).ToList(); var blockedHosts = db.BlockedHosts.Select(x => x.HostName).ToList(); /*if (acc.Country == "MY") * { * client.Say(TasClient.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); * }*/ if (blockedHosts.Any(x => data["abuse-mailbox"].Contains(x)) || (blockedHosts.Any(x => data["notify"].Contains(x)))) { client.AdminKickFromLobby(args.Name, "Connection using proxy or VPN is not allowed! (You can ask for exception)"); } 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)) { client.AdminKickFromLobby(args.Name, "Connection using proxy or VPN is not allowed! (You can ask for exception)"); break; } } var hostname = Dns.GetHostEntry(args.IP).HostName; if (blockedHosts.Any(hostname.Contains)) { client.AdminKickFromLobby(args.Name, "Connection using proxy or VPN is not allowed! (You can ask for exception)"); } } } } } catch (System.Net.Sockets.SocketException sockEx) { // do nothing } catch (Exception ex) { Trace.TraceError("VPN check error: {0}", ex); client.Say(TasClient.SayPlace.Channel, ModeratorChannel, ex.ToString(), false); } } catch (Exception ex) { Trace.TraceError("Error getting user IP: {0}", ex); //client.Say(TasClient.SayPlace.User, "KingRaptor", ex.ToString(), false); } }); }; this.client.UserStatusChanged += (s, e) => { var user = client.ExistingUsers[e.ServerParams[0]]; Task.Factory.StartNew(() => { try { using (var db = new ZkDataContext()) UpdateUser(user.LobbyID, user.Name, user, null, db); } catch (Exception ex) { Trace.TraceError(ex.ToString()); } }, TaskCreationOptions.LongRunning); }; this.client.BattleUserJoined += (s, e) => { var battle = client.ExistingBattles[e.BattleID]; var founder = battle.Founder; if (founder.IsSpringieManaged) { try { var user = client.ExistingUsers[e.UserName]; /* obsolete; all major lobbies have multiengine support * if (!user.IsZkLobbyUser && !user.IsNotaLobby && battle.EngineVersion != client.ServerSpringVersion && * battle.EngineVersion != client.ServerSpringVersion + ".0") { * client.Say(TasClient.SayPlace.User, * user.Name, * string.Format( * "ALERT! YOU WILL DESYNC!! You NEED SPRING ENGINE {0} to play here. Simply join the game with Zero-K lobby ( http://zero-k.info/Wiki/Download ) OR get the engine from http://springrts.com/dl/buildbot/default/ OR build it on your Linux: http://springrts.com/wiki/Building_Spring_on_Linux ", * battle.EngineVersion), * false); * } */ using (var db = new ZkDataContext()) { var acc = Account.AccountByLobbyID(db, user.LobbyID); var name = founder.Name.TrimNumbers(); var aconf = db.AutohostConfigs.FirstOrDefault(x => x.Login == name); if (acc != null && user != null && aconf != null && (acc.LastLobbyVersionCheck == null || DateTime.UtcNow.Subtract(acc.LastLobbyVersionCheck.Value).TotalDays > 3) && aconf.AutohostMode != 0) { client.RequestLobbyVersion(user.Name); } /* * if (acc != null) * { * int numIDs = acc.AccountUserIDS != null ? acc.AccountUserIDS.Count : 0; * if (numIDs == 0) client.Say(TasClient.SayPlace.User, "KingRaptor", string.Format("USER {0} joined battle {1}; has {2} userIDs; lobby version {3}", acc.Name, founder.Name, numIDs, acc.LobbyVersion), false); * } * else * client.Say(TasClient.SayPlace.User, "KingRaptor", string.Format("USER {0} joined battle {1}", e.UserName + " (NO ACCOUNT)", founder.Name), false); * * if (acc != null) * { * if (!acc.AccountUserIDS.Any()) * { * string reason = string.Format("Sorry you are using unsupported lobby ({0}), please upgrade or use Zero-K Lobby, Weblobby or SpringLobby", acc.LobbyVersion); * client.Say(TasClient.SayPlace.User, user.Name, reason, false); * client.Say(TasClient.SayPlace.User, founder.Name, string.Format("!kick {0} {1}", acc.LobbyVersion, reason), false); * } * }*/ } } catch (Exception ex) { //client.Say(TasClient.SayPlace.User, "KingRaptor", ex.ToString(), false); Trace.TraceError("Error procesisng battle user joined: {0}", ex); } } }; this.client.TestLoginDenied += (s, e) => { RequestInfo entry; if (requests.TryGetValue(client.MessageID, out entry)) { entry.WaitHandle.Set(); } requests.TryRemove(client.MessageID, out entry); }; this.client.UserLobbyVersionRecieved += (s, e) => { using (var db = new ZkDataContext()) { var acc = Account.AccountByName(db, e.Name); if (acc != null) { acc.LobbyVersion = e.LobbyVersion; acc.LastLobbyVersionCheck = DateTime.UtcNow; db.SubmitAndMergeChanges(); if (!acc.LobbyVersion.StartsWith("ZK")) { // FIXME abma broke this (LobbyVersion is now some huge-ass integer instead) //client.Say(TasClient.SayPlace.User, // e.Name, // string.Format( // "WARNING: You are connected using {0} which is not fully compatible with this host. Please use Zero-K lobby. Download it from http://zero-k.info NOTE: to play all Spring games with Zero-K lobby, untick \"Official games\" on its multiplayer tab. Thank you!", // e.LobbyVersion), // false); } } } }; this.client.BattleFound += (s, e) => { if (e.Data.Founder.IsZkLobbyUser && !e.Data.Founder.IsBot) { client.SetBotMode(e.Data.Founder.Name, true); } }; this.client.ChannelUserAdded += (sender, args) => { try { var channel = args.ServerParams[0]; var user = args.ServerParams[1]; if (channel == ModeratorChannel) { var u = client.ExistingUsers[user]; if (u.SpringieLevel <= 2 && !u.IsZeroKAdmin) { client.ForceLeaveChannel(user, ModeratorChannel); } } else if (channel == Top20Channel) { var u = client.ExistingUsers[user]; if (!topPlayers.IsTop20(u.LobbyID) && u.Name != client.UserName) { client.ForceLeaveChannel(user, Top20Channel); } } else { using (var db = new ZkDataContext()) { var fac = db.Factions.FirstOrDefault(x => x.Shortcut == channel); if (fac != null) { // faction channel var u = client.ExistingUsers[user]; var acc = Account.AccountByLobbyID(db, u.LobbyID); if (acc == null || acc.FactionID != fac.FactionID || acc.Level < GlobalConst.FactionChannelMinLevel) { client.ForceLeaveChannel(user, channel); } } } } } catch (Exception ex) { Trace.TraceError("Error procesisng channel user added: {0}", ex); } }; this.client.ChannelUserRemoved += (sender, args) => { try { var channel = args.ServerParams[0]; var user = args.ServerParams[1]; if (channel == ModeratorChannel) { var u = client.ExistingUsers[user]; if (u.SpringieLevel > 2 || u.IsZeroKAdmin) { client.ForceJoinChannel(user, ModeratorChannel); } } } catch (Exception ex) { Trace.TraceError("Error procesisng channel user added: {0}", ex); } }; }
public ActionResult Minimap() { var db = new ZkDataContext(); return(View(db.Galaxies.Single(g => g.IsDefault))); }
//private //Runs in O(N log(N)) for all players private void UpdateRankings(IEnumerable <Player> players) { var debriefings = new Dictionary <int, PendingDebriefing>(pendingDebriefings); int matched = 0; try { //check for ladder elo updates using (var db = new ZkDataContext()) { var battleIDs = debriefings.Keys.ToList(); foreach (var battleId in debriefings.Keys) { List <SpringBattlePlayer> lastBattlePlayers = db.SpringBattlePlayers.Where(p => p.SpringBattleID == battleId && !p.IsSpectator).Include(x => x.Account).DistinctBy(x => x.AccountID).ToList(); Dictionary <int, float> oldRatings = lastBattlePlayers.ToDictionary(p => (p.AccountID), p => GetPlayerRating(p.AccountID).LadderElo); lastBattlePlayers.Where(p => !playerRatings.ContainsKey((p.AccountID))).ForEach(p => playerRatings[(p.AccountID)] = new PlayerRating(DefaultRating)); Dictionary <int, float> winChances = db.SpringBattles.Where(p => p.SpringBattleID == battleId).First().GetAllyteamWinChances(); lastBattlePlayers.ForEach(p => { float eloChange = (p.IsInVictoryTeam ? (1f - winChances[p.AllyNumber]) : (-winChances[p.AllyNumber])) * GlobalConst.LadderEloClassicEloK / lastBattlePlayers.Count(x => x.AllyNumber == p.AllyNumber); playerRatings[p.AccountID].LadderElo = Ranks.UpdateLadderRating(p.Account, category, getPlayerById(p.AccountID).avgElo + RatingOffset, p.IsInVictoryTeam, !p.IsInVictoryTeam, eloChange, db); }); lastBattlePlayers.Where(p => !p.EloChange.HasValue).ForEach(p => { p.EloChange = playerRatings[(p.AccountID)].LadderElo - oldRatings[(p.AccountID)]; db.SpringBattlePlayers.Attach(p); db.Entry(p).Property(x => x.EloChange).IsModified = true; }); db.SaveChanges(); } } //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.days.Last().naturalRatingVariance; 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; if (playerKeys.ContainsKey(p.id)) { sortedPlayers.Remove(playerKeys[p.id]); } while (sortedPlayers.ContainsKey(rating)) { rating += 0.01f; } 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>(); List <float> newPercentileBrackets = new List <float>(); newPercentileBrackets.Add(playerRatings[sortedPlayers.First().Value].LadderElo); 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); } } if (rank != playerCount) { Trace.TraceWarning("WHR has " + playerCount + " active players, but " + rank + " sorted active players"); } while (newPercentileBrackets.Count < Ranks.Percentiles.Length + 1) { newPercentileBrackets.Add(playerRatings[sortedPlayers.Last().Value].LadderElo); } 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(); } } catch (Exception ex) { Trace.TraceError("WHR " + category + ": Failed to update rankings: " + ex); PendingDebriefing discard2; debriefings.ForEach(x => pendingDebriefings.TryRemove(x.Key, out discard2)); return; } try { //check for rank updates if (debriefings.Any()) { Trace.TraceInformation("WHR Filling in Debriefings for Battles: " + debriefings.Keys.Select(x => "B" + x).StringJoin()); using (var db = new ZkDataContext()) { foreach (var battleId in debriefings.Keys) { List <SpringBattlePlayer> lastBattlePlayers = db.SpringBattlePlayers.Where(p => p.SpringBattleID == battleId && !p.IsSpectator).Include(x => x.Account).DistinctBy(x => x.AccountID).ToList(); Dictionary <int, SpringBattlePlayer> involvedPlayers = lastBattlePlayers.ToDictionary(p => p.AccountID, p => p); Trace.TraceInformation("WHR Debriefing players: " + involvedPlayers.Values.Select(x => x.Account.Name).StringJoin()); Dictionary <int, int> oldRanks = lastBattlePlayers.ToDictionary(p => p.AccountID, p => p.Account.Rank); Dictionary <int, Account> 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.Accounts.Attach(p); db.Entry(p).Property(x => x.Rank).IsModified = true; }); List <int> playersWithRatingChange = lastBattlePlayers.Select(x => x.AccountID).ToList(); db.SaveChanges(); //Publish new results only after saving new stats to db. debriefings[battleId].partialDebriefing.DebriefingUsers.Values.ForEach(user => { try { user.EloChange = involvedPlayers[user.AccountID].EloChange ?? 0; 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(involvedPlayers[user.AccountID].Account, 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); } }); debriefings[battleId].partialDebriefing.RatingCategory = category.ToString(); debriefings[battleId].debriefingConsumer.Invoke(debriefings[battleId].partialDebriefing); RatingsUpdated(this, new RatingUpdate() { affectedPlayers = playersWithRatingChange }); } } } //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) { Trace.TraceError("WHR " + category + ": Failed to process battles for rankings: " + ex); } PendingDebriefing discard; debriefings.ForEach(x => pendingDebriefings.TryRemove(x.Key, out discard)); }
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 })); }
private bool HasVpn(string ip, Account acc, ZkDataContext db) { // check user IP against http://dnsbl.tornevall.org // does not catch all smurfs // mostly false positives, do not use var reversedIP = string.Join(".", ip.Split('.').Reverse().ToArray()); try { var 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))); return(true); } } catch (SocketException sockEx) { // not in database, do nothing } try { //for (int i = 0; i <= 1; i++) { for (var i = 1; i <= 1; i++) { var whois = new Whois(); var 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"; } var blockedCompanies = db.BlockedCompanies.Select(x => x.CompanyName.ToLower()).ToList(); var blockedHosts = db.BlockedHosts.Select(x => x.HostName).ToList(); //Trace.TraceInformation($"VPN check for USER {acc.Name}\nnetname: {data["netname"]}\norgname: {data["org-name"]}\ndescr: {data["descr"]}\nabuse-mailbox: {data["abuse-mailbox"]}", false); if (blockedHosts.Any(x => data["abuse-mailbox"].Contains(x)) || blockedHosts.Any(x => data["notify"].Contains(x))) { return(true); } foreach (var 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)) { return(true); } } // this can throw a SocketException, so make sure we block login already if we ought to try { var hostname = Dns.GetHostEntry(ip)?.HostName; if (blockedHosts.Any(hostname.Contains)) { return(true); } } catch (SocketException) { } } } catch (Exception ex) { Trace.TraceError("VPN check error for user {0}: {1}", acc.Name, ex); } return(false); }
public ActionResult RunSetPlanetOwners() { using (var db = new ZkDataContext()) PlanetWarsTurnHandler.SetPlanetOwners(new PlanetwarsEventCreator(), db); return(Content("Done.")); }
public static PlayerJoinResult AutohostPlayerJoined(BattleContext context, int accountID) { var res = new PlayerJoinResult(); var db = new ZkDataContext(); AutohostMode mode = context.GetMode(); if (mode == AutohostMode.Planetwars) { Planet planet = db.Galaxies.Single(x => x.IsDefault).Planets.SingleOrDefault(x => x.Resource.InternalName == context.Map); if (planet == null) { res.PublicMessage = "Invalid map"; return(res); } Account account = Account.AccountByLobbyID(db, accountID); // accountID is in fact lobbyID if (account != null) { if (account.Level < context.GetConfig().MinLevel) { res.PrivateMessage = string.Format("Sorry, PlanetWars is competive online campaign for experienced players. You need to be at least level {0} to play here. To increase your level, play more games on other hosts or open multiplayer game and play against computer AI bots. You can still spectate this game, however.", context.GetConfig().MinLevel); res.ForceSpec = true; return(res); } /* * if (account.Faction == null) * { * res.PrivateMessage = * string.Format( * "{0} this is competitive PlanetWars campaign server. Join a clan to conquer the galaxy http://zero-k.info/Factions", * account.Name); * return res; * }*/ string owner = ""; if (planet.Account != null) { owner = planet.Account.Name; } string facRoles = string.Join(",", account.AccountRolesByAccountID.Where(x => !x.RoleType.IsClanOnly).Select(x => x.RoleType.Name).ToList()); if (!string.IsNullOrEmpty(facRoles)) { facRoles += " of " + account.Faction.Name + ", "; } string clanRoles = string.Join(",", account.AccountRolesByAccountID.Where(x => x.RoleType.IsClanOnly).Select(x => x.RoleType.Name).ToList()); if (!string.IsNullOrEmpty(clanRoles)) { clanRoles += " of " + account.Clan.ClanName; } res.PublicMessage = string.Format("Greetings {0} {1}{2}, welcome to {3} planet {4} http://zero-k.info/PlanetWars/Planet/{5}", account.Name, facRoles, clanRoles, owner, planet.Name, planet.PlanetID); return(res); } } Account acc = Account.AccountByLobbyID(db, accountID); // accountID is in fact lobbyID if (acc != null) { AutohostConfig config = context.GetConfig(); if (acc.Level < config.MinLevel) { res.PrivateMessage = string.Format("Sorry, you need to be at least level {0} to play here. To increase your level, play more games on other hosts or open multiplayer game and play against computer AI bots. You can still spectate this game, however.", config.MinLevel); res.ForceSpec = true; return(res); } else if (acc.Level > config.MaxLevel) { res.PrivateMessage = string.Format("Sorry, your level must be {0} or lower to play here. Pick on someone your own size! You can still spectate this game, however.", config.MaxLevel); res.ForceSpec = true; return(res); } // FIXME: use 1v1 Elo for 1v1 if (acc.EffectiveElo < config.MinElo) { res.PrivateMessage = string.Format("Sorry, you need to have an Elo rating of at least {0} to play here. Win games against human opponents to raise your Elo. You can still spectate this game, however.", config.MinElo); res.ForceSpec = true; return(res); } else if (acc.EffectiveElo > config.MaxElo) { res.PrivateMessage = string.Format("Sorry, your Elo rating must be {0} or lower to play here. Pick on someone your own size! You can still spectate this game, however.", config.MaxElo); res.ForceSpec = true; return(res); } } return(null); }
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); }
/// <summary> /// Returns the main battle replay list; params filter /// </summary> public ActionResult Index(BattleSearchModel model) { var db = new ZkDataContext(); model = model ?? new BattleSearchModel(); var q = db.SpringBattles.Include(x => x.SpringBattlePlayers); if (!string.IsNullOrEmpty(model.Title)) { q = q.Where(b => b.Title.Contains(model.Title)); } if (!string.IsNullOrEmpty(model.Map)) { q = q.Where(b => b.ResourceByMapResourceID.InternalName == model.Map); } //if (user == null && Global.IsAccountAuthorized) user = Global.Account.Name; if (model.UserId != null) { int uniqueIds = model.UserId.Distinct().Count(); q = q.Where(b => b.SpringBattlePlayers.Where(p => model.UserId.Contains(p.AccountID) && !p.IsSpectator).Count() == uniqueIds); } if (model.PlayersFrom.HasValue) { q = q.Where(b => b.SpringBattlePlayers.Count(p => !p.IsSpectator) >= model.PlayersFrom); } if (model.PlayersTo.HasValue) { q = q.Where(b => b.SpringBattlePlayers.Count(p => !p.IsSpectator) <= model.PlayersTo); } if (model.Age != AgeOption.Any) { var limit = DateTime.UtcNow; switch (model.Age) { case AgeOption.Today: limit = DateTime.Now.AddDays(-1); break; case AgeOption.ThisWeek: limit = DateTime.UtcNow.AddDays(-7); break; case AgeOption.ThisMonth: limit = DateTime.UtcNow.AddDays(-31); break; } q = q.Where(b => b.StartTime >= limit); } if (model.Mission != YesNoAny.Any) { var bval = model.Mission == YesNoAny.Yes; q = q.Where(b => b.IsMission == bval); } if (model.Bots != YesNoAny.Any) { var bval = model.Bots == YesNoAny.Yes; q = q.Where(b => b.HasBots == bval); } q = q.OrderByDescending(b => b.StartTime); if (model.offset.HasValue) { q = q.Skip(model.offset.Value); } q = q.Take(Global.AjaxScrollCount); var result = q.ToList() .Select( b => new BattleQuickInfo { Battle = b, Players = b.SpringBattlePlayers, Map = b.ResourceByMapResourceID, Mod = b.ResourceByModResourceID }) .ToList(); //if(result.Count == 0) // return Content(""); model.Data = result; if (model.offset.HasValue) { return(View("BattleTileList", model)); } return(View("BattleIndex", model)); }
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.SubmitChanges(); 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 } resource.ResourceContentFiles.Add(new ResourceContentFile { FileName = archiveName, Length = length, Md5 = md5 }); File.WriteAllBytes(GetTorrentPath(internalName, md5), torrentData); // add new torrent file db.SubmitChanges(); return(ReturnValue.Ok); }
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, 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 ActionResult NominateRole(int roleTypeID, string text, bool isRemoval = false, int?removalAccountID = null) { var db = new ZkDataContext(); var pollActive = Global.Account.PollsByRoleTargetAccountID.Any(x => x.ExpireBy > DateTime.UtcNow); if (pollActive) { return(Content("Poll already active, wait until it ends")); } var rt = db.RoleTypes.Single(x => x.RoleTypeID == roleTypeID); if (Global.Account.Level < GlobalConst.MinLevelForForumVote) { return(Content($"You need to be level {GlobalConst.MinLevelForForumVote} to vote")); } if (!rt.IsClanOnly && MiscVar.PlanetWarsMode == PlanetWarsModes.AllOffline) { return(Content("Round over, no nominations can be made")); } if (rt.RestrictFactionID != null && rt.RestrictFactionID != Global.FactionID) { throw new ApplicationException("Invalid faction"); } if (!rt.IsClanOnly && Global.FactionID == 0) { throw new ApplicationException("No faction"); } if (!rt.IsClanOnly && rt.Faction.IsDeleted) { throw new ApplicationException("Disabled faction"); } if (rt.IsClanOnly && Global.ClanID == 0) { throw new ApplicationException("No clan"); } if (!rt.IsVoteable) { throw new ApplicationException("Cannot be voted"); } int targetID = Global.AccountID; if (isRemoval) { var target = db.Accounts.Single(x => x.AccountID == removalAccountID); if (Global.Account.CanVoteRecall(target, rt)) { targetID = removalAccountID.Value; } else { return(Content("Cannot recall him/her")); } } var p = new Poll() { CreatedAccountID = Global.AccountID, RoleTargetAccountID = targetID, ExpireBy = DateTime.UtcNow.AddDays(rt.PollDurationDays), IsAnonymous = true, IsHeadline = true, RoleIsRemoval = isRemoval, RoleType = rt, RestrictClanID = rt.IsClanOnly ? Global.Account.ClanID : null, RestrictFactionID = rt.IsClanOnly ? null : Global.Account.FactionID, QuestionText = text }; p.PollOptions.Add(new PollOption() { OptionText = "Yes" }); p.PollOptions.Add(new PollOption() { OptionText = "No" }); db.Polls.InsertOnSubmit(p); db.SaveChanges(); return(RedirectToAction("Detail", "Users", new { id = Global.AccountID })); }
public ActionResult VotePost(int forumPostID, int delta) { var db = new ZkDataContext(); var myAcc = Global.Account; var penalty = Punishment.GetActivePunishment(Global.AccountID, Request.UserHostAddress, 0, 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 })); }
public ActionResult TreatyDetail(int id) { var db = new ZkDataContext(); return(View("~/Views/Shared/DisplayTemplates/FactionTreaty.cshtml", db.FactionTreaties.Single(x => x.FactionTreatyID == id))); }