public virtual async Task ProcessPlayerJoin(ConnectedUser user, string joinPassword)
        {
            if (IsPassworded && (Password != joinPassword))
            {
                await user.Respond("Invalid password");

                return;
            }

            if (IsKicked(user.Name))
            {
                await KickFromBattle(user.Name, "Banned for five minutes");

                return;
            }

            if ((user.MyBattle != null) && (user.MyBattle != this))
            {
                await user.Process(new LeaveBattle());
            }

            UserBattleStatus ubs;

            if (!Users.TryGetValue(user.Name, out ubs))
            {
                ubs = new UserBattleStatus(user.Name, user.User, GenerateClientScriptPassword(user.Name));
                Users[user.Name] = ubs;
            }

            ValidateBattleStatus(ubs);
            user.MyBattle = this;


            await server.TwoWaySyncUsers(user.Name, Users.Keys); // mutually sync user statuses

            await server.SyncUserToAll(user);

            await RecalcSpectators();

            await
            user.SendCommand(new JoinBattleSuccess()
            {
                BattleID = BattleID,
                Players  = Users.Values.Select(x => x.ToUpdateBattleStatus()).ToList(),
                Bots     = Bots.Values.Select(x => x.ToUpdateBotStatus()).ToList(),
                Options  = ModOptions
            });


            await server.Broadcast(Users.Keys.Where(x => x != user.Name), ubs.ToUpdateBattleStatus()); // send my UBS to others in battle

            if (spring.IsRunning)
            {
                spring.AddUser(ubs.Name, ubs.ScriptPassword, ubs.LobbyUser);
                var started = DateTime.UtcNow.Subtract(spring.IngameStartTime ?? RunningSince ?? DateTime.UtcNow);
                started = new TimeSpan((int)started.TotalHours, started.Minutes, started.Seconds);
                await SayBattle($"THIS GAME IS CURRENTLY IN PROGRESS, PLEASE WAIT UNTIL IT ENDS! Running for {started}", ubs.Name);
                await SayBattle("If you say !notify, I will message you when the current game ends.", ubs.Name);
            }

            try
            {
                var ret = PlayerJoinHandler.AutohostPlayerJoined(GetContext(), ubs.LobbyUser.AccountID);
                if (ret != null)
                {
                    if (!IsNullOrEmpty(ret.PrivateMessage))
                    {
                        await SayBattle(ret.PrivateMessage, ubs.Name);
                    }
                    if (!IsNullOrEmpty(ret.PublicMessage))
                    {
                        await SayBattle(ret.PublicMessage);
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                await SayBattle("ServerManage error: " + ex);
            }
        }
Exemple #2
0
        public async Task Process(Login login)
        {
            var ret = await Task.Run(() => server.LoginChecker.DoLogin(login, RemoteEndpointIP));

            if (ret.LoginResponse.ResultCode == LoginResponse.Code.Ok)
            {
                var user = ret.User;
                //Trace.TraceInformation("{0} login: {1}", this, response.ResultCode.Description());

                await this.SendCommand(user); // send self to self first

                connectedUser      = server.ConnectedUsers.GetOrAdd(user.Name, (n) => new ConnectedUser(server, user));
                connectedUser.User = user;
                connectedUser.Connections.TryAdd(this, true);

                // close other connections
                foreach (var otherConnection in connectedUser.Connections.Keys.Where(x => x != null && x != this).ToList())
                {
                    otherConnection.RequestClose();
                    bool oth;
                    connectedUser.Connections.TryRemove(otherConnection, out oth);
                }

                server.SessionTokens[ret.LoginResponse.SessionToken] = user.AccountID;

                await SendCommand(ret.LoginResponse); // login accepted

                connectedUser.ResetHasSeen();


                foreach (var b in server.Battles.Values.Where(x => x != null))
                {
                    await SendCommand(new BattleAdded()
                    {
                        Header = b.GetHeader()
                    });
                }

                // mutually syncs users based on visibility rules
                await server.TwoWaySyncUsers(Name, server.ConnectedUsers.Keys);


                server.OfflineMessageHandler.SendMissedMessagesAsync(this, SayPlace.User, Name, user.AccountID);

                var defChans = await server.ChannelManager.GetDefaultChannels(user.AccountID);

                defChans.AddRange(server.Channels.Where(x => x.Value.Users.ContainsKey(user.Name)).Select(x => x.Key)); // add currently connected channels to list too

                foreach (var chan in defChans.ToList().Distinct())
                {
                    await connectedUser.Process(new JoinChannel()
                    {
                        ChannelName = chan,
                        Password    = null
                    });
                }


                foreach (var bat in server.Battles.Values.Where(x => x != null && x.IsInGame))
                {
                    var s = bat.spring;
                    if (s.LobbyStartContext.Players.Any(x => !x.IsSpectator && x.Name == Name) && !s.Context.ActualPlayers.Any(x => x.Name == Name && x.LoseTime != null))
                    {
                        await SendCommand(new RejoinOption()
                        {
                            BattleID = bat.BattleID
                        });
                    }
                }


                await SendCommand(new FriendList()
                {
                    Friends = connectedUser.FriendEntries.ToList()
                });
                await SendCommand(new IgnoreList()
                {
                    Ignores = connectedUser.Ignores.ToList()
                });

                await server.MatchMaker.OnLoginAccepted(connectedUser);

                await server.PlanetWarsMatchMaker.OnLoginAccepted(connectedUser);

                await SendCommand(server.NewsListManager.GetCurrentNewsList());
                await SendCommand(server.LadderListManager.GetCurrentLadderList());
                await SendCommand(server.ForumListManager.GetCurrentForumList(user.AccountID));

                using (var db = new ZkDataContext())
                {
                    var acc = db.Accounts.Find(user.AccountID);
                    if (acc != null)
                    {
                        await server.PublishUserProfileUpdate(acc);
                    }
                }
            }
            else
            {
                await SendCommand(ret.LoginResponse);

                if (ret.LoginResponse.ResultCode == LoginResponse.Code.Banned)
                {
                    transport.RequestClose();
                }
            }
        }
        public async Task Process(Login login)
        {
            var user     = new User();
            var response = await Task.Run(() => state.LoginChecker.Login(user, login, this));

            if (response.ResultCode == LoginResponse.Code.Ok)
            {
                connectedUser = state.ConnectedUsers.GetOrAdd(user.Name, (n) => new ConnectedUser(state, user));
                connectedUser.Connections.TryAdd(this, true);
                connectedUser.User = user;

                Trace.TraceInformation("{0} login: {1}", this, response.ResultCode.Description());

                await state.Broadcast(state.ConnectedUsers.Values, connectedUser.User); // send self to all

                await SendCommand(response);                                            // login accepted

                foreach (var c in state.ConnectedUsers.Values.Where(x => x != connectedUser))
                {
                    await SendCommand(c.User);                                                                           // send others to self
                }
                foreach (var b in state.Battles.Values)
                {
                    if (b != null)
                    {
                        await
                        SendCommand(new BattleAdded()
                        {
                            Header =
                                new BattleHeader()
                            {
                                BattleID       = b.BattleID,
                                Engine         = b.EngineVersion,
                                Game           = b.ModName,
                                Founder        = b.Founder.Name,
                                Map            = b.MapName,
                                Ip             = b.Ip,
                                Port           = b.HostPort,
                                Title          = b.Title,
                                SpectatorCount = b.SpectatorCount,
                                MaxPlayers     = b.MaxPlayers,
                                Password       = b.Password != null ? "?" : null
                            }
                        });

                        foreach (var u in b.Users.Values.Select(x => x.ToUpdateBattleStatus()).ToList())
                        {
                            await SendCommand(new JoinedBattle()
                            {
                                BattleID = b.BattleID, User = u.Name
                            });
                        }
                    }
                }


                await state.OfflineMessageHandler.SendMissedMessages(this, SayPlace.User, Name, user.AccountID);

                foreach (var chan in await state.ChannelManager.GetDefaultChannels(user.AccountID))
                {
                    await connectedUser.Process(new JoinChannel()
                    {
                        ChannelName = chan,
                        Password    = null
                    });
                }
            }
            else
            {
                await SendCommand(response);

                if (response.ResultCode == LoginResponse.Code.Banned)
                {
                    transport.RequestClose();
                }
            }
        }