Exemple #1
0
 public Network(LoginRegulator loginReg, CityConnectionRegulator cityReg, LotConnectionRegulator lotReg, IShardsDomain shards)
 {
     this.Shards         = shards;
     this.CityRegulator  = cityReg;
     this.LoginRegulator = loginReg;
     this.LotRegulator   = lotReg;
 }
 public PersonSelectionController(PersonSelection view, LoginRegulator regulator, IShardsDomain shards, ICache cache)
 {
     Shards    = shards;
     View      = view;
     Regulator = regulator;
     Cache     = cache;
 }
Exemple #3
0
        public RealestateDomain(IShardsDomain shards, FSO.Content.Content content)
        {
            _Shards  = shards;
            _Content = content;
            _ByShard = new Dictionary <int, ShardRealestateDomain>();

            foreach (var item in shards.All)
            {
                GetByShard(item.Id);
            }
        }
Exemple #4
0
        public LoginRegulator(AuthClient authClient, CityClient cityClient, IShardsDomain domain)
        {
            this.Shards     = domain;
            this.AuthClient = authClient;
            this.CityClient = cityClient;

            AddState("NotLoggedIn")
            .Default()
            .Transition()
            .OnData(typeof(AuthRequest)).TransitionTo("AuthLogin");

            AddState("AuthLogin").OnlyTransitionFrom("NotLoggedIn");
            AddState("InitialConnect").OnlyTransitionFrom("AuthLogin");
            AddState("AvatarData").OnlyTransitionFrom("InitialConnect", "UpdateRequired", "LoggedIn");
            AddState("ShardStatus").OnlyTransitionFrom("AvatarData");
            AddState("LoggedIn").OnlyTransitionFrom("ShardStatus");

            AddState("UpdateRequired").OnlyTransitionFrom("InitialConnect");
        }
Exemple #5
0
        public CityConnectionRegulator(CityClient cityApi, [Named("City")] AriesClient cityClient, IDatabaseService db, IClientDataService ds, IKernel kernel, IShardsDomain shards)
        {
            this.CityApi = cityApi;
            this.Client  = cityClient;
            this.Client.AddSubscriber(this);
            this.DB          = db;
            this.DataService = ds;
            this.Shards      = shards;

            AddState("Disconnected")
            .Default()
            .Transition()
            .OnData(typeof(ShardSelectorServletRequest))
            .TransitionTo("SelectCity");

            AddState("SelectCity")
            .OnlyTransitionFrom("Disconnected", "Reconnecting");

            AddState("ConnectToCitySelector")
            .OnData(typeof(ShardSelectorServletResponse))
            .TransitionTo("CitySelected")
            .OnlyTransitionFrom("SelectCity");

            AddState("CitySelected")
            .OnData(typeof(ShardSelectorServletResponse))
            .TransitionTo("OpenSocket")
            .OnlyTransitionFrom("ConnectToCitySelector");

            AddState("OpenSocket")
            .OnData(typeof(AriesConnected)).TransitionTo("SocketOpen")
            .OnData(typeof(AriesDisconnected)).TransitionTo("UnexpectedDisconnect")
            .OnlyTransitionFrom("CitySelected");

            AddState("SocketOpen")
            .OnData(typeof(RequestClientSession)).TransitionTo("RequestClientSession")
            .OnData(typeof(AriesDisconnected)).TransitionTo("UnexpectedDisconnect")
            .OnlyTransitionFrom("OpenSocket");

            AddState("RequestClientSession")
            .OnData(typeof(HostOnlinePDU)).TransitionTo("HostOnline")
            .OnData(typeof(AriesDisconnected)).TransitionTo("UnexpectedDisconnect")
            .OnlyTransitionFrom("SocketOpen");

            AddState("HostOnline").OnlyTransitionFrom("RequestClientSession");
            AddState("PartiallyConnected")
            .OnData(typeof(AriesDisconnected)).TransitionTo("UnexpectedDisconnect")
            .OnData(typeof(ShardSelectorServletRequest)).TransitionTo("CompletePartialConnection")
            .OnlyTransitionFrom("HostOnline");

            AddState("CompletePartialConnection").OnlyTransitionFrom("PartiallyConnected");
            AddState("AskForAvatarData")
            .OnData(typeof(LoadAvatarByIDResponse)).TransitionTo("ReceivedAvatarData")
            .OnlyTransitionFrom("PartiallyConnected", "CompletePartialConnection");
            AddState("ReceivedAvatarData").OnlyTransitionFrom("AskForAvatarData");
            AddState("AskForCharacterData").OnlyTransitionFrom("ReceivedAvatarData");
            AddState("ReceivedCharacterData").OnlyTransitionFrom("AskForCharacterData");

            AddState("Connected")
            .OnData(typeof(AriesDisconnected)).TransitionTo("UnexpectedDisconnect")
            .OnlyTransitionFrom("ReceivedCharacterData");

            AddState("UnexpectedDisconnect");

            AddState("Disconnect")
            .OnData(typeof(AriesDisconnected))
            .TransitionTo("Disconnected");

            AddState("Reconnect")
            .OnData(typeof(AriesDisconnected))
            .TransitionTo("Reconnecting");

            AddState("Reconnecting")
            .OnData(typeof(ShardSelectorServletRequest))
            .TransitionTo("SelectCity")
            .OnlyTransitionFrom("Reconnect");

            GameThread.SetInterval(() =>
            {
                if (Client.IsConnected)
                {
                    Client.Write(new Server.Protocol.Electron.Packets.KeepAlive());
                }
            }, 10000); //keep alive every 10 seconds. prevents disconnection by aggressive NAT.
        }
Exemple #6
0
 public ClientLotProvider(ICache cache, IShardsDomain shards)
 {
     this.Shards = shards;
     this.Cache  = cache;
 }
        public CitySelectorController(IDAFactory DAFactory, ApiServerConfiguration config, JWTFactory jwt, IShardsDomain shardsDomain) : base("/cityselector")
        {
            JsonWebToken.JWTTokenAuthentication.Enable(this, jwt);

            var str   = GetServerVersion();
            var split = str.LastIndexOf('-');

            VersionName = str;
            if (split != -1)
            {
                VersionName   = str.Substring(0, split);
                VersionNumber = str.Substring(split + 1);
            }

            try
            {
                using (var file = File.Open("updateUrl.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    var reader = new StreamReader(file);
                    DownloadURL = reader.ReadLine();
                    reader.Close();
                }
            } catch (Exception)
            {
                DownloadURL = ""; // couldn't find info from the watchdog
            }

            //Take the auth ticket, establish trust and then create a cookie (reusing JWT)
            this.Get["/app/InitialConnectServlet"] = _ =>
            {
                var ticketValue = this.Request.Query["ticket"];
                var version     = this.Request.Query["version"];

                if (ticketValue == null)
                {
                    return(Response.AsXml(new XMLErrorMessage(ERROR_MISSING_TOKEN_CODE, ERROR_MISSING_TOKEN_MSG)));
                }

                using (var db = DAFactory.Get())
                {
                    var ticket = db.AuthTickets.Get((string)ticketValue);
                    if (ticket == null)
                    {
                        return(Response.AsXml(new XMLErrorMessage(ERROR_MISSING_TOKEN_CODE, ERROR_MISSING_TOKEN_MSG)));
                    }


                    db.AuthTickets.Delete((string)ticketValue);
                    if (ticket.date + config.AuthTicketDuration < Epoch.Now)
                    {
                        return(Response.AsXml(new XMLErrorMessage(ERROR_EXPIRED_TOKEN_CODE, ERROR_EXPIRED_TOKEN_MSG)));
                    }

                    /** Is it a valid account? **/
                    var user = db.Users.GetById(ticket.user_id);
                    if (user == null)
                    {
                        return(Response.AsXml(new XMLErrorMessage(ERROR_MISSING_TOKEN_CODE, ERROR_MISSING_TOKEN_MSG)));
                    }

                    //Use JWT to create and sign an auth cookies
                    var session = new JWTUserIdentity()
                    {
                        UserID   = user.user_id,
                        UserName = user.username
                    };

                    var token = jwt.CreateToken(session);
                    return(Response.AsXml(new UserAuthorized()
                    {
                        FSOBranch = VersionName,
                        FSOVersion = VersionNumber,
                        FSOUpdateUrl = DownloadURL
                    })
                           .WithCookie("fso", token.Token));
                }
            };

            //Return a list of the users avatars
            this.Get["/app/AvatarDataServlet"] = _ =>
            {
                this.RequiresAuthentication();
                var user = (JWTUserIdentity)this.Context.CurrentUser;

                var result = new XMLList <AvatarData>("The-Sims-Online");

                using (var db = DAFactory.Get())
                {
                    var avatars = db.Avatars.GetSummaryByUserId(user.UserID);

                    foreach (var avatar in avatars)
                    {
                        result.Add(new AvatarData {
                            ID             = avatar.avatar_id,
                            Name           = avatar.name,
                            ShardName      = shardsDomain.GetById(avatar.shard_id).Name,
                            HeadOutfitID   = avatar.head,
                            BodyOutfitID   = avatar.body,
                            AppearanceType = (AvatarAppearanceType)Enum.Parse(typeof(AvatarAppearanceType), avatar.skin_tone.ToString()),
                            Description    = avatar.description,
                            LotId          = avatar.lot_id,
                            LotName        = avatar.lot_name,
                            LotLocation    = avatar.lot_location
                        });
                    }
                }

                return(Response.AsXml(result));
            };

            this.Get["/app/ShardSelectorServlet"] = _ =>
            {
                this.RequiresAuthentication();
                var user = (JWTUserIdentity)this.Context.CurrentUser;

                var shardName = this.Request.Query["shardName"];
                var avatarId  = this.Request.Query["avatarId"];
                if (avatarId == null)
                {
                    //Using 0 to mean no avatar for CAS
                    avatarId = "0";
                }

                using (var db = DAFactory.Get())
                {
                    ShardStatusItem shard = shardsDomain.GetByName(shardName);
                    if (shard != null)
                    {
                        var tryIP = Request.Headers["X-Forwarded-For"].FirstOrDefault();
                        if (tryIP != null)
                        {
                            tryIP = tryIP.Substring(tryIP.LastIndexOf(',') + 1).Trim();
                        }
                        var ip = tryIP ?? this.Request.UserHostAddress;

                        uint avatarDBID = uint.Parse(avatarId);

                        if (avatarDBID != 0)
                        {
                            var avatar = db.Avatars.Get(avatarDBID);
                            if (avatar == null)
                            {
                                //can't join server with an avatar that doesn't exist
                                return(Response.AsXml(new XMLErrorMessage(ERROR_AVATAR_NOT_FOUND_CODE, ERROR_AVATAR_NOT_FOUND_MSG)));
                            }
                            if (avatar.user_id != user.UserID || avatar.shard_id != shard.Id)
                            {
                                //make sure we own the avatar we're trying to connect with
                                LOG.Info("SECURITY: Invalid avatar login attempt from " + ip + ", user " + user.UserID);
                                return(Response.AsXml(new XMLErrorMessage(ERROR_AVATAR_NOT_YOURS_CODE, ERROR_AVATAR_NOT_YOURS_MSG)));
                            }
                        }

                        var ban = db.Bans.GetByIP(ip);
                        if (ban != null || db.Users.GetById(user.UserID)?.is_banned != false)
                        {
                            return(Response.AsXml(new XMLErrorMessage(ERROR_BANNED_CODE, ERROR_BANNED_MSG)));
                        }

                        /** Make an auth ticket **/
                        var ticket = new ShardTicket
                        {
                            ticket_id = Guid.NewGuid().ToString().Replace("-", ""),
                            user_id   = user.UserID,
                            avatar_id = avatarDBID,
                            date      = Epoch.Now,
                            ip        = ip
                        };

                        db.Users.UpdateConnectIP(ticket.user_id, ip);
                        db.Shards.CreateTicket(ticket);

                        var result = new ShardSelectorServletResponse();
                        result.PreAlpha = false;

                        result.Address      = shard.PublicHost;
                        result.PlayerID     = user.UserID;
                        result.Ticket       = ticket.ticket_id;
                        result.ConnectionID = ticket.ticket_id;
                        result.AvatarID     = avatarId;

                        return(Response.AsXml(result));
                    }
                    else
                    {
                        return(Response.AsXml(new XMLErrorMessage(ERROR_SHARD_NOT_FOUND_CODE, ERROR_SHARD_NOT_FOUND_MSG)));
                    }
                }
            };

            //Get a list of shards (cities)
            this.Get["/shard-status.jsp"] = _ =>
            {
                var result = new XMLList <ShardStatusItem>("Shard-Status-List");
                var shards = shardsDomain.All;

                foreach (var shard in shards)
                {
                    var status = Protocol.CitySelector.ShardStatus.Down;

                    /*switch (shard.Status)
                     * {
                     *  case Database.DA.Shards.ShardStatus.Up:
                     *      status = Protocol.CitySelector.ShardStatus.Up;
                     *      break;
                     *  case Database.DA.Shards.ShardStatus.Full:
                     *      status = Protocol.CitySelector.ShardStatus.Full;
                     *      break;
                     *  case Database.DA.Shards.ShardStatus.Frontier:
                     *      status = Protocol.CitySelector.ShardStatus.Frontier;
                     *      break;
                     *  case Database.DA.Shards.ShardStatus.Down:
                     *      status = Protocol.CitySelector.ShardStatus.Down;
                     *      break;
                     *  case Database.DA.Shards.ShardStatus.Closed:
                     *      status = Protocol.CitySelector.ShardStatus.Closed;
                     *      break;
                     *  case Database.DA.Shards.ShardStatus.Busy:
                     *      status = Protocol.CitySelector.ShardStatus.Busy;
                     *      break;
                     * }*/

                    result.Add(shard);
                }

                return(Response.AsXml(result));
            };
        }