public ActionResult ChangeFeaturedOrder(int id, float? featuredOrder, string script)
        {
            var db = new ZkDataContext();
            var mis = db.Missions.SingleOrDefault(x => x.MissionID == id);
            mis.FeaturedOrder = featuredOrder;
            if (mis.IsScriptMission && !string.IsNullOrEmpty(script)) mis.Script = script;
            db.SubmitChanges();

            var order = 1;
            if (featuredOrder.HasValue) foreach (var m in db.Missions.Where(x => x.FeaturedOrder != null).OrderBy(x => x.FeaturedOrder)) m.FeaturedOrder = order++;
            db.SubmitChanges();

            return RedirectToAction("Index");
        }
 public ActionResult Delete(int id)
 {
     var db = new ZkDataContext();
     db.Missions.First(x => x.MissionID == id).IsDeleted = true;
     db.SubmitChanges();
     return RedirectToAction("Index");
 }
		void client_ChannelUserAdded(object sender, ChannelUserInfo e)
		{
			Task.Run(async () =>
				{
					try
					{
						var chan = e.Channel.Name;
						List<LobbyMessage> messages;
					    foreach (var user in e.Users) {
					        using (var db = new ZkDataContext()) {
					            messages = db.LobbyMessages.Where(x => x.TargetName == user.Name && x.Channel == chan).OrderBy(x => x.Created).ToList();
					            db.LobbyMessages.DeleteAllOnSubmit(messages);
					            db.SubmitChanges();
					        }
					        foreach (var m in messages) {
					            var text = string.Format("!pm|{0}|{1}|{2}|{3}", m.Channel, m.SourceName, m.Created.ToString(CultureInfo.InvariantCulture), m.Message);
					            await client.Say(SayPlace.User, user.Name, text, false);
					            await Task.Delay(MessageDelay);
					        }
					    }
					}
					catch (Exception ex)
					{
						Trace.TraceError("Error adding user: {0}", ex);
					}
				});
		}
Exemplo n.º 4
0
    static void Main(string[] args)
    {
      var db = new ZkDataContext();

      var dict = db.Accounts.ToDictionary(x => x.AccountID);

      var path = args.Length > 0 ? args[0] : @"accounts.txt";
      using (var r = new StreamReader(path)) {
        string line;
        while ((line = r.ReadLine()) != null) {
          Account ac = null;
          try {
            var parts = line.Split(' ');
            if (parts.Length < 9) {
              Trace.TraceError("Faulty line: ", line);
              continue;
            }

            var name = parts[0];
            var pass = parts[1];
            var flags = parts[2];
            //var cookie = int.Parse(parts[3]);
            var lastLogin = ConvertTimestamp(double.Parse(parts[4]) / 1000);
            var lastIP = parts[5];
            var registered = ConvertTimestamp(double.Parse(parts[6]) / 1000);
            var country = parts[7];
            var id = int.Parse(parts[8]);

            Account de = null;
            dict.TryGetValue(id, out de);

            Console.WriteLine(string.Format("{0} {1}", id, name));
            if (de == null || name != de.Name || pass != de.Password || registered != de.FirstLogin ) {
              if (de == null) {
                ac = new Account();
                db.Accounts.InsertOnSubmit(ac);
              } else ac = db.Accounts.SingleOrDefault(x => x.LobbyID == id);

              ac.LobbyID = id;
              ac.Name = name;
              //ac.Flags = flags;
              ac.Password = pass;
              //ac.UserCookie = cookie;
              if (lastLogin.HasValue) ac.LastLogin = lastLogin.Value;
              //ac.LastIP = lastIP;
              if (registered.HasValue) ac.FirstLogin = registered.Value;
              if (ac.LastLogin == DateTime.MinValue) ac.LastLogin = registered ?? DateTime.UtcNow;
              //ac.Created = registered;
              ac.Country = country;
              Console.Write(" CHANGED!");
              db.SubmitChanges();
            }
          } catch (Exception e) {
            Console.WriteLine("Problem importing line: {0}: {1}", line, e);
            db = new ZkDataContext();
          }
        }
      }
    }
        public ActionResult NewPoll(string question, string answers, bool? isAnonymous)
        {
            var p = new Poll() { CreatedAccountID = Global.AccountID, IsHeadline = true, QuestionText = question, IsAnonymous = isAnonymous == true, };
            var db = new ZkDataContext();

            foreach (var a in answers.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)) p.PollOptions.Add(new PollOption() { OptionText = a });

            db.Polls.InsertOnSubmit(p);
            db.SubmitChanges();
            return RedirectToAction("UserVotes", new { id = Global.AccountID });
        }
        public ActionResult ChangeHideCountry(int accountID, bool hideCountry)
        {
            var db = new ZkDataContext();
            Account acc = db.Accounts.Single(x => x.AccountID == accountID);

            if (hideCountry) acc.Country = "??";
            // TODO reimplement ? Global.Nightwatch.Tas.SetHideCountry(acc.Name, hideCountry);
            db.SubmitChanges();

            return RedirectToAction("Detail", "Users", new { id = acc.AccountID });
        }
		public ActionResult DeletePost(int? postID)
		{
			var db = new ZkDataContext();
			var post = db.ForumPosts.Single(x => x.ForumPostID == postID);
			var thread = post.ForumThread;
            int threadID = thread.ForumThreadID;
            //int index = post.ForumThread.ForumPosts.IndexOf(post);
            int page = GetPostPage(post);

			db.ForumPosts.DeleteOnSubmit(post);
			if (thread.ForumPosts.Count() <= 1 && IsNormalThread(thread)) {
                db.ForumThreadLastReads.DeleteAllOnSubmit(db.ForumThreadLastReads.Where(x => x.ForumThreadID == thread.ForumThreadID).ToList());
				db.ForumThreads.DeleteOnSubmit(thread);
				db.SubmitChanges();
				return RedirectToAction("Index");
			}
			db.SubmitChanges();
            ResetThreadLastPostTime(threadID);
			return RedirectToAction("Thread", new { id = threadID, page = page });
		}
        public static ReturnValue DeleteResource(string internalName)
        {
            var db = new ZkDataContext();
            var todel = db.Resources.SingleOrDefault(x => x.InternalName == internalName);
            if (todel == null) return ReturnValue.ResourceNotFound;
            RemoveResourceFiles(todel);

            db.Resources.Remove(todel);
            db.SubmitChanges();
            return ReturnValue.Ok;
        }
        //
        // GET: /Battles/

        public ActionResult Detail(int id)
        {
          var db = new ZkDataContext();
          var bat = db.SpringBattles.FirstOrDefault(x => x.SpringBattleID == id);
            if (bat == null) return Content("No such battle exists");
          if (bat.ForumThread != null)
          {
            bat.ForumThread.UpdateLastRead(Global.AccountID, false);
            db.SubmitChanges();
          }
          return View(bat);
        }
        public ActionResult JoinFaction(int id) {
            if (Global.Account.FactionID != null) return Content("Already in faction");
            if (Global.Account.Clan != null && Global.Account.Clan.FactionID != id) return Content("Must leave current clan first");
            var db = new ZkDataContext();
            Account acc = db.Accounts.Single(x => x.AccountID == Global.AccountID);
            acc.FactionID = id;

            Faction faction = db.Factions.Single(x => x.FactionID == id);
            if (faction.IsDeleted && !(Global.Account.Clan != null && Global.Account.Clan.FactionID == id)) throw new ApplicationException("Cannot join deleted faction");
            db.Events.InsertOnSubmit(Global.CreateEvent("{0} joins {1}", acc, faction));
            db.SubmitChanges();
            return RedirectToAction("Index", "Factions");
        }
		public void UndeleteMission(int missionID, string author, string password)
		{
			var db = new ZkDataContext();
			var prev = db.Missions.Where(x => x.MissionID == missionID).SingleOrDefault();
			if (prev != null)
			{
				var acc = AuthServiceClient.VerifyAccountPlain(author, password);
				if (acc == null) throw new ApplicationException("Invalid login name or password");
				if (acc.AccountID != prev.AccountID && !acc.IsZeroKAdmin) throw new ApplicationException("You cannot undelete a mission from an other user");
				prev.IsDeleted = false;
				db.SubmitChanges();
			}
			else throw new ApplicationException("No such mission found");
		}
 /// <summary>
 /// Shows clan page
 /// </summary>
 /// <returns></returns>
 public ActionResult Detail(int id)
 {
     var db = new ZkDataContext();
     var clan = db.Clans.First(x => x.ClanID == id);
     if (Global.ClanID == clan.ClanID)
     {
         if (clan.ForumThread != null)
         {
             clan.ForumThread.UpdateLastRead(Global.AccountID, false);
             db.SubmitChanges();
         }
     }
     return View(clan);
 }
        public ActionResult AddBlockedHost(string hostname, string comment)
        {
            ZkDataContext db = new ZkDataContext();
            if (String.IsNullOrWhiteSpace(hostname)) return Content("Hostname cannot be empty");
            db.BlockedHosts.InsertOnSubmit(new BlockedHost()
            {
                HostName = hostname,
                Comment = comment,
            });
            db.SubmitChanges();

            var str = string.Format("{0} added new blocked VPN host: {1}", Global.Account.Name, hostname);
            Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, str);
            return RedirectToAction("BlockedVPNs");
        }
        public ActionResult ChangeAccountDeleted(int accountID, bool isDeleted)
        {
            var db = new ZkDataContext();
            Account acc = db.Accounts.Single(x => x.AccountID == accountID);

            if (acc.IsDeleted != isDeleted)
            {
                Global.Nightwatch.Tas.Say(SayPlace.Channel, AuthService.ModeratorChannel, string.Format("Account {0} {1} deletion status changed by {2}", acc.Name, Url.Action("Detail", "Users", new { id = acc.AccountID }, "http"), Global.Account.Name), true);
                Global.Nightwatch.Tas.Say(SayPlace.Channel, AuthService.ModeratorChannel, string.Format(" - {0} -> {1}", acc.IsDeleted, isDeleted), true);
                acc.IsDeleted = isDeleted;
            }
            db.SubmitChanges();

            return RedirectToAction("Detail", "Users", new { id = acc.AccountID });
        }     
 /// <summary>
 ///     Set the last post time of the thread to current time (includes edits)
 /// </summary>
 void ResetThreadLastPostTime(int threadID) {
     var db = new ZkDataContext();
     var thread = db.ForumThreads.FirstOrDefault(x => x.ForumThreadID == threadID);
     var lastPost = thread.Created;
     foreach (var p in thread.ForumPosts.Reverse())
     {
         if (p.ForumPostEdits.Count > 0)
         {
             var lastEdit = p.ForumPostEdits.Last().EditTime;
             if (lastEdit > lastPost) lastPost = lastEdit;
         } else if (p.Created > lastPost) lastPost = p.Created;
     }
     thread.LastPost = lastPost;
     db.SubmitChanges();
 }
        public ActionResult Detail(int id)
        {
            var db = new ZkDataContext();
            var mission = db.Missions.Single(x => x.MissionID == id);
            mission.ForumThread.UpdateLastRead(Global.AccountID, false);
            db.SubmitChanges();

            return View("Detail",
                        new MissionDetailData
                        {
                            Mission = mission,
                            TopScores = mission.MissionScores.Where(x=> x.Score > 0).OrderByDescending(x => x.Score).AsQueryable(),
                            MyRating = mission.Ratings.SingleOrDefault(x => x.AccountID == Global.AccountID) ?? new Rating(),
                        });
        }
        //
        // GET: /Battles/

        /// <summary>
        ///     Returns the page of the <see cref="SpringBattle" /> with the specified ID
        /// </summary>
        public ActionResult Detail(int id, bool showWinners = false) {
            var db = new ZkDataContext();
            ViewBag.ShowWinners = showWinners;
            var bat = db.SpringBattles.FirstOrDefault(x => x.SpringBattleID == id);
            if (bat == null) return Content("No such battle exists");

            if (bat.ForumThread != null)
            {
                bat.ForumThread.UpdateLastRead(Global.AccountID, false);
                db.SubmitChanges();
            }

            if (Global.AccountID != 0 && !showWinners && bat.SpringBattlePlayers.Any(y => y.AccountID == Global.AccountID && !y.IsSpectator)) ViewBag.ShowWinners = true; // show winners if player played thatbattle

            return View("BattleDetail", bat);
        }
        public static void PurgeGalaxy(int galaxyID, bool resetclans = false, bool resetroles = false)
        {
            System.Console.WriteLine("Purging galaxy " + galaxyID);
            using (var db = new ZkDataContext())
            {
                db.Database.CommandTimeout = 300;

                var gal = db.Galaxies.Single(x => x.GalaxyID == galaxyID);
                foreach (var p in gal.Planets)
                {
                    //p.ForumThread = null;
                    p.OwnerAccountID = null;
                    p.Faction = null;
                    p.Account = null;
                }
                foreach (var f in db.Factions)
                {
                    f.Metal = 0;
                    f.EnergyDemandLastTurn = 0;
                    f.EnergyProducedLastTurn = 0;
                    f.Bombers = 0;
                    f.Dropships = 0;
                    f.Warps = 0;
                }
                db.SubmitChanges();

                db.Database.ExecuteSqlCommand("update accounts set pwbombersproduced=0, pwbombersused=0, pwdropshipsproduced=0, pwdropshipsused=0, pwmetalproduced=0, pwmetalused=0, pwattackpoints=0, pwwarpproduced=0, pwwarpused=0, elopw=1500");
                if (resetclans) db.Database.ExecuteSqlCommand("update accounts set clanid=null");
                db.Database.ExecuteSqlCommand("delete from events");
                db.Database.ExecuteSqlCommand("delete from planetownerhistories");
                db.Database.ExecuteSqlCommand("delete from planetstructures");
                db.Database.ExecuteSqlCommand("delete from planetfactions");
                db.Database.ExecuteSqlCommand("delete from accountplanets");
                if (resetroles) db.Database.ExecuteSqlCommand("delete from accountroles where clanID is null");
                db.Database.ExecuteSqlCommand("delete from factiontreaties");
                db.Database.ExecuteSqlCommand("delete from treatyeffects");

                db.Database.ExecuteSqlCommand("delete from forumthreads where forumcategoryid={0}", db.ForumCategories.Single(x => x.ForumMode ==ForumMode.Planets).ForumCategoryID);

                if (resetclans)
                {
                    db.Database.ExecuteSqlCommand("delete from clans");
                    db.Database.ExecuteSqlCommand("delete from forumthreads where forumcategoryid={0}", db.ForumCategories.Single(x => x.ForumMode==ForumMode.Clans).ForumCategoryID);
                }
            }
        }
		protected void lqResources_Deleting(object sender, LinqDataSourceDeleteEventArgs e)
		{
			e.Cancel = true;
			if ((bool?)Session["login"] == true) {
				var db = new ZkDataContext();
				var todel = db.Resources.Single(x=>x.InternalName == ((Resource)e.OriginalObject).InternalName);
        PlasmaServer.RemoveResourceFiles(todel);

				
				db.Resources.DeleteOnSubmit(todel);
				db.SubmitChanges();
				
				MessageBox.Show("Deleted " +  todel.InternalName);
        
			} else {
				MessageBox.Show("Not logged in");
			}
		}
		protected void lqContentFiles_Deleting(object sender, LinqDataSourceDeleteEventArgs e)
		{
			e.Cancel = true;
			if ((bool?)Session["login"] == true)
			{
				var db = new ZkDataContext();
				var todel = db.ResourceContentFiles.Single(x => x.Md5 == ((ResourceContentFile)e.OriginalObject).Md5);
				Utils.SafeDelete(PlasmaServer.GetTorrentPath(todel));

				db.ResourceContentFiles.DeleteOnSubmit(todel);
				db.SubmitChanges();

				MessageBox.Show("Deleted " + todel.FileName);

			}
			else
			{
				MessageBox.Show("Not logged in");
			}

		}
        public ActionResult Index(int? campaignID = null)
        {
            var db = new ZkDataContext();

            Campaign camp;
            if (campaignID != null) camp = db.Campaigns.Single(x => x.CampaignID == campaignID);
            else camp = db.Campaigns.Single(x => x.CampaignID == 1);
            string cachePath = Server.MapPath(string.Format("/img/galaxies/campaign/render_{0}.jpg", camp.CampaignID));
            // /*
            if (camp.IsDirty || !System.IO.File.Exists(cachePath)) {
                using (Image im = GenerateGalaxyImage(camp.CampaignID)) {
                    im.SaveJpeg(cachePath, 85);
                    camp.IsDirty = false;
                    camp.MapWidth = im.Width;
                    camp.MapHeight = im.Height;
                    db.SubmitChanges();
                }
            }
            // */
            return View("CampaignMap", camp);
        }
 public ActionResult ChangePermissions(int accountID, int adminAccountID, int springieLevel, bool zkAdmin, bool vpnException)
 {
     var db = new ZkDataContext();
     Account acc = db.Accounts.Single(x => x.AccountID == accountID);
     Account adminAcc = db.Accounts.Single(x => x.AccountID == adminAccountID);
     Global.Nightwatch.Tas.Say(SayPlace.Channel, AuthService.ModeratorChannel, string.Format("Permissions changed for {0} {1} by {2}", acc.Name, Url.Action("Detail", "Users", new { id = acc.AccountID }, "http"), adminAcc.Name), true);
     if (acc.SpringieLevel != springieLevel)
     {
         Global.Nightwatch.Tas.Say(SayPlace.Channel, AuthService.ModeratorChannel, string.Format(" - Springie rights: {0} -> {1}", acc.SpringieLevel, springieLevel), true);
         acc.SpringieLevel = springieLevel;
     }
    if (acc.IsZeroKAdmin != zkAdmin)
     {
         //reset chat priviledges to 2 if removing adminhood; remove NW subsciption to admin channel
         // FIXME needs to also terminate forbidden clan/faction subscriptions
         if (zkAdmin == false)
         {
             Global.Nightwatch.Tas.Say(SayPlace.Channel, AuthService.ModeratorChannel, string.Format(" - Springie rights: {0} -> {1}", acc.SpringieLevel, 2), true);
             acc.SpringieLevel = 2;
             var channelSub = db.LobbyChannelSubscriptions.FirstOrDefault(x => x.Account == acc && x.Channel == GlobalConst.ModeratorChannel);
             db.LobbyChannelSubscriptions.DeleteOnSubmit(channelSub);
         }
         Global.Nightwatch.Tas.Say(SayPlace.Channel, AuthService.ModeratorChannel, string.Format(" - Admin status: {0} -> {1}", acc.IsZeroKAdmin, zkAdmin), true);
         acc.IsZeroKAdmin = zkAdmin;
         
     }
     if (acc.HasVpnException != vpnException)
     {
         Global.Nightwatch.Tas.Say(SayPlace.Channel, AuthService.ModeratorChannel, string.Format(" - VPN exception: {0} -> {1}", acc.HasVpnException, vpnException), true);
         acc.HasVpnException = vpnException;
     }
     db.SubmitChanges();
     Global.Nightwatch.Tas.Extensions.PublishAccountData(acc);
     
     return RedirectToAction("Detail", "Users", new { id = acc.AccountID });
 }
 public ActionResult ChangePermissions(int accountID, int adminAccountID, int springieLevel, bool zkAdmin, bool vpnException)
 {
     var db = new ZkDataContext();
     Account acc = db.Accounts.Single(x => x.AccountID == accountID);
     Account adminAcc = db.Accounts.Single(x => x.AccountID == adminAccountID);
     Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("Permissions changed for {0} {1} by {2}", acc.Name, Url.Action("Detail", "Users", new { id = acc.AccountID }, "http"), adminAcc.Name));
     if (acc.SpringieLevel != springieLevel)
     {
         Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format(" - Springie rights: {0} -> {1}", acc.SpringieLevel, springieLevel));
         acc.SpringieLevel = springieLevel;
     }
    if (acc.IsZeroKAdmin != zkAdmin)
     {
         //reset chat priviledges to 2 if removing adminhood; remove NW subsciption to admin channel
         // FIXME needs to also terminate forbidden clan/faction subscriptions
         if (zkAdmin == false)
         {
             Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format(" - Springie rights: {0} -> {1}", acc.SpringieLevel, 2));
             acc.SpringieLevel = 2;
             
         }
         Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format(" - Admin status: {0} -> {1}", acc.IsZeroKAdmin, zkAdmin));
         acc.IsZeroKAdmin = zkAdmin;
         
     }
     if (acc.HasVpnException != vpnException)
     {
         Global.Server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format(" - VPN exception: {0} -> {1}", acc.HasVpnException, vpnException));
         acc.HasVpnException = vpnException;
     }
     db.SubmitChanges();
     
     Global.Server.PublishAccountUpdate(acc);
     
     return RedirectToAction("Detail", "Users", new { id = acc.AccountID });
 }
Exemplo n.º 24
0
        static void Downloader_PackagesChanged(object sender, EventArgs e)
        {
            foreach (var ver in Downloader.PackageDownloader.Repositories.SelectMany(x => x.VersionsByTag.Keys)) {
                if (ver.EndsWith(":test") || ver.EndsWith(":latest")) {
                    if (!Downloader.PackageDownloader.SelectedPackages.Contains(ver))
                    {
                        Trace.TraceInformation("Selecting package: {0}",ver);
                        Downloader.PackageDownloader.SelectPackage(ver);
                        Downloader.GetResource(DownloadType.MOD, ver);
                    }

                }
            }

            var waiting = false;
            do
            {
                var downs = Downloader.Downloads.ToList().Where(x => x.IsComplete == null && !x.IsAborted).ToList();
                if (downs.Any())
                {
                    waiting = true;
                    var d = downs.First();
                    Trace.TraceInformation("Waiting for: {0} - {1} {2}", d.Name, d.TotalProgress, d.TimeRemaining);
                } else if (Scanner.GetWorkCost() > 0) {
                    waiting = true;
                    Trace.TraceInformation("Waiting for scanner: {0}", Scanner.GetWorkCost());
                }
                else waiting = false;
                if (waiting) Thread.Sleep(10000);
            } while (waiting);



            lock (Locker)
            {
                foreach (var id in new ZkDataContext(false).Missions.Where(x => !x.IsScriptMission && x.ModRapidTag != "" && !x.IsDeleted).Select(x=>x.MissionID).ToList())
                {
                    using (var db = new ZkDataContext(false))
                    {
                        var mis = db.Missions.Single(x => x.MissionID == id);
                        try
                        {
                            if (!string.IsNullOrEmpty(mis.ModRapidTag))
                            {
                                var latestMod = Downloader.PackageDownloader.GetByTag(mis.ModRapidTag);
                                if (latestMod != null && mis.Mod != latestMod.InternalName)
                                {
                                    mis.Mod = latestMod.InternalName;
                                    Trace.TraceInformation("Updating mission {0} {1} to {2}", mis.MissionID, mis.Name, mis.Mod);
                                    var mu = new MissionUpdater();
                                    Mod modInfo = null;
                                    Scanner.MetaData.GetMod(mis.NameWithVersion, m => { modInfo = m; }, (er) => { });
                                    mis.Revision++;
                                    mu.UpdateMission(db, mis, modInfo);
                                    db.SubmitChanges();
                                }

                            }


                        }
                        catch (Exception ex)
                        {
                            Trace.TraceError("Failed to update mission {0}: {1}", mis.MissionID, ex);
                        }
                    }
                }
            }
        }
        public static void ProgressCampaign(int accountID, int missionID, string missionVars = "")
        {
            ZkDataContext db = new ZkDataContext();
            CampaignPlanet planet = db.CampaignPlanets.FirstOrDefault(p => p.MissionID == missionID);
            if (planet != null)
            {
                Account acc = db.Accounts.First(x => x.AccountID == accountID);
                bool alreadyCompleted = false;
                int campID = planet.CampaignID;
                Campaign camp = planet.Campaign;
                List<int> unlockedPlanetIDs = new List<int>();
                List<int> unlockedJournalIDs = new List<int>();
                //List<CampaignPlanet> unlockedPlanets = new List<CampaignPlanet>();
                //List<CampaignJournal> unlockedJournals = new List<CampaignJournal>();

                // start with processing the mission vars, if there are any
                byte[] missionVarsAsByteArray = System.Convert.FromBase64String(missionVars);
                string missionVarsDecoded = System.Text.Encoding.UTF8.GetString(missionVarsAsByteArray);
                foreach (string kvpRaw in missionVarsDecoded.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    string kvpRaw2 = kvpRaw.Trim();
                    string key = "", value = "";
                    string[] kvpSplit = kvpRaw2.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                    if (kvpSplit.Length == 2)
                    {
                        key = kvpSplit[0].Trim();
                        value = kvpSplit[1].Trim();
                    }
                    else
                    {
                        throw new Exception("Invalid key-value pair in decoded mission vars: " + missionVarsDecoded);
                    }
                    if (!(string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value)))
                    {
                        CampaignVar cv = camp.CampaignVars.First(x => x.KeyString == key);
                        AccountCampaignVar acv = acc.AccountCampaignVars.FirstOrDefault(x => x.CampaignID == campID && x.VarID == cv.VarID);
                        if (acv == null)
                        {
                            db.AccountCampaignVars.InsertOnSubmit(new AccountCampaignVar() { AccountID = accountID, CampaignID = campID, VarID = cv.VarID, Value = value });
                        }
                        else acv.Value = value;
                    }
                }

                //reload DB - this allows the vars submitted this session to be used by the following code
                db.SubmitChanges();
                db = new ZkDataContext();
                acc = db.Accounts.First(x => x.AccountID == accountID);
                planet = db.CampaignPlanets.FirstOrDefault(p => p.MissionID == missionID);
                camp = planet.Campaign;

                // now we unlock planets and journal entries
                // first mark this planet as completed - but only if it's already unlocked
                AccountCampaignProgress progress = acc.AccountCampaignProgress.FirstOrDefault(x => x.PlanetID == planet.PlanetID && x.CampaignID == planet.CampaignID);
                if (progress != null)
                {
                    alreadyCompleted = progress.IsCompleted;
                }
                else if (planet.StartsUnlocked)
                {
                    progress = new AccountCampaignProgress() { AccountID = accountID, CampaignID = campID, PlanetID = planet.PlanetID, IsCompleted = false, IsUnlocked = true };
                    db.AccountCampaignProgress.InsertOnSubmit(progress);
                }

                if (progress != null && planet.IsUnlocked(accountID))
                {
                    progress.IsCompleted = true;


                    // unlock planets made available by completing this one
                    var links = camp.CampaignLinks.Where(x => x.UnlockingPlanetID == planet.PlanetID);
                    foreach (CampaignLink link in links)
                    {
                        CampaignPlanet toUnlock = link.PlanetToUnlock;
                        bool proceed = true;
                        var requiredVars = toUnlock.CampaignPlanetVars;
                        if (requiredVars.Count() == 0) proceed = true;
                        else
                        {
                            foreach (CampaignPlanetVar variable in requiredVars)
                            {
                                AccountCampaignVar accountVar = acc.AccountCampaignVars.FirstOrDefault(x => x.CampaignID == campID && x.VarID == variable.RequiredVarID);
                                if (!(accountVar != null && accountVar.Value == variable.RequiredValue))
                                {
                                    proceed = false;
                                    break;  // failed to meet var requirement, stop here
                                }
                            }
                        }

                        if (proceed)    // met requirements for unlocking planet
                        {
                            AccountCampaignProgress progress2 = toUnlock.AccountCampaignProgress.FirstOrDefault(x => x.CampaignID == campID && x.AccountID == accountID);
                            if (progress2 == null)
                            {
                                progress2 = new AccountCampaignProgress() { AccountID = accountID, CampaignID = campID, PlanetID = toUnlock.PlanetID, IsCompleted = false, IsUnlocked = true };
                                db.AccountCampaignProgress.InsertOnSubmit(progress2);
                                unlockedPlanetIDs.Add(toUnlock.PlanetID);
                            }
                            else if (!progress2.IsUnlocked)
                            {
                                progress2.IsUnlocked = true;
                                unlockedPlanetIDs.Add(toUnlock.PlanetID);
                            }
                        }
                    }
                }
                // unlock journals
                var journalsWithVars = db.CampaignJournals.Where(x => x.CampaignID == campID && x.CampaignJournalVars.Any());
                foreach (CampaignJournal journal in journalsWithVars)
                {
                    bool proceed = true;

                    var requiredVars = journal.CampaignJournalVars.Where(x => x.CampaignID == campID).ToList();
                    foreach (CampaignJournalVar variable in requiredVars)
                    {
                        AccountCampaignVar accountVar = acc.AccountCampaignVars.FirstOrDefault(x => x.CampaignID == campID && x.VarID == variable.RequiredVarID);
                        if (!(accountVar != null && accountVar.Value == variable.RequiredValue))
                        {
                            proceed = false;
                            break;  // failed to meet var requirement, stop here
                        }
                    }

                    if (proceed)    // met requirements for unlocking journal
                    {
                        System.Console.WriteLine(journal.Title);
                        AccountCampaignJournalProgress jp = journal.AccountCampaignJournalProgress.FirstOrDefault(x => x.AccountID == accountID);
                        if (jp == null)
                        {
                            jp = new AccountCampaignJournalProgress() { AccountID = accountID, CampaignID = campID, JournalID = journal.JournalID, IsUnlocked = true };
                            db.AccountCampaignJournalProgress.InsertOnSubmit(jp);
                            unlockedJournalIDs.Add(journal.JournalID);
                        }
                        else if (!jp.IsUnlocked)
                        {
                            jp.IsUnlocked = true;
                            unlockedJournalIDs.Add(journal.JournalID);
                        }
                    }
                }
                db.SubmitChanges();
                db = new ZkDataContext();
                planet = db.CampaignPlanets.FirstOrDefault(p => p.MissionID == missionID);

                //throw new Exception("DEBUG: Campaign " + campID + ", planet " + planet.PlanetID);
                if (!alreadyCompleted)
                {
                    db.CampaignEvents.InsertOnSubmit(Global.CreateCampaignEvent(accountID, campID, "Planet completed: {0}", planet));
                    foreach (CampaignJournal journal in db.CampaignJournals.Where(x => x.CampaignID == campID && x.PlanetID == planet.PlanetID && x.UnlockOnPlanetCompletion))
                    {
                        unlockedJournalIDs.Add(journal.JournalID);
                    }
                }
                foreach (int unlockedID in unlockedPlanetIDs)
                {
                    CampaignPlanet unlocked = db.CampaignPlanets.FirstOrDefault(x => x.PlanetID == unlockedID && x.CampaignID == campID);
                    db.CampaignEvents.InsertOnSubmit(Global.CreateCampaignEvent(accountID, campID, "Planet unlocked: {0}", unlocked));
                    foreach (CampaignJournal journal in db.CampaignJournals.Where(x => x.CampaignID == campID && x.PlanetID == unlocked.PlanetID && x.UnlockOnPlanetUnlock))
                    {
                        unlockedJournalIDs.Add(journal.JournalID);
                    }
                }
                foreach (int ujid in unlockedJournalIDs)
                {
                    CampaignJournal uj = db.CampaignJournals.FirstOrDefault(x => x.JournalID == ujid && x.CampaignID == campID);
                    db.CampaignEvents.InsertOnSubmit(Global.CreateCampaignEvent(accountID, campID, "{1} - Journal entry unlocked: {0}", uj, uj.CampaignPlanet));
                }
                db.SubmitChanges();
            }
        }
        public void SubmitMissionScore(string login, string passwordHash, string missionName, int score, int gameSeconds, string missionVars = "")
        {
            missionName = Mission.GetNameWithoutVersion(missionName);

            using (var db = new ZkDataContext())
            {
                var acc = AuthServiceClient.VerifyAccountHashed(login, passwordHash);
                if (acc == null) throw new ApplicationException("Invalid login or password");

                acc.Xp += GlobalConst.XpForMissionOrBots;

                var mission = db.Missions.Single(x => x.Name == missionName);

                if (score != 0)
                {
                    var scoreEntry = mission.MissionScores.FirstOrDefault(x => x.AccountID == acc.AccountID);
                    if (scoreEntry == null)
                    {
                        scoreEntry = new MissionScore() { MissionID = mission.MissionID, AccountID = acc.AccountID, Score = int.MinValue };
                        mission.MissionScores.Add(scoreEntry);
                    }

                    if (score > scoreEntry.Score)
                    {
                        var max = mission.MissionScores.Max(x => (int?)x.Score);
                        if (max == null || max <= score)
                        {
                            mission.TopScoreLine = login;
                            acc.Xp += 150; // 150 for getting top score
                        }
                        scoreEntry.Score = score;
                        scoreEntry.Time = DateTime.UtcNow;
                        scoreEntry.MissionRevision = mission.Revision;
                        scoreEntry.GameSeconds = gameSeconds;
                    }
                }
                acc.CheckLevelUp();
                db.SubmitChanges();

                // ====================
                // campaign stuff
                ProgressCampaign(acc.AccountID, mission.MissionID, missionVars);
            }
        }
 public void NotifyMissionRun(string login, string missionName)
 {
     missionName = Mission.GetNameWithoutVersion(missionName);
     using (var db = new ZkDataContext())
     {
         db.Missions.Single(x => x.Name == missionName).MissionRunCount++;
         Account.AccountByName(db, login).MissionRunCount++;
         db.SubmitChanges();
     }
 }
        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

            //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.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());
                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.SubmitChanges(); // make sure event gets correct details
                    if (clan.FactionID != null) 
                        db.Events.InsertOnSubmit(Global.CreateEvent("Clan {0} moved to faction {1}", orgClan, orgClan.Faction));
                    else
                        db.Events.InsertOnSubmit(Global.CreateEvent("Clan {0} left faction {1}", orgClan, oldFaction));
                }
                db.SubmitChanges();
            }
            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);

                var acc = db.Accounts.Single(x => x.AccountID == Global.AccountID);
                acc.ClanID = clan.ClanID;

                // we created a new clan, set self as founder and rights
                AddClanLeader(acc.AccountID, clan.ClanID, db);

                db.SubmitChanges(); // needed to get clan id for images

                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(Global.CreateEvent("New clan {0} formed by {1}", clan, acc));
                db.SubmitChanges();
            }

            //scope.Complete();
            Global.Server.ChannelManager.AddClanChannel(clan);;
            Global.Server.SetTopic(clan.GetClanChannel(), clan.SecretTopic, Global.Account.Name);
            //}
            return RedirectToAction("Detail", new { id = clan.ClanID });
        }
 public ActionResult KickPlayerFromClan(int clanID, int accountID)
 {
     var db = new ZkDataContext();
     var clan = db.Clans.Single(c => clanID == c.ClanID);
     if (!(Global.Account.HasClanRight(x => x.RightKickPeople) && clan.ClanID == Global.Account.ClanID)) return Content("Unauthorized");
     PerformLeaveClan(accountID);
     db.SubmitChanges();
     PlanetwarsController.SetPlanetOwners();
     return RedirectToAction("Detail", new { id = clanID });
 }
        public ActionResult JoinClan(int id, string password)
        {
            var db = new ZkDataContext();
            var clan = db.Clans.Single(x => x.ClanID == id);
            

            if (clan.CanJoin(Global.Account))
            {
                if (!string.IsNullOrEmpty(clan.Password) && clan.Password != password) return View(clan.ClanID);
                else
                {
                    var acc = db.Accounts.Single(x => x.AccountID == Global.AccountID);
                    acc.ClanID = clan.ClanID;
                    acc.FactionID = clan.FactionID;
                    db.Events.InsertOnSubmit(Global.CreateEvent("{0} joins clan {1}", acc, clan));

                    if (clan.IsDeleted) // recreate clan
                    {
                        AddClanLeader(acc.AccountID, clan.ClanID, db);
                        clan.IsDeleted = false;
                        db.Events.InsertOnSubmit(Global.CreateEvent("Clan {0} reformed by {1}", clan, acc));
                    }

                    db.SubmitChanges();
                    return RedirectToAction("Detail", new { id = clan.ClanID });
                }
            }
            else return Content("You cannot join this clan - its full, or has password, or is different faction");
        }