示例#1
0
        static void AddPwPlayer(BattleContext context, string matchUser, BalanceTeamsResult res, int allyID)
        {
            PlayerTeam player = context.Players.FirstOrDefault(x => x.Name == matchUser);

            if (player == null)
            {
                player = new PlayerTeam()
                {
                    Name = matchUser
                };
                User us;
                if (Global.Nightwatch.Tas.GetExistingUser(matchUser, out us))
                {
                    player.LobbyID = us.AccountID;
                }
                else
                {
                    var db  = new ZkDataContext();
                    var acc = Account.AccountByName(db, matchUser);
                    if (acc != null)
                    {
                        player.LobbyID = acc.AccountID;
                    }
                }
            }
            res.Players.Add(new PlayerTeam {
                AllyID = allyID, IsSpectator = false, Name = player.Name, LobbyID = player.LobbyID, TeamID = player.TeamID
            });
        }
示例#2
0
 private async Task JoinPlanet(string name, int planetId)
 {
     try
     {
         var user = server.ConnectedUsers.Get(name)?.User;
         if (user != null)
         {
             var faction = factions.FirstOrDefault(x => x.Shortcut == user.Faction);
             if (faction == null)
             {
                 var db  = new ZkDataContext(); // this is a fallback, should not be needed
                 var acc = Account.AccountByName(db, name);
                 faction = factions.FirstOrDefault(x => x.FactionID == acc.FactionID);
             }
             if (faction == AttackingFaction)
             {
                 await JoinPlanetAttack(planetId, name);
             }
             else if ((Challenge != null) && GetDefendingFactions(Challenge).Contains(faction))
             {
                 await JoinPlanetDefense(planetId, name);
             }
         }
     }
     catch (Exception ex)
     {
         Trace.TraceError("PlanetWars {0} {1} {2} : {3}", nameof(JoinPlanet), name, planetId, ex);
     }
 }
        void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e)
        {
            if (DateTime.UtcNow.Subtract(lastPollCheck).TotalMinutes > 15)
            {
                PollController.AutoClosePolls();
                lastPollCheck = DateTime.UtcNow;
            }

            Account acc = null;

            if (Request[GlobalConst.ASmallCakeCookieName] != null)
            {
                var testAcc = Account.AccountByName(new ZkDataContext(), Request[GlobalConst.ASmallCakeLoginCookieName]);
                if (testAcc != null)
                {
                    if (AuthTools.ValidateSiteAuthToken(testAcc.Name, testAcc.Password, Request[GlobalConst.ASmallCakeCookieName]))
                    {
                        acc = testAcc;
                    }
                }
            }
            if (acc == null)
            {
                if (Request[GlobalConst.LoginCookieName] != null)
                {
                    acc = AuthServiceClient.VerifyAccountHashed(Request[GlobalConst.LoginCookieName], Request[GlobalConst.PasswordHashCookieName]);
                }
            }

            if (acc != null)
            {
                var ip = GetUserIP();
                using (var db = new ZkDataContext()) {
                    var penalty = Punishment.GetActivePunishment(acc.AccountID, ip, null, x => x.BanSite, db);
                    if (penalty != null)
                    {
                        Response.Write(string.Format("You are banned! (IP match to account {0})\n", penalty.AccountByAccountID.Name));
                        Response.Write(string.Format("Ban expires: {0} UTC\n", penalty.BanExpires));
                        Response.Write(string.Format("Reason: {0}\n", penalty.Reason));
                        Response.End();
                    }
                    else
                    {
                        HttpContext.Current.User = acc;
                        // todo replace with safer permanent cookie
                        Response.SetCookie(new HttpCookie(GlobalConst.LoginCookieName, acc.Name)
                        {
                            Expires = DateTime.Now.AddMonths(12)
                        });
                        Response.SetCookie(new HttpCookie(GlobalConst.PasswordHashCookieName, acc.Password)
                        {
                            Expires = DateTime.Now.AddMonths(12)
                        });
                    }
                }
            }
        }
示例#4
0
 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();
     }
 }
        private void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e)
        {
            if (DateTime.UtcNow.Subtract(lastPollCheck).TotalMinutes > 60)
            {
                PollController.AutoClosePolls(); // this is silly here, should be a seaprate timer/thread
                lastPollCheck = DateTime.UtcNow;
            }

            Account acc = null;


            if (FormsAuthentication.IsEnabled && User.Identity.IsAuthenticated)
            {
                acc = Account.AccountByName(new ZkDataContext(), User.Identity.Name);
            }
            else if (Request[GlobalConst.SessionTokenVariable] != null)
            {
                int id = 0;
                if (Global.Server?.SessionTokens.TryRemove(Request[GlobalConst.SessionTokenVariable], out id) == true)
                {
                    acc = new ZkDataContext().Accounts.Find(id);
                }
            }

            if (acc != null)
            {
                var ip        = Request.UserHostAddress;
                var lastLogin = acc.AccountUserIDs.OrderByDescending(x => x.LastLogin).FirstOrDefault();
                var userID    = lastLogin?.UserID;
                var installID = lastLogin?.InstallID;
                var penalty   = Punishment.GetActivePunishment(acc.AccountID, ip, userID, installID, x => x.BanSite);
                if (penalty != null)
                {
                    Response.Write(string.Format("You are banned! (IP match to account {0})\n", penalty.AccountByAccountID.Name));
                    Response.Write(string.Format("Ban expires: {0} UTC\n", penalty.BanExpires));
                    Response.Write(string.Format("Reason: {0}\n", penalty.Reason));
                    Response.End();
                }
                else
                {
                    HttpContext.Current.User = acc;
                    FormsAuthentication.SetAuthCookie(acc.Name, true);
                }
            }

            // remove cake from URL
            var removeCake = Regex.Replace(Request.Url.ToString(), $"([?|&])({GlobalConst.SessionTokenVariable}=[^&?]+[?|&]*)", m => m.Groups[1].Value);

            if (removeCake != Request.Url.ToString())
            {
                Response.Redirect(removeCake, true);
            }
        }
示例#6
0
        /// <summary>
        /// Get user detail page by username or <see cref="Account"/> ID
        /// </summary>
        /// <param name="id">Name or ID</param>
        public ActionResult LobbyDetail(string id)
        {
            var     db = new ZkDataContext();
            int     idint;
            Account user = null;

            if (int.TryParse(id, out idint))
            {
                user = db.Accounts.Find(idint);
            }
            if (user == null)
            {
                user = Account.AccountByName(db, id);
            }

            return(View("UserDetail", user));
        }
示例#7
0
        public ActionResult ReportToAdminFromLobby(string id)
        {
            var     db = new ZkDataContext();
            int     idint;
            Account user = null;

            if (int.TryParse(id, out idint))
            {
                user = db.Accounts.Find(idint);
            }
            if (user == null)
            {
                user = Account.AccountByName(db, id);
            }

            return(View("ReportToAdmin", user));
        }
示例#8
0
        public ActionResult GetReplayList()
        {
            if (!Global.IsTourneyController)
            {
                return(DenyAccess());
            }
            var           db             = new ZkDataContext();
            List <string> replayList     = new List <string>();
            var           tourneyBattles = Global.Server.Battles.Values.Where(x => x != null).OfType <TourneyBattle>().ToList();

            foreach (var tBat in tourneyBattles)
            {
                string line = string.Format("");
                foreach (var team in tBat.Prototype.TeamPlayers)
                {
                    foreach (var p in team)
                    {
                        line += "@U" + Account.AccountByName(db, p).AccountID + ", ";
                    }
                    line  = line.Remove(line.Length - 2);
                    line += " vs ";
                }
                line  = line.Remove(line.Length - 4);
                line += ": ";

                int batCount = 0;
                foreach (var deb in tBat.Debriefings)
                {
                    var bat = db.SpringBattles.FirstOrDefault(x => x.SpringBattleID == deb.ServerBattleID);
                    if (bat != null)
                    {
                        batCount++;
                        line += "@B" + deb.ServerBattleID + ", ";
                    }
                }
                line = line.Remove(line.Length - 2);
                if (batCount > 0)
                {
                    replayList.Add(line);
                }
            }
            return(Content(string.Join("<br />", replayList)));
        }
示例#9
0
        /// <summary>
        /// <para>Converts strings preceded with an @ to a printed <see cref="Account"/>, <see cref="SpringBattle"/>, etc. as appropriate</para>
        /// <para>e.g. @KingRaptor becomes the printed account for user KingRaptor</para>
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ProcessAtSignTags(string str)
        {
            var db = new ZkDataContext();

            str = Regex.Replace(str,
                                @"@([\w\[\]]+)",
                                m =>
            {
                var val = m.Groups[1].Value;
                var acc = Account.AccountByName(db, val);
                if (acc != null)
                {
                    return(PrintAccount(null, acc).ToString());
                }
                var clan = db.Clans.FirstOrDefault(x => x.Shortcut == val);
                if (clan != null)
                {
                    return(PrintClan(null, clan).ToString());
                }
                var fac = db.Factions.FirstOrDefault(x => x.Shortcut == val);
                if (fac != null)
                {
                    return(PrintFaction(null, fac, false).ToString());
                }

                if (val.StartsWith("b", StringComparison.InvariantCultureIgnoreCase))
                {
                    var bid = 0;
                    if (int.TryParse(val.Substring(1), out bid))
                    {
                        var bat = db.SpringBattles.FirstOrDefault(x => x.SpringBattleID == bid);
                        if (bat != null)
                        {
                            return(PrintBattle(null, bat).ToString());
                        }
                    }
                }
                return("@" + val);
            });
            return(str);
        }
        public ActionResult Detail(string id)
        {
            var db = new ZkDataContext();

            int     idint;
            Account user = null;

            if (int.TryParse(id, out idint))
            {
                user = db.Accounts.Find(idint);
            }
            if (user == null)
            {
                user = Account.AccountByName(db, id);
            }
            if (user == null)
            {
                return(Content("Invalid account (neither an ID nor name)"));
            }
            return(View("UserDetail", user));
        }
示例#11
0
 public void JoinPlanet(string name, int planetId)
 {
     if (tas.ExistingUsers.ContainsKey(name))
     {
         Faction faction = factions.FirstOrDefault(x => x.Shortcut == tas.ExistingUsers[name].Faction);
         if (faction == null)
         {
             var db  = new ZkDataContext(); // this is a fallback, should not be needed
             var acc = Account.AccountByName(db, name);
             faction = factions.FirstOrDefault(x => x.FactionID == acc.FactionID);
         }
         if (faction == AttackingFaction)
         {
             JoinPlanetAttack(planetId, name);
         }
         else if (Challenge != null && GetDefendingFactions(Challenge).Contains(faction))
         {
             JoinPlanetDefense(planetId, name);
         }
     }
 }
示例#12
0
        public async Task Process(SetAccountRelation rel)
        {
            if (!IsLoggedIn)
            {
                return;
            }

            if (string.IsNullOrEmpty(rel.TargetName) && string.IsNullOrEmpty(rel.SteamID))
            {
                return;
            }

            using (var db = new ZkDataContext())
            {
                ulong steamId = 0;

                var srcAccount = db.Accounts.Find(User.AccountID);
                ulong.TryParse(rel.SteamID, out steamId);
                var trgtAccount = Account.AccountByName(db, rel.TargetName) ?? db.Accounts.FirstOrDefault(x => x.SteamID == steamId);
                if (trgtAccount == null)
                {
                    if (!string.IsNullOrEmpty(rel.TargetName))
                    {
                        await Respond("No such account found");                                        // only warn if name is set and not just steam id
                    }
                    return;
                }

                var friendAdded = false;

                var entry = srcAccount.RelalationsByOwner.FirstOrDefault(x => x.TargetAccountID == trgtAccount.AccountID);
                if ((rel.Relation == Relation.None) && (entry != null))
                {
                    db.AccountRelations.Remove(entry);
                }
                if (rel.Relation != Relation.None)
                {
                    if (entry == null)
                    {
                        if (rel.Relation == Relation.Friend)
                        {
                            friendAdded = true;
                        }
                        entry = new AccountRelation()
                        {
                            Owner = srcAccount, Target = trgtAccount, Relation = rel.Relation
                        };
                        srcAccount.RelalationsByOwner.Add(entry);
                    }
                    else
                    {
                        entry.Relation = rel.Relation;
                    }
                }
                db.SaveChanges();

                ConnectedUser targetConnectedUser;
                if (server.ConnectedUsers.TryGetValue(trgtAccount.Name, out targetConnectedUser))
                {
                    targetConnectedUser.LoadFriendsIgnores(); // update partner's mutual lists

                    if (friendAdded)                          // friend added, sync new friend to me (user, battle and channels)
                    {
                        await server.TwoWaySyncUsers(Name, new List <string>() { targetConnectedUser.Name });

                        foreach (var chan in
                                 server.Channels.Values.Where(
                                     x => (x != null) && x.Users.ContainsKey(Name) && x.Users.ContainsKey(targetConnectedUser.Name)))
                        {
                            await SendCommand(new ChannelUserAdded()
                            {
                                ChannelName = chan.Name, UserName = targetConnectedUser.Name
                            });
                        }
                    }
                }

                LoadFriendsIgnores();
                await SendCommand(new FriendList()
                {
                    Friends = FriendEntries.ToList()
                });
                await SendCommand(new IgnoreList()
                {
                    Ignores = Ignores.ToList()
                });
            }
        }
示例#13
0
        public ActionResult AddMultipleBattles(string battleList)
        {
            if (!Global.IsTourneyController)
            {
                return(DenyAccess());
            }
            var db = new ZkDataContext();

            string[] splitters   = { "//" };
            string[] battleSpecs = battleList.Split(splitters, System.StringSplitOptions.RemoveEmptyEntries);

            foreach (var bSpec in battleSpecs)
            {
                bool     validBattle = true;
                string[] bItems      = bSpec.Split(',');
                string   bName       = bItems[0];
                // must have an even number of players; the first N/2 are assigned to the first team
                if (bItems.Length % 2 == 0)
                {
                    validBattle = false;
                }
                ;
                int        playersPerTeam = (bItems.Length - 1) / 2;
                List <int> team1Ids       = new List <int>();
                List <int> team2Ids       = new List <int>();
                // if any of the remaining entries are not ints or account names the battle is invalid
                for (int i = 1; i <= playersPerTeam; i++)
                {
                    Account tryAcc = Account.AccountByName(db, bItems[i]);
                    if (tryAcc != null)
                    {
                        team1Ids.Add(tryAcc.AccountID);
                    }
                    else
                    {
                        try { team1Ids.Add(Int32.Parse(bItems[i])); }
                        catch (FormatException) { validBattle = false; }
                    }
                }
                for (int i = playersPerTeam + 1; i < bItems.Length; i++)
                {
                    Account tryAcc = Account.AccountByName(db, bItems[i]);
                    if (tryAcc != null)
                    {
                        team2Ids.Add(tryAcc.AccountID);
                    }
                    else
                    {
                        try { team2Ids.Add(Int32.Parse(bItems[i])); }
                        catch (FormatException) { validBattle = false; }
                    }
                }

                if (validBattle)
                {
                    var tb = new TourneyBattle(Global.Server, new TourneyBattle.TourneyPrototype()
                    {
                        Title       = bName,
                        FounderName = Global.Account.Name,
                        TeamPlayers = new List <List <string> >()
                        {
                            team1Ids.Select(x => db.Accounts.Find(x)?.Name).Where(x => x != null).ToList(),
                            team2Ids.Select(x => db.Accounts.Find(x)?.Name).Where(x => x != null).ToList()
                        }
                    });
                    Global.Server.AddBattle(tb);
                }
            }

            return(RedirectToAction("Index"));
        }
        void client_Said(object sender, TasSayEventArgs e)
        {
            User user;

            if (!client.ExistingUsers.TryGetValue(e.UserName, out user))
            {
                return;
            }
            if (e.Place == SayPlace.Channel && e.Channel != "main")
            {
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        using (var db = new ZkDataContext())
                        {
                            Channel channel;
                            if (!client.JoinedChannels.TryGetValue(e.Channel, out channel))
                            {
                                return;
                            }
                            foreach (var s in db.LobbyChannelSubscriptions.Where(x => x.Channel == e.Channel).Select(x => x.Account))
                            {
                                if (!channel.Users.ContainsKey(s.Name))
                                {
                                    var fac = db.Factions.FirstOrDefault(x => x.Shortcut == e.Channel);
                                    // if faction channel check if allowed
                                    if (fac == null || (fac.FactionID == s.AccountID && s.Level >= GlobalConst.FactionChannelMinLevel))
                                    {
                                        var message = new LobbyMessage()
                                        {
                                            SourceLobbyID = user.AccountID,
                                            SourceName    = e.UserName,
                                            Created       = DateTime.UtcNow,
                                            Message       = e.Text,
                                            TargetName    = s.Name,
                                            Channel       = e.Channel
                                        };
                                        db.LobbyMessages.InsertOnSubmit(message);
                                    }
                                }
                            }
                            db.SubmitChanges();
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Error storing message: {0}", ex);
                    }
                });
            }
            else if (e.Place == SayPlace.User)
            {
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        if (e.Place == SayPlace.User)
                        {
                            if (e.Text.StartsWith("!pm"))
                            {
                                var regex = Regex.Match(e.Text, "!pm ([^ ]+) (.+)");
                                if (regex.Success)
                                {
                                    var name = regex.Groups[1].Value;
                                    var text = regex.Groups[2].Value;

                                    var message = new LobbyMessage()
                                    {
                                        SourceLobbyID = user.AccountID, SourceName = e.UserName, Created = DateTime.UtcNow, Message = text, TargetName = name
                                    };
                                    using (var db = new ZkDataContext())
                                    {
                                        db.LobbyMessages.InsertOnSubmit(message);
                                        db.SubmitChanges();
                                    }
                                }
                            }
                            else if (e.Text.StartsWith("!subscribe"))
                            {
                                var regex = Regex.Match(e.Text, "!subscribe #([^ ]+)");
                                if (regex.Success)
                                {
                                    var chan = regex.Groups[1].Value;
                                    if (chan != "main")
                                    {
                                        using (var db = new ZkDataContext()) {
                                            Account account = Account.AccountByName(db, e.UserName);
                                            if (chan == AuthService.ModeratorChannel && !(account.IsZeroKAdmin))
                                            {
                                                client.Say(SayPlace.User, user.Name, "Not authorized to subscribe to this channel", false);
                                            }
                                            else
                                            {
                                                var accountID = account.AccountID;
                                                var subs      = db.LobbyChannelSubscriptions.FirstOrDefault(x => x.AccountID == accountID && x.Channel == chan);
                                                if (subs == null)
                                                {
                                                    subs = new LobbyChannelSubscription()
                                                    {
                                                        AccountID = accountID, Channel = chan
                                                    };
                                                    db.LobbyChannelSubscriptions.InsertOnSubmit(subs);
                                                    db.SubmitChanges();
                                                    client.JoinChannel(chan);
                                                }
                                                client.Say(SayPlace.User, user.Name, "Subscribed", false);
                                            }
                                        }
                                    }
                                }
                            }
                            else if (e.Text.StartsWith("!unsubscribe"))
                            {
                                var regex = Regex.Match(e.Text, "!unsubscribe #([^ ]+)");
                                if (regex.Success)
                                {
                                    var chan = regex.Groups[1].Value;

                                    using (var db = new ZkDataContext()) {
                                        var accountID = Account.AccountByName(db, e.UserName).AccountID;
                                        var subs      = db.LobbyChannelSubscriptions.FirstOrDefault(x => x.AccountID == accountID && x.Channel == chan);
                                        if (subs != null)
                                        {
                                            db.LobbyChannelSubscriptions.DeleteOnSubmit(subs);
                                            db.SubmitChanges();
                                        }
                                        client.Say(SayPlace.User, user.Name, "Unsubscribed", false);
                                    }
                                }
                            }
                            else if (e.Text.Equals("!listsubscriptions"))
                            {
                                using (var db = new ZkDataContext())
                                {
                                    var accountID        = Account.AccountByName(db, e.UserName).AccountID;
                                    var subscriptionList = "No channels subscribed.";
                                    var subs             = db.LobbyChannelSubscriptions.Where(x => x.AccountID == accountID).OrderBy(x => x.Channel).Select(x => x.Channel);
                                    if (subs != null)
                                    {
                                        subscriptionList = "Subscribed to: " + String.Join(", ", subs);
                                    }
                                    client.Say(SayPlace.User, user.Name, subscriptionList, false);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Error sending stored message: {0}", ex);
                    }
                });
            }
        }
        private static SpringBattle SaveSpringBattle(SpringBattleContext result, ZkDataContext db)
        {
            var sb = new SpringBattle
            {
                HostAccountID     = Account.AccountByName(db, result.LobbyStartContext.FounderName)?.AccountID,
                Mode              = result.LobbyStartContext.Mode,
                Duration          = result.Duration,
                EngineGameID      = result.EngineBattleID,
                MapResourceID     = db.Resources.Single(x => x.InternalName == result.LobbyStartContext.Map).ResourceID,
                ModResourceID     = db.Resources.Single(x => x.InternalName == result.LobbyStartContext.Mod).ResourceID,
                HasBots           = result.LobbyStartContext.Bots.Any(),
                IsMission         = result.LobbyStartContext.IsMission,
                PlayerCount       = result.ActualPlayers.Count(x => !x.IsSpectator),
                StartTime         = result.StartTime,
                Title             = result.LobbyStartContext.Title,
                ReplayFileName    = Path.GetFileName(result.ReplayName),
                EngineVersion     = result.LobbyStartContext.EngineVersion,
                IsMatchMaker      = result.LobbyStartContext.IsMatchMakerGame,
                ApplicableRatings = 0,
            };

            db.SpringBattles.InsertOnSubmit(sb);

            // store players
            foreach (BattlePlayerResult p in result.ActualPlayers)
            {
                var account = Account.AccountByName(db, p.Name);
                if (account != null)
                {
                    sb.SpringBattlePlayers.Add(new SpringBattlePlayer
                    {
                        Account         = account,
                        AccountID       = account.AccountID,
                        AllyNumber      = p.AllyNumber,
                        IsInVictoryTeam = p.IsVictoryTeam,
                        IsSpectator     = p.IsSpectator,
                        LoseTime        = p.LoseTime
                    });
                }
            }

            // store bots
            var victoryAllyID = result.ActualPlayers.Where(x => x.IsVictoryTeam).Select(x => (int?)x.AllyNumber).FirstOrDefault() ?? -1;

            if (victoryAllyID == -1)
            {
                victoryAllyID = (result.ActualPlayers.Min(x => (int?)x.AllyNumber) ?? -1) + 1;                    // no player won, its likely to be next lowes team (stupid hack needed)
            }
            foreach (var bot in result.LobbyStartContext.Bots)
            {
                sb.SpringBattleBots.Add(new SpringBattleBot()
                {
                    AllyNumber      = bot.AllyID,
                    BotAI           = bot.BotAI,
                    BotName         = bot.BotName,
                    IsInVictoryTeam = bot.AllyID == victoryAllyID
                });
            }

            db.SaveChanges();

            return(db.SpringBattles.FirstOrDefault(x => x.SpringBattleID == sb.SpringBattleID)); // reselect from db to get proper lazy proxies
        }
示例#16
0
        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);
                }
            };
        }
示例#17
0
        List <Faction> GetDefendingFactions(AttackOption target)
        {
            if (target.OwnerFactionID != null)
            {
                return new List <Faction> {
                           factions.Find(x => x.FactionID == target.OwnerFactionID)
                }
            }
            ;
            return(factions.Where(x => x != AttackingFaction).ToList());
        }

        void JoinPlanetAttack(int targetPlanetId, string userName)
        {
            AttackOption attackOption = AttackOptions.Find(x => x.PlanetID == targetPlanetId);

            if (attackOption != null)
            {
                User user;

                if (tas.ExistingUsers.TryGetValue(userName, out user))
                {
                    var     db      = new ZkDataContext();
                    Account account = Account.AccountByLobbyID(db, user.LobbyID);
                    if (account != null && account.FactionID == AttackingFaction.FactionID && account.CanPlayerPlanetWars())
                    {
                        // remove existing user from other options
                        foreach (AttackOption aop in AttackOptions)
                        {
                            aop.Attackers.RemoveAll(x => x == userName);
                        }

                        // add user to this option
                        if (attackOption.Attackers.Count < attackOption.TeamSize)
                        {
                            attackOption.Attackers.Add(user.Name);
                            tas.Say(TasClient.SayPlace.Channel, user.Faction, string.Format("{0} joins attack on {1}", userName, attackOption.Name), true);

                            if (attackOption.Attackers.Count == attackOption.TeamSize)
                            {
                                StartChallenge(attackOption);
                            }
                            else
                            {
                                UpdateLobby();
                            }
                        }
                    }
                }
            }
        }

        void JoinPlanetDefense(int targetPlanetID, string userName)
        {
            if (Challenge != null && Challenge.PlanetID == targetPlanetID && Challenge.Defenders.Count < Challenge.TeamSize)
            {
                User user;
                if (tas.ExistingUsers.TryGetValue(userName, out user))
                {
                    var     db      = new ZkDataContext();
                    Account account = Account.AccountByLobbyID(db, user.LobbyID);
                    if (account != null && GetDefendingFactions(Challenge).Any(y => y.FactionID == account.FactionID) && account.CanPlayerPlanetWars())
                    {
                        if (!Challenge.Defenders.Any(y => y == user.Name))
                        {
                            Challenge.Defenders.Add(user.Name);
                            tas.Say(TasClient.SayPlace.Channel, user.Faction, string.Format("{0} joins defense of {1}", userName, Challenge.Name), true);

                            if (Challenge.Defenders.Count == Challenge.TeamSize)
                            {
                                AcceptChallenge();
                            }
                            else
                            {
                                UpdateLobby();
                            }
                        }
                    }
                }
            }
        }

        void RecordPlanetwarsLoss(AttackOption option)
        {
            if (option.OwnerFactionID != null)
            {
                if (option.OwnerFactionID == missedDefenseFactionID)
                {
                    missedDefenseCount++;
                }
                else
                {
                    missedDefenseCount     = 0;
                    missedDefenseFactionID = option.OwnerFactionID.Value;
                }
            }


            var message = string.Format("{0} won because nobody tried to defend", AttackingFaction.Name);

            foreach (var fac in factions)
            {
                tas.Say(TasClient.SayPlace.Channel, fac.Shortcut, message, true);
            }


            var text = new StringBuilder();

            try
            {
                var           db        = new ZkDataContext();
                List <string> playerIds = option.Attackers.Select(x => x).Union(option.Defenders.Select(x => x)).ToList();


                PlanetWarsTurnHandler.EndTurn(option.Map, null, db, 0, db.Accounts.Where(x => playerIds.Contains(x.Name) && x.Faction != null).ToList(), text, null, db.Accounts.Where(x => option.Attackers.Contains(x.Name) && x.Faction != null).ToList());
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                text.Append(ex);
            }
        }

        void ResetAttackOptions()
        {
            AttackOptions.Clear();
            AttackerSideChangeTime = DateTime.UtcNow;
            Challenge     = null;
            ChallengeTime = null;

            using (var db = new ZkDataContext())
            {
                var gal      = db.Galaxies.First(x => x.IsDefault);
                int cnt      = 2;
                var attacker = db.Factions.Single(x => x.FactionID == AttackingFaction.FactionID);
                var planets  = gal.Planets.Where(x => x.OwnerFactionID != AttackingFaction.FactionID).OrderByDescending(x => x.PlanetFactions.Where(y => y.FactionID == AttackingFaction.FactionID).Sum(y => y.Dropships)).ThenByDescending(x => x.PlanetFactions.Where(y => y.FactionID == AttackingFaction.FactionID).Sum(y => y.Influence)).ToList();
                // list of planets by attacker's influence

                foreach (var planet in planets)
                {
                    if (planet.CanMatchMakerPlay(attacker))
                    {
                        // pick only those where you can actually attack atm
                        InternalAddOption(planet);
                        cnt--;
                    }
                    if (cnt == 0)
                    {
                        break;
                    }
                }

                if (!AttackOptions.Any(y => y.TeamSize == 2))
                {
                    var planet = planets.FirstOrDefault(x => x.TeamSize == 2 && x.CanMatchMakerPlay(attacker));
                    if (planet != null)
                    {
                        InternalAddOption(planet);
                    }
                }
            }

            UpdateLobby();

            tas.Say(TasClient.SayPlace.Channel, AttackingFaction.Shortcut, "It's your turn! Select a planet to attack", true);
        }

        void InternalAddOption(Planet planet)
        {
            AttackOptions.Add(new AttackOption
            {
                PlanetID       = planet.PlanetID,
                Map            = planet.Resource.InternalName,
                OwnerFactionID = planet.OwnerFactionID,
                Name           = planet.Name,
                TeamSize       = planet.TeamSize,
            });
        }

        void SaveStateToDb()
        {
            var    db  = new ZkDataContext();
            Galaxy gal = db.Galaxies.First(x => x.IsDefault);

            gal.MatchMakerState = JsonConvert.SerializeObject((MatchMakerState)this);

            gal.AttackerSideCounter    = AttackerSideCounter;
            gal.AttackerSideChangeTime = AttackerSideChangeTime;
            db.SubmitAndMergeChanges();
        }

        void StartChallenge(AttackOption attackOption)
        {
            Challenge     = attackOption;
            ChallengeTime = DateTime.UtcNow;
            AttackOptions.Clear();
            UpdateLobby();
        }

        void TasOnChannelUserAdded(object sender, TasEventArgs args)
        {
            string  chan     = args.ServerParams[0];
            string  userName = args.ServerParams[1];
            Faction faction  = factions.FirstOrDefault(x => x.Shortcut == chan);

            if (faction != null)
            {
                var db  = new ZkDataContext();
                var acc = Account.AccountByName(db, userName);
                if (acc != null && acc.CanPlayerPlanetWars())
                {
                    UpdateLobby(userName);
                }
            }
        }

        /// <summary>
        ///     Intercept channel messages for attacking/defending
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void TasOnPreviewSaid(object sender, CancelEventArgs <TasSayEventArgs> args)
        {
            if (args.Data.Text.StartsWith("!") && (args.Data.Place == TasSayEventArgs.Places.Channel || args.Data.Place == TasSayEventArgs.Places.Normal) &&
                args.Data.Origin == TasSayEventArgs.Origins.Player && args.Data.UserName != GlobalConst.NightwatchName)
            {
                int targetPlanetId;
                if (int.TryParse(args.Data.Text.Substring(1), out targetPlanetId))
                {
                    JoinPlanet(args.Data.UserName, targetPlanetId);
                }
            }
        }

        /// <summary>
        ///     Remove/reduce poll count due to lobby quits
        /// </summary>
        void TasOnUserRemoved(object sender, TasEventArgs args)
        {
            if (Challenge == null)
            {
                if (AttackOptions.Count > 0)
                {
                    string userName   = args.ServerParams[0];
                    int    sumRemoved = 0;
                    foreach (AttackOption aop in AttackOptions)
                    {
                        sumRemoved += aop.Attackers.RemoveAll(x => x == userName);
                    }
                    if (sumRemoved > 0)
                    {
                        UpdateLobby();
                    }
                }
            }
            else
            {
                string userName = args.ServerParams[0];
                if (Challenge.Defenders.RemoveAll(x => x == userName) > 0)
                {
                    UpdateLobby();
                }
            }
        }

        void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            try
            {
                if (Challenge == null)
                {
                    // attack timer
                    if (DateTime.UtcNow > GetAttackDeadline())
                    {
                        AttackerSideCounter++;
                        ResetAttackOptions();
                    }
                }
                else
                {
                    // accept timer
                    if (DateTime.UtcNow > GetAcceptDeadline())
                    {
                        if (Challenge.Defenders.Count >= Challenge.Attackers.Count - 1 && Challenge.Defenders.Count > 0)
                        {
                            AcceptChallenge();
                        }
                        else
                        {
                            RecordPlanetwarsLoss(Challenge);
                            AttackerSideCounter++;
                            ResetAttackOptions();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
            }
        }
示例#18
0
        public override async Task ExecuteArmed(ServerBattle battle, Say e)
        {
            var b = battle;
            List <IEnumerable <Account> > teams;

            RatingCategory cat = RatingCategory.Casual;

            if (b.IsMatchMakerBattle)
            {
                cat = RatingCategory.MatchMaking;
            }
            if (b.Mode == PlasmaShared.AutohostMode.Planetwars)
            {
                cat = RatingCategory.Planetwars;
            }

            using (var db = new ZkDataContext())
            {
                if (battle.IsInGame)
                {
                    teams = b.spring.LobbyStartContext?.Players.Where(u => !u.IsSpectator)
                            .GroupBy(u => u.AllyID)
                            .Select(x => x.Select(p => Account.AccountByName(db, p.Name))).ToList();
                }
                else
                {
                    switch (battle.Mode)
                    {
                    case PlasmaShared.AutohostMode.Game1v1:
                        teams = b.Users.Values.Where(u => !u.IsSpectator)
                                .GroupBy(u => u.Name)
                                .Select(x => x.Select(p => Account.AccountByName(db, p.Name))).ToList();
                        break;

                    case PlasmaShared.AutohostMode.Teams:
                        teams = PartitionBalance.Balance(battle.IsCbalEnabled ? Balancer.BalanceMode.ClanWise : Balancer.BalanceMode.Normal, b.Users.Values.Where(u => !u.IsSpectator).Select(x => x.LobbyUser).Select(x => new PartitionBalance.PlayerItem(x.AccountID, x.EffectiveElo, x.Clan, x.PartyID)).ToList())
                                .Players
                                .GroupBy(u => u.AllyID)
                                .Select(x => x.Select(p => db.Accounts.Where(a => a.AccountID == p.LobbyID).FirstOrDefault())).ToList();
                        break;

                    default:
                        teams = b.Users.Values.Where(u => !u.IsSpectator)
                                .GroupBy(u => u.AllyNumber)
                                .Select(x => x.Select(p => Account.AccountByName(db, p.Name))).ToList();
                        break;
                    }
                }

                if (teams.Count < 2)
                {
                    await battle.SayBattle($"!predict needs at least two human teams to work");

                    return;
                }

                var chances = RatingSystems.GetRatingSystem(cat).PredictOutcome(teams, DateTime.UtcNow);
                for (int i = 0; i < teams.Count; i++)
                {
                    await battle.SayBattle($"Team {teams[i].OrderByDescending(x => x.GetRating(cat).Elo).Select(x => x.Name).Aggregate((a, y) => a + ", " + y)} has a {Math.Round(1000 * chances[i]) / 10}% chance to win");
                }
            }
        }
示例#19
0
        public override LinkedListNode <Tag> Translate(TranslateContext context, LinkedListNode <Tag> self)
        {
            if (!(self.Previous?.Value is LiteralTag)) // previous is not a continuous text
            {
                var ender = self.Next.FirstNode(x => !(x.Value is LiteralTag || x.Value is UnderscoreTag));
                var text  = self.Next.GetOriginalContentUntilNode(ender); // get next string

                if (!string.IsNullOrEmpty(text))
                {
                    int idx;
                    for (idx = 0; idx < text.Length; idx++)
                    {
                        if (!Utils.ValidLobbyNameCharacter(text[idx]))
                        {
                            break;
                        }
                    }
                    string remainder = null;
                    string val       = text;
                    if (idx != 0 && idx < text.Length)
                    {
                        remainder = text.Substring(idx, text.Length - idx);
                        val       = text.Substring(0, idx);
                    }

                    if (!string.IsNullOrEmpty(val))
                    {
                        var db = new ZkDataContext();

                        var fac = db.Factions.FirstOrDefault(x => x.Shortcut == val);
                        if (fac != null)
                        {
                            context.Append(context.Html.PrintFaction(fac, false));
                            context.Append(remainder);
                            return(ender);
                        }
                        var acc = Account.AccountByName(db, val);
                        if (acc != null)
                        {
                            context.Append(context.Html.PrintAccount(acc));
                            context.Append(remainder);
                            return(ender);
                        }
                        var clan = db.Clans.FirstOrDefault(x => x.Shortcut == val);
                        if (clan != null)
                        {
                            context.Append(context.Html.PrintClan(clan));
                            context.Append(remainder);
                            return(ender);
                        }
                        if (val.StartsWith("b", StringComparison.InvariantCultureIgnoreCase))
                        {
                            var bid = 0;
                            if (int.TryParse(val.Substring(1), out bid))
                            {
                                var bat = db.SpringBattles.FirstOrDefault(x => x.SpringBattleID == bid);
                                if (bat != null)
                                {
                                    context.Append(context.Html.PrintBattle(bat));
                                    context.Append(remainder);
                                    return(ender);
                                }
                            }
                        }
                    }
                }
            }
            context.Append("@");
            return(self.Next);
        }
示例#20
0
        public override async Task ExecuteArmed(ServerBattle battle, Say e)
        {
            var b = battle;
            Dictionary <int, double> grouping;

            using (var db = new ZkDataContext())
            {
                if (battle.IsInGame)
                {
                    grouping = b.spring.LobbyStartContext?.Players.Where(u => !u.IsSpectator)
                               .GroupBy(u => u.AllyID)
                               .ToDictionary(x => x.Key, x => x.Average(y => RatingSystems.DisableRatingSystems ? Account.AccountByName(db, y.Name).BestEffectiveElo : Account.AccountByName(db, y.Name).GetBestRating().Elo));
                }
                else
                {
                    grouping = b.Users.Values.Where(u => !u.IsSpectator)
                               .GroupBy(u => u.AllyNumber)
                               .ToDictionary(x => x.Key, x => x.Average(y => Math.Max(y.LobbyUser.EffectiveMmElo, y.LobbyUser.EffectiveElo)));
                }
            }

            KeyValuePair <int, double>?oldg = null;

            foreach (var g in grouping)
            {
                if (oldg != null)
                {
                    var t1elo = oldg.Value.Value;
                    var t2elo = g.Value;
                    await
                    battle.Respond(e,
                                   $"team {oldg.Value.Key + 1} has {Utils.GetWinChancePercent(t2elo - t1elo)}% chance to win over team {g.Key + 1}");
                }
                oldg = g;
            }
        }
示例#21
0
        public override async Task ExecuteArmed(ServerBattle battle, Say e)
        {
            var b = battle;
            List <IEnumerable <Account> > teams;

            RatingCategory cat = RatingCategory.Casual;

            if (b.IsMatchMakerBattle)
            {
                cat = RatingCategory.MatchMaking;
            }
            if (b.Mode == PlasmaShared.AutohostMode.Planetwars)
            {
                cat = RatingCategory.Planetwars;
            }

            using (var db = new ZkDataContext())
            {
                if (battle.IsInGame)
                {
                    teams = b.spring.LobbyStartContext?.Players.Where(u => !u.IsSpectator)
                            .GroupBy(u => u.AllyID)
                            .Select(x => x.Select(p => Account.AccountByName(db, p.Name))).ToList();
                }
                else
                {
                    switch (battle.Mode)
                    {
                    case PlasmaShared.AutohostMode.Game1v1:
                        teams = b.Users.Values.Where(u => !u.IsSpectator)
                                .GroupBy(u => u.Name)
                                .Select(x => x.Select(p => Account.AccountByName(db, p.Name))).ToList();
                        break;

                    case PlasmaShared.AutohostMode.Teams:
                        await battle.SayBattle($"The battle will be balanced when it starts");

                        return;

                    default:
                        teams = b.Users.Values.Where(u => !u.IsSpectator)
                                .GroupBy(u => u.AllyNumber)
                                .Select(x => x.Select(p => Account.AccountByName(db, p.Name))).ToList();
                        break;
                    }
                }

                if (teams.Count < 2)
                {
                    await battle.SayBattle($"!predict needs at least two human teams to work");

                    return;
                }

                var chances = RatingSystems.GetRatingSystem(cat).PredictOutcome(teams, DateTime.UtcNow);
                for (int i = 0; i < teams.Count; i++)
                {
                    await battle.SayBattle($"Team {teams[i].OrderByDescending(x => x.GetRating(cat).Elo).First().Name} has a {Math.Round(1000 * chances[i]) / 10}% chance to win");
                }
            }
        }
示例#22
0
        public override LinkedListNode <Tag> Translate(TranslateContext context, LinkedListNode <Tag> self)
        {
            if (self.Previous?.Value is LiteralTag) // previous is contiguous text
            {
                context.Append("@");
                return(self.Next);
            }
            var ender = self.Next.FirstNode(x => !(x.Value is LiteralTag || x.Value is UnderscoreTag));
            var text  = self.Next.GetOriginalContentUntilNode(ender); // get next string

            if (string.IsNullOrEmpty(text))
            {
                context.Append("@");
                return(self.Next);
            }
            int idx;

            for (idx = 0; idx < text.Length; idx++)
            {
                if (!Utils.ValidLobbyNameCharacter(text[idx]))
                {
                    break;
                }
            }
            string remainder = null;
            string val       = text;

            if (idx != 0 && idx < text.Length)
            {
                remainder = text.Substring(idx, text.Length - idx);
                val       = text.Substring(0, idx);
            }

            if (string.IsNullOrEmpty(val))
            {
                context.Append("@");
                return(self.Next);
            }
            var  db     = new ZkDataContext();
            char prefix = Char.ToLowerInvariant(val[0]);
            int  id     = 0;

            int.TryParse(val.Substring(1), out id);

            var fac = db.Factions.FirstOrDefault(x => x.Shortcut == val);

            if (fac == null && prefix == 'f')
            {
                fac = db.Factions.FirstOrDefault(x => x.FactionID == id);
            }
            if (fac != null)
            {
                context.Append(context.Html.PrintFaction(fac, false));
                context.Append(remainder);
                return(ender);
            }

            var acc = Account.AccountByName(db, val);

            if (acc == null && prefix == 'u')
            {
                acc = db.Accounts.FirstOrDefault(x => x.AccountID == id);
            }
            if (acc != null)
            {
                context.Append(context.Html.PrintAccount(acc));
                context.Append(remainder);
                return(ender);
            }

            var clan = db.Clans.FirstOrDefault(x => x.Shortcut == val);

            if (clan == null && prefix == 'c')
            {
                clan = db.Clans.FirstOrDefault(x => x.ClanID == id);
            }
            if (clan != null)
            {
                context.Append(context.Html.PrintClan(clan));
                context.Append(remainder);
                return(ender);
            }

            // can't tag a battle by its name
            SpringBattle bat = null;

            if (prefix == 'b')
            {
                bat = db.SpringBattles.FirstOrDefault(x => x.SpringBattleID == id);
            }
            if (bat != null)
            {
                context.Append(context.Html.PrintBattle(bat));
                context.Append(remainder);
                return(ender);
            }

            context.Append("@");
            return(self.Next);
        }