public async Task <bool> TryMigrateTo( ISocket socket, Character character, ServerServiceInfo to, Func <ServerServiceInfo, IPacket> getMigrationCommand = null) { var accountID = character.Data.Account.ID.ToString(); var characterID = character.ID.ToString(); if (await MigrationCache.ExistsAsync(characterID)) { return(false); } socket.ReadOnlyMode = true; await socket.OnUpdate(); await AccountStatusCache.SetAsync( accountID, AccountState.MigratingIn, 15.Seconds() ); await MigrationCache.AddAsync( characterID, new MigrationInfo { ID = character.ID, FromService = Info.Name, ToService = to.Name }, 15.Seconds() ); if (getMigrationCommand == null) { getMigrationCommand = info => { using (var p = new Packet(SendPacketOperations.MigrateCommand)) { p.Encode <bool>(true); var endpoint = new IPEndPoint(IPAddress.Parse(info.Host), info.Port); var address = endpoint.Address.MapToIPv4().GetAddressBytes(); var port = endpoint.Port; address.ForEach(b => p.Encode <byte>(b)); p.Encode <short>((short)port); return(p); } } } ; character.Data.Account.LatestConnectedService = to.Name; character.Data.Account.PreviousConnectedService = Info.Name; await socket.SendPacket(getMigrationCommand.Invoke(to)); return(true); }
protected override async Task OnStarted() { using (var db = DataContextFactory.Create()) { var accounts = db.Accounts .Where(a => a.LatestConnectedService == Info.Name) .Select(a => a.ID.ToString()); if (accounts.Any()) { await AccountStatusCache.RemoveAllAsync(db.Accounts .Where(a => a.LatestConnectedService == Info.Name) .Select(a => a.ID.ToString())); Logger.Info( $"Forcibly reset account states of {"account".ToQuantity(accounts.Count())} previously connected to {Info.Name}" ); } } await base.OnStarted(); }
public async Task <bool> TryMigrateFrom(Character character, ServerServiceInfo current) { var accountID = character.Data.Account.ID.ToString(); var characterID = character.ID.ToString(); if (!await MigrationCache.ExistsAsync(characterID)) { return(false); } var migration = (await MigrationCache.GetAsync <MigrationInfo>(characterID)).Value; if (migration.ToService != current.Name) { return(false); } character.Data.Account.LatestConnectedService = migration.ToService; character.Data.Account.PreviousConnectedService = migration.FromService; await AccountStatusCache.SetAsync(accountID, AccountState.LoggedIn); await MigrationCache.RemoveAsync(characterID); return(true); }