ZeroTier helper
This commit is contained in:
parent
29202906e1
commit
339f817c7e
@ -425,5 +425,15 @@ namespace RageCoop.Core
|
||||
{
|
||||
return BitConverter.ToString(data).Replace("-", String.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a string to IP address
|
||||
/// </summary>
|
||||
/// <param name="ip"></param>
|
||||
/// <returns></returns>
|
||||
public static IPAddress ToIP(this string ip)
|
||||
{
|
||||
return IPAddress.Parse(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
130
RageCoop.Core/Networking/ZeroTierHelper.cs
Normal file
130
RageCoop.Core/Networking/ZeroTierHelper.cs
Normal file
@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal class ZeroTierNetwork
|
||||
{
|
||||
public ZeroTierNetwork(string line)
|
||||
{
|
||||
// <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips>
|
||||
var v = Regex.Split(line," ").Skip(2).ToArray();
|
||||
ID=v[0];
|
||||
Name=v[1];
|
||||
Mac=v[2];
|
||||
Status=v[3];
|
||||
Type=v[4];
|
||||
Device=v[5];
|
||||
foreach (var i in v[6].Split(','))
|
||||
{
|
||||
Addresses.Add(i.Split('/')[0]);
|
||||
}
|
||||
}
|
||||
public string ID;
|
||||
public string Name;
|
||||
public string Mac;
|
||||
public string Status;
|
||||
public string Type;
|
||||
public string Device;
|
||||
public List<string> Addresses=new List<string>();
|
||||
|
||||
}
|
||||
internal static class ZeroTierHelper
|
||||
{
|
||||
private static readonly string _path="zerotier-cli";
|
||||
private static readonly string _arg = "";
|
||||
static ZeroTierHelper()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
var batpath= Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "ZeroTier", "One", "zerotier-cli.bat");
|
||||
_arg=$"/c \"{batpath}\" ";
|
||||
_path="cmd.exe";
|
||||
}
|
||||
var status = RunCommand("status");
|
||||
if (!status.StartsWith("200"))
|
||||
{
|
||||
throw new Exception("ZeroTier not ready: "+status);
|
||||
}
|
||||
}
|
||||
public static ZeroTierNetwork Join(string networkId, bool waitIpAssign=true)
|
||||
{
|
||||
var p = Run("join "+networkId);
|
||||
var o = p.StandardOutput.ReadToEnd();
|
||||
if (!o.StartsWith("200 join OK"))
|
||||
{
|
||||
throw new Exception(o+p.StandardError.ReadToEnd());
|
||||
}
|
||||
if (!waitIpAssign) { return ListNetworks()[networkId]; }
|
||||
while (true)
|
||||
{
|
||||
if(ListNetworks().TryGetValue(networkId,out var n))
|
||||
{
|
||||
if (n.Addresses.Count!=0 && (!n.Addresses.Where(x=>x=="-").Any()))
|
||||
{
|
||||
return n;
|
||||
}
|
||||
System.Threading.Thread.Sleep(100);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static void Leave(string networkId)
|
||||
{
|
||||
var p = Run("leave "+networkId);
|
||||
var o = p.StandardOutput.ReadToEnd();
|
||||
if (!o.StartsWith("200 leave OK"))
|
||||
{
|
||||
throw new Exception(o+p.StandardError.ReadToEnd());
|
||||
}
|
||||
}
|
||||
public static Dictionary<string, ZeroTierNetwork> ListNetworks()
|
||||
{
|
||||
Dictionary<string, ZeroTierNetwork> networks=new Dictionary<string, ZeroTierNetwork>();
|
||||
var p = Run("listnetworks");
|
||||
var lines=Regex.Split(p.StandardOutput.ReadToEnd(),"\n").Skip(1);
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var l=line.Replace("\r","");
|
||||
if (!string.IsNullOrWhiteSpace(l))
|
||||
{
|
||||
var n = new ZeroTierNetwork(l);
|
||||
networks.Add(n.ID,n);
|
||||
}
|
||||
}
|
||||
return networks;
|
||||
}
|
||||
private static Process Run(string args)
|
||||
{
|
||||
var p = new Process();
|
||||
p.StartInfo=new ProcessStartInfo()
|
||||
{
|
||||
FileName = _path,
|
||||
Arguments =_arg+args,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
};
|
||||
p.Start();
|
||||
p.WaitForExit();
|
||||
return p;
|
||||
}
|
||||
private static string RunCommand(string command)
|
||||
{
|
||||
var p = Run(command);
|
||||
return p.StandardOutput.ReadToEnd()+p.StandardError.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
/// <summary>
|
||||
/// Settings for RageCoop Server
|
||||
/// </summary>
|
||||
public class ServerSettings
|
||||
public class Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// Port to listen for incoming connections
|
||||
@ -86,8 +86,18 @@
|
||||
public string AllowedUsernameChars { get; set; } = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890-_";
|
||||
|
||||
/// <summary>
|
||||
/// Whether to use direct connection between players to send entity information
|
||||
/// Whether to use direct connection between players to send entity information, <see cref="UseZeroTier"/> needs to be enabled if on WAN for this feature to function properly.
|
||||
/// </summary>
|
||||
public bool UseP2P { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to enable zerotier VLAN functionality, allowing you to host a server behind NAT firewall, no port forward required.
|
||||
/// </summary>
|
||||
public bool UseZeroTier { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// The zerotier network id to join, default value is zerotier's public Earth network.
|
||||
/// </summary>
|
||||
public string ZeroTierNetworkID = "8056c2e21c000001";
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user