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()); }
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? }
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); } }); }
public void SessionMigrated(IAriesSession session) { if (!(session is IVoltronSession)) { return; } IVoltronSession voltronSession = (IVoltronSession)session; Lots.SessionMigrated(voltronSession); }
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); }
public void Add(IAriesSession session) { if (session is IGluonSession) { lock (_GluonSessions) _GluonSessions.Add((IGluonSession)session); } else { lock (_Sessions) _Sessions.Add(session); } }
public void Remove(IAriesSession session) { if (session is IGluonSession) { lock (_GluonSessions) _GluonSessions.Remove((IGluonSession)session); } else { lock (_Sessions) _Sessions.Remove(session); } }
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); }
public async void SessionClosed(IAriesSession session) { if (!(session is IVoltronSession)) { return; } var voltronSession = (IVoltronSession)session; Lots.SessionClosed(voltronSession); }
public void Handle(IAriesSession session, object message) { var type = message.GetType(); if (Handlers.ContainsKey(type)) { foreach (var handler in Handlers[type]) { handler(session, message); } } }
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 }); }
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); } }
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 }); }
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); }
public void SessionCreated(IAriesSession session) { }
public void Enroll(IAriesSession session) { lock (_Sessions) _Sessions.Add(session); }
protected virtual void RouteMessage(IAriesSession session, object message) { _Router.Handle(session, message); }
/// <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);
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(); }
public void UnEnroll(IAriesSession session) { lock (_Sessions) _Sessions.Remove(session); }
public void SessionMigrated(IAriesSession session) { //on reconnect to city. nothing right now. }
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(); }
protected override void HandleVoltronSessionResponse(IAriesSession session, object message) { }