public void AddForbiddenUser(RayPort port, RayPortUser user) { JObject rootJObj = this.rootJObj; RayConfigExtension configEx = JsonConvert.DeserializeObject <RayConfigExtension>( rootJObj.ToString()); if (configEx.ForbiddenedUsersPorts == null) { configEx.ForbiddenedUsersPorts = new List <RayPort>(); } else if (!configEx.ForbiddenedUsersPorts.Contains( port, RayPortEqualityComparer.Default)) { configEx.ForbiddenedUsersPorts.Add(port); } RayPort p = configEx.ForbiddenedUsersPorts.FirstOrDefault( r => r.Port == port.Port); ((p.Settings ??= new RayPortSettings()) .Clients ??= new List <RayPortUser>()).Add(user); SaveConfigEx(configEx); }
/// <summary> /// 生成 V2ray 分享链接 /// </summary> /// <param name="rayPortUser"></param> /// <param name="rayPort"></param> /// <returns></returns> public static string GenerateShareUrl(this RayPortUser rayPortUser, RayPort rayPort) { ClientUserConfig clientConfig = new ClientUserConfig(rayPort, rayPortUser); string jStr = clientConfig.ToJsonString(RayConfigJsonSetting.JsonSerializerSettings); return("vmess://" + Convert.ToBase64String(Encoding.Default.GetBytes(jStr))); }
public void AddPort(RayPort port) { var rayPorts = GetRayPorts(); if (rayPorts.Any(p => p.Port == port.Port)) { throw new ArgumentOutOfRangeException(nameof(port), $"端口号{port.Port}冲突"); } if (rayPorts.Any(p => p.Settings?.Clients?.Any(c => { bool confict = false; foreach (var client in port.Settings?.Clients ?? new List <RayPortUser>()) { if (client.Uuid == c.Uuid) { confict = true; break; } } return(confict); }) ?? false)) { throw new ArgumentOutOfRangeException(nameof(port), $"用户id冲突"); } JObject rayConfigObj = GetRayConfigJObject(); if (rayConfigObj.SelectToken("inbounds") is JArray rayPortsObj) { rayPortsObj.Add(ToJObject(port)); WriteJsonToFile(rayConfigObj); } }
public void AddUserToPort(RayPort rayPort, RayPortUser user) { var rayConfigObj = GetRayConfigJObject(); if (!(rayConfigObj.SelectToken($"inbounds[?(@port == {rayPort.Port})].settings.clients") is JArray rayPortUsersObj)) { throw new ArgumentException(nameof(rayPort), "端口不存在, 请创建端口"); } JObject userObj = JObject.FromObject(user, RayConfigJsonSetting.JsonSerializer); rayPortUsersObj.Add(userObj); WriteJsonToFile(rayConfigObj); }
public static RayPort GetRayPort(RayPortUser rayPortUser) { var repo = new RayConfigRepository(); var rayPorts = repo.GetRayPorts(); RayPort rayPort = null; foreach (var r in rayPorts) { if (r.Settings?.Clients?.Any(obj => obj.Uuid == rayPortUser.Uuid) ?? false) { rayPort = r; break; } } return(rayPort); }
private void ShowRayPortsAndGetRayPortToDelete() { IList <RayPort> rayPorts = repo.GetRayPorts(); ConsoleConfigDisplayer.DisplayRayPorts(rayPorts, false); int?ch = InputHelper.TryGetNumberInput( "输入索引选择要删除的端口", "删除端口将删除端口下的全部用户", new Tuple <int, int>(1, rayPorts.Count)); if (ch == null) { throw new Exception("输入有误"); } rayPortToDelete = rayPorts[ch.Value - 1]; }
public void DeleteRayPort(RayPort rayPort) { var configObj = GetRayConfigJObject(); if (!(configObj.SelectToken("inbounds") is JArray rayPortsObj)) { throw new Exception("列表中没有可用的端口."); } var rayPortObj = configObj.SelectToken($"inbounds[?(@port == {rayPort.Port})]"); if (rayPortObj == null) { throw new Exception($"找不到端口{rayPort.Port}"); } rayPortsObj.Remove(rayPortObj); WriteJsonToFile(configObj); }
public void UpdatePort(int portToModify, RayPort toModify) { JObject rayConfig = GetRayConfigJObject(); JArray portsObj = rayConfig.SelectToken("inbounds") as JArray; int index = -1; if (portsObj.FirstOrDefault( j => j["port"].ToString() == portToModify.ToString()) is JObject portObj) { index = portsObj.IndexOf(portObj); portsObj.Remove(portObj); } portsObj.Insert( index, JObject.FromObject(toModify, RayConfigJsonSetting.JsonSerializer)); WriteJsonToFile(rayConfig); }
public void Execute() { Console.Clear(); Console.WriteLine(); Displayer.ShowLine("新建端口向导!", 2, ConsoleColor.Yellow); Console.WriteLine(); Displayer.ShowCutLine(); Console.WriteLine("\r\n"); ConsoleInputRayPortConfigBuilder rayPortBuilder = new ConsoleInputRayPortConfigBuilder(); try { RayConfigRepository repo = new RayConfigRepository(); RayPort rayPort = rayPortBuilder.BuildPort(); repo.AddPort(rayPort); Displayer.ShowLine(" 创建成功!\r\n", ConsoleColor.DarkGreen); ConsoleConfigDisplayer.DisplayRayPort(rayPort, displayUser: true); } catch (Exception ex) { Console.WriteLine(ex); } }
public static void DisplayRayPort(RayPort rayPort, int?index = null, bool displayUser = false, bool displayUserIndex = false, bool addReturn = true) { Displayer.ShowConfigItem("索引", index, ConsoleColor.Green); Displayer.ShowConfigItem("端口号", rayPort.Port); Displayer.ShowConfigItem("服务类型", rayPort.Protocol); Displayer.ShowConfigItem("传输协议", rayPort.StreamSettings?.NetWork ?? "tcp"); Displayer.ShowConfigItem("底层传输安全", rayPort.StreamSettings?.Security ?? ""); Displayer.ShowConfigItem("Ws路径(path)", rayPort?.StreamSettings?.WSSettings?.Path); Displayer.ShowConfigItem("端口监听地址", rayPort?.Listen); Displayer.ShowConfigItem("tls证书文件路径", rayPort?.StreamSettings?.TlsSettings?.Certificates?.FirstOrDefault().CertificateFile); Displayer.ShowConfigItem("tls证书文件路径", rayPort?.StreamSettings?.TlsSettings?.Certificates?.FirstOrDefault().KeyFile); if (displayUser) { Console.WriteLine(); DisplayRayPortUsers(rayPort.Settings?.Clients, displayUserIndex, intend: 4); } if (addReturn) { Console.WriteLine(); } }
public ConsoleInputRayPortConfigBuilder(RayPort rayPort) { this.rayPort = rayPort; }
/// <summary> /// 配置流量统计功能 /// </summary> /* * "stats": {}, * "api": { * "tag": "api", * "services": [ * "StatsService" * ] * }, * "policy": { * "levels": { * "0": { * "statsUserUplink": true, * "statsUserDownlink": true * } * }, * "system": { * "statsInboundUplink": true, * "statsInboundDownlink": true * } * }, */ public static void ConfigTrafficStatistic() { JObject rootJObj = RayConfig.RayConfigJObject; bool hasChange = false; if (!rootJObj.ContainsKey("stats")) { rootJObj.Add("stats", JObject.Parse("{}")); hasChange = true; } if (!rootJObj.ContainsKey("api") || (!(rootJObj.SelectToken("api.services") as JArray)?.Children().Contains("StatsService") ?? false)) { var api = new { tag = "api", services = new string[] { "StatsService", "LoggerService", "HandlerService" }, }; rootJObj.Add("api", JObject.FromObject(api)); hasChange = true; } if (!rootJObj.ContainsKey("policy")) { var policy = new { levels = new Dictionary <string, object> { { "1", new Dictionary <string, bool> { { "statsUserUplink", true }, { "statsUserDownlink", true }, } }, }, system = new Dictionary <string, bool> { { "statsInboundUplink", true }, { "statsInboundDownlink", true }, } }; rootJObj.Add("policy", JObject.FromObject(policy)); hasChange = true; } if (!(rootJObj.SelectToken("routing.rules[?(@inboundTag[0] == 'api')]") is JObject)) { JArray rules = (rootJObj.SelectToken("routing.rules") as JArray) ?? new JArray(); var rule = new { inboundTag = new string[] { "api" }, outboundTag = "api", type = "field" }; rules.Insert(0, JObject.FromObject(rule)); hasChange = true; } if (null == (rootJObj.SelectToken("routing") as JObject).Property("strategy")) { (rootJObj.SelectToken("routing") as JObject).Add("strategy", "rules"); hasChange = true; } RayConfigRepository repo = new RayConfigRepository(); RayPort statPort = new RayPort { Listen = "127.0.0.1", Port = 13888, Protocol = "dokodemo-door", Settings = new RayPortSettings { Address = "127.0.0.1" }, Tag = "api", }; repo.AddPort(statPort); if (hasChange) { WriteJsonToFile(rootJObj); } }