mirror of
https://github.com/snltty/linker.git
synced 2025-10-06 01:26:54 +08:00
cdkey
This commit is contained in:
2
.github/workflows/dotnet.yml
vendored
2
.github/workflows/dotnet.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
|||||||
release_name: v1.6.9.${{ steps.date.outputs.today }}
|
release_name: v1.6.9.${{ steps.date.outputs.today }}
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: false
|
prerelease: false
|
||||||
body: "1. 修复litedb抢锁超时导致客户端登录失败问题\r\n2. 同步信标服务器\r\n3. 其它一些修复优化"
|
body: "1. 优化linux下路由跟踪问题\r\n2. 优化linux下获取本机IP问题\r\n3. 增加ICS,让win7+、win server2008+支持NAT\r\n4. 增加中继卡密\r\n5. 增加内外穿透定时开关功能\r\n6. 优化管理页面连接接口的体验\r\n7. 优化一些UI体验,去除同步页面,将同步功能放置各个实际的位置\r\n8. 其它一些修复优化"
|
||||||
- name: publish projects
|
- name: publish projects
|
||||||
run: ./publish.bat
|
run: ./publish.bat
|
||||||
- name: upload-win-x86-oss
|
- name: upload-win-x86-oss
|
||||||
|
@@ -57,10 +57,11 @@ sidebar_position: 1
|
|||||||
:::
|
:::
|
||||||
|
|
||||||
:::danger[win10以下]
|
:::danger[win10以下]
|
||||||
1. win7 或 win8 可能需要安装一些环境,才能运行
|
1. win7、win8、win server 2008、win server 2008 R2 可能需要安装一些环境,才能运行
|
||||||
2. <a href="https://aka.ms/vs/16/release/vc_redist.x64.exe" target="_blank">Microsoft Visual C++ 2015-2019 Redistributable </a>
|
2. <a href="https://aka.ms/vs/16/release/vc_redist.x64.exe" target="_blank">Microsoft Visual C++ 2015-2019 Redistributable 运行库</a>
|
||||||
3. <a href="https://www.microsoft.com/download/details.aspx?id=47442" target="_blank">KB3063858 </a>
|
3. <a href="https://www.microsoft.com/download/details.aspx?id=47442" target="_blank">KB3063858 运行库</a>
|
||||||
4. <a href="https://www.microsoft.com/zh-cn/download/details.aspx?id=46148" target="_blank">KB3033929 </a>
|
4. <a href="https://www.microsoft.com/zh-cn/download/details.aspx?id=46148" target="_blank">KB3033929 全球化补丁</a>
|
||||||
|
5. <a href="https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/thank-you/net462-web-installer" target="_blank">netframework4.6.2 ICS NAT运行库</a>
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
@@ -1,24 +0,0 @@
|
|||||||
---
|
|
||||||
sidebar_position: 4
|
|
||||||
---
|
|
||||||
|
|
||||||
# 1.1.2、RRAS
|
|
||||||
|
|
||||||
:::tip[说明]
|
|
||||||
1. 操作不当可能会导致网络无法访问,请谨慎操作
|
|
||||||
2. 有局限性,创建虚拟网卡后,需要重新`“配置并启用路由和远程访问”`
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||
:::
|
|
@@ -1,12 +1,11 @@
|
|||||||
---
|
---
|
||||||
sidebar_position: 5
|
sidebar_position: 4
|
||||||
---
|
---
|
||||||
|
|
||||||
# 1.1.3、ICS
|
# 1.1.3、ICS
|
||||||
|
|
||||||
:::tip[说明]
|
:::tip[说明]
|
||||||
1. 操作不当可能会导致网络无法访问,请谨慎操作
|
1. 如果系统没有<a href="https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/thank-you/net462-web-installer" target="_blank">netframework4.6.2</a>,就下载安装一下
|
||||||
|
2. 需要linker v1.7.0+版本
|
||||||

|
3. 剩下的交给linker
|
||||||
|
|
||||||
:::
|
:::
|
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
sidebar_position: 6
|
sidebar_position: 5
|
||||||
---
|
---
|
||||||
|
|
||||||
# 1.2、网对网
|
# 1.2、网对网
|
||||||
|
@@ -9,9 +9,9 @@ namespace linker.libs
|
|||||||
{
|
{
|
||||||
public static string Windows(string arg, string[] commands)
|
public static string Windows(string arg, string[] commands)
|
||||||
{
|
{
|
||||||
return Execute("cmd.exe", arg, commands,out string error);
|
return Execute("cmd.exe", arg, commands, out string error);
|
||||||
}
|
}
|
||||||
public static string Windows(string arg, string[] commands,out string error)
|
public static string Windows(string arg, string[] commands, out string error)
|
||||||
{
|
{
|
||||||
return Execute("cmd.exe", arg, commands, out error);
|
return Execute("cmd.exe", arg, commands, out error);
|
||||||
}
|
}
|
||||||
@@ -23,14 +23,14 @@ namespace linker.libs
|
|||||||
error = "PowerShell is not installed";
|
error = "PowerShell is not installed";
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
return Execute("powershell.exe", arg, commands,out error);
|
return Execute("powershell.exe", arg, commands, out error);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Linux(string arg, string[] commands)
|
public static string Linux(string arg, string[] commands)
|
||||||
{
|
{
|
||||||
return Execute("/bin/bash", arg, commands, out string error);
|
return Execute("/bin/bash", arg, commands, out string error);
|
||||||
}
|
}
|
||||||
public static string Linux(string arg, string[] commands,out string error)
|
public static string Linux(string arg, string[] commands, out string error)
|
||||||
{
|
{
|
||||||
return Execute("/bin/bash", arg, commands, out error);
|
return Execute("/bin/bash", arg, commands, out error);
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ namespace linker.libs
|
|||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Execute(string fileName, string arg, string[] commands,out string error)
|
public static string Execute(string fileName, string arg, string[] commands, out string error)
|
||||||
{
|
{
|
||||||
using Process proc = new Process();
|
using Process proc = new Process();
|
||||||
proc.StartInfo.WorkingDirectory = Path.GetFullPath(Path.Join("./"));
|
proc.StartInfo.WorkingDirectory = Path.GetFullPath(Path.Join("./"));
|
||||||
@@ -80,12 +80,9 @@ namespace linker.libs
|
|||||||
proc.StandardInput.WriteLine("exit");
|
proc.StandardInput.WriteLine("exit");
|
||||||
proc.StandardInput.Close();
|
proc.StandardInput.Close();
|
||||||
|
|
||||||
|
string output = proc.StandardOutput.ReadToEnd();
|
||||||
error = proc.StandardError.ReadToEnd();
|
error = proc.StandardError.ReadToEnd();
|
||||||
string output = string.Empty;
|
|
||||||
if (string.IsNullOrWhiteSpace(error))
|
|
||||||
{
|
|
||||||
output = proc.StandardOutput.ReadToEnd();
|
|
||||||
}
|
|
||||||
proc.WaitForExit();
|
proc.WaitForExit();
|
||||||
proc.Close();
|
proc.Close();
|
||||||
proc.Dispose();
|
proc.Dispose();
|
||||||
|
@@ -36,7 +36,7 @@ namespace linker.libs
|
|||||||
|
|
||||||
public bool Equals(IPNetwork other)
|
public bool Equals(IPNetwork other)
|
||||||
{
|
{
|
||||||
return ToValue() == other.ToValue();
|
return ToValue() == other.ToValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ namespace linker.libs
|
|||||||
{
|
{
|
||||||
result = new List<IPAddress>();
|
result = new List<IPAddress>();
|
||||||
|
|
||||||
string str = CommandHelper.Linux(string.Empty, new string[] { $"traceroute {server} -4 -m 5" });
|
string str = CommandHelper.Linux(string.Empty, new string[] { $"traceroute {server} -4 -m 5 -w 1" });
|
||||||
string[] lines = str.Split(Environment.NewLine);
|
string[] lines = str.Split(Environment.NewLine);
|
||||||
|
|
||||||
Regex regex = new Regex(@"(\d+\.\d+\.\d+\.\d+)");
|
Regex regex = new Regex(@"(\d+\.\d+\.\d+\.\d+)");
|
||||||
@@ -191,33 +191,41 @@ namespace linker.libs
|
|||||||
|
|
||||||
|
|
||||||
private static byte[] ipv6LocalBytes = new byte[] { 254, 128, 0, 0, 0, 0, 0, 0 };
|
private static byte[] ipv6LocalBytes = new byte[] { 254, 128, 0, 0, 0, 0, 0, 0 };
|
||||||
public static IPAddress[] GetIPV6()
|
|
||||||
|
private static IPAddress[] GetIP()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Dns.GetHostAddresses(Dns.GetHostName())
|
return Dns.GetHostEntry(Dns.GetHostName()).AddressList;
|
||||||
.Where(c => c.AddressFamily == AddressFamily.InterNetworkV6)
|
|
||||||
.Where(c => c.GetAddressBytes().AsSpan(0, 8).SequenceEqual(ipv6LocalBytes) == false).Distinct().ToArray();
|
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return NetworkInterface.GetAllNetworkInterfaces()
|
||||||
|
.SelectMany(c => c.GetIPProperties().UnicastAddresses)
|
||||||
|
.Select(c => c.Address)
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Array.Empty<IPAddress>();
|
return Array.Empty<IPAddress>();
|
||||||
}
|
}
|
||||||
|
public static IPAddress[] GetIPV6()
|
||||||
|
{
|
||||||
|
return GetIP()
|
||||||
|
.Where(c => c.AddressFamily == AddressFamily.InterNetworkV6)
|
||||||
|
.Where(c => c.GetAddressBytes().AsSpan(0, 8).SequenceEqual(ipv6LocalBytes) == false).Distinct().ToArray(); ;
|
||||||
|
}
|
||||||
public static IPAddress[] GetIPV4()
|
public static IPAddress[] GetIPV4()
|
||||||
{
|
{
|
||||||
try
|
return GetIP()
|
||||||
{
|
.Where(c => c.AddressFamily == AddressFamily.InterNetwork)
|
||||||
return Dns.GetHostEntry(Dns.GetHostName()).AddressList
|
|
||||||
.Where(c => c.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
|
||||||
.Where(c => c.IsIPv4MappedToIPv6 == false)
|
.Where(c => c.IsIPv4MappedToIPv6 == false)
|
||||||
.Where(c => c.Equals(IPAddress.Loopback) == false)
|
.Where(c => c.Equals(IPAddress.Loopback) == false)
|
||||||
.Distinct().ToArray();
|
.Distinct().ToArray();
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
return Array.Empty<IPAddress>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte ToPrefixLength(uint ip)
|
public static byte ToPrefixLength(uint ip)
|
||||||
|
@@ -38,7 +38,7 @@ namespace linker.libs.api
|
|||||||
server = new WebSocketServer();
|
server = new WebSocketServer();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
server.Start( port);
|
server.Start(port);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -51,6 +51,13 @@ namespace linker.libs.api
|
|||||||
{
|
{
|
||||||
header.SetHeaderValue(WebsocketHeaderKey.SecWebSocketExtensions, string.Empty);
|
header.SetHeaderValue(WebsocketHeaderKey.SecWebSocketExtensions, string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||||
|
{
|
||||||
|
header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketProtocol, out string _password1);
|
||||||
|
LoggerHelper.Instance.Info($"websocket client password {_password1} eq {password}");
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
server.OnOpen = (connection) =>
|
server.OnOpen = (connection) =>
|
||||||
|
@@ -313,6 +313,8 @@ namespace linker.libs.websocket
|
|||||||
{
|
{
|
||||||
token.Connectrion.SendFrameClose(WebSocketFrameInfo.EnumCloseStatus.ExtendsError);
|
token.Connectrion.SendFrameClose(WebSocketFrameInfo.EnumCloseStatus.ExtendsError);
|
||||||
token.Connectrion.Close();
|
token.Connectrion.Close();
|
||||||
|
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||||
|
LoggerHelper.Instance.Error($"websocket opcode error:{token.FrameInfo.Opcode}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -356,6 +358,8 @@ namespace linker.libs.websocket
|
|||||||
header.StatusCode = HttpStatusCode.MethodNotAllowed;
|
header.StatusCode = HttpStatusCode.MethodNotAllowed;
|
||||||
token.Connectrion.ConnectResponse(header);
|
token.Connectrion.ConnectResponse(header);
|
||||||
token.Connectrion.Close();
|
token.Connectrion.Close();
|
||||||
|
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||||
|
LoggerHelper.Instance.Error("websocket SecWebSocketKey error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,6 +374,8 @@ namespace linker.libs.websocket
|
|||||||
header.StatusCode = HttpStatusCode.Unauthorized;
|
header.StatusCode = HttpStatusCode.Unauthorized;
|
||||||
token.Connectrion.ConnectResponse(header);
|
token.Connectrion.ConnectResponse(header);
|
||||||
token.Connectrion.Close();
|
token.Connectrion.Close();
|
||||||
|
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||||
|
LoggerHelper.Instance.Error("websocket OnConnecting false");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,6 +485,9 @@ namespace linker.libs.websocket
|
|||||||
{
|
{
|
||||||
Disposabled = true;
|
Disposabled = true;
|
||||||
Connectrion.Close();
|
Connectrion.Close();
|
||||||
|
|
||||||
|
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||||
|
LoggerHelper.Instance.Error($"websocket connection clear");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -136,6 +136,9 @@
|
|||||||
[AccessDisplay("重置所有接口密码")]
|
[AccessDisplay("重置所有接口密码")]
|
||||||
SetApiPasswordOther = (ulong)1 << 42,
|
SetApiPasswordOther = (ulong)1 << 42,
|
||||||
|
|
||||||
|
[AccessDisplay("管理中继CDKEY")]
|
||||||
|
RelayCdkey = (ulong)1 << 43,
|
||||||
|
|
||||||
Full = ulong.MaxValue >> 64 - 52,
|
Full = ulong.MaxValue >> 64 - 52,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,9 +1,12 @@
|
|||||||
using linker.libs.api;
|
using linker.libs;
|
||||||
|
using linker.libs.api;
|
||||||
using linker.libs.extends;
|
using linker.libs.extends;
|
||||||
using linker.messenger.api;
|
using linker.messenger.api;
|
||||||
using linker.messenger.relay.client;
|
using linker.messenger.relay.client;
|
||||||
using linker.messenger.relay.client.transport;
|
using linker.messenger.relay.client.transport;
|
||||||
|
using linker.messenger.relay.messenger;
|
||||||
using linker.messenger.relay.server;
|
using linker.messenger.relay.server;
|
||||||
|
using linker.messenger.signin;
|
||||||
|
|
||||||
namespace linker.messenger.relay
|
namespace linker.messenger.relay
|
||||||
{
|
{
|
||||||
@@ -15,19 +18,23 @@ namespace linker.messenger.relay
|
|||||||
private readonly RelayClientTestTransfer relayTestTransfer;
|
private readonly RelayClientTestTransfer relayTestTransfer;
|
||||||
private readonly RelayClientTransfer relayTransfer;
|
private readonly RelayClientTransfer relayTransfer;
|
||||||
private readonly IRelayClientStore relayClientStore;
|
private readonly IRelayClientStore relayClientStore;
|
||||||
|
private readonly SignInClientState signInClientState;
|
||||||
|
private readonly IMessengerSender messengerSender;
|
||||||
|
private readonly ISerializer serializer;
|
||||||
|
private readonly ISignInClientStore signInClientStore;
|
||||||
|
|
||||||
public RelayApiController(RelayClientTestTransfer relayTestTransfer, RelayClientTransfer relayTransfer, IRelayClientStore relayClientStore)
|
public RelayApiController(RelayClientTestTransfer relayTestTransfer, RelayClientTransfer relayTransfer, IRelayClientStore relayClientStore,
|
||||||
|
SignInClientState signInClientState, IMessengerSender messengerSender, ISerializer serializer, ISignInClientStore signInClientStore)
|
||||||
{
|
{
|
||||||
this.relayTestTransfer = relayTestTransfer;
|
this.relayTestTransfer = relayTestTransfer;
|
||||||
this.relayTransfer = relayTransfer;
|
this.relayTransfer = relayTransfer;
|
||||||
this.relayClientStore = relayClientStore;
|
this.relayClientStore = relayClientStore;
|
||||||
|
this.signInClientState = signInClientState;
|
||||||
|
this.messengerSender = messengerSender;
|
||||||
|
this.serializer = serializer;
|
||||||
|
this.signInClientStore = signInClientStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置中继协议
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="param"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[Access(AccessValue.Config)]
|
[Access(AccessValue.Config)]
|
||||||
public bool SetServers(ApiControllerParamsInfo param)
|
public bool SetServers(ApiControllerParamsInfo param)
|
||||||
{
|
{
|
||||||
@@ -50,6 +57,90 @@ namespace linker.messenger.relay
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<bool> AccessCdkey(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = signInClientState.Connection,
|
||||||
|
MessengerId = (ushort)RelayMessengerIds.AccessCdkey,
|
||||||
|
Payload = serializer.Serialize(relayClientStore.Server.SecretKey)
|
||||||
|
});
|
||||||
|
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Access(AccessValue.RelayCdkey)]
|
||||||
|
public async Task<bool> AddCdkey(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
RelayServerCdkeyInfo info = param.Content.DeJson<RelayServerCdkeyInfo>();
|
||||||
|
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = signInClientState.Connection,
|
||||||
|
MessengerId = (ushort)RelayMessengerIds.AddCdkey,
|
||||||
|
Payload = serializer.Serialize(new RelayServerCdkeyAddInfo
|
||||||
|
{
|
||||||
|
Data = info,
|
||||||
|
SecretKey = relayClientStore.Server.SecretKey
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Access(AccessValue.RelayCdkey)]
|
||||||
|
public async Task<bool> DelCdkey(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = signInClientState.Connection,
|
||||||
|
MessengerId = (ushort)RelayMessengerIds.DelCdkey,
|
||||||
|
Payload = serializer.Serialize(new RelayServerCdkeyDelInfo
|
||||||
|
{
|
||||||
|
Id = param.Content,
|
||||||
|
SecretKey = relayClientStore.Server.SecretKey
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Access(AccessValue.RelayCdkey)]
|
||||||
|
public async Task<RelayServerCdkeyPageResultInfo> PageCdkey(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
RelayServerCdkeyPageRequestInfo info = param.Content.DeJson<RelayServerCdkeyPageRequestInfo>();
|
||||||
|
info.SecretKey = relayClientStore.Server.SecretKey;
|
||||||
|
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = signInClientState.Connection,
|
||||||
|
MessengerId = (ushort)RelayMessengerIds.PageCdkey,
|
||||||
|
Payload = serializer.Serialize(info)
|
||||||
|
});
|
||||||
|
if (resp.Code == MessageResponeCodes.OK)
|
||||||
|
{
|
||||||
|
return serializer.Deserialize<RelayServerCdkeyPageResultInfo>(resp.Data.Span);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RelayServerCdkeyPageResultInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RelayServerCdkeyPageResultInfo> MyCdkey(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
RelayServerCdkeyPageRequestInfo info = param.Content.DeJson<RelayServerCdkeyPageRequestInfo>();
|
||||||
|
info.SecretKey = relayClientStore.Server.SecretKey;
|
||||||
|
info.UserId = signInClientStore.Server.UserId;
|
||||||
|
var resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = signInClientState.Connection,
|
||||||
|
MessengerId = (ushort)RelayMessengerIds.PageCdkey,
|
||||||
|
Payload = serializer.Serialize(info)
|
||||||
|
});
|
||||||
|
if (resp.Code == MessageResponeCodes.OK)
|
||||||
|
{
|
||||||
|
return serializer.Deserialize<RelayServerCdkeyPageResultInfo>(resp.Data.Span);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RelayServerCdkeyPageResultInfo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class RelayConnectInfo
|
public sealed class RelayConnectInfo
|
||||||
|
@@ -18,10 +18,12 @@ namespace linker.messenger.relay.client
|
|||||||
private Dictionary<string, List<Action<ITunnelConnection>>> OnConnected { get; } = new Dictionary<string, List<Action<ITunnelConnection>>>();
|
private Dictionary<string, List<Action<ITunnelConnection>>> OnConnected { get; } = new Dictionary<string, List<Action<ITunnelConnection>>>();
|
||||||
|
|
||||||
private readonly IRelayClientStore relayClientStore;
|
private readonly IRelayClientStore relayClientStore;
|
||||||
public RelayClientTransfer(IMessengerSender messengerSender,ISerializer serializer,IRelayClientStore relayClientStore,SignInClientState signInClientState,IMessengerStore messengerStore)
|
private readonly ISignInClientStore signInClientStore;
|
||||||
|
public RelayClientTransfer(IMessengerSender messengerSender, ISerializer serializer, IRelayClientStore relayClientStore, SignInClientState signInClientState, IMessengerStore messengerStore, ISignInClientStore signInClientStore)
|
||||||
{
|
{
|
||||||
this.relayClientStore = relayClientStore;
|
this.relayClientStore = relayClientStore;
|
||||||
Transports = new List<IRelayClientTransport> {
|
this.signInClientStore = signInClientStore;
|
||||||
|
Transports = new List<IRelayClientTransport> {
|
||||||
new RelayClientTransportSelfHost(messengerSender,serializer,relayClientStore,signInClientState,messengerStore),
|
new RelayClientTransportSelfHost(messengerSender,serializer,relayClientStore,signInClientState,messengerStore),
|
||||||
};
|
};
|
||||||
LoggerHelper.Instance.Info($"load relay transport:{string.Join(",", Transports.Select(c => c.GetType().Name))}");
|
LoggerHelper.Instance.Info($"load relay transport:{string.Join(",", Transports.Select(c => c.GetType().Name))}");
|
||||||
@@ -87,7 +89,8 @@ namespace linker.messenger.relay.client
|
|||||||
TransactionId = transactionId,
|
TransactionId = transactionId,
|
||||||
TransportName = transport.Name,
|
TransportName = transport.Name,
|
||||||
SSL = relayClientStore.Server.SSL,
|
SSL = relayClientStore.Server.SSL,
|
||||||
NodeId = nodeId
|
NodeId = nodeId,
|
||||||
|
UserId = signInClientStore.Server.UserId,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||||
|
@@ -112,6 +112,11 @@ namespace linker.messenger.relay.client.transport
|
|||||||
/// 是否ssl
|
/// 是否ssl
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool SSL { get; set; } = true;
|
public bool SSL { get; set; } = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// UserId
|
||||||
|
/// </summary>
|
||||||
|
public string UserId { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -45,14 +45,18 @@ namespace linker.messenger.relay.messenger
|
|||||||
private readonly RelayServerMasterTransfer relayServerTransfer;
|
private readonly RelayServerMasterTransfer relayServerTransfer;
|
||||||
private readonly RelayServerValidatorTransfer relayValidatorTransfer;
|
private readonly RelayServerValidatorTransfer relayValidatorTransfer;
|
||||||
private readonly ISerializer serializer;
|
private readonly ISerializer serializer;
|
||||||
|
private readonly IRelayServerCdkeyStore relayServerCdkeyStore;
|
||||||
|
private readonly IRelayServerStore relayServerStore;
|
||||||
|
|
||||||
public RelayServerMessenger(IMessengerSender messengerSender, SignInServerCaching signCaching, ISerializer serializer, RelayServerMasterTransfer relayServerTransfer, RelayServerValidatorTransfer relayValidatorTransfer)
|
public RelayServerMessenger(IMessengerSender messengerSender, SignInServerCaching signCaching, ISerializer serializer, RelayServerMasterTransfer relayServerTransfer, RelayServerValidatorTransfer relayValidatorTransfer, IRelayServerCdkeyStore relayServerCdkeyStore, IRelayServerStore relayServerStore)
|
||||||
{
|
{
|
||||||
this.messengerSender = messengerSender;
|
this.messengerSender = messengerSender;
|
||||||
this.signCaching = signCaching;
|
this.signCaching = signCaching;
|
||||||
this.relayServerTransfer = relayServerTransfer;
|
this.relayServerTransfer = relayServerTransfer;
|
||||||
this.relayValidatorTransfer = relayValidatorTransfer;
|
this.relayValidatorTransfer = relayValidatorTransfer;
|
||||||
this.serializer = serializer;
|
this.serializer = serializer;
|
||||||
|
this.relayServerCdkeyStore = relayServerCdkeyStore;
|
||||||
|
this.relayServerStore = relayServerStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -89,7 +93,7 @@ namespace linker.messenger.relay.messenger
|
|||||||
[MessengerId((ushort)RelayMessengerIds.RelayAsk)]
|
[MessengerId((ushort)RelayMessengerIds.RelayAsk)]
|
||||||
public async Task RelayAsk(IConnection connection)
|
public async Task RelayAsk(IConnection connection)
|
||||||
{
|
{
|
||||||
client.transport.RelayInfo info = serializer.Deserialize<client.transport.RelayInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
RelayInfo info = serializer.Deserialize<RelayInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||||
if (signCaching.TryGet(connection.Id, out SignCacheInfo cacheFrom) == false || signCaching.TryGet(info.RemoteMachineId, out SignCacheInfo cacheTo) == false || cacheFrom.GroupId != cacheTo.GroupId)
|
if (signCaching.TryGet(connection.Id, out SignCacheInfo cacheFrom) == false || signCaching.TryGet(info.RemoteMachineId, out SignCacheInfo cacheTo) == false || cacheFrom.GroupId != cacheTo.GroupId)
|
||||||
{
|
{
|
||||||
connection.Write(serializer.Serialize(new RelayAskResultInfo { }));
|
connection.Write(serializer.Serialize(new RelayAskResultInfo { }));
|
||||||
@@ -105,9 +109,11 @@ namespace linker.messenger.relay.messenger
|
|||||||
string error = await relayValidatorTransfer.Validate(info, cacheFrom, cacheTo);
|
string error = await relayValidatorTransfer.Validate(info, cacheFrom, cacheTo);
|
||||||
result.Nodes = relayServerTransfer.GetNodes(string.IsNullOrWhiteSpace(error));
|
result.Nodes = relayServerTransfer.GetNodes(string.IsNullOrWhiteSpace(error));
|
||||||
|
|
||||||
|
List<RelayServerCdkeyInfo> cdkeys = await relayServerCdkeyStore.Get(info.UserId);
|
||||||
|
|
||||||
if (result.Nodes.Count > 0)
|
if (result.Nodes.Count > 0)
|
||||||
{
|
{
|
||||||
result.FlowingId = relayServerTransfer.AddRelay(cacheFrom.MachineId, cacheFrom.MachineName, cacheTo.MachineId, cacheTo.MachineName, cacheFrom.GroupId);
|
result.FlowingId = relayServerTransfer.AddRelay(cacheFrom.MachineId, cacheFrom.MachineName, cacheTo.MachineId, cacheTo.MachineName, cacheFrom.GroupId, cdkeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.Write(serializer.Serialize(result));
|
connection.Write(serializer.Serialize(result));
|
||||||
@@ -167,5 +173,89 @@ namespace linker.messenger.relay.messenger
|
|||||||
connection.Write(Helper.FalseArray);
|
connection.Write(Helper.FalseArray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查权限
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connection"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[MessengerId((ushort)RelayMessengerIds.AccessCdkey)]
|
||||||
|
public void AccessCdkey(IConnection connection)
|
||||||
|
{
|
||||||
|
string secretKey = serializer.Deserialize<string>(connection.ReceiveRequestWrap.Payload.Span);
|
||||||
|
connection.Write(relayServerStore.SecretKey == secretKey ? Helper.TrueArray : Helper.FalseArray);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 添加CDKEY
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connection"></param>
|
||||||
|
[MessengerId((ushort)RelayMessengerIds.AddCdkey)]
|
||||||
|
public async Task AddCdkey(IConnection connection)
|
||||||
|
{
|
||||||
|
RelayServerCdkeyAddInfo info = serializer.Deserialize<RelayServerCdkeyAddInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||||
|
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
|
||||||
|
{
|
||||||
|
connection.Write(Helper.FalseArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (relayServerStore.SecretKey != info.SecretKey)
|
||||||
|
{
|
||||||
|
connection.Write(Helper.FalseArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await relayServerCdkeyStore.Add(info.Data);
|
||||||
|
connection.Write(Helper.TrueArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除Cdkey
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connection"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[MessengerId((ushort)RelayMessengerIds.DelCdkey)]
|
||||||
|
public async Task DelCdkey(IConnection connection)
|
||||||
|
{
|
||||||
|
RelayServerCdkeyDelInfo info = serializer.Deserialize<RelayServerCdkeyDelInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||||
|
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
|
||||||
|
{
|
||||||
|
connection.Write(Helper.FalseArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (relayServerStore.SecretKey != info.SecretKey)
|
||||||
|
{
|
||||||
|
connection.Write(Helper.FalseArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await relayServerCdkeyStore.Del(info.Id);
|
||||||
|
connection.Write(Helper.TrueArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询CDKEY
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="connection"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[MessengerId((ushort)RelayMessengerIds.PageCdkey)]
|
||||||
|
public async Task PageCdkey(IConnection connection)
|
||||||
|
{
|
||||||
|
RelayServerCdkeyPageRequestInfo info = serializer.Deserialize<RelayServerCdkeyPageRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||||
|
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache) == false)
|
||||||
|
{
|
||||||
|
connection.Write(serializer.Serialize(new RelayServerCdkeyPageResultInfo { }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (relayServerStore.SecretKey != info.SecretKey && string.IsNullOrWhiteSpace(info.UserId))
|
||||||
|
{
|
||||||
|
connection.Write(serializer.Serialize(new RelayServerCdkeyPageResultInfo { }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var page = await relayServerCdkeyStore.Get(info);
|
||||||
|
|
||||||
|
connection.Write(serializer.Serialize(page));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,11 @@
|
|||||||
NodeDelay = 2106,
|
NodeDelay = 2106,
|
||||||
NodeDelayForward = 2107,
|
NodeDelayForward = 2107,
|
||||||
|
|
||||||
|
AddCdkey = 2108,
|
||||||
|
PageCdkey = 2109,
|
||||||
|
DelCdkey = 2110,
|
||||||
|
AccessCdkey = 2111,
|
||||||
|
|
||||||
Max = 2199
|
Max = 2199
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
104
src/linker.messenger.relay/server/IRelayServerCdkeyStore.cs
Normal file
104
src/linker.messenger.relay/server/IRelayServerCdkeyStore.cs
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
namespace linker.messenger.relay.server
|
||||||
|
{
|
||||||
|
public interface IRelayServerCdkeyStore
|
||||||
|
{
|
||||||
|
public Task<bool> Add(RelayServerCdkeyInfo info);
|
||||||
|
public Task<bool> Del(string id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取有效的CDKEY
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userid"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Task<List<RelayServerCdkeyInfo>> Get(string userid);
|
||||||
|
public Task<RelayServerCdkeyPageResultInfo> Get(RelayServerCdkeyPageRequestInfo relayServerCdkeyPageRequestInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed partial class RelayServerCdkeyPageRequestInfo
|
||||||
|
{
|
||||||
|
public int Page { get; set; }
|
||||||
|
public int Size { get; set; }
|
||||||
|
public string Order { get; set; }
|
||||||
|
public string Sort { get; set; }
|
||||||
|
public string UserId { get; set; }
|
||||||
|
public string Remark { get; set; }
|
||||||
|
public string SecretKey { get; set; }
|
||||||
|
}
|
||||||
|
public sealed partial class RelayServerCdkeyPageResultInfo
|
||||||
|
{
|
||||||
|
public int Page { get; set; }
|
||||||
|
public int Size { get; set; }
|
||||||
|
public int Count { get; set; }
|
||||||
|
public List<RelayServerCdkeyInfo> List { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed partial class RelayServerCdkeyAddInfo
|
||||||
|
{
|
||||||
|
public string SecretKey { get; set; }
|
||||||
|
public RelayServerCdkeyInfo Data { get; set; }
|
||||||
|
}
|
||||||
|
public sealed partial class RelayServerCdkeyDelInfo
|
||||||
|
{
|
||||||
|
public string SecretKey { get; set; }
|
||||||
|
public string Id { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 中继CDKEY
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class RelayServerCdkeyInfo
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用户标识
|
||||||
|
/// </summary>
|
||||||
|
public string UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// KEY
|
||||||
|
/// </summary>
|
||||||
|
public string CdKey { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 添加时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime AddTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 开始时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime StartTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 结束时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime EndTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 允许节点
|
||||||
|
/// </summary>
|
||||||
|
public List<string> Nodes { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 带宽Mbps
|
||||||
|
/// </summary>
|
||||||
|
public double Bandwidth { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 流量
|
||||||
|
/// </summary>
|
||||||
|
public ulong MaxBytes { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 剩余流量
|
||||||
|
/// </summary>
|
||||||
|
public ulong LastBytes { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 原价
|
||||||
|
/// </summary>
|
||||||
|
public double Memory { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 支付金额
|
||||||
|
/// </summary>
|
||||||
|
public double PayMemory { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 备注
|
||||||
|
/// </summary>
|
||||||
|
public string Remark { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@@ -26,7 +26,7 @@ namespace linker.messenger.relay.server
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ulong AddRelay(string fromid, string fromName, string toid, string toName, string groupid)
|
public ulong AddRelay(string fromid, string fromName, string toid, string toName, string groupid, List<RelayServerCdkeyInfo> cdkeys)
|
||||||
{
|
{
|
||||||
ulong flowingId = Interlocked.Increment(ref relayFlowingId);
|
ulong flowingId = Interlocked.Increment(ref relayFlowingId);
|
||||||
|
|
||||||
@@ -37,7 +37,8 @@ namespace linker.messenger.relay.server
|
|||||||
FromName = fromName,
|
FromName = fromName,
|
||||||
ToId = toid,
|
ToId = toid,
|
||||||
ToName = toName,
|
ToName = toName,
|
||||||
GroupId = groupid
|
GroupId = groupid,
|
||||||
|
Cdkey = cdkeys
|
||||||
};
|
};
|
||||||
bool added = relayCaching.TryAdd($"{fromid}->{toid}->{flowingId}", cache, 15000);
|
bool added = relayCaching.TryAdd($"{fromid}->{toid}->{flowingId}", cache, 15000);
|
||||||
if (added == false) return 0;
|
if (added == false) return 0;
|
||||||
@@ -81,7 +82,7 @@ namespace linker.messenger.relay.server
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if(LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||||
{
|
{
|
||||||
LoggerHelper.Instance.Error(ex);
|
LoggerHelper.Instance.Error(ex);
|
||||||
}
|
}
|
||||||
|
@@ -256,6 +256,8 @@ namespace linker.messenger.relay.server
|
|||||||
public string ToId { get; set; }
|
public string ToId { get; set; }
|
||||||
public string ToName { get; set; }
|
public string ToName { get; set; }
|
||||||
public string GroupId { get; set; }
|
public string GroupId { get; set; }
|
||||||
|
|
||||||
|
public List<RelayServerCdkeyInfo> Cdkey { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class RelayWrapInfo
|
public sealed class RelayWrapInfo
|
||||||
|
@@ -25,7 +25,7 @@ namespace linker.messenger.serializer.memorypack
|
|||||||
MemoryPackFormatterProvider.Register(new SignInResponseInfoFormatter());
|
MemoryPackFormatterProvider.Register(new SignInResponseInfoFormatter());
|
||||||
MemoryPackFormatterProvider.Register(new SignInConfigSetNameInfoFormatter());
|
MemoryPackFormatterProvider.Register(new SignInConfigSetNameInfoFormatter());
|
||||||
MemoryPackFormatterProvider.Register(new SignInNamesResponseItemInfoFormatter());
|
MemoryPackFormatterProvider.Register(new SignInNamesResponseItemInfoFormatter());
|
||||||
|
|
||||||
|
|
||||||
MemoryPackFormatterProvider.Register(new SyncInfoFormatter());
|
MemoryPackFormatterProvider.Register(new SyncInfoFormatter());
|
||||||
|
|
||||||
@@ -55,6 +55,12 @@ namespace linker.messenger.serializer.memorypack
|
|||||||
MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter());
|
MemoryPackFormatterProvider.Register(new RelayAskResultInfoFormatter());
|
||||||
MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter());
|
MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter());
|
||||||
MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter());
|
MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter());
|
||||||
|
MemoryPackFormatterProvider.Register(new RelayServerCdkeyInfoFormatter());
|
||||||
|
MemoryPackFormatterProvider.Register(new RelayServerCdkeyPageRequestInfoFormatter());
|
||||||
|
MemoryPackFormatterProvider.Register(new RelayServerCdkeyPageResultInfoFormatter());
|
||||||
|
MemoryPackFormatterProvider.Register(new RelayServerCdkeyAddInfoFormatter());
|
||||||
|
MemoryPackFormatterProvider.Register(new RelayServerCdkeyDelInfoFormatter());
|
||||||
|
|
||||||
|
|
||||||
MemoryPackFormatterProvider.Register(new AccessUpdateInfoFormatter());
|
MemoryPackFormatterProvider.Register(new AccessUpdateInfoFormatter());
|
||||||
MemoryPackFormatterProvider.Register(new AccessInfoFormatter());
|
MemoryPackFormatterProvider.Register(new AccessInfoFormatter());
|
||||||
@@ -83,7 +89,7 @@ namespace linker.messenger.serializer.memorypack
|
|||||||
|
|
||||||
MemoryPackFormatterProvider.Register(new FlowItemInfoFormatter());
|
MemoryPackFormatterProvider.Register(new FlowItemInfoFormatter());
|
||||||
MemoryPackFormatterProvider.Register(new FlowReportNetInfoFormatter());
|
MemoryPackFormatterProvider.Register(new FlowReportNetInfoFormatter());
|
||||||
|
|
||||||
MemoryPackFormatterProvider.Register(new FlowInfoFormatter());
|
MemoryPackFormatterProvider.Register(new FlowInfoFormatter());
|
||||||
MemoryPackFormatterProvider.Register(new RelayFlowItemInfoFormatter());
|
MemoryPackFormatterProvider.Register(new RelayFlowItemInfoFormatter());
|
||||||
MemoryPackFormatterProvider.Register(new RelayFlowRequestInfoFormatter());
|
MemoryPackFormatterProvider.Register(new RelayFlowRequestInfoFormatter());
|
||||||
|
@@ -58,7 +58,7 @@ namespace linker.messenger.serializer.memorypack
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[MemoryPackable]
|
[MemoryPackable]
|
||||||
public readonly partial struct SerializableRelayInfo
|
public readonly partial struct SerializableRelayInfo
|
||||||
@@ -89,11 +89,14 @@ namespace linker.messenger.serializer.memorypack
|
|||||||
[MemoryPackInclude]
|
[MemoryPackInclude]
|
||||||
bool SSL => info.SSL;
|
bool SSL => info.SSL;
|
||||||
|
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string UserId => info.UserId;
|
||||||
|
|
||||||
[MemoryPackConstructor]
|
[MemoryPackConstructor]
|
||||||
SerializableRelayInfo(string fromMachineId, string fromMachineName,
|
SerializableRelayInfo(string fromMachineId, string fromMachineName,
|
||||||
string remoteMachineId, string remoteMachineName,
|
string remoteMachineId, string remoteMachineName,
|
||||||
string transactionId, string secretKey, string transportName, ulong flowingId,
|
string transactionId, string secretKey, string transportName, ulong flowingId,
|
||||||
string nodeId, IPEndPoint server, bool ssl)
|
string nodeId, IPEndPoint server, bool ssl, string userid)
|
||||||
{
|
{
|
||||||
var info = new RelayInfo
|
var info = new RelayInfo
|
||||||
{
|
{
|
||||||
@@ -107,7 +110,8 @@ namespace linker.messenger.serializer.memorypack
|
|||||||
TransactionId = transactionId,
|
TransactionId = transactionId,
|
||||||
TransportName = transportName,
|
TransportName = transportName,
|
||||||
SecretKey = secretKey,
|
SecretKey = secretKey,
|
||||||
Server = server
|
Server = server,
|
||||||
|
UserId = userid
|
||||||
};
|
};
|
||||||
this.info = info;
|
this.info = info;
|
||||||
}
|
}
|
||||||
@@ -295,7 +299,6 @@ namespace linker.messenger.serializer.memorypack
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[MemoryPackable]
|
[MemoryPackable]
|
||||||
public readonly partial struct SerializableRelayCacheInfo
|
public readonly partial struct SerializableRelayCacheInfo
|
||||||
{
|
{
|
||||||
@@ -315,8 +318,11 @@ namespace linker.messenger.serializer.memorypack
|
|||||||
[MemoryPackInclude]
|
[MemoryPackInclude]
|
||||||
string GroupId => info.GroupId;
|
string GroupId => info.GroupId;
|
||||||
|
|
||||||
|
[MemoryPackInclude, MemoryPackAllowSerialize]
|
||||||
|
List<RelayServerCdkeyInfo> Cdkey => info.Cdkey;
|
||||||
|
|
||||||
[MemoryPackConstructor]
|
[MemoryPackConstructor]
|
||||||
SerializableRelayCacheInfo(ulong flowId, string fromId, string fromName, string toId, string toName, string groupId)
|
SerializableRelayCacheInfo(ulong flowId, string fromId, string fromName, string toId, string toName, string groupId, List<RelayServerCdkeyInfo> cdkey)
|
||||||
{
|
{
|
||||||
var info = new RelayCacheInfo
|
var info = new RelayCacheInfo
|
||||||
{
|
{
|
||||||
@@ -326,6 +332,7 @@ namespace linker.messenger.serializer.memorypack
|
|||||||
GroupId = groupId,
|
GroupId = groupId,
|
||||||
ToId = toId,
|
ToId = toId,
|
||||||
ToName = toName,
|
ToName = toName,
|
||||||
|
Cdkey = cdkey
|
||||||
};
|
};
|
||||||
this.info = info;
|
this.info = info;
|
||||||
}
|
}
|
||||||
@@ -427,4 +434,340 @@ namespace linker.messenger.serializer.memorypack
|
|||||||
value = wrapped.info;
|
value = wrapped.info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[MemoryPackable]
|
||||||
|
public readonly partial struct SerializableRelayServerCdkeyInfo
|
||||||
|
{
|
||||||
|
[MemoryPackIgnore]
|
||||||
|
public readonly RelayServerCdkeyInfo info;
|
||||||
|
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string Id => info.Id;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string UserId => info.UserId;
|
||||||
|
|
||||||
|
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string CdKey => info.CdKey;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
DateTime AddTime => info.AddTime;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
DateTime StartTime => info.StartTime;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
DateTime EndTime => info.EndTime;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
List<string> Nodes => info.Nodes;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
double Bandwidth => info.Bandwidth;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
ulong MaxBytes => info.MaxBytes;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
ulong LastBytes => info.LastBytes;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
double Memory => info.Memory;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
double PayMemory => info.PayMemory;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string Remark => info.Remark;
|
||||||
|
|
||||||
|
[MemoryPackConstructor]
|
||||||
|
SerializableRelayServerCdkeyInfo(string id, string userid, string cdKey, DateTime addTime, DateTime startTime, DateTime endTime,
|
||||||
|
List<string> nodes, double bandwidth, ulong maxBytes, ulong lastBytes, double memory, double payMemory, string remark)
|
||||||
|
{
|
||||||
|
var info = new RelayServerCdkeyInfo
|
||||||
|
{
|
||||||
|
Id = id,
|
||||||
|
UserId = userid,
|
||||||
|
CdKey = cdKey,
|
||||||
|
AddTime = addTime,
|
||||||
|
StartTime = startTime,
|
||||||
|
EndTime = endTime,
|
||||||
|
Nodes = nodes,
|
||||||
|
Bandwidth = bandwidth,
|
||||||
|
MaxBytes = maxBytes,
|
||||||
|
LastBytes = lastBytes,
|
||||||
|
Memory = memory,
|
||||||
|
PayMemory = payMemory,
|
||||||
|
Remark = remark
|
||||||
|
};
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SerializableRelayServerCdkeyInfo(RelayServerCdkeyInfo info)
|
||||||
|
{
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class RelayServerCdkeyInfoFormatter : MemoryPackFormatter<RelayServerCdkeyInfo>
|
||||||
|
{
|
||||||
|
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerCdkeyInfo value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNullObjectHeader();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WritePackable(new SerializableRelayServerCdkeyInfo(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerCdkeyInfo value)
|
||||||
|
{
|
||||||
|
if (reader.PeekIsNull())
|
||||||
|
{
|
||||||
|
reader.Advance(1); // skip null block
|
||||||
|
value = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapped = reader.ReadPackable<SerializableRelayServerCdkeyInfo>();
|
||||||
|
value = wrapped.info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[MemoryPackable]
|
||||||
|
public readonly partial struct SerializableRelayServerCdkeyAddInfo
|
||||||
|
{
|
||||||
|
[MemoryPackIgnore]
|
||||||
|
public readonly RelayServerCdkeyAddInfo info;
|
||||||
|
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string SecretKey => info.SecretKey;
|
||||||
|
[MemoryPackInclude, MemoryPackAllowSerialize]
|
||||||
|
RelayServerCdkeyInfo Data => info.Data;
|
||||||
|
|
||||||
|
[MemoryPackConstructor]
|
||||||
|
SerializableRelayServerCdkeyAddInfo(string secretKey, RelayServerCdkeyInfo data)
|
||||||
|
{
|
||||||
|
var info = new RelayServerCdkeyAddInfo
|
||||||
|
{
|
||||||
|
SecretKey = secretKey,
|
||||||
|
Data = data
|
||||||
|
};
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SerializableRelayServerCdkeyAddInfo(RelayServerCdkeyAddInfo info)
|
||||||
|
{
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class RelayServerCdkeyAddInfoFormatter : MemoryPackFormatter<RelayServerCdkeyAddInfo>
|
||||||
|
{
|
||||||
|
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerCdkeyAddInfo value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNullObjectHeader();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WritePackable(new SerializableRelayServerCdkeyAddInfo(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerCdkeyAddInfo value)
|
||||||
|
{
|
||||||
|
if (reader.PeekIsNull())
|
||||||
|
{
|
||||||
|
reader.Advance(1); // skip null block
|
||||||
|
value = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapped = reader.ReadPackable<SerializableRelayServerCdkeyAddInfo>();
|
||||||
|
value = wrapped.info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[MemoryPackable]
|
||||||
|
public readonly partial struct SerializableRelayServerCdkeyDelInfo
|
||||||
|
{
|
||||||
|
[MemoryPackIgnore]
|
||||||
|
public readonly RelayServerCdkeyDelInfo info;
|
||||||
|
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string SecretKey => info.SecretKey;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string Id => info.Id;
|
||||||
|
|
||||||
|
[MemoryPackConstructor]
|
||||||
|
SerializableRelayServerCdkeyDelInfo(string secretKey, string id)
|
||||||
|
{
|
||||||
|
var info = new RelayServerCdkeyDelInfo
|
||||||
|
{
|
||||||
|
SecretKey = secretKey,
|
||||||
|
Id = id
|
||||||
|
};
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SerializableRelayServerCdkeyDelInfo(RelayServerCdkeyDelInfo info)
|
||||||
|
{
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class RelayServerCdkeyDelInfoFormatter : MemoryPackFormatter<RelayServerCdkeyDelInfo>
|
||||||
|
{
|
||||||
|
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerCdkeyDelInfo value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNullObjectHeader();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WritePackable(new SerializableRelayServerCdkeyDelInfo(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerCdkeyDelInfo value)
|
||||||
|
{
|
||||||
|
if (reader.PeekIsNull())
|
||||||
|
{
|
||||||
|
reader.Advance(1); // skip null block
|
||||||
|
value = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapped = reader.ReadPackable<SerializableRelayServerCdkeyDelInfo>();
|
||||||
|
value = wrapped.info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[MemoryPackable]
|
||||||
|
public readonly partial struct SerializableRelayServerCdkeyPageRequestInfo
|
||||||
|
{
|
||||||
|
[MemoryPackIgnore]
|
||||||
|
public readonly RelayServerCdkeyPageRequestInfo info;
|
||||||
|
|
||||||
|
[MemoryPackInclude]
|
||||||
|
int Page => info.Page;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
int Size => info.Size;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string Order => info.Order;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string Sort => info.Sort;
|
||||||
|
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string UserId => info.UserId;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string Remark => info.Remark;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
string SecretKey => info.SecretKey;
|
||||||
|
|
||||||
|
[MemoryPackConstructor]
|
||||||
|
SerializableRelayServerCdkeyPageRequestInfo(int page, int size, string order, string sort, string userid, string remark, string secretKey)
|
||||||
|
{
|
||||||
|
var info = new RelayServerCdkeyPageRequestInfo
|
||||||
|
{
|
||||||
|
Sort = sort,
|
||||||
|
Order = order,
|
||||||
|
Size = size,
|
||||||
|
Page = page,
|
||||||
|
UserId = userid,
|
||||||
|
Remark = remark,
|
||||||
|
SecretKey = secretKey
|
||||||
|
};
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SerializableRelayServerCdkeyPageRequestInfo(RelayServerCdkeyPageRequestInfo info)
|
||||||
|
{
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class RelayServerCdkeyPageRequestInfoFormatter : MemoryPackFormatter<RelayServerCdkeyPageRequestInfo>
|
||||||
|
{
|
||||||
|
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerCdkeyPageRequestInfo value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNullObjectHeader();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WritePackable(new SerializableRelayServerCdkeyPageRequestInfo(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerCdkeyPageRequestInfo value)
|
||||||
|
{
|
||||||
|
if (reader.PeekIsNull())
|
||||||
|
{
|
||||||
|
reader.Advance(1); // skip null block
|
||||||
|
value = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapped = reader.ReadPackable<SerializableRelayServerCdkeyPageRequestInfo>();
|
||||||
|
value = wrapped.info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[MemoryPackable]
|
||||||
|
public readonly partial struct SerializableRelayServerCdkeyPageResultInfo
|
||||||
|
{
|
||||||
|
[MemoryPackIgnore]
|
||||||
|
public readonly RelayServerCdkeyPageResultInfo info;
|
||||||
|
|
||||||
|
[MemoryPackInclude]
|
||||||
|
int Page => info.Page;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
int Size => info.Size;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
int Count => info.Count;
|
||||||
|
[MemoryPackInclude]
|
||||||
|
List<RelayServerCdkeyInfo> List => info.List;
|
||||||
|
|
||||||
|
[MemoryPackConstructor]
|
||||||
|
SerializableRelayServerCdkeyPageResultInfo(int page, int size, int count, List<RelayServerCdkeyInfo> list)
|
||||||
|
{
|
||||||
|
var info = new RelayServerCdkeyPageResultInfo
|
||||||
|
{
|
||||||
|
Count = count,
|
||||||
|
List = list,
|
||||||
|
Size = size,
|
||||||
|
Page = page
|
||||||
|
};
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SerializableRelayServerCdkeyPageResultInfo(RelayServerCdkeyPageResultInfo info)
|
||||||
|
{
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class RelayServerCdkeyPageResultInfoFormatter : MemoryPackFormatter<RelayServerCdkeyPageResultInfo>
|
||||||
|
{
|
||||||
|
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerCdkeyPageResultInfo value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNullObjectHeader();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.WritePackable(new SerializableRelayServerCdkeyPageResultInfo(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerCdkeyPageResultInfo value)
|
||||||
|
{
|
||||||
|
if (reader.PeekIsNull())
|
||||||
|
{
|
||||||
|
reader.Advance(1); // skip null block
|
||||||
|
value = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrapped = reader.ReadPackable<SerializableRelayServerCdkeyPageResultInfo>();
|
||||||
|
value = wrapped.info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -42,7 +42,8 @@ namespace linker.messenger.signin
|
|||||||
public string Name { get; set; } = string.Empty;
|
public string Name { get; set; } = string.Empty;
|
||||||
public string Host { get; set; } = string.Empty;
|
public string Host { get; set; } = string.Empty;
|
||||||
public string SecretKey { get; set; } = string.Empty;
|
public string SecretKey { get; set; } = string.Empty;
|
||||||
|
public string UserId { get; set; } = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class SignInConfigServerInfo
|
public sealed class SignInConfigServerInfo
|
||||||
|
@@ -45,6 +45,11 @@
|
|||||||
/// <param name="secretKey"></param>
|
/// <param name="secretKey"></param>
|
||||||
public void SetSecretKey(string secretKey);
|
public void SetSecretKey(string secretKey);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// 设置用户id
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userid"></param>
|
||||||
|
public void SetUserId(string userid);
|
||||||
|
/// <summary>
|
||||||
/// 信标服务器
|
/// 信标服务器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="host"></param>
|
/// <param name="host"></param>
|
||||||
|
@@ -59,6 +59,7 @@ namespace linker.messenger.store.file
|
|||||||
serviceCollection.AddSingleton<IRelayServerStore, RelayServerStore>();
|
serviceCollection.AddSingleton<IRelayServerStore, RelayServerStore>();
|
||||||
serviceCollection.AddSingleton<IRelayServerNodeStore, RelayServerNodeStore>();
|
serviceCollection.AddSingleton<IRelayServerNodeStore, RelayServerNodeStore>();
|
||||||
serviceCollection.AddSingleton<IRelayServerMasterStore, RelayServerMasterStore>();
|
serviceCollection.AddSingleton<IRelayServerMasterStore, RelayServerMasterStore>();
|
||||||
|
serviceCollection.AddSingleton<IRelayServerCdkeyStore, RelayServerCdkeyStore>();
|
||||||
|
|
||||||
|
|
||||||
serviceCollection.AddSingleton<ITunnelClientStore, TunnelClientStore>();
|
serviceCollection.AddSingleton<ITunnelClientStore, TunnelClientStore>();
|
||||||
@@ -66,6 +67,7 @@ namespace linker.messenger.store.file
|
|||||||
serviceCollection.AddSingleton<ISignInClientStore, SignInClientStore>();
|
serviceCollection.AddSingleton<ISignInClientStore, SignInClientStore>();
|
||||||
serviceCollection.AddSingleton<ISignInServerStore, SignInServerStore>();
|
serviceCollection.AddSingleton<ISignInServerStore, SignInServerStore>();
|
||||||
serviceCollection.AddSingleton<SignInSyncSecretKey>();
|
serviceCollection.AddSingleton<SignInSyncSecretKey>();
|
||||||
|
serviceCollection.AddSingleton<SignInSyncUserId>();
|
||||||
serviceCollection.AddSingleton<SignInSyncServer>();
|
serviceCollection.AddSingleton<SignInSyncServer>();
|
||||||
|
|
||||||
serviceCollection.AddSingleton<SignInSyncGroupSecretKey>();
|
serviceCollection.AddSingleton<SignInSyncGroupSecretKey>();
|
||||||
@@ -107,6 +109,7 @@ namespace linker.messenger.store.file
|
|||||||
SyncTreansfer syncTreansfer = serviceProvider.GetService<SyncTreansfer>();
|
SyncTreansfer syncTreansfer = serviceProvider.GetService<SyncTreansfer>();
|
||||||
syncTreansfer.AddSyncs(new List<ISync> {
|
syncTreansfer.AddSyncs(new List<ISync> {
|
||||||
serviceProvider.GetService<SignInSyncSecretKey>(),
|
serviceProvider.GetService<SignInSyncSecretKey>(),
|
||||||
|
serviceProvider.GetService<SignInSyncUserId>(),
|
||||||
serviceProvider.GetService<SignInSyncGroupSecretKey>(),
|
serviceProvider.GetService<SignInSyncGroupSecretKey>(),
|
||||||
serviceProvider.GetService<SignInSyncServer>(),
|
serviceProvider.GetService<SignInSyncServer>(),
|
||||||
|
|
||||||
|
@@ -0,0 +1,65 @@
|
|||||||
|
using linker.messenger.relay.server;
|
||||||
|
using LiteDB;
|
||||||
|
|
||||||
|
namespace linker.messenger.store.file.relay
|
||||||
|
{
|
||||||
|
public sealed class RelayServerCdkeyStore : IRelayServerCdkeyStore
|
||||||
|
{
|
||||||
|
private readonly Storefactory dBfactory;
|
||||||
|
private readonly ILiteCollection<RelayServerCdkeyInfo> liteCollection;
|
||||||
|
public RelayServerCdkeyStore(Storefactory dBfactory, FileConfig fileConfig)
|
||||||
|
{
|
||||||
|
this.dBfactory = dBfactory;
|
||||||
|
liteCollection = dBfactory.GetCollection<RelayServerCdkeyInfo>("relayCdkey");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> Add(RelayServerCdkeyInfo info)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(info.Id))
|
||||||
|
{
|
||||||
|
info.Id = ObjectId.NewObjectId().ToString();
|
||||||
|
liteCollection.Insert(info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
liteCollection.Update(info);
|
||||||
|
}
|
||||||
|
return await Task.FromResult(true);
|
||||||
|
}
|
||||||
|
public async Task<bool> Del(string id)
|
||||||
|
{
|
||||||
|
return await Task.FromResult(liteCollection.Delete(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<RelayServerCdkeyInfo>> Get(string userid)
|
||||||
|
{
|
||||||
|
return await Task.FromResult(liteCollection.Find(x => x.UserId == userid && x.LastBytes > 0 && x.StartTime <= DateTime.Now && x.EndTime < DateTime.Now).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RelayServerCdkeyPageResultInfo> Get(RelayServerCdkeyPageRequestInfo relayServerCdkeyPageRequestInfo)
|
||||||
|
{
|
||||||
|
ILiteQueryable<RelayServerCdkeyInfo> query = liteCollection.Query();
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(relayServerCdkeyPageRequestInfo.Order) == false)
|
||||||
|
{
|
||||||
|
query = query.OrderBy(relayServerCdkeyPageRequestInfo.Order, relayServerCdkeyPageRequestInfo.Sort == "asc" ? Query.Ascending : Query.Descending);
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(relayServerCdkeyPageRequestInfo.UserId) == false)
|
||||||
|
{
|
||||||
|
query = query.Where(x => x.UserId == relayServerCdkeyPageRequestInfo.UserId);
|
||||||
|
}
|
||||||
|
if (string.IsNullOrWhiteSpace(relayServerCdkeyPageRequestInfo.Remark) == false)
|
||||||
|
{
|
||||||
|
query = query.Where(x => x.Remark.Contains(relayServerCdkeyPageRequestInfo.Remark));
|
||||||
|
}
|
||||||
|
|
||||||
|
return await Task.FromResult(new RelayServerCdkeyPageResultInfo
|
||||||
|
{
|
||||||
|
Page = relayServerCdkeyPageRequestInfo.Page,
|
||||||
|
Size = relayServerCdkeyPageRequestInfo.Size,
|
||||||
|
Count = query.Count(),
|
||||||
|
List = query.Skip((relayServerCdkeyPageRequestInfo.Page - 1) * relayServerCdkeyPageRequestInfo.Size).Limit(relayServerCdkeyPageRequestInfo.Size).ToList()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -43,6 +43,11 @@ namespace linker.messenger.store.file.signIn
|
|||||||
Server.SecretKey = secretKey;
|
Server.SecretKey = secretKey;
|
||||||
config.Data.Update();
|
config.Data.Update();
|
||||||
}
|
}
|
||||||
|
public void SetUserId(string userid)
|
||||||
|
{
|
||||||
|
Server.UserId = userid;
|
||||||
|
config.Data.Update();
|
||||||
|
}
|
||||||
public void SetHost(string host)
|
public void SetHost(string host)
|
||||||
{
|
{
|
||||||
Server.Host = host;
|
Server.Host = host;
|
||||||
|
@@ -46,6 +46,27 @@ namespace linker.messenger.store.file.signIn
|
|||||||
signInClientStore.SetSecretKey(serializer.Deserialize<string>(data.Span));
|
signInClientStore.SetSecretKey(serializer.Deserialize<string>(data.Span));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public sealed class SignInSyncUserId : ISync
|
||||||
|
{
|
||||||
|
public string Name => "SignInUserId";
|
||||||
|
|
||||||
|
private readonly ISignInClientStore signInClientStore;
|
||||||
|
private readonly ISerializer serializer;
|
||||||
|
public SignInSyncUserId(ISignInClientStore signInClientStore, ISerializer serializer)
|
||||||
|
{
|
||||||
|
this.signInClientStore = signInClientStore;
|
||||||
|
this.serializer = serializer;
|
||||||
|
}
|
||||||
|
public Memory<byte> GetData()
|
||||||
|
{
|
||||||
|
return serializer.Serialize(signInClientStore.Server.UserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetData(Memory<byte> data)
|
||||||
|
{
|
||||||
|
signInClientStore.SetUserId(serializer.Deserialize<string>(data.Span));
|
||||||
|
}
|
||||||
|
}
|
||||||
public sealed class SignInSyncGroupSecretKey : ISync
|
public sealed class SignInSyncGroupSecretKey : ISync
|
||||||
{
|
{
|
||||||
public string Name => "GroupSecretKey";
|
public string Name => "GroupSecretKey";
|
||||||
|
@@ -35,10 +35,13 @@ namespace linker.messenger.tunnel
|
|||||||
{
|
{
|
||||||
LoggerHelper.Instance.Info($"tunnel route level getting.");
|
LoggerHelper.Instance.Info($"tunnel route level getting.");
|
||||||
Info.RouteLevel = NetworkHelper.GetRouteLevel(signInClientStore.Server.Host, out List<IPAddress> ips);
|
Info.RouteLevel = NetworkHelper.GetRouteLevel(signInClientStore.Server.Host, out List<IPAddress> ips);
|
||||||
Info.RouteIPs = ips.ToArray();
|
|
||||||
Info.LocalIPs = NetworkHelper.GetIPV6().Concat(NetworkHelper.GetIPV4()).ToArray();
|
|
||||||
LoggerHelper.Instance.Warning($"route ips:{string.Join(",", ips.Select(c => c.ToString()))}");
|
LoggerHelper.Instance.Warning($"route ips:{string.Join(",", ips.Select(c => c.ToString()))}");
|
||||||
LoggerHelper.Instance.Warning($"tunnel local ips :{string.Join(",", Info.LocalIPs.Select(c => c.ToString()))}");
|
Info.RouteIPs = ips.ToArray();
|
||||||
|
var ipv6 = NetworkHelper.GetIPV6();
|
||||||
|
LoggerHelper.Instance.Warning($"tunnel local ip6 :{string.Join(",", ipv6.Select(c => c.ToString()))}");
|
||||||
|
var ipv4 = NetworkHelper.GetIPV4();
|
||||||
|
LoggerHelper.Instance.Warning($"tunnel local ip4 :{string.Join(",", ipv4.Select(c => c.ToString()))}");
|
||||||
|
Info.LocalIPs = ipv6.Concat(ipv4).ToArray();
|
||||||
LoggerHelper.Instance.Warning($"tunnel route level:{Info.RouteLevel}");
|
LoggerHelper.Instance.Warning($"tunnel route level:{Info.RouteLevel}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -22,6 +22,8 @@ namespace linker.tun
|
|||||||
private IPAddress address;
|
private IPAddress address;
|
||||||
private byte prefixLength = 24;
|
private byte prefixLength = 24;
|
||||||
|
|
||||||
|
private string defaultInterfaceName = string.Empty;
|
||||||
|
|
||||||
private CancellationTokenSource tokenSource;
|
private CancellationTokenSource tokenSource;
|
||||||
|
|
||||||
public LinkerWinTunDevice()
|
public LinkerWinTunDevice()
|
||||||
@@ -67,6 +69,7 @@ namespace linker.tun
|
|||||||
AddIPV6();
|
AddIPV6();
|
||||||
|
|
||||||
GetWindowsInterfaceNum();
|
GetWindowsInterfaceNum();
|
||||||
|
GetDefaultInterface();
|
||||||
tokenSource = new CancellationTokenSource();
|
tokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -115,7 +118,6 @@ namespace linker.tun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Shutdown()
|
public void Shutdown()
|
||||||
{
|
{
|
||||||
tokenSource?.Cancel();
|
tokenSource?.Cancel();
|
||||||
@@ -137,7 +139,6 @@ namespace linker.tun
|
|||||||
interfaceNumber = 0;
|
interfaceNumber = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void SetMtu(int value)
|
public void SetMtu(int value)
|
||||||
{
|
{
|
||||||
CommandHelper.Windows(string.Empty, new string[] {
|
CommandHelper.Windows(string.Empty, new string[] {
|
||||||
@@ -157,20 +158,18 @@ namespace linker.tun
|
|||||||
|
|
||||||
IPAddress network = NetworkHelper.ToNetworkIP(this.address, NetworkHelper.ToPrefixValue(prefixLength));
|
IPAddress network = NetworkHelper.ToNetworkIP(this.address, NetworkHelper.ToPrefixValue(prefixLength));
|
||||||
CommandHelper.PowerShell($"New-NetNat -Name {Name} -InternalIPInterfaceAddressPrefix {network}/{prefixLength}", [], out error);
|
CommandHelper.PowerShell($"New-NetNat -Name {Name} -InternalIPInterfaceAddressPrefix {network}/{prefixLength}", [], out error);
|
||||||
|
if (string.IsNullOrWhiteSpace(error))
|
||||||
if (string.IsNullOrWhiteSpace(error) == false)
|
|
||||||
{
|
{
|
||||||
error = "NetNat Not Supported";
|
return;
|
||||||
string result = CommandHelper.Windows(string.Empty, ["netsh routing"]);
|
|
||||||
if (result.Contains("netsh routing ip"))
|
|
||||||
{
|
|
||||||
error = string.Empty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
error += ",RRAS Not Supported";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandHelper.Windows(string.Empty, [$"net start SharedAccess"]);
|
||||||
|
string result = CommandHelper.Windows(string.Empty, [$"linker.ics.exe {defaultInterfaceName} {Name} enable"]);
|
||||||
|
if (result.Contains($"enable success"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
error = "NetNat and ICS not supported";
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -186,6 +185,7 @@ namespace linker.tun
|
|||||||
{
|
{
|
||||||
CommandHelper.PowerShell($"start-service WinNat", [], out error);
|
CommandHelper.PowerShell($"start-service WinNat", [], out error);
|
||||||
CommandHelper.PowerShell($"Remove-NetNat -Name {Name} -Confirm:$false", [], out error);
|
CommandHelper.PowerShell($"Remove-NetNat -Name {Name} -Confirm:$false", [], out error);
|
||||||
|
CommandHelper.Windows(string.Empty, [$"linker.ics.exe {Name} disable"]);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -327,6 +327,33 @@ namespace linker.tun
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
private void GetDefaultInterface()
|
||||||
|
{
|
||||||
|
string[] lines = CommandHelper.Windows(string.Empty, new string[] { $"route print" }).Split(Environment.NewLine);
|
||||||
|
foreach (var item in lines)
|
||||||
|
{
|
||||||
|
if (item.Trim().StartsWith("0.0.0.0"))
|
||||||
|
{
|
||||||
|
string[] arr = Regex.Replace(item.Trim(), @"\s+", " ").Split(' ');
|
||||||
|
IPAddress ip = IPAddress.Parse(arr[arr.Length - 2]);
|
||||||
|
|
||||||
|
foreach (var inter in NetworkInterface.GetAllNetworkInterfaces())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (ip.Equals(inter.GetIPProperties().UnicastAddresses.FirstOrDefault(c => c.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).Address))
|
||||||
|
{
|
||||||
|
defaultInterfaceName = inter.Name;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ClearRegistry()
|
private void ClearRegistry()
|
||||||
{
|
{
|
||||||
|
@@ -8,4 +8,7 @@ export const setRelaySubscribe = () => {
|
|||||||
}
|
}
|
||||||
export const relayConnect = (data) => {
|
export const relayConnect = (data) => {
|
||||||
return sendWebsocketMsg('relay/Connect', data);
|
return sendWebsocketMsg('relay/Connect', data);
|
||||||
|
}
|
||||||
|
export const relayCdkeyAccess = () => {
|
||||||
|
return sendWebsocketMsg('relay/AccessCdkey');
|
||||||
}
|
}
|
@@ -119,18 +119,34 @@ a.a-line {
|
|||||||
padding-right: 1rem;
|
padding-right: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.m-r-1 {
|
.mgr-1 {
|
||||||
margin-right: 1rem;
|
margin-right: 1rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.m-l-1 {
|
.mgl-1 {
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.m-b-0 {
|
.mgl-2 {
|
||||||
|
margin-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mgl-3 {
|
||||||
|
margin-left: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mgb-0 {
|
||||||
margin-bottom: 0 !important;
|
margin-bottom: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mgb-3 {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mgt-3 {
|
||||||
|
margin-top: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
@@ -174,6 +190,10 @@ span.split-pad10 {
|
|||||||
color: #e68906 !important;
|
color: #e68906 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.disable {
|
||||||
|
color: #ddd !important;
|
||||||
|
}
|
||||||
|
|
||||||
.gateway {
|
.gateway {
|
||||||
&.green {
|
&.green {
|
||||||
/* background: linear-gradient(270deg, #caff00, green, #0d6d23, #e38a00, green); */
|
/* background: linear-gradient(270deg, #caff00, green, #0d6d23, #e38a00, green); */
|
||||||
|
@@ -7,6 +7,7 @@ export default {
|
|||||||
'common.operating': 'In operation',
|
'common.operating': 'In operation',
|
||||||
'common.tips': 'Tips',
|
'common.tips': 'Tips',
|
||||||
'common.option': 'Option',
|
'common.option': 'Option',
|
||||||
|
'common.access': 'No access',
|
||||||
|
|
||||||
'head.home': 'Home',
|
'head.home': 'Home',
|
||||||
'head.server': 'Server',
|
'head.server': 'Server',
|
||||||
@@ -36,6 +37,8 @@ export default {
|
|||||||
'server.messengerText': 'ip:port or domain:port',
|
'server.messengerText': 'ip:port or domain:port',
|
||||||
'server.messengerSecretKey': 'Messenger SecretKey',
|
'server.messengerSecretKey': 'Messenger SecretKey',
|
||||||
'server.messengerSecretKeyText': 'Messenger SecretKey',
|
'server.messengerSecretKeyText': 'Messenger SecretKey',
|
||||||
|
'server.messengerUserId': 'User Id',
|
||||||
|
'server.messengerUserIdText': 'Your unique identifier,for card key (CDKEY).',
|
||||||
|
|
||||||
'permission.closed': 'Closed',
|
'permission.closed': 'Closed',
|
||||||
'permission.simple': 'Simple',
|
'permission.simple': 'Simple',
|
||||||
@@ -120,6 +123,8 @@ export default {
|
|||||||
'server.relayPublic': 'Public',
|
'server.relayPublic': 'Public',
|
||||||
'server.relayOper': 'Oper',
|
'server.relayOper': 'Oper',
|
||||||
'server.relayUse': 'Use',
|
'server.relayUse': 'Use',
|
||||||
|
'server.relayMyCdkey': 'My CDKEY',
|
||||||
|
'server.relayCdkey': 'Manager CDKEY',
|
||||||
|
|
||||||
'server.sforwardSecretKey': 'Server forward secretKey',
|
'server.sforwardSecretKey': 'Server forward secretKey',
|
||||||
'server.sforwardText': 'The server forward can be used when the key is correct',
|
'server.sforwardText': 'The server forward can be used when the key is correct',
|
||||||
@@ -148,5 +153,7 @@ export default {
|
|||||||
'server.asyncRelaySecretKey': 'Relay secretKey',
|
'server.asyncRelaySecretKey': 'Relay secretKey',
|
||||||
'server.asyncSForwardSecretKey': 'Server forward secretKey',
|
'server.asyncSForwardSecretKey': 'Server forward secretKey',
|
||||||
'server.asyncUpdaterSecretKey': 'Update secretKey',
|
'server.asyncUpdaterSecretKey': 'Update secretKey',
|
||||||
'server.asyncTunnelTransports': 'Tunnel transports'
|
'server.asyncTunnelTransports': 'Tunnel transports',
|
||||||
|
'server.asyncSignInUserId': 'User Id',
|
||||||
|
|
||||||
}
|
}
|
@@ -7,6 +7,7 @@ export default {
|
|||||||
'common.operating': '正在操作',
|
'common.operating': '正在操作',
|
||||||
'common.tips': '提示',
|
'common.tips': '提示',
|
||||||
'common.option': '选项',
|
'common.option': '选项',
|
||||||
|
'common.access': '无权限',
|
||||||
|
|
||||||
'head.home': '首页',
|
'head.home': '首页',
|
||||||
'head.server': '服务器',
|
'head.server': '服务器',
|
||||||
@@ -35,6 +36,8 @@ export default {
|
|||||||
'server.messengerText': 'ip:端口 或者 域名:端口',
|
'server.messengerText': 'ip:端口 或者 域名:端口',
|
||||||
'server.messengerSecretKey': '信标密钥',
|
'server.messengerSecretKey': '信标密钥',
|
||||||
'server.messengerSecretKeyText': '密钥正确时可连接服务器',
|
'server.messengerSecretKeyText': '密钥正确时可连接服务器',
|
||||||
|
'server.messengerUserId': '用户id',
|
||||||
|
'server.messengerUserIdText': '你的唯一标识,用于流量卡密CDKEY',
|
||||||
|
|
||||||
'permission.closed': '禁止通行',
|
'permission.closed': '禁止通行',
|
||||||
'permission.simple': '简单管理',
|
'permission.simple': '简单管理',
|
||||||
@@ -122,6 +125,8 @@ export default {
|
|||||||
'server.relayPublic': '公开',
|
'server.relayPublic': '公开',
|
||||||
'server.relayOper': '操作',
|
'server.relayOper': '操作',
|
||||||
'server.relayUse': '使用',
|
'server.relayUse': '使用',
|
||||||
|
'server.relayMyCdkey': '我的CDKEY',
|
||||||
|
'server.relayCdkey': '管理CDKEY',
|
||||||
|
|
||||||
'server.sforwardSecretKey': '服务器穿透密钥',
|
'server.sforwardSecretKey': '服务器穿透密钥',
|
||||||
'server.sforwardText': '当密钥正确是可用',
|
'server.sforwardText': '当密钥正确是可用',
|
||||||
@@ -150,5 +155,6 @@ export default {
|
|||||||
'server.asyncRelaySecretKey': '中继密钥',
|
'server.asyncRelaySecretKey': '中继密钥',
|
||||||
'server.asyncSForwardSecretKey': '服务器穿透密钥',
|
'server.asyncSForwardSecretKey': '服务器穿透密钥',
|
||||||
'server.asyncUpdaterSecretKey': '更新密钥',
|
'server.asyncUpdaterSecretKey': '更新密钥',
|
||||||
'server.asyncTunnelTransports': '打洞协议'
|
'server.asyncTunnelTransports': '打洞协议',
|
||||||
|
'server.asyncSignInUserId': '用户唯一标识',
|
||||||
}
|
}
|
@@ -6,7 +6,7 @@
|
|||||||
接口 : <el-input v-model="state.api" style="width:70%"></el-input>
|
接口 : <el-input v-model="state.api" style="width:70%"></el-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="pdt-10">
|
<div class="pdt-10">
|
||||||
秘钥 : <el-input type="password" v-model="state.psd" style="width:70%"></el-input>
|
秘钥 : <el-input show-password type="password" v-model="state.psd" style="width:70%"></el-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="pdt-10">
|
<div class="pdt-10">
|
||||||
<el-checkbox v-model="state.save" >保存密码</el-checkbox>
|
<el-checkbox v-model="state.save" >保存密码</el-checkbox>
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
<el-checkbox v-model="state.ruleForm.Multicast" label="禁用广播" size="large" />
|
<el-checkbox v-model="state.ruleForm.Multicast" label="禁用广播" size="large" />
|
||||||
<el-checkbox v-model="state.ruleForm.Nat" label="禁用NAT" size="large" />
|
<el-checkbox v-model="state.ruleForm.Nat" label="禁用NAT" size="large" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="upgrade" class="m-b-0">
|
<el-form-item prop="upgrade" class="mgb-0">
|
||||||
<el-checkbox v-model="state.ruleForm.Upgrade" label="我很懂,我要使用高级功能(点对网和网对网)" size="large" />
|
<el-checkbox v-model="state.ruleForm.Upgrade" label="我很懂,我要使用高级功能(点对网和网对网)" size="large" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<div class="upgrade-wrap" v-if="state.ruleForm.Upgrade">
|
<div class="upgrade-wrap" v-if="state.ruleForm.Upgrade">
|
||||||
|
@@ -34,13 +34,13 @@
|
|||||||
<div>
|
<div>
|
||||||
<template v-for="(item1,index) in tuntap.list[item.MachineId].Lans" :key="index">
|
<template v-for="(item1,index) in tuntap.list[item.MachineId].Lans" :key="index">
|
||||||
<template v-if="item1.Disabled">
|
<template v-if="item1.Disabled">
|
||||||
<div class="flex yellow" title="已禁用">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
<div class="flex disable" title="已禁用">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item1.Exists">
|
<template v-else-if="item1.Exists">
|
||||||
<div class="flex yellow" title="与其它设备填写IP、或本机局域网IP有冲突">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
<div class="flex yellow" title="与其它设备填写IP、或本机局域网IP有冲突">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="flex" title="正常使用" :class="{green:tuntap.list[item.MachineId].running}">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
<div class="flex green" title="正常使用">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -32,6 +32,11 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="Oper" :label="$t('server.groupOper')" width="160">
|
<el-table-column prop="Oper" :label="$t('server.groupOper')" width="160">
|
||||||
|
<template #header>
|
||||||
|
<div class="flex">
|
||||||
|
<strong>{{ $t('server.groupOper') }}</strong><span class="flex-1"></span><Sync name="GroupSecretKey"></Sync>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div>
|
<div>
|
||||||
<el-popconfirm :title="$t('server.groupDelConfirm')" @confirm="handleDel(scope.$index)">
|
<el-popconfirm :title="$t('server.groupDelConfirm')" @confirm="handleDel(scope.$index)">
|
||||||
@@ -60,8 +65,9 @@ import { ElMessage } from 'element-plus';
|
|||||||
import { computed, reactive, watch } from 'vue'
|
import { computed, reactive, watch } from 'vue'
|
||||||
import { Delete,Plus,Select } from '@element-plus/icons-vue';
|
import { Delete,Plus,Select } from '@element-plus/icons-vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import Sync from '../sync/Index.vue'
|
||||||
export default {
|
export default {
|
||||||
components:{Delete,Plus,Select },
|
components:{Delete,Plus,Select,Sync },
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const {t} = useI18n();
|
const {t} = useI18n();
|
||||||
const globalData = injectGlobalData();
|
const globalData = injectGlobalData();
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
<div class="inner">
|
<div class="inner">
|
||||||
<div class="head flex">
|
<div class="head flex">
|
||||||
<div>
|
<div>
|
||||||
<el-select v-model="state.type" @change="loadData" size="small" class="m-r-1" style="width: 6rem;">
|
<el-select v-model="state.type" @change="loadData" size="small" class="mgr-1" style="width: 6rem;">
|
||||||
<el-option :value="-1" label="all"></el-option>
|
<el-option :value="-1" label="all"></el-option>
|
||||||
<el-option :value="0" label="debug"></el-option>
|
<el-option :value="0" label="debug"></el-option>
|
||||||
<el-option :value="1" label="info"></el-option>
|
<el-option :value="1" label="info"></el-option>
|
||||||
|
@@ -1,88 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div :style="{ height: `${state.height}px` }">
|
|
||||||
<el-card shadow="never">
|
|
||||||
<template #header>{{ $t('server.asyncText') }}</template>
|
|
||||||
<div>
|
|
||||||
<el-checkbox v-model="state.checkAll" :indeterminate="state.isIndeterminate"
|
|
||||||
@change="handleCheckAllChange">{{
|
|
||||||
$t('server.asyncCheckAll') }}</el-checkbox>
|
|
||||||
<el-checkbox-group v-model="state.checkeds" @change="handleCheckedsChange">
|
|
||||||
<el-row>
|
|
||||||
<template v-for="name in state.names">
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-checkbox :key="name.name" :label="name.label" :value="name.name">{{ name.label
|
|
||||||
}}</el-checkbox>
|
|
||||||
</el-col>
|
|
||||||
</template>
|
|
||||||
</el-row>
|
|
||||||
</el-checkbox-group>
|
|
||||||
</div>
|
|
||||||
<template #footer>
|
|
||||||
<div class="t-c">
|
|
||||||
<el-button type="success" @click="handleSync">{{ $t('common.confirm') }}</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import { injectGlobalData } from '@/provide';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
import { computed, onMounted, reactive } from 'vue'
|
|
||||||
import { getSyncNames, setSync } from '@/apis/sync';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
export default {
|
|
||||||
setup(props) {
|
|
||||||
const { t } = useI18n();
|
|
||||||
const globalData = injectGlobalData();
|
|
||||||
const state = reactive({
|
|
||||||
names: [],
|
|
||||||
checkAll: false,
|
|
||||||
isIndeterminate: false,
|
|
||||||
checkeds: [],
|
|
||||||
height: computed(() => globalData.value.height - 90),
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleCheckAllChange = (val) => {
|
|
||||||
state.checkeds = val ? state.names.map(c => c.name) : [];
|
|
||||||
state.isIndeterminate = false
|
|
||||||
}
|
|
||||||
const handleCheckedsChange = (value) => {
|
|
||||||
const checkedCount = value.length
|
|
||||||
state.checkAll = checkedCount === state.names.length
|
|
||||||
state.isIndeterminate = checkedCount > 0 && checkedCount < state.names.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
const labels = {
|
|
||||||
'SignInServer': t('server.asyncSignInServer'),
|
|
||||||
'SignInSecretKey': t('server.asyncSignInSecretKey'),
|
|
||||||
'GroupSecretKey': t('server.asyncGroupSecretKey'),
|
|
||||||
'RelaySecretKey': t('server.asyncRelaySecretKey'),
|
|
||||||
'SForwardSecretKey': t('server.asyncSForwardSecretKey'),
|
|
||||||
'UpdaterSecretKey': t('server.asyncUpdaterSecretKey'),
|
|
||||||
'TunnelTransports': t('server.asyncTunnelTransports')
|
|
||||||
}
|
|
||||||
onMounted(() => {
|
|
||||||
getSyncNames().then(res => {
|
|
||||||
state.names = res.map(c => {
|
|
||||||
return { name: c, label: labels[c] }
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
const handleSync = () => {
|
|
||||||
if (state.checkeds.length == 0) {
|
|
||||||
ElMessage.error(t('server.asyncSelect'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setSync(state.checkeds).then(res => {
|
|
||||||
ElMessage.success(t('common.oper'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return { state, handleCheckAllChange, handleCheckedsChange, handleSync }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
|
|
||||||
</style>
|
|
@@ -1,32 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="servers-wrap" >
|
<div class="servers-wrap" >
|
||||||
<el-tabs type="border-card" style="width:100%" v-model="state.tab">
|
<SignInServers v-if="hasConfig"></SignInServers>
|
||||||
<el-tab-pane :label="$t('server.messenger')" name="signin" v-if="hasConfig">
|
|
||||||
<SignInServers></SignInServers>
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane :label="$t('server.sync')" name="async" v-if="hasSync">
|
|
||||||
<Async></Async>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { computed, reactive } from 'vue';
|
import { computed, reactive } from 'vue';
|
||||||
import { injectGlobalData } from '@/provide';
|
import { injectGlobalData } from '@/provide';
|
||||||
import SignInServers from './SignInServers.vue';
|
import SignInServers from './SignInServers.vue';
|
||||||
import Async from './Async.vue';
|
|
||||||
export default {
|
export default {
|
||||||
components:{SignInServers,Async},
|
components:{SignInServers},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
|
||||||
const globalData = injectGlobalData();
|
const globalData = injectGlobalData();
|
||||||
const hasConfig = computed(()=>globalData.value.hasAccess('Config'))
|
const hasConfig = computed(()=>globalData.value.hasAccess('Config'))
|
||||||
const hasSync = computed(()=>globalData.value.hasAccess('Sync'));
|
const state = reactive({});
|
||||||
const state = reactive({
|
|
||||||
tab:'signin'
|
|
||||||
});
|
|
||||||
return {
|
return {
|
||||||
state,hasConfig,hasSync
|
state,hasConfig
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,9 +26,4 @@ export default {
|
|||||||
color:#555;
|
color:#555;
|
||||||
a{color:#333;}
|
a{color:#333;}
|
||||||
}
|
}
|
||||||
.el-checkbox{
|
|
||||||
vertical-align:middle;
|
|
||||||
margin-right:1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
@@ -1,11 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-form-item :label="$t('server.relaySecretKey')">
|
<el-form-item :label="$t('server.relaySecretKey')">
|
||||||
<el-input type="password" show-password v-model="state.list.SecretKey" maxlength="36" @change="handleSave" />
|
<div class="flex">
|
||||||
<el-checkbox v-model="state.list.SSL" :label="$t('server.relaySSL')" size="large" @change="handleSave" />
|
<el-input class="flex-1" type="password" show-password v-model="state.list.SecretKey" maxlength="36" @change="handleSave" />
|
||||||
<el-checkbox v-model="state.list.Disabled" :label="$t('server.relayDisable')" size="large" @change="handleSave" />
|
<Sync class="mgl-1" name="RelaySecretKey"></Sync>
|
||||||
<a href="javascript:;" @click="state.show=true" class="delay a-line" :class="{red:state.nodes.length==0,green:state.nodes.length>0}">
|
<div class="mgl-1">
|
||||||
{{$t('server.relayNodes')}} : {{state.nodes.length}}
|
<el-checkbox class="mgr-1" v-model="state.list.SSL" :label="$t('server.relaySSL')" @change="handleSave" />
|
||||||
</a>
|
<el-checkbox v-model="state.list.Disabled" :label="$t('server.relayDisable')" @change="handleSave" />
|
||||||
|
</div>
|
||||||
|
<a href="javascript:;" @click="state.show=true" class="mgl-1 delay a-line" :class="{red:state.nodes.length==0,green:state.nodes.length>0}">
|
||||||
|
{{$t('server.relayNodes')}} : {{state.nodes.length}}
|
||||||
|
</a>
|
||||||
|
<Relay></Relay>
|
||||||
|
</div>
|
||||||
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-dialog v-model="state.show" :title="$t('server.relayTitle')" width="760" top="2vh">
|
<el-dialog v-model="state.show" :title="$t('server.relayTitle')" width="760" top="2vh">
|
||||||
@@ -60,7 +67,10 @@ import { injectGlobalData } from '@/provide';
|
|||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { onMounted, onUnmounted, reactive, watch } from 'vue'
|
import { onMounted, onUnmounted, reactive, watch } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import Sync from '../sync/Index.vue'
|
||||||
|
import Relay from './relay/Index.vue'
|
||||||
export default {
|
export default {
|
||||||
|
components:{Sync,Relay},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const {t} = useI18n();
|
const {t} = useI18n();
|
||||||
const globalData = injectGlobalData();
|
const globalData = injectGlobalData();
|
||||||
@@ -103,5 +113,4 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.delay{margin-left:3rem;}
|
|
||||||
</style>
|
</style>
|
@@ -2,7 +2,8 @@
|
|||||||
<el-form-item :label="$t('server.sforwardSecretKey')">
|
<el-form-item :label="$t('server.sforwardSecretKey')">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-input class="flex-1" type="password" show-password v-model="state.SForwardSecretKey" maxlength="36" @blur="handleChange" />
|
<el-input class="flex-1" type="password" show-password v-model="state.SForwardSecretKey" maxlength="36" @blur="handleChange" />
|
||||||
<span>{{$t('server.sforwardText')}}</span>
|
<Sync class="mgl-1" name="SForwardSecretKey"></Sync>
|
||||||
|
<span class="mgl-1">{{$t('server.sforwardText')}}</span>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -11,7 +12,9 @@ import { getSForwardSecretKey,setSForwardSecretKey } from '@/apis/sforward';
|
|||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import {onMounted, reactive } from 'vue'
|
import {onMounted, reactive } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import Sync from '../sync/Index.vue'
|
||||||
export default {
|
export default {
|
||||||
|
components:{Sync},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const {t} = useI18n();
|
const {t} = useI18n();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
@@ -7,16 +7,25 @@
|
|||||||
<el-form-item :label="$t('server.messengerAddr')">
|
<el-form-item :label="$t('server.messengerAddr')">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-input class="flex-1" v-model="state.list.Host" @change="handleSave" />
|
<el-input class="flex-1" v-model="state.list.Host" @change="handleSave" />
|
||||||
<span>{{$t('server.messengerText')}}</span>
|
<Sync class="mgl-1" name="SignInServer"></Sync>
|
||||||
|
<span class="mgl-1">{{$t('server.messengerText')}}</span>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('server.messengerSecretKey')">
|
<el-form-item :label="$t('server.messengerSecretKey')">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-input class="flex-1" type="password" show-password maxlength="36" v-model="state.list.SecretKey" @change="handleSave" />
|
<el-input class="flex-1" type="password" show-password maxlength="36" v-model="state.list.SecretKey" @change="handleSave" />
|
||||||
<span>{{$t('server.messengerSecretKeyText')}}</span>
|
<Sync class="mgl-1" name="SignInSecretKey"></Sync>
|
||||||
|
<span class="mgl-1">{{$t('server.messengerSecretKeyText')}}</span>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<RelayServers></RelayServers>
|
<el-form-item :label="$t('server.messengerUserId')">
|
||||||
|
<div class="flex">
|
||||||
|
<el-input class="flex-1" type="password" show-password maxlength="36" v-model="state.list.UserId" @change="handleSave" />
|
||||||
|
<Sync class="mgl-1" name="SignInUserId"></Sync>
|
||||||
|
<span class="mgl-1">{{$t('server.messengerUserIdText')}}</span>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
<RelayServers class="mgt-2"></RelayServers>
|
||||||
<SForward></SForward>
|
<SForward></SForward>
|
||||||
<Updater></Updater>
|
<Updater></Updater>
|
||||||
</el-form>
|
</el-form>
|
||||||
@@ -38,8 +47,9 @@ import SForward from './SForward.vue';
|
|||||||
import Updater from './Updater.vue';
|
import Updater from './Updater.vue';
|
||||||
import RelayServers from './RelayServers.vue';
|
import RelayServers from './RelayServers.vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import Sync from '../sync/Index.vue'
|
||||||
export default {
|
export default {
|
||||||
components:{SForward,Updater,RelayServers},
|
components:{SForward,Updater,RelayServers,Sync},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const {t} = useI18n();
|
const {t} = useI18n();
|
||||||
const globalData = injectGlobalData();
|
const globalData = injectGlobalData();
|
||||||
|
@@ -2,10 +2,11 @@
|
|||||||
<el-form-item :label="$t('server.updaterSecretKey')">
|
<el-form-item :label="$t('server.updaterSecretKey')">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<el-input class="flex-1" type="password" show-password v-model="state.secretKey" maxlength="36" @blur="handleChange"/>
|
<el-input class="flex-1" type="password" show-password v-model="state.secretKey" maxlength="36" @blur="handleChange"/>
|
||||||
<span>{{$t('server.updaterText')}}</span>
|
<Sync class="mgl-1" name="UpdaterSecretKey"></Sync>
|
||||||
|
<span class="mgl-1">{{$t('server.updaterText')}}</span>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="$t('server.updaterRate')">
|
<!-- <el-form-item :label="$t('server.updaterRate')">
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<el-input-number v-model="state.year" :min="0" :max="99" style="width:12rem" @change="handleSecChange" /> {{$t('server.updaterY') }}
|
<el-input-number v-model="state.year" :min="0" :max="99" style="width:12rem" @change="handleSecChange" /> {{$t('server.updaterY') }}
|
||||||
@@ -18,7 +19,7 @@
|
|||||||
<el-input-number v-model="state.sec" :min="0" :max="99" style="width:12rem" @change="handleSecChange"/> {{$t('server.updaterS') }}
|
<el-input-number v-model="state.sec" :min="0" :max="99" style="width:12rem" @change="handleSecChange"/> {{$t('server.updaterS') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item> -->
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getSecretKey,setSecretKey, setUpdateInterval } from '@/apis/updater';
|
import { getSecretKey,setSecretKey, setUpdateInterval } from '@/apis/updater';
|
||||||
@@ -26,7 +27,9 @@ import { injectGlobalData } from '@/provide';
|
|||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { onMounted, reactive } from 'vue'
|
import { onMounted, reactive } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import Sync from '../sync/Index.vue'
|
||||||
export default {
|
export default {
|
||||||
|
components:{Sync},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const {t} = useI18n();
|
const {t} = useI18n();
|
||||||
const globalData = injectGlobalData();
|
const globalData = injectGlobalData();
|
||||||
|
33
src/linker.web/src/views/full/server/relay/Index.vue
Normal file
33
src/linker.web/src/views/full/server/relay/Index.vue
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<a href="javascript:;" class="mgl-1 a-line">{{$t('server.relayMyCdkey')}}</a>
|
||||||
|
<a v-if="state.showManager && hasRelayCdkey" href="javascript:;" class="mgl-1 a-line">{{$t('server.relayCdkey')}}</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { relayCdkeyAccess } from '@/apis/relay';
|
||||||
|
import { injectGlobalData } from '@/provide';
|
||||||
|
import { computed, onMounted, reactive } from 'vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup () {
|
||||||
|
|
||||||
|
const globalData = injectGlobalData();
|
||||||
|
const hasRelayCdkey = computed(()=>globalData.value.hasAccess('RelayCdkey'));
|
||||||
|
const state = reactive({
|
||||||
|
showManager:false
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
relayCdkeyAccess().then(res=>{
|
||||||
|
state.showManager = res;
|
||||||
|
}).catch(()=>{})
|
||||||
|
})
|
||||||
|
|
||||||
|
return {state,hasRelayCdkey}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
</style>
|
@@ -56,7 +56,6 @@ export default {
|
|||||||
const hasExport = computed(()=>globalData.value.hasAccess('Export'));
|
const hasExport = computed(()=>globalData.value.hasAccess('Export'));
|
||||||
const onlyNode = computed(()=>globalData.value.config.Client.OnlyNode);
|
const onlyNode = computed(()=>globalData.value.config.Client.OnlyNode);
|
||||||
const machineId = computed(()=>globalData.value.config.Client.Id);
|
const machineId = computed(()=>globalData.value.config.Client.Id);
|
||||||
console.log(globalData.value.config.Client);
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
show: false,
|
show: false,
|
||||||
loading:false,
|
loading:false,
|
||||||
|
45
src/linker.web/src/views/full/sync/Index.vue
Normal file
45
src/linker.web/src/views/full/sync/Index.vue
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-button class="btn" size="small" @click="handleSync"><el-icon><Share /></el-icon></el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { setSync } from '@/apis/sync';
|
||||||
|
import { injectGlobalData } from '@/provide';
|
||||||
|
import {Share} from '@element-plus/icons-vue'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
export default {
|
||||||
|
props:['name'],
|
||||||
|
components: {Share},
|
||||||
|
setup (props) {
|
||||||
|
const { t } = useI18n();
|
||||||
|
const globalData = injectGlobalData();
|
||||||
|
const hasSync = computed(()=>globalData.value.hasAccess('Sync'));
|
||||||
|
const handleSync = ()=>{
|
||||||
|
if(!hasSync.value){
|
||||||
|
ElMessage.success(t('common.access'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ElMessageBox.confirm(`${t('server.sync')} ${t(`server.async${props.name}`)} ? `, t('common.tips'), {
|
||||||
|
confirmButtonText: t('common.confirm'),
|
||||||
|
cancelButtonText:t('common.cancel'),
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
setSync([props.name]).then(res => {
|
||||||
|
ElMessage.success(t('common.oper'));
|
||||||
|
});
|
||||||
|
}).catch(() => {});
|
||||||
|
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
handleSync
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
</style>
|
@@ -27,6 +27,11 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="Order" :label="$t('status.tunnelSort')" width="104" fixed="right">
|
<el-table-column prop="Order" :label="$t('status.tunnelSort')" width="104" fixed="right">
|
||||||
|
<template #header>
|
||||||
|
<div class="flex">
|
||||||
|
<strong>{{ $t('status.tunnelSort') }}</strong><span class="flex-1"></span><Sync name="TunnelTransports"></Sync>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div>
|
<div>
|
||||||
<el-input-number v-model="scope.row.Order" :min="1" :max="255" @change="handleOrderChange" size="small" />
|
<el-input-number v-model="scope.row.Order" :min="1" :max="255" @change="handleOrderChange" size="small" />
|
||||||
@@ -43,11 +48,12 @@ import { ElMessage } from 'element-plus';
|
|||||||
import { computed,reactive, watch } from 'vue'
|
import { computed,reactive, watch } from 'vue'
|
||||||
import { Delete,Plus,Top,Bottom } from '@element-plus/icons-vue';
|
import { Delete,Plus,Top,Bottom } from '@element-plus/icons-vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import Sync from '../sync/Index.vue'
|
||||||
export default {
|
export default {
|
||||||
label:'打洞协议',
|
label:'打洞协议',
|
||||||
name:'transports',
|
name:'transports',
|
||||||
order:2,
|
order:2,
|
||||||
components:{Delete,Plus,Top,Bottom},
|
components:{Delete,Plus,Top,Bottom,Sync},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const {t} = useI18n();
|
const {t} = useI18n();
|
||||||
const globalData = injectGlobalData();
|
const globalData = injectGlobalData();
|
||||||
|
@@ -20,9 +20,14 @@
|
|||||||
<Title>linker</Title>
|
<Title>linker</Title>
|
||||||
<Authors>snltty</Authors>
|
<Authors>snltty</Authors>
|
||||||
<Company>snltty</Company>
|
<Company>snltty</Company>
|
||||||
<Description>1. 修复litedb抢锁超时导致客户端登录失败问题
|
<Description>1. 优化linux下路由跟踪问题
|
||||||
2. 同步信标服务器
|
2. 优化linux下获取本机IP问题
|
||||||
3. 其它一些修复优化</Description>
|
3. 增加ICS,让win7+、win server2008+支持NAT
|
||||||
|
4. 增加中继卡密
|
||||||
|
5. 增加内外穿透定时开关功能
|
||||||
|
6. 优化管理页面连接接口的体验
|
||||||
|
7. 优化一些UI体验,去除同步页面,将同步功能放置各个实际的位置
|
||||||
|
8. 其它一些修复优化</Description>
|
||||||
<Copyright>snltty</Copyright>
|
<Copyright>snltty</Copyright>
|
||||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||||
|
13
version.txt
13
version.txt
@@ -1,5 +1,10 @@
|
|||||||
v1.6.9
|
v1.6.9
|
||||||
2025-03-01 02:24:18
|
2025-03-02 17:55:03
|
||||||
1. 修复litedb抢锁超时导致客户端登录失败问题
|
1. 优化linux下路由跟踪问题
|
||||||
2. 同步信标服务器
|
2. 优化linux下获取本机IP问题
|
||||||
3. 其它一些修复优化
|
3. 增加ICS,让win7+、win server2008+支持NAT
|
||||||
|
4. 增加中继卡密
|
||||||
|
5. 增加内外穿透定时开关功能
|
||||||
|
6. 优化管理页面连接接口的体验
|
||||||
|
7. 优化一些UI体验,去除同步页面,将同步功能放置各个实际的位置
|
||||||
|
8. 其它一些修复优化
|
Reference in New Issue
Block a user