Exemplo n.º 1
0
        public AuthService(TasClient client)
        {
            this.client = client;


            this.client.LoginAccepted += (s, e) =>
            {
                client.JoinChannel(ModeratorChannel);
                client.JoinChannel(Top20Channel);
                using (var db = new ZkDataContext()) foreach (var fac in db.Factions.Where(x => !x.IsDeleted))
                    {
                        client.JoinChannel(fac.Shortcut);
                    }
            };


            this.client.UserAdded += (s, e) =>
            {
                if (e.SpringieLevel > 2 || e.IsAdmin)
                {
                    client.ForceJoinChannel(e.Name, ModeratorChannel);
                }
                if (topPlayers.IsTop20(e.AccountID))
                {
                    client.ForceJoinChannel(e.Name, Top20Channel);
                }
                if (e.Clan != null)
                {
                    client.ForceJoinChannel(e.Name, Clan.GetClanChannel(e.Clan));
                }
                if (e.Faction != null && e.Level >= GlobalConst.FactionChannelMinLevel)
                {
                    client.ForceJoinChannel(e.Name, e.Faction);
                }
            };

            // TODO set bot mode
            //this.client.BattleFound +=
            //  (s, e) => { if (e.Data.Founder.IsZkLobbyUser && !e.Data.Founder.IsBot) client.SetBotMode(e.Data.Founder.Name, true); };

            this.client.ChannelUserAdded += (sender, args) =>
            {
                try
                {
                    var channel = args.Channel.Name;
                    foreach (var u in args.Users)
                    {
                        if (channel == ModeratorChannel)
                        {
                            if (u.SpringieLevel <= 2 && !u.IsAdmin)
                            {
                                client.ForceLeaveChannel(u.Name, ModeratorChannel);
                            }
                        }
                        else if (channel == Top20Channel)
                        {
                            if (!topPlayers.IsTop20(u.AccountID) && u.Name != client.UserName)
                            {
                                client.ForceLeaveChannel(u.Name, Top20Channel);
                            }
                        }
                        else
                        {
                            using (var db = new ZkDataContext())
                            {
                                var fac = db.Factions.FirstOrDefault(x => x.Shortcut == channel);
                                if (fac != null)
                                {
                                    // faction channel
                                    var acc = db.Accounts.Find(u.AccountID);
                                    if (acc == null || acc.FactionID != fac.FactionID || acc.Level < GlobalConst.FactionChannelMinLevel)
                                    {
                                        client.ForceLeaveChannel(u.Name, channel);
                                    }
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError("Error procesisng channel user added: {0}", ex);
                }
            };
            this.client.ChannelUserRemoved += (sender, args) =>
            {
                try
                {
                    var channel = args.Channel.Name;
                    if (channel == ModeratorChannel)
                    {
                        var u = args.User;
                        if (u.SpringieLevel > 2 || u.IsAdmin)
                        {
                            client.ForceJoinChannel(u.Name, ModeratorChannel);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError("Error procesisng channel user added: {0}", ex);
                }
            };
        }
        public static string SubmitSpringBattleResult(BattleContext context,
                                                      string password,
                                                      BattleResult result,
                                                      List <BattlePlayerResult> players,
                                                      List <string> extraData)
        {
            try
            {
                Account acc = AuthServiceClient.VerifyAccountPlain(context.AutohostName, password);
                if (acc == null)
                {
                    throw new Exception("Account name or password not valid");
                }
                AutohostMode mode = context.GetMode();
                var          db   = new ZkDataContext();

                if (extraData == null)
                {
                    extraData = new List <string>();
                }


                var sb = new SpringBattle
                {
                    HostAccountID  = acc.AccountID,
                    Duration       = result.Duration,
                    EngineGameID   = result.EngineBattleID,
                    MapResourceID  = db.Resources.Single(x => x.InternalName == result.Map).ResourceID,
                    ModResourceID  = db.Resources.Single(x => x.InternalName == result.Mod).ResourceID,
                    HasBots        = result.IsBots,
                    IsMission      = result.IsMission,
                    PlayerCount    = players.Count(x => !x.IsSpectator),
                    StartTime      = result.StartTime,
                    Title          = result.Title,
                    ReplayFileName = result.ReplayName,
                    EngineVersion  = result.EngineVersion,
                };
                db.SpringBattles.InsertOnSubmit(sb);

                foreach (BattlePlayerResult p in players)
                {
                    sb.SpringBattlePlayers.Add(new SpringBattlePlayer
                    {
                        AccountID       = db.Accounts.First(x => x.AccountID == p.LobbyID).AccountID,
                        AllyNumber      = p.AllyNumber,
                        CommanderType   = p.CommanderType,
                        IsInVictoryTeam = p.IsVictoryTeam,
                        IsSpectator     = p.IsSpectator,
                        LoseTime        = p.LoseTime
                    });
                }

                db.SubmitChanges();

                // awards
                foreach (string line in extraData.Where(x => x.StartsWith("award")))
                {
                    string[] partsSpace = line.Substring(6).Split(new[] { ' ' }, 3);
                    string   name       = partsSpace[0];
                    string   awardType  = partsSpace[1];
                    string   awardText  = partsSpace[2];

                    SpringBattlePlayer player = sb.SpringBattlePlayers.FirstOrDefault(x => x.Account.Name == name);
                    if (player != null)
                    {
                        db.AccountBattleAwards.InsertOnSubmit(new AccountBattleAward
                        {
                            AccountID        = player.AccountID,
                            SpringBattleID   = sb.SpringBattleID,
                            AwardKey         = awardType,
                            AwardDescription = awardText
                        });
                    }
                }

                var  text         = new StringBuilder();
                bool isPlanetwars = false;
                if (mode == AutohostMode.Planetwars && sb.SpringBattlePlayers.Count(x => !x.IsSpectator) >= 2 && sb.Duration >= GlobalConst.MinDurationForPlanetwars)
                {
                    // test that factions are not intermingled (each faction only has one ally number) - if they are it wasnt actually PW balanced
                    if (
                        sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.Account.Faction != null)
                        .GroupBy(x => x.Account.Faction)
                        .All(grp => grp.Select(x => x.AllyNumber).Distinct().Count() < 2))
                    {
                        isPlanetwars = true;


                        List <int> winnerTeams =
                            sb.SpringBattlePlayers.Where(x => x.IsInVictoryTeam && !x.IsSpectator).Select(x => x.AllyNumber).Distinct().ToList();
                        int?winNum = null;
                        if (winnerTeams.Count == 1)
                        {
                            winNum = winnerTeams[0];
                            if (winNum > 1)
                            {
                                winNum = null;
                                text.AppendLine("ERROR: Invalid winner");
                            }
                        }

                        PlanetWarsTurnHandler.EndTurn(result.Map, extraData, db, winNum, sb.SpringBattlePlayers.Where(x => !x.IsSpectator).Select(x => x.Account).ToList(), text, sb, sb.SpringBattlePlayers.Where(x => !x.IsSpectator && x.AllyNumber == 0).Select(x => x.Account).ToList());

                        Global.PlanetWarsMatchMaker.RemoveFromRunningBattles(context.AutohostName);
                    }
                    else
                    {
                        text.AppendLine("Battle wasn't PlanetWars balanced, it counts as a normal team game only");
                    }
                }

                bool noElo = (extraData.FirstOrDefault(x => x.StartsWith("noElo")) != null);
                try
                {
                    db.SubmitChanges();
                }
                catch (System.Data.Linq.DuplicateKeyException ex)
                {
                    Trace.TraceError(ex.ToString());
                }

                Dictionary <int, int> orgLevels = sb.SpringBattlePlayers.Select(x => x.Account).ToDictionary(x => x.AccountID, x => x.Level);

                sb.CalculateAllElo(noElo, isPlanetwars);
                foreach (var u in sb.SpringBattlePlayers.Where(x => !x.IsSpectator))
                {
                    u.Account.CheckLevelUp();
                }

                db.SubmitAndMergeChanges();

                try
                {
                    foreach (Account a in sb.SpringBattlePlayers.Where(x => !x.IsSpectator).Select(x => x.Account))
                    {
                        Global.Nightwatch.Tas.Extensions.PublishAccountData(a);
                    }
                }
                catch (Exception ex)
                {
                    Trace.TraceError("error updating extension data: {0}", ex);
                }

                foreach (Account account in sb.SpringBattlePlayers.Select(x => x.Account))
                {
                    if (account.Level > orgLevels[account.AccountID])
                    {
                        try
                        {
                            string message =
                                string.Format("Congratulations {0}! You just leveled up to level {1}. {3}/Users/Detail/{2}",
                                              account.Name,
                                              account.Level,
                                              account.AccountID,
                                              GlobalConst.BaseSiteUrl);
                            //text.AppendLine(message);
                            AuthServiceClient.SendLobbyMessage(account, message);
                        }
                        catch (Exception ex)
                        {
                            Trace.TraceError("Error sending level up lobby message: {0}", ex);
                        }
                    }
                }

                text.AppendLine(string.Format("BATTLE DETAILS AND REPLAY ----> {1}/Battles/Detail/{0} <-----", sb.SpringBattleID, GlobalConst.BaseSiteUrl));

                // create debriefing room, join players there and output message
                string channelName = "B" + sb.SpringBattleID;
                var    joinplayers = new List <string>();
                joinplayers.AddRange(context.Players.Select(x => x.Name));                                              // add those who were there at start
                joinplayers.AddRange(sb.SpringBattlePlayers.Select(x => x.Account.Name));                               // add those who played
                TasClient tas = Global.Nightwatch.Tas;
                Battle    bat = tas.ExistingBattles.Values.FirstOrDefault(x => x.Founder.Name == context.AutohostName); // add those in lobby atm


                var conf = context.GetConfig();
                if (bat != null && (conf == null || conf.MinToJuggle == null)) // if not qm room do not join those who are in battle
                {
                    List <string> inbatPlayers = bat.Users.Keys.ToList();
                    joinplayers.RemoveAll(x => inbatPlayers.Contains(x));
                }
                foreach (string jp in joinplayers.Distinct().Where(x => x != context.AutohostName))
                {
                    tas.ForceJoinChannel(jp, channelName);
                }
                tas.JoinChannel(channelName); // join nightwatch and say it
                tas.Say(SayPlace.Channel, channelName, text.ToString(), true);
                tas.LeaveChannel(channelName);

                //text.Append(string.Format("Debriefing in #{0} - zk://chat/channel/{0}  ", channelName));
                return(text.ToString());
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                return(ex.ToString());
            }
        }
        public AuthService(TasClient client)
        {
            this.client = client;


            this.client.LoginAccepted += (s, e) =>
                {
                    client.JoinChannel(ModeratorChannel);
                    client.JoinChannel(Top20Channel);
                    using (var db = new ZkDataContext()) foreach (var fac in db.Factions.Where(x => !x.IsDeleted)) client.JoinChannel(fac.Shortcut);
                };


            this.client.UserAdded += (s, e) =>
            {
                if (e.Name == client.UserName) return;
                if (e.SpringieLevel > 2 || e.IsAdmin) client.ForceJoinChannel(e.Name, ModeratorChannel);
                if (topPlayers.IsTop20(e.AccountID)) client.ForceJoinChannel(e.Name, Top20Channel);
                if (e.Clan != null) client.ForceJoinChannel(e.Name, Clan.GetClanChannel(e.Clan));
                if (e.Faction != null && e.Level >= GlobalConst.FactionChannelMinLevel) client.ForceJoinChannel(e.Name, e.Faction);
            };

            // TODO set bot mode
            //this.client.BattleFound +=
            //  (s, e) => { if (e.Data.Founder.IsZkLobbyUser && !e.Data.Founder.IsBot) client.SetBotMode(e.Data.Founder.Name, true); };

            this.client.ChannelUserAdded += (sender, args) =>
                {
                    try
                    {
                        var channel = args.Channel.Name;
                        foreach (var u in args.Users)
                        {
                            if (u.Name == client.UserName) continue;
                            if (channel == ModeratorChannel)
                            {
                                if (u.SpringieLevel <= 2 && !u.IsAdmin) client.ForceLeaveChannel(u.Name, ModeratorChannel);
                            }
                            else if (channel == Top20Channel)
                            {
                                if (!topPlayers.IsTop20(u.AccountID) && u.Name != client.UserName) client.ForceLeaveChannel(u.Name, Top20Channel);
                            }
                            else
                            {
                                using (var db = new ZkDataContext())
                                {
                                    var fac = db.Factions.FirstOrDefault(x => x.Shortcut == channel);
                                    if (fac != null)
                                    {
                                        // faction channel
                                        var acc = db.Accounts.Find(u.AccountID);
                                        if (acc == null || acc.FactionID != fac.FactionID || acc.Level < GlobalConst.FactionChannelMinLevel) client.ForceLeaveChannel(u.Name, channel);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Error procesisng channel user added: {0}", ex);
                    }
                };
            this.client.ChannelUserRemoved += (sender, args) =>
                {
                    try
                    {
                        var channel = args.Channel.Name;
                        if (channel == ModeratorChannel)
                        {
                            var u = args.User;
                            if (u.SpringieLevel > 2 || u.IsAdmin) client.ForceJoinChannel(u.Name, ModeratorChannel);
                        }

                    }
                    catch (Exception ex)
                    {
                        Trace.TraceError("Error procesisng channel user added: {0}", ex);
                    }
                };
        }
Exemplo n.º 4
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);
                }
            };
        }