validate method

List<XrayValidationIssue> validate({
  1. bool allowUnknownProtocols = false,
  2. bool allowRawSettings = true,
})

Implementation

List<XrayValidationIssue> validate({
  bool allowUnknownProtocols = false,
  bool allowRawSettings = true,
}) {
  final issues = <XrayValidationIssue>[];
  if (reverse != null) {
    issues.add(
      const XrayValidationIssue(
        'reverse',
        'legacy reverse has been removed; use VLESS Reverse Proxy',
      ),
    );
  }
  final inboundTags = _collectTags(
    inbounds?.map((item) => item.tag),
    'inbounds',
    issues,
  );
  final outboundTags = _collectTags(
    outbounds?.map((item) => item.tag),
    'outbounds',
    issues,
  );
  // A simplified VLESS reverse outbound supplies the inbound tag for
  // traffic arriving from its server. Core ignores root reverse options
  // when the outbound uses the full vnext form (without address).
  for (final outbound in outbounds ?? const <OutboundDetourConfig>[]) {
    final settings = outbound.settings;
    if (outbound.protocol.toLowerCase() == 'vless' &&
        settings is VLessOutboundConfig &&
        settings.address != null) {
      final tag = settings.reverse?.tag;
      if (tag != null && tag.isNotEmpty) inboundTags.add(tag);
    }
  }
  // VLESS inbound accounts register reverse outbounds dynamically. Multiple
  // accounts may share a reverse tag; these are references, not declarations
  // of duplicate static outbounds. Core gives clients precedence over users.
  for (final inbound in inbounds ?? const <InboundDetourConfig>[]) {
    final settings = inbound.settings;
    if (inbound.protocol.toLowerCase() != 'vless' ||
        settings is! VLessInboundConfig) {
      continue;
    }
    for (final user
        in settings.clients ?? settings.users ?? const <VLessUser>[]) {
      final tag = user.reverse?.tag;
      if (tag != null && tag.isNotEmpty) outboundTags.add(tag);
    }
  }
  final balancerTags = _collectTags(
    routing?.balancers?.map((item) => item.tag),
    'routing.balancers',
    issues,
  );

  final inboundList = inbounds ?? const <InboundDetourConfig>[];
  for (var index = 0; index < inboundList.length; index++) {
    inboundList[index]._validate(
      issues,
      'inbounds[$index]',
      outboundTags: outboundTags,
      allowUnknownProtocols: allowUnknownProtocols,
      allowRawSettings: allowRawSettings,
    );
  }

  final outboundList = outbounds ?? const <OutboundDetourConfig>[];
  for (var index = 0; index < outboundList.length; index++) {
    final outbound = outboundList[index];
    outbound._validate(
      issues,
      'outbounds[$index]',
      outboundTags: outboundTags,
      allowUnknownProtocols: allowUnknownProtocols,
      allowRawSettings: allowRawSettings,
    );
  }

  final rules = routing?.ruleList ?? const <RouterRule>[];
  for (var index = 0; index < rules.length; index++) {
    rules[index]._validate(
      issues,
      'routing.rules[$index]',
      inboundTags: inboundTags,
      outboundTags: outboundTags,
      balancerTags: balancerTags,
    );
  }

  final balancers = routing?.balancers ?? const <BalancingRule>[];
  for (var index = 0; index < balancers.length; index++) {
    balancers[index]._validate(
      issues,
      'routing.balancers[$index]',
      outboundTags: outboundTags,
    );
  }

  return issues;
}