Esempio n. 1
0
        public async Task TryMigrateTo(Account account, Character character, ServerServiceInfo to)
        {
            if (account == null || character == null)
            {
                throw new MigrationException("account or character is null");
            }
            if (await _service.MigrationStateCache.ExistsAsync(character.ID.ToString()))
            {
                throw new MigrationException("Already migrating");
            }

            account.PreviousConnectedService = _service.Info.Name;

            await OnUpdate();

            await _service.AccountStateCache.SetAsync(
                account.ID.ToString(),
                MigrationState.Migrating,
                TimeSpan.FromSeconds(15)
                );

            await _service.MigrationStateCache.SetAsync(
                character.ID.ToString(),
                to.Name,
                TimeSpan.FromSeconds(15)
                );

            await SendPacket(GetMigrationPacket(to));
        }
        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);
        }
Esempio n. 3
0
        protected virtual IPacket GetMigrationPacket(ServerServiceInfo to)
        {
            using var p = new Packet(SendPacketOperations.MigrateCommand);
            p.Encode <bool>(true);

            var endpoint = new IPEndPoint(IPAddress.Parse(to.Host), to.Port);
            var address  = endpoint.Address.MapToIPv4().GetAddressBytes();
            var port     = endpoint.Port;

            foreach (var b in address)
            {
                p.Encode <byte>(b);
            }
            p.Encode <short>((short)port);
            return(p);
        }
        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);
        }