예제 #1
0
        public void Handle(IAriesSession session, AnswerChallenge answer)
        {
            var challenge = session.GetAttribute("challenge") as string;

            if (challenge == null)
            {
                session.Close();
                return;
            }

            var myAnswer = ChallengeResponse.AnswerChallenge(challenge, Secret);

            if (myAnswer != answer.Answer)
            {
                session.Close();
                return;
            }

            //Trust established, good to go
            var newSession = Sessions.UpgradeSession <GluonSession>(session, x => {
                x.IsAuthenticated = true;
                x.CallSign        = (string)session.GetAttribute("callSign");
                x.PublicHost      = (string)session.GetAttribute("publicHost");
                x.InternalHost    = (string)session.GetAttribute("internalHost");
            });

            newSession.Write(new AnswerAccepted());
        }
예제 #2
0
        public async void SessionUpgraded(IAriesSession oldSession, IAriesSession newSession)
        {
            if (!(newSession is IVoltronSession))
            {
                return;
            }

            //Aries session has upgraded to a voltron session
            IVoltronSession voltronSession = (IVoltronSession)newSession;

            //TODO: Make sure this user is not already connected, if they are disconnect them
            newSession.Write(new HostOnlinePDU
            {
                ClientBufSize     = 4096,
                HostVersion       = 0x7FFF,
                HostReservedWords = 0
            });

            //CAS, don't hydrate the user
            if (voltronSession.IsAnonymous)
            {
                return;
            }

            //New avatar, enroll in voltron group
            var avatar = await DataService.Get <Avatar>(voltronSession.AvatarId);

            //Mark as online
            avatar.Avatar_IsOnline = true;
            VoltronSessions.Enroll(newSession);

            //TODO: Somehow alert people this sim is online?
        }
예제 #3
0
        public async void SessionClosed(IAriesSession session)
        {
            if (!(session is IVoltronSession))
            {
                return;
            }

            var voltronSession = (IVoltronSession)session;

            VoltronSessions.UnEnroll(session);

            if (voltronSession.IsAnonymous)
            {
                return;
            }

            Liveness.EnqueueChange(() => {
                //unenroll in voltron group, mark as offline in data service.
                //since this can happen async make sure our session hasnt been reopened before trying to delete its claim
                if (Sessions.GetByAvatarId(voltronSession.AvatarId)?.Connected == true)
                {
                    return;
                }

                var avatar = DataService.Get <Avatar>(voltronSession.AvatarId).Result;
                if (avatar != null)
                {
                    avatar.Avatar_IsOnline = false;
                }

                using (var db = DAFactory.Get)
                {
                    // if we don't own the claim for the avatar, we need to tell the server that does to release the avatar.
                    // right now it's just lot servers.

                    var claim = db.AvatarClaims.GetByAvatarID((uint)voltronSession.AvatarClaimId);
                    if (claim != null && claim.owner != Context.Config.Call_Sign)
                    {
                        var lotServer = LotServers.GetLotServerSession(claim.owner);
                        if (lotServer != null)
                        {
                            var lot = db.Lots.GetByLocation(Context.ShardId, claim.location);
                            lotServer.Write(new RequestLotClientTermination()
                            {
                                AvatarId  = voltronSession.AvatarId,
                                LotId     = (lot != null) ? lot.lot_id : ((int)claim.location),
                                FromOwner = Context.Config.Call_Sign
                            });
                        }
                    }

                    //nuke the claim anyways to be sure.
                    db.AvatarClaims.Delete(voltronSession.AvatarClaimId, Context.Config.Call_Sign);
                }
            });
        }
예제 #4
0
        public void SessionMigrated(IAriesSession session)
        {
            if (!(session is IVoltronSession))
            {
                return;
            }
            IVoltronSession voltronSession = (IVoltronSession)session;

            Lots.SessionMigrated(voltronSession);
        }
예제 #5
0
        public T UpgradeSession <T>(IAriesSession session, Callback <T> init) where T : AriesSession
        {
            var newSession = ((AriesSession)session).UpgradeSession <T>();

            Remove(session);
            Add(newSession);
            init(newSession);

            _Server.SessionInterceptors.ForEach(x => x.SessionUpgraded(session, newSession));
            return(newSession);
        }
예제 #6
0
 public void Add(IAriesSession session)
 {
     if (session is IGluonSession)
     {
         lock (_GluonSessions) _GluonSessions.Add((IGluonSession)session);
     }
     else
     {
         lock (_Sessions) _Sessions.Add(session);
     }
 }
예제 #7
0
 public void Remove(IAriesSession session)
 {
     if (session is IGluonSession)
     {
         lock (_GluonSessions) _GluonSessions.Remove((IGluonSession)session);
     }
     else
     {
         lock (_Sessions) _Sessions.Remove(session);
     }
 }
예제 #8
0
        protected override void RouteMessage(IAriesSession session, object message)
        {
            if (session is IVoltronSession)
            {
                //Route to a specific lot
                Lots.RouteMessage(session as IVoltronSession, message);
                return;
            }

            base.RouteMessage(session, message);
        }
예제 #9
0
        public async void SessionClosed(IAriesSession session)
        {
            if (!(session is IVoltronSession))
            {
                return;
            }

            var voltronSession = (IVoltronSession)session;

            Lots.SessionClosed(voltronSession);
        }
예제 #10
0
        public void Handle(IAriesSession session, object message)
        {
            var type = message.GetType();

            if (Handlers.ContainsKey(type))
            {
                foreach (var handler in Handlers[type])
                {
                    handler(session, message);
                }
            }
        }
예제 #11
0
        public void Handle(IAriesSession session, RequestChallenge request)
        {
            var challenge = ChallengeResponse.GetChallenge();

            session.SetAttribute("challenge", challenge);
            session.SetAttribute("callSign", request.CallSign);
            session.SetAttribute("publicHost", request.PublicHost);
            session.SetAttribute("internalHost", request.InternalHost);

            session.Write(new RequestChallengeResponse {
                Challenge = challenge
            });
        }
예제 #12
0
        public async void SessionClosed(IAriesSession session)
        {
            if (!(session is IVoltronSession))
            {
                return;
            }

            IVoltronSession voltronSession = (IVoltronSession)session;

            VoltronSessions.UnEnroll(session);

            if (voltronSession.IsAnonymous)
            {
                return;
            }

            //unenroll in voltron group, mark as offline in data service.
            var avatar = await DataService.Get <Avatar>(voltronSession.AvatarId);

            if (avatar != null)
            {
                avatar.Avatar_IsOnline = false;
            }

            using (var db = DAFactory.Get())
            {
                // if we don't own the claim for the avatar, we need to tell the server that does to release the avatar.
                // right now it's just lot servers.

                var claim = db.AvatarClaims.GetByAvatarID((uint)voltronSession.AvatarClaimId);
                if (claim != null && claim.owner != Context.Config.Call_Sign)
                {
                    var lotServer = LotServers.GetLotServerSession(claim.owner);
                    if (lotServer != null)
                    {
                        var lot = db.Lots.GetByLocation(Context.ShardId, claim.location);
                        lotServer.Write(new RequestLotClientTermination()
                        {
                            AvatarId  = voltronSession.AvatarId,
                            LotId     = (lot != null)?lot.lot_id:((int)claim.location),
                            FromOwner = Context.Config.Call_Sign
                        });
                    }
                }

                //nuke the claim anyways to be sure.
                db.AvatarClaims.Delete(voltronSession.AvatarClaimId, Context.Config.Call_Sign);
            }
        }
예제 #13
0
        public async void SessionUpgraded(IAriesSession oldSession, IAriesSession newSession)
        {
            if (!(newSession is IVoltronSession))
            {
                return;
            }

            //Aries session has upgraded to a voltron session
            var voltronSession = (IVoltronSession)newSession;

            //TODO: Make sure this user is not already connected, if they are disconnect them
            newSession.Write(new HostOnlinePDU
            {
                ClientBufSize     = 4096,
                HostVersion       = 0x7FFF,
                HostReservedWords = 0
            });
        }
예제 #14
0
        public void Sync(IAriesSession target, T item)
        {
            var asObject = (object)item;
            var updates  = DataService.SerializeUpdate(Fields, asObject, (uint)KeyField.GetValue(asObject));

            if (updates.Count == 0)
            {
                return;
            }
            var packets = new DataServiceWrapperPDU[updates.Count];

            for (int i = 0; i < updates.Count; i++)
            {
                var update = updates[i];
                packets[i] = new DataServiceWrapperPDU()
                {
                    Body            = update,
                    RequestTypeID   = 0,
                    SendingAvatarID = 0
                };
            }

            target.Write(packets);
        }
예제 #15
0
 public void SessionCreated(IAriesSession session)
 {
 }
예제 #16
0
 public void Enroll(IAriesSession session)
 {
     lock (_Sessions)
         _Sessions.Add(session);
 }
예제 #17
0
 protected virtual void RouteMessage(IAriesSession session, object message)
 {
     _Router.Handle(session, message);
 }
예제 #18
0
 /// <summary>
 /// Voltron clients respond with RequestClientSessionResponse in response to RequestClientSession
 /// This handler validates that response, performs auth and upgrades the session to a voltron session.
 ///
 /// This will allow this session to make voltron requests from this point onwards
 /// </summary>
 protected abstract void HandleVoltronSessionResponse(IAriesSession session, object message);
예제 #19
0
        protected override void HandleVoltronSessionResponse(IAriesSession session, object message)
        {
            var rawSession = (AriesSession)session;
            var packet     = message as RequestClientSessionResponse;

            if (message != null)
            {
                using (var da = DAFactory.Get())
                {
                    var ticket = da.Shards.GetTicket(packet.Password);
                    if (ticket != null)
                    {
                        //TODO: Check if its expired
                        da.Shards.DeleteTicket(packet.Password);

                        int?claim = 0;
                        //We need to lock this avatar
                        if (ticket.avatar_id != 0) //if is 0, we're "anonymous", which limits what we can do to basically only CAS.
                        {
                            claim = da.AvatarClaims.TryCreate(new DbAvatarClaim
                            {
                                avatar_id = ticket.avatar_id,
                                location  = 0,
                                owner     = Config.Call_Sign
                            });

                            if (!claim.HasValue)
                            {
                                //Try and disconnect this user, if we still can't get a claim out of luck
                                //The voltron session close should handle removing any lot tickets and disconnecting them from the target servers
                                //then it will remove the avatar claim. This takes time but it should be less than 5 seconds.
                                var existingSession = Sessions.GetByAvatarId(ticket.avatar_id);
                                if (existingSession != null)
                                {
                                    existingSession.Close();
                                }
                                else
                                {
                                    //check if there really is an old claim
                                    var oldClaim = da.AvatarClaims.GetByAvatarID(ticket.avatar_id);
                                    if (oldClaim != null)
                                    {
                                        da.AvatarClaims.Delete(oldClaim.avatar_claim_id, Config.Call_Sign);
                                        LOG.Debug("Zombie Avatar claim removed: Avatar ID " + ticket.avatar_id);
                                    }
                                    else
                                    {
                                        LOG.Debug("Unknown claim error occurred. Connection will likely time out. Avatar ID " + ticket.avatar_id);
                                    }
                                }

                                //TODO: Broadcast to lot servers to disconnect

                                int i = 0;
                                while (i < 10)
                                {
                                    claim = da.AvatarClaims.TryCreate(new DbAvatarClaim
                                    {
                                        avatar_id = ticket.avatar_id,
                                        location  = 0,
                                        owner     = Config.Call_Sign
                                    });

                                    if (claim.HasValue)
                                    {
                                        break;
                                    }

                                    Thread.Sleep(500);
                                    i++;
                                }

                                if (!claim.HasValue)
                                {
                                    //No luck
                                    session.Close();
                                    return;
                                }
                            }
                        }

                        //Time to upgrade to a voltron session
                        var newSession = Sessions.UpgradeSession <VoltronSession>(rawSession, x => {
                            x.UserId          = ticket.user_id;
                            x.AvatarId        = ticket.avatar_id;
                            x.IsAuthenticated = true;
                            x.AvatarClaimId   = claim.Value;
                        });
                        return;
                    }
                }
            }

            //Failed authentication
            rawSession.Close();
        }
예제 #20
0
 public void UnEnroll(IAriesSession session)
 {
     lock (_Sessions)
         _Sessions.Remove(session);
 }
 public void SessionMigrated(IAriesSession session)
 {
     //on reconnect to city. nothing right now.
 }
예제 #22
0
        protected override void HandleVoltronSessionResponse(IAriesSession session, object message)
        {
            var rawSession = (AriesSession)session;
            var packet     = message as RequestClientSessionResponse;

            if (message != null)
            {
                DbLotServerTicket ticket = null;

                using (var da = DAFactory.Get())
                {
                    ticket = da.Lots.GetLotServerTicket(packet.Password);
                    if (ticket != null)
                    {
                        //TODO: Check if its expired
                        da.Lots.DeleteLotServerTicket(packet.Password);
                    }


                    if (ticket != null)
                    {
                        uint location = 0;
                        if ((ticket.lot_id & 0x40000000) > 0)
                        {
                            location = (uint)ticket.lot_id;
                        }
                        else
                        {
                            location = da.Lots.Get(ticket.lot_id).location;
                        }

                        //We need to claim a lock for the avatar, if we can't do that we cant let them join
                        var didClaim = da.AvatarClaims.Claim(ticket.avatar_claim_id, ticket.avatar_claim_owner, Config.Call_Sign, location);
                        if (!didClaim)
                        {
                            rawSession.Close();
                            return;
                        }


                        //Time to upgrade to a voltron session
                        var newSession = Sessions.UpgradeSession <VoltronSession>(rawSession, x =>
                        {
                            x.UserId          = ticket.user_id;
                            x.AvatarId        = ticket.avatar_id;
                            x.IsAuthenticated = true;
                            x.AvatarClaimId   = ticket.avatar_claim_id;
                        });

                        newSession.SetAttribute("cityCallSign", ticket.avatar_claim_owner);

                        //Try and join the lot, no reason to keep this connection alive if you can't get in
                        if (!Lots.TryJoin(ticket.lot_id, newSession))
                        {
                            newSession.Close();
                            using (var db = DAFactory.Get())
                            {
                                //return claim to the city we got it from.
                                db.AvatarClaims.Claim(newSession.AvatarClaimId, Config.Call_Sign, (string)newSession.GetAttribute("cityCallSign"), 0);
                            }
                        }
                        return;
                    }
                }
            }

            //Failed authentication
            rawSession.Close();
        }
예제 #23
0
 protected override void HandleVoltronSessionResponse(IAriesSession session, object message)
 {
 }