This commit is contained in:
snltty
2025-04-26 19:35:50 +08:00
parent ac0502ae4d
commit 595d921864
27 changed files with 369 additions and 140 deletions

View File

@@ -34,12 +34,12 @@ for %%r in (win-x86,win-x64,win-arm64) do (
echo F|xcopy "src\\linker\\WinDivert64-%%r.sys" "public\\extends\\%%r\\linker-%%r\\WinDivert64.sys" /s /f /h /y
)
msbuild "src\\linker.ics\\linker.ics.csproj" -p:Configuration=Release -p:OutputPath=../../public/extends/win-x64/linker-win-x64
del /f .\public\extends\win-x64\linker-win-x64\linker.ics.pdb
msbuild "src\\linker.ics\\linker.ics.csproj" -p:Configuration=Release -p:OutputPath=../../public/extends/win-arm64/linker-win-arm64
del /f .\public\extends\win-arm64\linker-win-arm64\linker.ics.pdb
msbuild "src\\linker.ics\\linker.ics.csproj" -p:Configuration=Release -p:OutputPath=../../public/extends/win-x86/linker-win-x86
del /f .\public\extends\win-x86\linker-win-x86\linker.ics.pdb
rem msbuild "src\\linker.ics\\linker.ics.csproj" -p:Configuration=Release -p:OutputPath=../../public/extends/win-x64/linker-win-x64
rem del /f .\public\extends\win-x64\linker-win-x64\linker.ics.pdb
rem msbuild "src\\linker.ics\\linker.ics.csproj" -p:Configuration=Release -p:OutputPath=../../public/extends/win-arm64/linker-win-arm64
rem del /f .\public\extends\win-arm64\linker-win-arm64\linker.ics.pdb
rem msbuild "src\\linker.ics\\linker.ics.csproj" -p:Configuration=Release -p:OutputPath=../../public/extends/win-x86/linker-win-x86
rem del /f .\public\extends\win-x86\linker-win-x86\linker.ics.pdb
for %%r in (win-x86,win-x64,win-arm64,linux-x64,linux-arm,linux-arm64,linux-musl-x64,linux-musl-arm,linux-musl-arm64) do (

View File

@@ -8,6 +8,9 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/appicon"

View File

@@ -16,6 +16,7 @@ using linker.libs.extends;
using linker.libs.web;
using linker.messenger.entry;
using linker.messenger.tuntap;
using linker.messenger.updater;
using linker.tun;
using linker.tunnel.connection;
using System.Net;
@@ -221,6 +222,8 @@ namespace linker.app
LinkerMessengerEntry.Initialize();
LinkerMessengerEntry.AddService<IWebServerFileReader, WebServerFileReader>();
LinkerMessengerEntry.AddService<ISystemInformation, SystemInformation>();
LinkerMessengerEntry.AddService<IUpdaterInstaller, UpdaterInstaller>();
LinkerMessengerEntry.Build();
LinkerMessengerEntry.Setup(ExcludeModule.Logger, config);
IPlatformApplication.Current.Services.GetService<InitializeService>().SendOnInitialized();
@@ -367,7 +370,7 @@ namespace linker.app
{
length.ToBytes(buffer);
length += 4;
return buffer;
}
WaitForTun();
@@ -375,6 +378,7 @@ namespace linker.app
}
catch (Exception ex)
{
fd = 0;
System.Console.WriteLine($"vpn read {ex.ToString()}");
}
return Helper.EmptyArray;
@@ -396,6 +400,7 @@ namespace linker.app
}
catch (Exception ex)
{
fd = 0;
System.Console.WriteLine($"vpn write {ex.ToString()}");
}
return false;
@@ -510,5 +515,32 @@ namespace linker.app
return $"{deviceInfo.Manufacturer} {deviceInfo.Name} {deviceInfo.VersionString} {deviceInfo.Platform} {deviceInfo.Idiom.ToString()}";
}
}
/// <summary>
/// 更新
/// </summary>
public sealed class UpdaterInstaller : messenger.updater.UpdaterInstaller
{
private readonly IUpdaterCommonStore updaterCommonTransfer;
public UpdaterInstaller(IUpdaterCommonStore updaterCommonTransfer) : base(updaterCommonTransfer)
{
this.updaterCommonTransfer = updaterCommonTransfer;
}
public override (string, string) DownloadUrlAndSavePath(string version)
{
return ($"{updaterCommonTransfer.UpdateUrl}/{version}/linker.apk", Path.Join(FileSystem.Current.AppDataDirectory, "linker.apk"));
}
public override async Task Install(Action<long, long> processs)
{
processs(100, 100);
await Task.CompletedTask;
}
public override void Clear()
{
}
}
}

View File

@@ -3,8 +3,8 @@
<PropertyGroup>
<IsFirstTimeProjectOpen>False</IsFirstTimeProjectOpen>
<ActiveDebugFramework>net8.0-android</ActiveDebugFramework>
<ActiveDebugProfile>OPPO PFDM00 (Android 12.0 - API 31)</ActiveDebugProfile>
<SelectedPlatformGroup>PhysicalDevice</SelectedPlatformGroup>
<ActiveDebugProfile>Pixel 5 - API 34 (Android 14.0 - API 34)</ActiveDebugProfile>
<SelectedPlatformGroup>Emulator</SelectedPlatformGroup>
<DefaultDevice>pixel_5_-_api_34</DefaultDevice>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net8.0-android|AnyCPU'">

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/><script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script><script defer="defer" src="js/chunk-vendors.cfba5739.js"></script><script defer="defer" src="js/app.9d5a1c80.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.7c444b43.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/><script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script><script defer="defer" src="js/chunk-vendors.cfba5739.js"></script><script defer="defer" src="js/app.79eba13b.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.7c444b43.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1745570627057" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="16372" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M235.52 235.52h552.96v552.96H235.52z" fill="#FFFFFF" fill-opacity=".01" p-id="16373"></path><path d="M510.0475173 233.41976955c1.81580891-49.00731556 15.58081189-92.05955891 41.00213652-128.06333976 25.5384736-36.15997946 67.77067423-61.85465169 125.58368672-76.42017254l1.19101447 5.33027772v9.31334247c0 21.12586273-5.11550466 45.33664809-15.229365 71.968512-10.601981 25.79229635-27.13950943 50.06165621-49.14398935 71.96851203-20.57916758 19.31005382-39.59634898 32.09881547-56.42674979 37.87816424a182.55713166 182.55713166 0 0 1-22.35592681 4.74453294c-8.18090245 1.26911374-16.4008546 2.36250404-24.60128192 3.2801709z" fill="#000000" p-id="16374"></path><path d="M519.71230662 306.16927466c-65.31054604 0-110.64719413-57.75443802-175.04007331-57.75443805-64.43192884 0-197.10312773 59.19927519-197.1031277 263.58516339s117.83233043 336.06132091 131.01158862 351.4468845c13.17925817 15.38556359 43.65751299 54.90381329 90.86854446 54.9038133 47.23055632 0 98.91277315-37.54624218 150.26306793-37.54624217 51.33076997 0 115.93842222 37.54624218 158.11204839 37.54624217 42.17362613 0 59.55072211-17.18184768 88.25221765-46.85958462 28.70149558-29.65821209 83.46863508-120.17530966 102.58344063-174.49337814-31.49354582-18.74383382-115.00123055-69.66458244-115.00123055-184.99773504 0-76.88876839 28.11575076-140.77400206 84.32772747-191.63617618-36.88239804-47.97249974-79.64176899-71.9489872-128.27811286-71.94898721-73.00332784 0-124.70506951 57.75443802-189.99609073 57.75443805z" fill="#000000" p-id="16375"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
"use strict";(self["webpackChunklinker_web"]=self["webpackChunklinker_web"]||[]).push([[61],{7332:function(e,n,a){a.r(n),a.d(n,{default:function(){return O}});var t=a(6768);const s={class:"net-wrap app-wrap"},l={class:"inner absolute flex flex-column flex-nowrap"},i={class:"head"},o={class:"body flex-1 relative"},c={class:"status"};function r(e,n,a,r,u,d){const g=(0,t.g2)("Head"),p=(0,t.g2)("List"),v=(0,t.g2)("Status");return(0,t.uX)(),(0,t.CE)("div",s,[(0,t.Lk)("div",l,[(0,t.Lk)("div",i,[(0,t.bF)(g)]),(0,t.Lk)("div",o,[(0,t.bF)(p)]),(0,t.Lk)("div",c,[(0,t.bF)(v,{config:!1})])])])}a(4114);var u=a(4232);const d=e=>((0,t.Qi)("data-v-6bfe19a3"),e=e(),(0,t.jt)(),e),g={class:"head-wrap"},p={class:"tools flex"},v={class:"label"},h=d((()=>(0,t.Lk)("span",{class:"flex-1"},null,-1))),f={style:{"margin-left":"1rem"}};function k(e,n,a,s,l,i){const o=(0,t.g2)("Refresh"),c=(0,t.g2)("el-icon"),r=(0,t.g2)("el-button"),d=(0,t.g2)("Background");return(0,t.uX)(),(0,t.CE)("div",g,[(0,t.Lk)("div",p,[(0,t.Lk)("span",v,"分组 : "+(0,u.v_)(s.state.group),1),h,(0,t.bF)(r,{size:"small",onClick:s.handleRefresh},{default:(0,t.k6)((()=>[(0,t.eW)(" 刷新(F5)"),(0,t.bF)(c,null,{default:(0,t.k6)((()=>[(0,t.bF)(o)])),_:1})])),_:1},8,["onClick"]),(0,t.Lk)("div",f,[(0,t.bF)(d,{name:"net"})])])])}var C=a(3830),m=a(144),b=a(7477),L=a(5096),_={components:{Edit:b.ffu,Refresh:b.C42,Background:L.A},setup(){const e=(0,C.B)(),n=(0,m.Kh)({server:(0,t.EW)((()=>e.value.config.Client.Server.Host)),group:(0,t.EW)((()=>e.value.config.Client.Group.Name))}),a=()=>{window.location.reload()};return{state:n,handleRefresh:a}}},w=a(1241);const S=(0,w.A)(_,[["render",k],["__scopeId","data-v-6bfe19a3"]]);var F=S;const x=e=>((0,t.Qi)("data-v-68d1c30a"),e=e(),(0,t.jt)(),e),T={class:"net-list-wrap flex flex-column absolute"},z={class:"flex-1 scrollbar"},E={class:"flex"},A=x((()=>(0,t.Lk)("div",{class:"flex-1"},null,-1))),I={class:"tuntap"},P={class:"page t-c"},B={class:"page-wrap t-c"};function R(e,n,a,s,l,i){const o=(0,t.g2)("DeviceName"),c=(0,t.g2)("UpdaterBtn"),r=(0,t.g2)("TuntapShow"),u=(0,t.g2)("el-pagination");return(0,t.uX)(),(0,t.CE)("div",T,[(0,t.Lk)("div",z,[(0,t.Lk)("ul",null,[((0,t.uX)(!0),(0,t.CE)(t.FK,null,(0,t.pI)(s.devices.page.List,((e,n)=>((0,t.uX)(),(0,t.CE)("li",{key:n},[(0,t.Lk)("dl",null,[(0,t.Lk)("dt",E,[(0,t.Lk)("div",null,[(0,t.bF)(o,{item:e},null,8,["item"])]),A,(0,t.Lk)("div",null,[(0,t.bF)(c,{config:!1,item:e},null,8,["item"])])]),(0,t.Lk)("dd",I,[s.tuntap.list[e.MachineId]?((0,t.uX)(),(0,t.Wv)(r,{key:0,item:e},null,8,["item"])):(0,t.Q3)("",!0)])])])))),128))])]),(0,t.Lk)("div",P,[(0,t.Lk)("div",B,[(0,t.bF)(u,{size:"small",background:"",layout:"prev,pager, next","pager-count":5,total:s.devices.page.Count,"page-size":s.devices.page.Request.Size,"current-page":s.devices.page.Request.Page,onCurrentChange:s.handlePageChange,onSizeChange:s.handlePageSizeChange,"page-sizes":[10,20,50,100,255]},null,8,["total","page-size","current-page","onCurrentChange","onSizeChange"])])])])}var D=a(8104),X=a(7985),y=a(9383),N=a(7115),U=a(263),Q=a(3694),W=a(9983),H={components:{StarFilled:b.BQ2,UpdaterBtn:N.A,DeviceName:U.A,TuntapShow:Q.A},setup(e){(0,C.B)();const n=(0,m.Kh)({}),{devices:a,machineId:s,_getSignList:l,_getSignList1:i,handleDeviceEdit:o,handlePageChange:c,handlePageSizeChange:r,handleDel:u,clearDevicesTimeout:d}=(0,X.r)(),{tuntap:g,_getTuntapInfo:p,handleTuntapRefresh:v,clearTuntapTimeout:h,handleTuntapEdit:f,sortTuntapIP:k}=(0,D.O)(),{_getUpdater:b,_subscribeUpdater:L,clearUpdaterTimeout:_}=(0,y.d)(),{connections:w,forwardConnections:S,_getForwardConnections:F,tuntapConnections:x,_getTuntapConnections:T,socks5Connections:z,_getSocks5Connections:E,handleTunnelConnections:A,clearConnectionsTimeout:I}=(0,W.L2)();return(0,t.sV)((()=>{c(),v(),l(),i(),p(),b(),L()})),(0,t.hi)((()=>{d(),h(),_()})),{state:n,devices:a,machineId:s,handlePageChange:c,handlePageSizeChange:r,tuntap:g}}};const K=(0,w.A)(H,[["render",R],["__scopeId","data-v-68d1c30a"]]);var j=K,q=a(718),M=a(1387),V={components:{Head:F,List:j,Status:q.A},setup(){document.addEventListener("contextmenu",(function(e){e.preventDefault()}));const e=(0,C.B)(),n=(0,M.rd)();return(0,t.sV)((()=>{0==e.value.hasAccess("NetManager")&&n.push({name:"NoPermission"})})),{}}};const G=(0,w.A)(V,[["render",r],["__scopeId","data-v-6a3f3b43"]]);var O=G}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1745570802114" class="icon" viewBox="0 0 3071 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="22018" xmlns:xlink="http://www.w3.org/1999/xlink" width="599.8046875" height="200"><path d="M3070.08659 243.808595c41.837555 240.785368-611.033101 556.078644-1458.414254 704.216746C764.437469 1096.163443 43.6905 1021.070396 1.950469 780.187504-39.887086 539.304612 613.178616 224.108861 1460.413484 76.01952 2307.745875-72.167344 3028.346559 2.974465 3070.08659 243.808595z" fill="#F5F7F9" p-id="22019"></path><path d="M2281.707117 612.105859L2277.172277 341.332033h83.772634v341.332033h-120.441446l-83.577587-280.087314h-1.852945L2159.705296 682.664066h-83.285016V341.332033h125.707712l77.774942 270.773826zM853.232559 373.02715l-40.959844 309.636916H731.425785l55.442075-341.332033h133.119492L975.23438 682.664066h-80.505598l-39.838324-309.636916zM1195.588588 602.304753L1233.525206 341.332033h125.171332L1365.328132 682.664066h-76.702184l-2.047992-306.857498h-1.560375L1233.671491 682.664066h-77.872465L1104.452935 375.806568h-1.657898L1100.844568 682.664066H1023.996099l6.826641-341.332033h125.220094l37.887856 260.97272zM595.380589 580.264456c3.364559 7.65559 2.340563 17.554219 0.780188 23.600672-2.82818 10.532531-10.435008 21.406395-32.816637 21.406395-21.162586 0-33.986918-11.459004-33.986919-28.9157v-30.866168H438.904233L438.855471 590.163085C438.855471 661.20891 498.052198 682.664066 561.442433 682.664066c61.00091 0 111.176719-19.699734 119.173641-72.801246 4.095984-27.550371 0.975234-45.592207-0.341332-52.418848-14.238422-66.706032-142.189173-86.649575-151.697708-123.903528a39.692039 39.692039 0 0 1-0.341332-16.822793c2.340563-10.142438 9.703582-21.357633 30.768645-21.357633 19.699734 0 31.353785 11.556527 31.353785 28.915699v19.699735h84.065204v-22.332868C674.374574 352.157135 608.497491 341.332033 560.759769 341.332033c-59.976914 0-109.031204 18.7245-118.00336 70.606969a105.81293 105.81293 0 0 0 0.780187 43.056598c14.726039 65.048133 134.436059 83.918918 151.843993 125.220094zM1619.474212 580.313218c3.315797 7.704352 2.243039 17.554219 0.731425 23.55191-2.779418 10.727578-10.435008 21.455156-32.865398 21.455156-21.016301 0-33.889395-11.605289-33.889395-28.818175l-0.097523-30.91493h-90.355466l-0.146285 24.575906C1462.85157 661.257671 1522.048297 682.664066 1585.438532 682.664066c60.903387 0 111.127958-19.650973 119.076117-72.801246 4.144746-27.599133 1.219043-45.543446-0.29257-52.321325-14.238422-66.754793-142.140411-86.698336-151.648946-124.049813a38.619281 38.619281 0 0 1-0.390094-16.676508c2.438086-10.337484 9.752344-21.357633 30.866168-21.357633 19.748496 0 31.2075 11.312719 31.207501 28.818176v19.699735h84.26025v-22.430391C1698.516958 352.254658 1632.542352 341.332033 1584.755868 341.332033c-59.879391 0-108.982442 18.675738-117.808314 70.704493a104.350079 104.350079 0 0 0 0.82895 43.056597c14.628516 65.048133 134.338536 83.96768 151.648946 125.220095zM1877.423705 623.272292c24.039527 0 31.548832-15.89632 33.206731-24.088289a67.291172 67.291172 0 0 0 0.828949-12.629285V341.332033H1999.230479v237.664618c0.146285 6.095215-0.487617 18.626977-0.828949 21.747727C1992.257553 662.574238 1941.057748 682.664066 1877.326182 682.664066c-63.780328 0-115.028895-20.089828-121.12411-81.919688a310.953482 310.953482 0 0 1-0.780188-21.747727V341.332033h87.673571v245.173923c0 4.291031 0.146285 9.118441 0.828949 12.678047 1.950469 8.094445 9.264727 24.088289 33.499301 24.088289zM2559.600154 624.003718c24.770953 0 33.499301-14.921086 35.108438-23.600672 0.585141-3.705891 0.780188-8.289492 0.731425-12.385477v-47.298867h-35.157199v-47.591438H2681.894545v87.527286a219.183927 219.183927 0 0 1-1.267805 21.503918C2674.970381 661.50148 2620.796111 682.664066 2560.039009 682.664066c-60.854625 0-114.88261-21.162586-120.734016-80.456836a282.671685 282.671685 0 0 1-1.219043-21.55268l0.097524-137.264239c0-5.802645 0.731426-16.042606 1.462851-21.455156 7.558066-60.952149 59.489297-80.603122 120.441446-80.603122 60.757102 0 114.053661 19.504688 120.343923 80.55436 1.12152 10.386246 0.780188 21.503918 0.780187 21.503918v10.873863h-86.454528v-18.236883c0.048762 0.048762-0.146285-7.801875-1.121519-12.385476-1.462852-7.216734-7.996922-23.795719-34.181965-23.795719-25.014762 0-32.280258 15.60375-34.133204 23.795719-1.072758 4.291031-1.462852 10.093676-1.462851 15.359941v149.162099c-0.048762 4.095984 0.195047 8.679586 0.877711 12.385476 1.41409 8.533301 10.044914 23.405625 34.864629 23.405625z" fill="#040E3F" p-id="22020"></path></svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1745571122211" class="icon" viewBox="0 0 3910 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="28272" xmlns:xlink="http://www.w3.org/1999/xlink" width="763.671875" height="200"><path d="M3481.771062 849.397238H3149.227374c-186.929303 0-203.538085-154.12581-203.538085-201.145684 0-47.065882 16.608781-201.145684 203.538085-201.145684h332.543688c186.929303 0 203.584092 154.079802 203.584092 201.145684 0 47.065882-16.654789 201.145684-203.584092 201.145684z m7.223209-570.955612h-334.015934c-347.128131 0-377.9993 283.269437-377.999301 369.809928 0 86.540492 30.87117 369.809929 377.999301 369.809929h334.015934c347.174138 0 378.045308-283.269437 378.045308-369.809929 0-86.540492-30.917177-369.855937-378.045308-369.855936z m-778.772414 25.902337h-108.302136c-46.375766 0-55.899361 7.82131-73.796358 33.999694-17.943005 26.178384-327.620864 492.604492-327.620864 492.604492-9.891656 14.354404-20.381413 20.151375-33.401594 20.151375-13.066188 0-23.509937-5.796971-33.401593-20.151375 0 0-309.769874-466.426108-327.666872-492.604492-17.850989-26.224392-27.420592-33.999694-73.796358-33.999694h-108.302136c-24.890168 0-36.346087 19.23122-20.657459 42.69515l369.947952 554.070785C2030.642054 984.383844 2072.739104 1018.061483 2167.100905 1018.061483c94.315794 0 136.458852-33.67764 193.876467-116.951585l369.901945-554.070785c15.64262-23.463929 4.278717-42.69515-20.65746-42.69515z m-1425.548724 45.271581c0-32.435432 12.652119-45.271581 44.627473-45.271581h79.501314c31.929347 0 44.581466 12.882157 44.581465 45.271581v623.174358c0 32.435432-12.652119 45.271581-44.581465 45.271581h-79.547321c-31.929347 0-44.581466-12.882157-44.581466-45.271581V349.615544z m-6.625109-197.465067c-25.764315-25.764315-25.764315-46.145728 0-71.910042L1333.073238 25.21522c25.764315-25.764315 46.145728-25.764315 71.910042 0l55.071223 55.025215c25.718307 25.764315 25.718307 46.145728 0 71.910042l-55.071223 55.025214c-25.764315 25.764315-46.145728 25.764315-71.910042 0L1278.094031 152.196484z m-164.523552 152.193486h-108.164113c-46.329758 0-55.899361 7.82131-73.75035 33.999694-17.896997 26.178384-327.29881 492.604492-327.29881 492.604492-9.845649 14.308396-20.335405 20.151375-33.355586 20.151375s-23.463929-5.842978-33.355586-20.151375c0 0-309.401813-466.472116-327.252802-492.604492-17.896997-26.178384-27.420592-33.999694-73.75035-33.999694H28.432761c-27.788654 0-36.346087 19.23122-20.657459 42.69515l369.533883 554.070785C434.634784 984.383844 476.731834 1018.061483 571.001621 1018.061483c94.177771 0 136.274821-33.67764 193.60042-116.951585l369.533883-554.070785c15.64262-23.463929 7.177202-42.69515-20.611452-42.69515z" fill="#415FFF" p-id="28273"></path></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -5,6 +5,8 @@ namespace linker.messenger.updater
{
public static class Entry
{
static bool added = false;
static bool used = false;
public static ServiceCollection AddUpdaterClient(this ServiceCollection serviceCollection)
{
serviceCollection.AddSingleton<UpdaterApiController>();
@@ -16,6 +18,8 @@ namespace linker.messenger.updater
serviceCollection.AddSingleton<UpdaterConfigSyncSecretKey>();
serviceCollection.AddSingleton<IUpdaterInstaller, UpdaterInstaller>();
return serviceCollection;
}
public static ServiceProvider UseUpdaterClient(this ServiceProvider serviceProvider)
@@ -40,15 +44,24 @@ namespace linker.messenger.updater
serviceCollection.AddSingleton<UpdaterHelper>();
serviceCollection.AddSingleton<UpdaterServerTransfer>();
serviceCollection.AddSingleton<UpdaterServerMessenger>();
serviceCollection.AddSingleton<IUpdaterInstaller, UpdaterInstaller>();
return serviceCollection;
}
public static ServiceProvider UseUpdaterServer(this ServiceProvider serviceProvider)
{
UpdaterServerTransfer updaterServerTransfer= serviceProvider.GetService<UpdaterServerTransfer>();
UpdaterServerTransfer updaterServerTransfer = serviceProvider.GetService<UpdaterServerTransfer>();
IMessengerResolver messengerResolver = serviceProvider.GetService<IMessengerResolver>();
messengerResolver.AddMessenger(new List<IMessenger> { serviceProvider.GetService<UpdaterServerMessenger>() });
if (used == false)
{
used = true;
IUpdaterInstaller updaterInstaller = serviceProvider.GetService<IUpdaterInstaller>();
}
return serviceProvider;
}
}

View File

@@ -0,0 +1,201 @@
using linker.libs;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Text;
namespace linker.messenger.updater
{
public interface IUpdaterInstaller
{
/// <summary>
/// 检查更新,时间,更新信息,版本
/// </summary>
/// <returns></returns>
public Task<(string, string[], string)> Check();
/// <summary>
/// 获取地址。下载地址,保存地址
/// </summary>
/// <param name="version"></param>
/// <returns></returns>
public (string, string) DownloadUrlAndSavePath(string version);
/// <summary>
/// 安装
/// </summary>
/// <param name="processs">安装进度回调,总长度,当前进度</param>
/// <returns></returns>
public Task Install(Action<long, long> processs);
/// <summary>
/// 清理文件
/// </summary>
public void Clear();
}
public class UpdaterInstaller : IUpdaterInstaller
{
private readonly IUpdaterCommonStore updaterCommonTransfer;
public UpdaterInstaller(IUpdaterCommonStore updaterCommonTransfer)
{
this.updaterCommonTransfer = updaterCommonTransfer;
}
public virtual async Task<(string, string[], string)> Check()
{
try
{
using HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
using HttpClient httpClient = new HttpClient(handler);
string str = await httpClient.GetStringAsync($"{updaterCommonTransfer.UpdateUrl}/version.txt").WaitAsync(TimeSpan.FromSeconds(15)).ConfigureAwait(false);
string[] arr = str.Split(Environment.NewLine).Select(c => c.Trim('\r').Trim('\n')).ToArray();
string version = arr[0];
string datetime = DateTime.Parse(arr[1]).ToString("yyyy-MM-dd HH:mm:ss");
string[] msg = arr.Skip(2).ToArray();
return (datetime, msg, version);
}
catch (Exception ex)
{
LoggerHelper.Instance.Error(ex);
}
return (string.Empty, [], string.Empty);
}
public virtual (string, string) DownloadUrlAndSavePath(string version)
{
if (OperatingSystem.IsWindows() || OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
{
StringBuilder sb = new StringBuilder("linker-");
sb.Append($"{(OperatingSystem.IsWindows() ? "win" : OperatingSystem.IsLinux() ? "linux" : "osx")}-");
if (OperatingSystem.IsLinux() && Directory.GetFiles("/lib", "*musl*").Length > 0)
{
sb.Append($"musl-");
}
sb.Append(RuntimeInformation.ProcessArchitecture.ToString().ToLower());
return ($"{updaterCommonTransfer.UpdateUrl}/{version}/{sb.ToString()}.zip", "updater.zip");
}
return (string.Empty, string.Empty);
}
public virtual async Task Install(Action<long, long> processs)
{
if (OperatingSystem.IsWindows() == false && OperatingSystem.IsLinux() == false && OperatingSystem.IsMacOS() == false)
{
processs(100, 100);
return;
}
using ZipArchive archive = ZipFile.OpenRead("updater.zip");
long total = archive.Entries.Sum(c => c.Length);
processs(total, 0);
string[] extractExcludeFiles = [];
foreach (ZipArchiveEntry entry in archive.Entries)
{
string entryPath = Path.GetFullPath(Path.Join(Helper.currentDirectory, entry.FullName.Substring(entry.FullName.IndexOf('/'))));
if (entryPath.EndsWith('\\') || entryPath.EndsWith('/'))
{
continue;
}
if (extractExcludeFiles.Contains(Path.GetFileName(entryPath)))
{
continue;
}
if (Directory.Exists(Path.GetDirectoryName(entryPath)) == false)
{
Directory.CreateDirectory(Path.GetDirectoryName(entryPath));
}
if (File.Exists(entryPath))
{
try
{
File.Move(entryPath, $"{entryPath}.temp", true);
}
catch (Exception)
{
continue;
}
}
using Stream entryStream = entry.Open();
using FileStream fileStream = File.Create(entryPath);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = await entryStream.ReadAsync(buffer).ConfigureAwait(false)) != 0)
{
await fileStream.WriteAsync(buffer.AsMemory(0, bytesRead));
processs(total, bytesRead);
}
entryStream.Dispose();
fileStream.Flush();
fileStream.Dispose();
}
archive.Dispose();
try
{
File.Delete("updater.zip");
}
catch (Exception)
{
}
if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
{
try
{
File.SetUnixFileMode("./linker", UnixFileMode.GroupExecute | UnixFileMode.OtherExecute | UnixFileMode.UserExecute);
}
catch (Exception)
{
}
}
try
{
File.Delete("./linker.service.exe");
}
catch (Exception)
{
}
try
{
File.Delete("./linker.ics.exe");
}
catch (Exception)
{
}
Environment.Exit(1);
}
public virtual void Clear()
{
ClearTempFiles();
}
private void ClearTempFiles(string path = "./")
{
string fullPath = Path.Join(Helper.currentDirectory, path);
if (Directory.Exists(fullPath))
{
foreach (var item in Directory.GetFiles(fullPath).Where(c => c.EndsWith(".temp")))
{
try
{
File.Delete(item);
}
catch (Exception)
{
}
}
foreach (var item in Directory.GetDirectories(fullPath))
{
ClearTempFiles(item);
}
}
}
}
}

View File

@@ -1,21 +1,18 @@
using linker.libs;
using linker.libs.timer;
using System.Diagnostics;
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Text;
namespace linker.messenger.updater
{
public sealed class UpdaterHelper
{
private string[] extractExcludeFiles = [];
private readonly IUpdaterCommonStore updaterCommonTransfer;
public UpdaterHelper(IUpdaterCommonStore updaterCommonTransfer)
private readonly IUpdaterInstaller updaterInstaller;
public UpdaterHelper(IUpdaterCommonStore updaterCommonTransfer, IUpdaterInstaller updaterInstaller)
{
this.updaterCommonTransfer = updaterCommonTransfer;
ClearFiles();
this.updaterInstaller = updaterInstaller;
updaterInstaller.Clear();
}
/// <summary>
@@ -34,21 +31,17 @@ namespace linker.messenger.updater
try
{
updateInfo.Status = UpdaterStatus.Checking;
using HttpClientHandler handler = new HttpClientHandler();
handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
using HttpClient httpClient = new HttpClient(handler);
string str = await httpClient.GetStringAsync($"{updaterCommonTransfer.UpdateUrl}/version.txt").WaitAsync(TimeSpan.FromSeconds(15)).ConfigureAwait(false);
string[] arr = str.Split(Environment.NewLine).Select(c => c.Trim('\r').Trim('\n')).ToArray();
string datetime = DateTime.Parse(arr[1]).ToString("yyyy-MM-dd HH:mm:ss");
string tag = arr[0];
string[] msg = arr.Skip(2).ToArray();
(string datetime, string[] msg, string version) = await updaterInstaller.Check();
if (string.IsNullOrWhiteSpace(datetime))
{
updateInfo.Status = status;
return;
}
updateInfo.DateTime = datetime;
updateInfo.Msg = msg;
updateInfo.Version = tag;
updateInfo.Version = version;
updateInfo.Status = UpdaterStatus.Checked;
}
catch (Exception ex)
@@ -56,6 +49,7 @@ namespace linker.messenger.updater
LoggerHelper.Instance.Error(ex);
updateInfo.Status = status;
}
}
/// <summary>
/// 下载更新
@@ -63,24 +57,23 @@ namespace linker.messenger.updater
/// <param name="updateInfo"></param>
/// <param name="version"></param>
/// <returns></returns>
public async Task DownloadUpdate(UpdaterInfo updateInfo, string version)
public async Task Download(UpdaterInfo updateInfo, string version)
{
UpdaterStatus status = updateInfo.Status;
(string url, string savePath) = updaterInstaller.DownloadUrlAndSavePath(version);
try
{
updateInfo.Status = UpdaterStatus.Downloading;
updateInfo.Current = 0;
updateInfo.Length = 0;
StringBuilder sb = new StringBuilder("linker-");
sb.Append($"{(OperatingSystem.IsWindows() ? "win" : OperatingSystem.IsLinux() ? "linux" : "osx")}-");
if (OperatingSystem.IsLinux() && Directory.GetFiles("/lib", "*musl*").Length > 0)
if (string.IsNullOrWhiteSpace(url) )
{
sb.Append($"musl-");
updateInfo.Status = status;
return;
}
sb.Append(RuntimeInformation.ProcessArchitecture.ToString().ToLower());
string url = $"{updaterCommonTransfer.UpdateUrl}/{version}/{sb.ToString()}.zip";
LoggerHelper.Instance.Warning($"updater {url}");
using HttpClient httpClient = new HttpClient();
@@ -90,7 +83,7 @@ namespace linker.messenger.updater
using Stream contentStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
using FileStream fileStream = new FileStream("updater.zip", FileMode.OpenOrCreate, FileAccess.ReadWrite);
using FileStream fileStream = new FileStream(savePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
byte[] buffer = new byte[4096];
int readBytes = 0;
while ((readBytes = await contentStream.ReadAsync(buffer).ConfigureAwait(false)) != 0)
@@ -106,7 +99,7 @@ namespace linker.messenger.updater
LoggerHelper.Instance.Error(ex);
try
{
File.Delete("updater.zip");
File.Delete(savePath);
}
catch (Exception)
{
@@ -119,14 +112,13 @@ namespace linker.messenger.updater
/// </summary>
/// <param name="updateInfo"></param>
/// <returns></returns>
public async Task ExtractUpdate(UpdaterInfo updateInfo)
public async Task Install(UpdaterInfo updateInfo)
{
//没下载完成
if (updateInfo.Status != UpdaterStatus.Downloaded)
{
return;
}
string fileName = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
UpdaterStatus status = updateInfo.Status;
try
{
@@ -134,55 +126,11 @@ namespace linker.messenger.updater
updateInfo.Current = 0;
updateInfo.Length = 0;
using ZipArchive archive = ZipFile.OpenRead("updater.zip");
updateInfo.Length = archive.Entries.Sum(c => c.Length);
foreach (ZipArchiveEntry entry in archive.Entries)
await updaterInstaller.Install((total, length) =>
{
string entryPath = Path.GetFullPath(Path.Join(Helper.currentDirectory, entry.FullName.Substring(entry.FullName.IndexOf('/'))));
if (entryPath.EndsWith('\\') || entryPath.EndsWith('/'))
{
continue;
}
if (extractExcludeFiles.Contains(Path.GetFileName(entryPath)))
{
continue;
}
if (Directory.Exists(Path.GetDirectoryName(entryPath)) == false)
{
Directory.CreateDirectory(Path.GetDirectoryName(entryPath));
}
if (File.Exists(entryPath))
{
try
{
File.Move(entryPath, $"{entryPath}.temp", true);
}
catch (Exception)
{
continue;
}
}
using Stream entryStream = entry.Open();
using FileStream fileStream = File.Create(entryPath);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = await entryStream.ReadAsync(buffer).ConfigureAwait(false)) != 0)
{
await fileStream.WriteAsync(buffer.AsMemory(0, bytesRead));
updateInfo.Current += bytesRead;
}
entryStream.Dispose();
fileStream.Flush();
fileStream.Dispose();
}
archive.Dispose();
File.Delete("updater.zip");
updateInfo.Length = total;
updateInfo.Current += length;
});
updateInfo.Status = UpdaterStatus.Extracted;
}
@@ -204,57 +152,9 @@ namespace linker.messenger.updater
TimerHelper.Async(async () =>
{
await DownloadUpdate(updateInfo, version).ConfigureAwait(false);
await ExtractUpdate(updateInfo).ConfigureAwait(false);
if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
{
try
{
File.SetUnixFileMode("./linker", UnixFileMode.GroupExecute | UnixFileMode.OtherExecute | UnixFileMode.UserExecute);
}
catch (Exception)
{
}
}
try
{
File.Delete("./linker.service.exe");
}
catch (Exception)
{
}
Environment.Exit(1);
await Download(updateInfo, version).ConfigureAwait(false);
await Install(updateInfo).ConfigureAwait(false);
});
}
/// <summary>
/// 清理旧文件
/// </summary>
private void ClearFiles()
{
ClearTempFiles();
}
private void ClearTempFiles(string path = "./")
{
string fullPath = Path.Join(Helper.currentDirectory,path);
if (Directory.Exists(fullPath))
{
foreach (var item in Directory.GetFiles(fullPath).Where(c => c.EndsWith(".temp")))
{
try
{
File.Delete(item);
}
catch (Exception)
{
}
}
foreach (var item in Directory.GetDirectories(fullPath))
{
ClearTempFiles(item);
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<project ver="10" name="linker.share.win" libEmbed="true" icon="res\favicon.ico" ui="win" output="linker.share.win.exe" CompanyName="snltty" FileDescription="linker.share.win" LegalCopyright="Copyright (C) snltty 2025" ProductName="linker.share.win" InternalName="linker.share.win" FileVersion="0.0.0.1" ProductVersion="0.0.0.1" publishDir="/dist/" dstrip="false">
<file name="main.aardio" path="main.aardio" comment="main.aardio"/>
<folder name="资源文件" path="res" embed="true" local="false" ignored="false">
<file name="connect.aardio" path="res\connect.aardio" comment="res\connect.aardio"/>
<file name="share.aardio" path="res\share.aardio" comment="res\share.aardio"/>
</folder>
<folder name="窗体文件" path="dlg" comment="目录" embed="true"/>
</project>

View File

@@ -0,0 +1,17 @@
//config 配置文件
import fsys.config;
config = fsys.config("/config/");
//config = fsys.config( io.appData("/软件作者/应用程序名/") );
//不需要序列化的配置名字前请添加下划线
namespace config {
__appName = "应用程序名";
__website = "http://www.aardio.com/";
}
/**intellisense(config)
__appName = 应用程序名
__website = 官方网站
saveAll() = 写入所有配置到文件
? = 获取值时指定不以下划线开始的配置表名称,\n返回一个可自动序列化到同名配置文件的表对象。\n如果此对象名以下划线开始则可以正常读写值不会序列化为配置文件。\n否则不能对此对象直接赋值只能对配置表对象的成员赋值。\n\n配置表可自动自文件加载,退出线程前自动序列化并存入文件。\n仅序列化以字符串、数值为键的元素\n仅序列化值为字符串、数值、buffer 以及定义了 _serialize 元方法的成员。\n循环引用的值转换为 null序列化时忽略成员函数\n!fsys_table.
end intellisense**/

View File

@@ -0,0 +1,21 @@
//RUNAS//
import win.ui;
/*DSG{{*/
mainForm = win.form(text="linker.share.win";right=250;bottom=291;border="thin";max=false;topmost=1)
mainForm.add(
mainTab={cls="tab";left=1;top=-2;right=250;bottom=254;aw=1;edge=1;z=1}
)
/*}}*/
import win.ui.atom;
import win.ui.atom
var atom,hwndConflict = mainForm.atom("CC31CBD7-B5B5-4709-A6B2-6126B611B8C2");
if(!atom){
win.quitMessage(); return;
};
mainForm.mainTab.loadForm("\res\connect.aardio");
mainForm.mainTab.loadForm("\res\share.aardio");
mainForm.show();
return win.loopMessage();

View File

@@ -0,0 +1,9 @@
import win.ui;
/*DSG{{*/
var winform = win.form(text="连接共享";right=759;bottom=469)
winform.add()
/*}}*/
winform.show();
win.loopMessage();
return winform;

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,13 @@
import win.ui;
/*DSG{{*/
var winform = win.form(text="发出共享";right=243;bottom=254)
winform.add(
button={cls="button";text="生成";left=195;top=12;right=234;bottom=35;z=3};
edit={cls="edit";text="Edit";left=44;top=14;right=189;bottom=35;edge=1;z=1};
static={cls="static";text="密钥";left=11;top=16;right=48;bottom=35;transparent=1;z=2}
)
/*}}*/
winform.show();
win.loopMessage();
return winform;

View File

@@ -1,5 +1,5 @@
v1.7.5
2025-04-26 11:39:08
2025-04-26 19:35:50
1. 一些优化
2. 安卓APP勉强能用
3. 如果你设备很多,请尝试升级其中一个成功重启后再升级其它