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(); }
public async void Handle(IVoltronSession session, FindLotRequest packet) { if (session.IsAnonymous) //CAS users can't do this. { return; } try { //special modes at 0x200-0x1000 //0x200: join my job lot //0x201-0x2FF: create job lot of type/lotgroup (client CANNOT join on demand.) // 0x01-0x10: Robot Factory // 0x11-0x20: Restaurant // 0x21-0x30: DJ/Dancer //0x300+: instanced lots (client CAN join on demand, and appear in data service) //note: lotgroup is not the same as a grade. eg. restaurant grade 5+6 share a lot. (zero based grade) //nightclub 7-10 share a lot group. (two lots, one chosen randomly) if (packet.LotId >= 0x200 && packet.LotId < 0x300) { //join my job lot. //look up our avatar's current job and attempt to match them to a job lot with <max players, or a new one. using (var db = DAFactory.Get) { var job = db.Avatars.GetCurrentJobLevel(session.AvatarId); if (job == null) { session.Write(new FindLotResponse { Status = Protocol.Electron.Model.FindLotResponseStatus.UNKNOWN_ERROR, LotId = packet.LotId }); } //ok, choose the correct type/lotgroup combo var type = job.job_type; //if (type > 2) type--; //cook and waiter share job lot //if (type > 3) type--; //dj and dancer share job lot packet.LotId = (uint)(0x201 + (type - 1) * 0x10 + job.job_level); } } var find = await Lots.TryFindOrOpen(packet.LotId, session.AvatarId, session); //null reference exception possible here if (find.Status == Protocol.Electron.Model.FindLotResponseStatus.FOUND) { DbLotServerTicket ticket = null; using (var db = DAFactory.Get) { //I need a shard ticket so I can connect to the lot server and assume the correct avatar ticket = new DbLotServerTicket { ticket_id = Guid.NewGuid().ToString().Replace("-", ""), user_id = session.UserId, avatar_id = session.AvatarId, lot_owner = find.Server.CallSign, date = Epoch.Now, ip = session.IpAddress, lot_id = find.LotDbId, avatar_claim_id = session.AvatarClaimId, avatar_claim_owner = Context.Config.Call_Sign }; db.Lots.CreateLotServerTicket(ticket); } session.Write(new FindLotResponse { Status = find.Status, LotId = find.LotId, //can be modified by job matchmaker LotServerTicket = ticket.ticket_id, Address = find.Server.PublicHost, User = session.UserId.ToString() }); } else { session.Write(new FindLotResponse { Status = find.Status, LotId = packet.LotId }); } } catch (Exception e) { LOG.Error(e); } }