From 276e73e72404745aaa610c3e26db9964b2c46984 Mon Sep 17 00:00:00 2001 From: Butterscotch! Date: Mon, 8 Dec 2025 23:24:20 -0500 Subject: [PATCH] Remove Ktor dependency --- server/android/.gitignore | 2 +- server/android/build.gradle.kts | 6 +-- .../src/main/java/dev/slimevr/android/Main.kt | 35 ------------- .../java/dev/slimevr/android/MainActivity.kt | 49 +++++++++++++----- server/android/src/main/resources/icon128.png | Bin 1896 -> 0 bytes server/android/src/main/resources/icon16.png | Bin 133 -> 0 bytes server/android/src/main/resources/icon256.png | Bin 3330 -> 0 bytes server/android/src/main/resources/icon32.png | Bin 642 -> 0 bytes server/android/src/main/resources/icon48.png | Bin 940 -> 0 bytes server/android/src/main/resources/icon64.png | Bin 1123 -> 0 bytes 10 files changed, 37 insertions(+), 55 deletions(-) delete mode 100644 server/android/src/main/resources/icon128.png delete mode 100644 server/android/src/main/resources/icon16.png delete mode 100644 server/android/src/main/resources/icon256.png delete mode 100644 server/android/src/main/resources/icon32.png delete mode 100644 server/android/src/main/resources/icon48.png delete mode 100644 server/android/src/main/resources/icon64.png diff --git a/server/android/.gitignore b/server/android/.gitignore index c39472d4b..64fd0e9a6 100644 --- a/server/android/.gitignore +++ b/server/android/.gitignore @@ -1,3 +1,3 @@ /build -/src/main/resources/web-gui +/src/main/assets/web-gui /secrets diff --git a/server/android/build.gradle.kts b/server/android/build.gradle.kts index 54afaf0a0..97d31d593 100644 --- a/server/android/build.gradle.kts +++ b/server/android/build.gradle.kts @@ -29,7 +29,7 @@ java { } tasks.register("copyGuiAssets") { - val target = layout.projectDirectory.dir("src/main/resources/web-gui") + val target = layout.projectDirectory.dir("src/main/assets/web-gui") delete(target) from(rootProject.layout.projectDirectory.dir("gui/dist")) into(target) @@ -86,10 +86,6 @@ dependencies { implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) androidTestImplementation("androidx.test.ext:junit:1.3.0") androidTestImplementation("androidx.test.espresso:espresso-core:3.7.0") - // For hosting web GUI - implementation("io.ktor:ktor-server-core:2.3.13") - implementation("io.ktor:ktor-server-netty:2.3.13") - implementation("io.ktor:ktor-server-caching-headers:2.3.13") // Serial implementation("com.github.mik3y:usb-serial-for-android:3.7.0") diff --git a/server/android/src/main/java/dev/slimevr/android/Main.kt b/server/android/src/main/java/dev/slimevr/android/Main.kt index 005f8a6ed..686644560 100644 --- a/server/android/src/main/java/dev/slimevr/android/Main.kt +++ b/server/android/src/main/java/dev/slimevr/android/Main.kt @@ -12,50 +12,15 @@ import dev.slimevr.android.tracking.trackers.hid.AndroidHIDManager import dev.slimevr.config.ConfigManager import dev.slimevr.tracking.trackers.Tracker import io.eiren.util.logging.LogManager -import io.ktor.http.CacheControl -import io.ktor.http.CacheControl.Visibility -import io.ktor.server.application.install -import io.ktor.server.engine.embeddedServer -import io.ktor.server.http.content.CachingOptions -import io.ktor.server.http.content.staticResources -import io.ktor.server.netty.Netty -import io.ktor.server.netty.NettyApplicationEngine -import io.ktor.server.plugins.cachingheaders.CachingHeaders -import io.ktor.server.routing.routing -import kotlinx.coroutines.runBlocking import java.io.File -import java.time.ZonedDateTime import kotlin.concurrent.thread import kotlin.system.exitProcess -lateinit var webServer: NettyApplicationEngine - private set - -val webServerInitialized: Boolean - get() = ::webServer.isInitialized - -var webServerPort = 0 - lateinit var vrServer: VRServer private set val vrServerInitialized: Boolean get() = ::vrServer.isInitialized -fun startWebServer() { - // Host the web GUI server - webServer = embeddedServer(Netty, port = 0) { - routing { - install(CachingHeaders) { - options { _, _ -> - CachingOptions(CacheControl.NoStore(Visibility.Public), ZonedDateTime.now()) - } - } - staticResources("/", "web-gui", "index.html") - } - }.start(wait = false) - webServerPort = runBlocking { webServer.resolvedConnectors().first().port } -} - fun startVRServer(activity: AppCompatActivity) { thread(start = true, name = "Main VRServer Thread") { try { diff --git a/server/android/src/main/java/dev/slimevr/android/MainActivity.kt b/server/android/src/main/java/dev/slimevr/android/MainActivity.kt index 5d6e2b58a..23453d46b 100644 --- a/server/android/src/main/java/dev/slimevr/android/MainActivity.kt +++ b/server/android/src/main/java/dev/slimevr/android/MainActivity.kt @@ -3,12 +3,16 @@ package dev.slimevr.android import android.content.Intent import android.os.Bundle import android.webkit.JavascriptInterface -import android.webkit.WebSettings +import android.webkit.WebResourceRequest +import android.webkit.WebResourceResponse import android.webkit.WebView +import android.webkit.WebViewClient import androidx.appcompat.app.AppCompatActivity import io.eiren.util.logging.LogManager import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.withLock +import java.io.IOException +import java.net.URLConnection class AndroidJsObject { @JavascriptInterface @@ -28,14 +32,6 @@ class MainActivity : AppCompatActivity() { } initLock.withLock { - // Start the GUI if it isn't already running - if (!webServerInitialized) { - LogManager.info("[MainActivity] WebServer isn't running yet, starting it...") - startWebServer() - } else { - LogManager.info("[MainActivity] WebServer is already running, skipping initialization.") - } - // Start the server if it isn't already running if (!vrServerInitialized) { LogManager.info("[MainActivity] VRServer isn't running yet, starting it...") @@ -53,6 +49,35 @@ class MainActivity : AppCompatActivity() { // Enable debug mode WebView.setWebContentsDebuggingEnabled(true) + // Handle path resolution + guiWebView.webViewClient = object : WebViewClient() { + override fun shouldInterceptRequest( + view: WebView, + request: WebResourceRequest, + ): WebResourceResponse? { + if ((request.url.scheme != "http" && request.url.scheme != "https") || + request.url.host != "slimevr.gui" + ) { + return null + } + + val path = when (request.url.path) { + null, "", "/" -> "/index.html" + else -> request.url.path + } + + return try { + WebResourceResponse( + URLConnection.guessContentTypeFromName(path) ?: "text/plain", + null, + assets.open("web-gui$path"), + ) + } catch (_: IOException) { + WebResourceResponse(null, null, null) + } + } + } + // Set required features guiWebView.settings.javaScriptEnabled = true guiWebView.settings.domStorageEnabled = true @@ -66,12 +91,8 @@ class MainActivity : AppCompatActivity() { guiWebView.settings.loadWithOverviewMode = true guiWebView.invokeZoomPicker() - // Disable cache! This is all local anyway - guiWebView.settings.cacheMode = WebSettings.LOAD_NO_CACHE - guiWebView.clearCache(true) - // Load GUI page - guiWebView.loadUrl("http://127.0.0.1:$webServerPort/") + guiWebView.loadUrl("https://slimevr.gui/") LogManager.info("[MainActivity] GUI WebView has been initialized and loaded.") // Start a foreground service to notify the user the SlimeVR Server is running diff --git a/server/android/src/main/resources/icon128.png b/server/android/src/main/resources/icon128.png deleted file mode 100644 index 4b0018856c25f07c4c080278397e972fd224a0e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1896 zcmZ{lS5VW57RLWXh!jDVMFkd6bSc7mfnWqe@1THE1gSqhdX!f!<{+j{N~Jj-`jWQ#62?9VQ1xI1pt6uPgm2JPRu{e ze1Sgq7gA|-FgmFjr~yDtGTX^BCi;HEUf0+F00Knlx<~*x`bWP80Nzpn@C^i`0Xf{F(H~o3l6^0FbRI;|P?WT|$`nY_4?A!O{-6Pt`+{pS1*=#3hmbXq}ZT5hd zI{pjwd)Si-XStlswLNFq99MJqLj_ln+`YcIjZnj9ARE7Z-3hm> zOmKYXET4nJkmBr!K}My^GaD}Q*qPxqKmDR~M8hm)ZRf|q=*Ptn(=tbB7D62#Zc#bj zv(!u&?r)xnvZ?B+pCS_{mZmp8wa%q^)W5G9PjspcHZHAs)BhUXG~BsRli8ma(q0rx zCPa4@Ms-%E_LRhTRiTjS^=L&QFI!`X76YpzYadPA@}&3DW$*atBn*>2Fl8zZqJ)Do_oMDII;=rzL9Fjk zr9ad>kaGpj?0aQJ>SuPg@3~x9_boYzXkI8&Kbz`%)&Qnn0F+Qm4Ojm?^|%i~7Jo#9 zd7MG@e~UY+8)%m558#9kCZ?18Ty~?=GEF>hk%>jmwAsYOUM7>U%OalTv7e@2b@*G! zvQ=5Bc8oXvlCV%tma%UheeIspj_IT*r^`4_E-uU$aF~viZ&2pSCK)`nvf+5X1nAO9 z-TlS~_&o7+LhFVC=3;B2f`-mFIQ)+E`M)m8z707Py!F>#Muvaz$xHfdDN_+THfvPl z!M`J3&2vb=Y)ljw?pGSf_;2}M2(8gCE?*3R3NrI5GF!n#EAu}g4g?!b7Oqe=WHcqv za5K487`28hl!ansL%g7SiR)1pfsao1T#``0|q+{E~DS#$RGxE_I2 z6xq{0*f~(UPPi6>kqde_^R`0Ll(`zc2C1XW@Et!X7!*+PE@j?}RgmUF_w{_b& zu3RlSW~F)1l+c65AnRdsWJ!Z?kZu#QyqDy3^0fq(Y_mK$MhqF9P&RH}85>$145@`# zT8~~1-RTqTh^b#<;pf1)jk6c)kN@IWGccY_5GlFo**j5PuRW|;79)A;rpK@qVZtwZ zWa+XQ(0lGWp*VH6(K0U7%-fb$8`@#j@0l^_UMpc)&vZ-Uv=70s_vh-VTf4!{AR@AYyrcadV}K_|(eNMkV^82smd54|f) zB_wK4Vkizpe_VhtTI&hg;Tifl%pUoi4gewrk+~y9FKJVV3=ARp11<20%~CP_tSc9{z9ND5R7C diff --git a/server/android/src/main/resources/icon16.png b/server/android/src/main/resources/icon16.png deleted file mode 100644 index c3fc44e5cac81d5aed8bbbc06b3fee850f2ca7af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`KAtX)Ar_~TeT--RoZrZF;E02w zL=xK>o4IZ?8DB2jY`~MKbWALzu*7-B1<}OKtkW%+fk4^vB}1A*Xi{VAg!>y=RgT6< fob;5GW?(3-Q(STM%gkFqa~V8c{an^LB{Ts5jgcvJ diff --git a/server/android/src/main/resources/icon256.png b/server/android/src/main/resources/icon256.png deleted file mode 100644 index 5a28fa19a0b36df73e750fcfb6b4b43340809f39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3330 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 diff --git a/server/android/src/main/resources/icon32.png b/server/android/src/main/resources/icon32.png deleted file mode 100644 index a810a952a61f3e241ec5ec01348a5b68b230de61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 642 zcmV-|0)737P)NklP12N_VTyRJ%_0I`TdW!rOdCNe;?m`gU<&N3IchPJnO?&RR=83 z>T%Pyl*Lq|qAyWA)2BLMd0oh=yh)xC3IY)Ey~{4!1!>|7B0gcxig^L`A*+6T{r%(X z@7my%!FlGwlDx=jcmy~S8XT$vR($>R^T*d;bs;Ou=KAvraWXJ4Ji7T-K}(boDLpZw z)d!4>44k~|-#-0BIDv`r-@pIpQHLtX#mn~X^DhPl26isiNe2`2?B@Uc{u{dw{{Lq{ zHl2Zi0n>C$L5S%L3=F@1{9#~V;1T4YRZjl@?>_?r11lRdT!aOWYDOkTR#s+qE*1`M zHdZ!fMkZ*;{{8ds*N;EnKL7gj>+hf6f6;XP{`D891*~k$avCCvI$|mY5?U5A?3}E~ zPW%7=|G$3>OiT<+NZIxOzyH@yJ-vMN(VYt~p5J@_``6!}-+r@kuwb`9N?9!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)pT}UnMXwSj}Ky5HFasE6|34fiWh)C&V?)WM+ohtkb*h z{QCK4|LUs+P77W={`mj@|G$6!)`zajwVk_Z=9ygEdApWeJhu5}nb(qZ(^;7ovsd>Y zpOm*P-E7wR{rBI${E}lccg=+3i(3yZZ9n|^{r81U2QtiOUqAKa=l9>w@4wHooL%a% z_~oMy^XvC-UvPf+(n}kspU$$H^WfU+#)#GTF2Bq$pOtPpGsk-FjPhN3mtQ`x=4y4o z@|wUE|Nj2Fa_rHm9e3(NR!+#-dU(V2G}D>0tM)AIIDFy2gKwXHw#2MGx&8LS=7UAf z3-_Cuc52a%Z0ot3XPsF)`NWEzqbs_PuAh49 z$i^F&k39PL=G*if2gLq+o1amd~+~d+`TX zm!n4x@^F@U=Db>ZW9iM*2|qR!z4^q|r7%rsw~^Ratv9QbvfjKZ*w?1kK22!zHogff zPoG)WzA$e7U4}PW&Ws%KF^xAn8V}w$B67q$+1x!m|6pDw>!P(ca}}7jm3b+gns=Ac z!)nv(#n}Z#*IEr?7MNu?Fdw_h>#;-Ga;nCIgL&Sw*!;^3FPT(qJUw}tW6RuF@zpza zY@gV_etv7~>UxKSfC7#fr|T`TET$J*+FIRRPHkSy_-w_C848XI_K33Y=9}~>!cuqz z*G~=h=R1D1xGYq;_hd@QiiD`DHU;+G3Y&h)yqVc{E%K)2ifcwMo;`Wy`NX-TkVE10 z6R`)Uue7?(dZT8jGL1#4d9jO@obD8NU^3VIukvrsTg@xLuvRT`jVMV;EJ?LWE=mPb z3`Pb<#<~VTWEf&(Y-MC=WniIgU|?ln@cG4xRum1n`6-!cmAExDZ56NtYGCkm^>bP0 Hl+XkK4uiMC diff --git a/server/android/src/main/resources/icon64.png b/server/android/src/main/resources/icon64.png deleted file mode 100644 index c0315fb1bf27a58c4775dc6fa7408e09a3a5e6d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1123 zcmV-p1f2VcP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw0004u zP)t-sW;B^+HkxQRnvrd`|NsB-?Dn&o%x^%SqlLo#{QZ(|wuN1;x1Z1G;P8@ewvA}B z{{8-OLZFarwbH}kk7~4#Yqe=Oo6x}Ecub{?X0r70_;pC5*UIF1O{Kb|(S%&B`S<&L zQKzeq$I7_eXEmAS-0l1N{b)9teN(8tr_-^R%li5Jns~c@Q>k}LrNpt=W;K~-HJZh; z*p6wmyr$BARH?6(%5+AesEoyPMWXlg`OUoExuVdSce}%|*N9=Th+?pyfxz0%=JM|L z*2v_pl*y%s!^^tdfmo}Ra=4Rkx8m9C-qY!6H=Ch@!F*AuZ9Sf-i^Xm~p4iLfYB`*O zS*&zNqI*!Mq=v$3Ih(be&UZ_sp@P82wc63b;M~#Z-_`2b%;wd{EiJ2==1jS`M;~xi)FHIKAxR@zJFG# zXg8Z|JDqbzqRzhFhF-36L!oLqoP=AgvYE{4hn6FX3qPyZT@YR&xB zm?TyUIP>W1IKWk}3O9(!YjjKe4c<2C>YE8#>>zay!e+q3qebex16uX;?|FFJ1Rpqm zZnW(KU}ZjX2xPjSfOZ{yM<==jQP2(aWTQeaxIVG%2L^8YZXQ8xJsUz;THPQJQS?I~ z!x=ULe3t6K37Q5`#J0?u#W!;3!_e=apHdm<~VwQHuF zF-fdzC