using System.Collections.Generic;
using System.Linq;
using System.Text;
using Netch.Utils;
namespace Netch.Models
{
public class Mode
{
///
/// 备注
///
public string Remark;
///
/// 文件相对路径(必须是存在的文件)
///
public string RelativePath;
///
/// 无后缀文件名
///
public string FileName;
///
/// 类型
/// 0. Socks5 + 进程加速
/// 1. Socks5 + TUN/TAP 规则内 IP CIDR 加速
/// 2. Socks5 + TUN/TAP 全局,绕过规则内 IP CIDR
/// 3. Socks5 + HTTP 代理(设置到系统代理)
/// 4. Socks5 代理(不设置到系统代理)
/// 5. Socks5 + HTTP 代理(不设置到系统代理)
///
public int Type = 0;
public bool SupportSocks5Auth => Type switch
{
0 => true,
_ => false
};
public bool TestNatRequired => Type switch
{
0 => true,
1 => true,
2 => true,
_ => false
};
///
/// 绕过中国(0. 不绕过 1. 绕过)
///
public bool BypassChina = false;
///
/// 规则
///
public readonly List Rule = new List();
public List FullRule
{
get
{
var result = new List();
foreach (var s in Rule)
{
if (string.IsNullOrWhiteSpace(s))
continue;
if (s.StartsWith("//"))
continue;
if (s.StartsWith("#include"))
{
var relativePath = new StringBuilder(s.Substring(8).Trim());
relativePath.Replace("<", "");
relativePath.Replace(">", "");
relativePath.Replace(".h", ".txt");
var mode = Global.Modes.FirstOrDefault(m => m.RelativePath.Equals(relativePath.ToString()));
if (mode == null)
{
Logging.Warning($"{relativePath} file included in {Remark} not found");
}
else if (mode == this)
{
Logging.Warning("Can't self-reference");
}
else
{
if (mode.Type != Type)
{
Logging.Warning($"{mode.Remark}'s mode is not as same as {Remark}'s mode");
}
else
{
if (mode.Rule.Any(rule => rule.StartsWith("#include")))
{
Logging.Warning("Cannot reference mode that reference other mode");
}
else
{
result.AddRange(mode.FullRule);
}
}
}
}
else
{
result.Add(s);
}
}
return result;
}
}
///
/// 获取备注
///
/// 备注
public override string ToString()
{
return $"[{Type + 1}] {i18N.Translate(Remark)}";
}
///
/// 获取模式文件字符串
///
/// 模式文件字符串
public string ToFileString()
{
StringBuilder fileString = new StringBuilder();
switch (Type)
{
case 0:
// 进程模式
fileString.Append($"# {Remark}");
break;
case 1:
// TUN/TAP 规则内 IP CIDR,无 Bypass China 设置
fileString.Append($"# {Remark}, {Type}, 0");
break;
default:
fileString.Append($"# {Remark}, {Type}, {(BypassChina ? 1 : 0)}");
break;
}
if (Rule.Any())
{
fileString.Append(Global.EOF);
fileString.Append(string.Join(Global.EOF, Rule));
}
return fileString.ToString();
}
public string TypeToString()
{
return Type switch
{
0 => "Process",
1 => "TUNTAP",
2 => "TUNTAP",
3 => "SYSTEM",
4 => "S5",
5 => "S5+HTTP",
_ => "ERROR",
};
}
}
}