From 718317276dac729a3aa8f1bc3863f7a0eb46b73b Mon Sep 17 00:00:00 2001 From: HarryCordewener Date: Mon, 6 Jul 2026 12:36:51 -0500 Subject: [PATCH 1/7] chore(android): rename applicationId + inset adaptive icon into safe zone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two Play-Store-readiness changes to the Android head, both in the app csproj plus the two keep-alive service references that must stay in lock-step. * ApplicationId: com.sharpmush.sharpclient.app -> com.sharpmush.sharpclient. This is the app's permanent Play identity, so it is fixed before the first upload. The [Service] Name and the AndroidManifest are updated to match (the manifest merger keys on the name to attach foregroundServiceType; a mismatch emits two services and startForeground throws). NOTE: this is a different package from prior Obtainium builds (…​.app), so existing installs will not update in place. * Adaptive icon: add ForegroundScale="0.65" (the stock MAUI/Google template value). The logo SVG fills its whole viewport, and MAUI does not inset the foreground for the adaptive safe zone automatically, so the launcher mask was cropping the M's peaks and outer legs. 0.65 shrinks + centers the foreground into the safe zone. Verified against the Release build output: the generated mipmap foreground insets to 0.653 and the whole M survives circle / squircle / rounded-square masks. (Resizetizer caches aggressively — the change only regenerates after a clean build; CI's fresh checkout is unaffected.) Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01HHCRc5CJ6595iMzEgYYdQp --- .../Platforms/Android/AndroidManifest.xml | 2 +- .../Platforms/Android/ConnectionKeepAliveService.cs | 4 ++-- src/SharpClient.App/SharpClient.App.csproj | 12 ++++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/SharpClient.App/Platforms/Android/AndroidManifest.xml b/src/SharpClient.App/Platforms/Android/AndroidManifest.xml index 489af82..d6f89ef 100644 --- a/src/SharpClient.App/Platforms/Android/AndroidManifest.xml +++ b/src/SharpClient.App/Platforms/Android/AndroidManifest.xml @@ -63,7 +63,7 @@ components. Explicit declaration required for Android 12+ (API 31). --> diff --git a/src/SharpClient.App/Platforms/Android/ConnectionKeepAliveService.cs b/src/SharpClient.App/Platforms/Android/ConnectionKeepAliveService.cs index 1d0f533..d271d88 100644 --- a/src/SharpClient.App/Platforms/Android/ConnectionKeepAliveService.cs +++ b/src/SharpClient.App/Platforms/Android/ConnectionKeepAliveService.cs @@ -15,13 +15,13 @@ namespace SharpClient.App; // semantically correct type. Crucially, connectedDevice has NO 6-hour time cap (unlike dataSync // which is capped at 6 h/24 h on Android 15+), which matters for sessions that last all day. // -// The Name is pinned to the real ApplicationId (com.sharpmush.sharpclient.app) so the static +// The Name is pinned to the real ApplicationId (com.sharpmush.sharpclient) so the static // AndroidManifest.xml can reference this service with a stable android:name to attach the // foregroundServiceType attribute (which cannot be set via the C# ServiceAttribute). It MUST stay // in lock-step with in SharpClient.App.csproj and the entry in the // manifest, otherwise the merger emits two distinct services and startForeground throws. // -[Service(Exported = false, Name = "com.sharpmush.sharpclient.app.ConnectionKeepAliveService")] +[Service(Exported = false, Name = "com.sharpmush.sharpclient.ConnectionKeepAliveService")] [SupportedOSPlatform("android26.0")] // Foreground services + NotificationChannel require API 26 internal sealed class ConnectionKeepAliveService : Service { diff --git a/src/SharpClient.App/SharpClient.App.csproj b/src/SharpClient.App/SharpClient.App.csproj index 54d49ff..cf46dbb 100644 --- a/src/SharpClient.App/SharpClient.App.csproj +++ b/src/SharpClient.App/SharpClient.App.csproj @@ -32,7 +32,7 @@ SharpClient - com.sharpmush.sharpclient.app + com.sharpmush.sharpclient 1.0 @@ -74,8 +74,16 @@ cleanly on it (adaptive icons, Android 8+); the teal base blends into the matching green so the background looks solid. Previously #0b0e12, which put the dark mark on near-black and rendered as "black on grey". + ForegroundScale="0.65": the logo SVG fills its whole viewport (peaks/legs run edge to + edge). Android adaptive icons reserve the outer 18dp of the 108dp layer + for the launcher mask (circle/squircle/rounded-square/teardrop), so a + full-bleed foreground gets its peaks and outer legs clipped. 0.65 is the + stock MAUI/Google template value: it shrinks + centers the foreground + into the safe zone so the whole M survives every mask. MAUI does NOT + apply this inset automatically — omitting it renders full-bleed (the + prior cropping). We never bake the mask shape ourselves; the OS does. --> - + From 4a9e6517c7df18c241ab06a1e1a6893b101a8f07 Mon Sep 17 00:00:00 2001 From: HarryCordewener Date: Mon, 6 Jul 2026 12:36:51 -0500 Subject: [PATCH 2/7] docs(store): add Play Store listing assets and release checklist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds docs/store/ with everything needed for the first Play submission: * play-listing-icon-512.png — 512x512 hi-res listing icon (opaque square, dark M on brand-green, scaled to match the launcher icon). * privacy-policy.md — accurate to actual storage: saved passwords in the OS Keystore-backed secure store, world/character config + transcripts in a local SQLite DB, local-only diagnostic logs, allowBackup=false, and an explicit cleartext-telnet disclosure. Collects/transmits nothing to us. * play-data-safety.md — Data Safety form answers (recommends "no data collected/shared" with the user-directed-server rationale) plus a caution flag and privacy-policy-hosting options. * release-checklist.md — end-to-end sequence (keystore/secrets -> tag -> Play Console), noting what is already done in-repo vs. what needs a human. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01HHCRc5CJ6595iMzEgYYdQp --- docs/store/play-data-safety.md | 74 +++++++++++++++++++++ docs/store/play-listing-icon-512.png | Bin 0 -> 17583 bytes docs/store/privacy-policy.md | 73 ++++++++++++++++++++ docs/store/release-checklist.md | 95 +++++++++++++++++++++++++++ 4 files changed, 242 insertions(+) create mode 100644 docs/store/play-data-safety.md create mode 100644 docs/store/play-listing-icon-512.png create mode 100644 docs/store/privacy-policy.md create mode 100644 docs/store/release-checklist.md diff --git a/docs/store/play-data-safety.md b/docs/store/play-data-safety.md new file mode 100644 index 0000000..1fbbed8 --- /dev/null +++ b/docs/store/play-data-safety.md @@ -0,0 +1,74 @@ +# Google Play — Data Safety declaration + +This document records the answers to fill into the **Play Console → App content → +Data safety** form, with the reasoning behind each answer so it can be defended +or revisited. It reflects the app as of 2026-07-06. Update it if data handling +changes. + +See also: [`privacy-policy.md`](./privacy-policy.md). + +## Key facts the form is based on + +- The app stores everything **locally on the device** (SQLite DB + OS secure + storage + a local log file). Nothing is sent to the developer. +- The only network traffic is a **direct, user-initiated connection to the + game (MUD/MUSH) server the user typed in.** That server is a third party the + user chooses, not an endpoint we operate. +- No analytics, ads, crash-reporting SDKs, or other third-party SDKs are bundled. + +## Form answers + +### 1. Data collection and sharing + +**Does your app collect or share any of the required user data types?** → **No.** + +Rationale: In Play's model, "collected" means data transmitted off the device to +the developer or a service acting on the developer's behalf, and "shared" means +transferred to a third party. SharpClient does neither. Passwords, character +names, server addresses, transcripts, triggers, and logs are all kept in the +app's private on-device storage and are never transmitted to us. + +The character name and password **are** sent to the game server at login, but: +- the server is an endpoint **the user explicitly enters and connects to**, and +- the transfer is core, user-initiated functionality (the same category as an + SSH, FTP, email, or IRC client sending credentials to a user-specified host), +which Play's guidance does not treat as developer "collection" or "sharing." + +> ⚠️ **Confirm before submitting:** this "No data collected/shared" position +> rests on the user-directed-server interpretation above. It is the standard +> position for this class of app, but you own the final declaration. If you +> prefer maximum caution, you can instead declare *App activity / "Other +> user-generated content"* and *Personal info / "User IDs"* as **collected but +> not shared**, processed for **App functionality**, and mark it not required — +> at the cost of a more alarming store label. Recommended answer remains **No.** + +### 2. Security practices + +- **Is data encrypted in transit?** + Disclose honestly: connections to game servers use **Telnet, which is not + encrypted**. If the form scopes this question only to *collected* data (of + which there is none), it may be N/A — but the privacy policy states the + cleartext fact plainly regardless. +- **Data stored on device is protected:** saved passwords use Android + Keystore–backed secure storage; automatic cloud backup is disabled + (`allowBackup=false`). + +### 3. Data deletion + +- **Can users request that their data be deleted?** → Users delete data + themselves in-app, and uninstalling removes all local data. No server-side + data exists to delete, so no deletion request mechanism is needed. + +## Privacy policy URL (required by Play) + +The Data Safety form and the store listing both require a public **Privacy +policy URL**. `privacy-policy.md` is the content; it needs to be reachable at a +stable public URL. Options, easiest first: + +1. **GitHub Pages** — enable Pages for the repo and publish `privacy-policy.md`, + giving e.g. `https://sharpmush.github.io/SharpClient/privacy-policy`. +2. **Raw GitHub URL** — Play accepts a link to the rendered file, e.g. + `https://github.com/SharpMUSH/SharpClient/blob/master/docs/store/privacy-policy.md`. + +Pick one and paste it into both **Data safety** and **Store listing → Privacy +policy**. diff --git a/docs/store/play-listing-icon-512.png b/docs/store/play-listing-icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..5ee81705069e11885196518dc87e6f3e457f13f3 GIT binary patch literal 17583 zcmeHvX*AXE*Z0>fLuSc5X3UsyGL@N(DME-urew}^jxr_lkdiU{%wr+SP=v}*Cm}-; z88XWd2j|(x@BZIwJumLHp7+oFN{egQ*S_|(_h*0h{`SDcNQah+oeDt^T0LD&GXx=q ze-a~<zY(UWk4e^L1A8ER4drXXivKTUci>^l5P$XCnK_r`T!CzPYN6Z}AArDe~a zmR2||eb!t?0VR7Dbw*xXS{fxSP1^cd8sHF@K#lLOa7+x?0hP3mKX1f5@t zW#7})14FTvIU%Ldr-jzuSiP;QlP^}pefOliKo{?JbtKj_Car^5{Y6pA!%PF64$Iv8 zev2KLOG!qWEVABr3s-|^M3_zG93+zF@Is#-frT|B1+AUzoZM$d>?Lgz24_wb37AHj zP3J`HF7F_ik#0NwgW>KX0S3`XGK`CW&$_H-qha|@z|ghCHW zWc%$%bgJ%OK(Qyw!ooaP1fy1h>)|F%u+koNv6FA^|&(pzo8t1{K3jX%BpIYW0+&Kkv^%xH<| z2G3f2bQ9i}e`A?jo_$d}-+n@s%WK0BkGm$vfZG&bc&zyoM%}J@*xOSpJ@hN{pbn13 zfE#GU-YO-lHEz4$J^OmLO~g*UPiSYu47rs^hI#QQXr4^aHhXg81Z%ABr0O-4WPSTy z2Xo%w2Dwq~?!%M>cx|?s6`Fgv?Exv7TO2;c0am#1K%@!e8R%+yy zsQj*$pzWbWd7ISXY_V={s2xhxLr7`PuygX@_1DQ0xHam+ZdDS7y91 z#8dppFZ&5`iqv5Lesz*xH%%vN$mvjK&2UE|-sKzGapAQ$HQr6~fJy{;rnzR#lQZ}E zdm|?=AChD#%XV}l?@~7N>B(Z@^eLIB#>-6aG94ylNTRZ<_vTFe;OJ2m@mU@wTw%y8+f&KteSqYG2sy*gC+g&w!Wv7o_EMFV0A z$T_%o988rbwFaMxyS!LPXJFm6MFG4SYFyEcUrq_5rp7}Un6dzo+lJkd|6O6I&RLea4W)ekP z8);BTm)sLT82Y4~d(C$qZ4i~MvxnzSSJhm$Y*hX^My{&ee|{Dld{-314|mRgTIqmA zFz0UfaJQ~uaO7eS2{X=~FXj2<+LjDlYt-QV0bL%kZazLJR>-nZ zl|S_5XpLtWo7cf)%=>0PD?c1Hy=Vd~Dekj%KfDiXto-Nr&)Wyqdr1OP>sSiiUh(Ob zcy8&sv#ye_5?`sB-Ka%O1cjVm$97)2O|kcQC_a^B_eNP|3iaa9t#H*F`?=If?D&e! zWTxGFuxPhUEBlj0ZmRt|)2pEgozD;Z6+T_{9#W&ntvzh#8E)Ra{@BjzGNMICjc6Gq zY2dA&duCEG$70*=&EKJ_S$WL2@kx6~yRYXC=R|(bb)r07z5YE4M&nkY?Z377km$ip zi$XMQa%#>RXYad@o!n}Nd!UdI+r44+8BtawmS!3!|E72E_W8YplhSnwzHvR$Lvu;3 zbE{Yx`-3}Fy;=rEj`Vk-(hSYEeyIbO};{AJAeAUZT0Y5cZ3e@;%U#iYA5_E zg4JNfh?(hXf!!N5&kvub9*()Qi4W^{Q>yrU6DwS?aK3%`*NsO&et~R(O*6-yDDRV8 znB~J>Kc*tb!GRb4Bv^Eq4N7~yX!S9XB2W@1@()o+hf#u&^RjExqZkGzYg& zs~lc!H8tmJSUXqvPm2Us0Su1M6n`m(c?&mx;WRugK{Dq91#vsfI}WnTy`V#<4D+tJ zJ{{NJ23VPxGO+c0r~Mk%p;hj*gwGW-j(_N%w&}vgos&2^Mq~UXl=kxq4&gWZHzR#% zp2fm_x;TX?aL>ldV`VahYeGGkEfowehs8`-KGo`rk@+wu=t@P6M4J8l7Lc@$Tg1wI z_=wsG?IdXqH)Iyf38h#cR(q6S`si=@pX4CTmb+A%zX(T{xl*NdbH;Lkt&(x@w7W*N zW3~+YEs~#iXhKZVXgvKf;VUezsmMO z5C7{9Tlo-3W%V<1Cn@XA*!fF}HAvD%Ts=q9NtSHmD+{qwfd}#)5 zR6Xf2AY!JHKnh>?$}{nA-E*xN;5(Rm0{dT|*rtrj65#5PGZn93z6L{HbUs`aP@2BH zz?Ng6vPs-4^+>my{=|`Qq{SCyS8DxAVbS8CMnuK2sby4JmW{?4MtuFvx5P{&^t#uy zmJ7e8!x1t8jeYoFqaZr?@vT)#)&cp?)i6mejf?y7#z_#X7uZ@$uQjlLCN@ZJCsxnO_*8@~j6BuH8 z<)^P#{V1a|gXb*T-E36-wA>Q?m^kg3o&RrUh)wwe`xK79P&c#_QsMp)7$l@>+%{I; zrFu1PrUI?oO?lDvgH5L@P8+42$2ib>e`ZMmZt5$bf)CO|PNs4pajZu^BKP>nT@YCA z?1=8<)?;59h9~7bGew9Q*r{ko^BvjV+gCtE*Td>LOCJmvbgx}=?PZeAs7y)Vd;9nL z>59pCus`!?GE5qM?hb?5rOnn$Iex>A(pRc85~et&qw96u!gwNPvJ{d-ex8Q643d_% zkJuN0J)e#~Ts+{uQk}TTQRugGk;G}JaSxRE;fXKSe>Qy*w>r%0GaD^sSH zV4UWn|ZmbW}a_g2lF^!bQSVneP!ItD5Ie$y0c@bxO_{y9{N?%$t_3zHIdJobi_@@8w@m}p z6Atj6_rQw6W7__lG^0}%;1Wpd6;k8fvJVUkSO~t^VN(kxCn8kba<5YkpO$bw)1HWT z@}xia69z|&gC0uXr3k;L7?q*zLxu@qLGSn!@&sC;v;_;fL&#?p#0wqI zh&Ff~Gox!0 zy)m_~nbljtNG2@=@PvwT6@>rA;m>b~8rl9yfsj_AcJWcdc?NJ} ztubvoJcZrLqFe$&`c)|kRCS)2A1bp$lQQ=h8Kpvbx$g6WR$n{MC7c-QC^=s`_C;l0#XS6x-BpKBF9fDff)qnxbrAx;T z4D=??QOw4E4Ohu&x*=pnrz##gGAi3OFYkH1 zCnO?|GKfpWV5H3Az;ggj)C+78qp~+AWIA@DYY(L(BaInmfBw?#F>v`FT5ppX>ewxMizq6V1Mu+GkHcnFzo+ zIS#CaJtuk}IDZgrDrs^*BSmJS1-ki)Md$ol6gDig+22YGy(*j&xN*7@-=w~`RzleM zDCZ!Lgv`HQe<}4{jpAnYnZ+(q_4gedWGn_XD?d2mK49sT<3S4j?z|)j&>JkVB_~x+ z4Qk*$4Xsf3RvmcI4`wFq{w&QA(!pA?NnM^ttK-K#3I)uoX87eCXyR;aQO6=Fsgd;4 z2aRpfLGx{&%Forcah&23par}*>b`k$&n&6Rj>>V)+@8qT|xL0KfWbhf}p!9g& z*BW@;&SWmtyp=?wTmh4DG~I%ED*-`n&I^kjhAm1xx38Gs4P|Q;=WIT)A-q+A^VzOD z^cu6o){3#>1_E>^7x4d>Fo(g46(i_Yt-Y%5LPv9#KewAU}0?;cs|P0;l=vfM>UV&%r*;g5_ns#GLzo$7~w(`W%V!{zr>lU6?v20&aJhb-Dx__sh$<=dWiE(R_v@Nq}3!@Ylm$a;%EnB<{DnVwmRC34pEk&tGW0?kzjzsHHVl)v4~@ zQPXGA;*XM=W^8S#^0WavlK{M5DLT zpgYH1q~hP!IDJJ3j;lMVatTE)3LL`k2dDRsFQ`SLkA04E>leqRhWd9R zyiY_H-8v))S@r8R+f;ncK8_>*`$DaaC+flYyScQ3EsiQ~);-f_fL1$N(lSEe^*`0R zF|UR;gImbJmsY-5+^!j*UZ0h!w4d0NHj$9uj}C!Y`=xN2?CoLh7i;;BwwIGDPVuKi zD@_1Cxk7mQUAUUqe)gFR(>GHMs{@a3277NNwC{6}9pE4n53PSQScgA-4U!2d0Y_i7C#YxV$T{ase;8QDcK0%vI(iRoT3BO*M6?>G6-R)Zz zWnhowch!y~%3Ax5efk_=}tHm+v_c+aE|A5q^06AU%UPhD<$p_NPTj*HNuDwZu-RX_;n=1e!r*Qgj)r+z18VVkZt%3Ikn`hGe7tOZ@ zk{=!ZkvM%N#N>}9;(Nv06yT2ZP&A&F_gn}v?orlu|LIeG-kmX@B06FE(pqCad8aDh zIQ1Jk$H`OHf1^!gZC|;cS)$S!jANsoxhtyfEP=2a7zQ3+S5Qq(Fs*lJ?5~Nwf?x1t z3SO%fc~q-+apdGKv5AO20OH!oVSvXw zla{&0$ynVF*!#hf{2b25z^+4mn<{}g;@Y-1{*dnZa1LFkBR1NyeniKPKXjFIflUxY zrY>j7z8BDs;*8YT*;t;NOH|3bY)zGFwIR$CaiKai1h@N6CE(tK8oNSD-QlWCr|N+| zikvKtOkEhrwe%ew$8Q$OQSQj_!gGt`+s+Z;`%dgV32gJYjv4La_nzwM@px=)kPX^+ zOG%NrM3JcrlIv+OeONu8&n%pnX`l`Fc?y)9lqstqtAQ`#I@f-9YfYo-+eh+<6k>BZany361 z6^My(Ad1PG5s>1O*?~Md=g!{NmET>;1XFqO#UCrjh+P~-qASG6aKVe?tgzu_6v|EcY%K51Q%o15G($@re;RmvV)Rg)&;@oxsWHy)0V z&R^Ucx+Q%gOqlDwau+eZ3?#mB{h!njTyb$eT+sp>tq(2gtn6ZIN5#tlPp^JuV4O%m zcLIK;Jv~Y#O}+r?G-;^SBY=~?*ZBo4`|Fv!ElpDDONm zrluxmmJ$0OLb02d4)hz*noC1=jq3j-=ejxOb1f4}$e z3~QjYQ^$RYn~+sKdeVm(#Qc$Dy!^5jYLt#&QJ^8wr~=xk2%o`G3)nzBGi{Jtrrt&(H3;&>ox!@{RO)6vXr@Go{5_ z_l7^3n(T|Z|6gQ*+391h7w<+(!DYtEr#w-+?-&=@%!ODnN#!TE5Xhi)k2d~f(vr^_ zZj6DU&c1QHutDoQz4481{r5bXouNrImCMJWnC z1=|4?_Nc{Mnm$plJEm2W^P543LT%MZ3pF52@W|$Xt&=nVzV@XlBc@i@J*ifqHM<9C zbD;Rmq1NOmlUg_D&*xZvzg5L+rZxKlf=ymxxjz+UZ)@OYiOwSS`D_Lf^MS-4Z0@SX zK^4L=@WT%*$ru2^cU zObIc}bOg%r$)s^o!juy3g!40aX$x$ZKiY;E6>eiJA_?FzH9H*l?Mv`T zJNCVw_|mu%^!(mtOMNElaAJ9kZ|9*L2=61oHQIi7_3vbfc`69(HTD(mVAfJnnXE|i z9Q-qlAU2B)3;kKxJ0);7SGWJ}B~;X0T?a*br5@q=ubgmxOS@}QudjdZMf5>xDl95| zvbyE|_0G=!kfkLomdJ&-mQAcr#Jk{a+0?EQy_ZJzNd08%jeNG3Itxx!%LVxao$TH9j{B;3BiK>-*h6TVQ$Qmo`jh1 zH>&e)pcN#{aB~X(jCcr-kQ6lDFZ`E=T{pu(ZHoC3fdq9v&>-x}+IRI+{QKNHY*ZA> zKqvSf9Y6-sA4<)Yjq?y;2#jU#)5IB|=^ahvV761mH%xCj1Lq!vJ-#i~bkq?%Rye$U zF)lveI*Wxr=fwR+S+@rYYU#R$WQSG%rD{!>U}k#LP2ygm&*$!pH=Mj7mGIrjrB8Ho zRM>mx{>~+E96J`(i-USMvtxKhO~F?Uu3R9L`2r#2J5Qsf!DX237a_K z8GRN;W^l=qND>w>64WkD zms&9+Z-ubY<7)w*{B%Z0o;A*V6hDF=MXA1Vd%*K57}73HZ4`6e19bIB)zwZg2Tk|> z34_g7W(Tm1m<!_$8aA4GU%!S=+T>FZQ*huNf6-dNYj_8adtlXq6E5shdkB!0 zB(!&Fbs%vmBpH~sw>EWVC~}WZ;ylX5=J}PZbhT|{Ch@qJVWaiAbrC|4)3}}Y!Z8>C zfgqQL()PfBW@&*{fXSIFmG>d<<^9p(PDSB=-{g=J&RA$ zw$W#M4s2Q!ltr5!;@(bZS6*PYUXwSwG&gj3{>Qk4-vTM_9#avTw)MS@9F#x4Vr5=* z6Z7^qALjRbR~s`FO5*x%_aj`P&Axawgn8C`%hts;`t_K8H@(GZEy)tK(W8XV7{6uB zJd=up`z8tlhubzUJ!G+MRCZ7m;*;~v@}*g>MJQtjaFnId1;Jw%an8zITix%s@MdeA zm-97oqEOy@&CCl%9pl#_`1oN4_`CS|wO>P0BSI&hES@T}Xh^wpL(25_^wYc|RREYf5v~q}q6yR+RlCY#7uOq4 z@IrM8FvxuKmPf6Q!mkGHvl$hddpX}|@#kMEphyzV-)Wn0()cT)grgPA4KzSS0sbex z>0V>%^G~Z#u0jm&a4@ z?BiR5-!F>2l`U9_eq%rcwPVW1ThUNbvk?QaBDt^qQjodz%;w4D0cLPssqPzlvf46z zr6<~2@j}a(K={+3bMCm1Kejgp{Og7T@(J60mqA8BErgqWT;I`Gany? z+MG)1LN)LAaWMw1{%@lku3L{1rpkLuDC|Spv{6xKL0t|LXUJxs%^yDyxXB+J$=@jJ zF|~zKT9ogc{Huv_BKcMxt-Z&@?Qp6tgD%a;G_h7Sdb2X|3|=di89{n%l}M}70hDk+ zWwghpcsBm^vlud71WM3JnR(wIy|Ar|&c^&q^oNRGdEAMmUOze_t*Q6dtVR7-iRXGd zz#zL$dc~mzlH;)f1AqlD|FJ9V$Dx<|3J({Vp(LZCAQD*_W$?s-yA3HC z{J!nPj2YS2(lxwv`$X6HFOqa?j@1V@hymH^6_<3|ykK6qW8AnONfnPEn9%$nYvJHh zNT--zfh_rCtQcOwpM;zz`>mb)tp!rQ4_um!o=?dgm&q4iZo!}^m3b&O=6pPu5lr(p zb<=s(yG2Ko5ESsx-IQN4yWOH6QxMKJnR%~$(p!D$O}C!TT84gZ%7-`y3A^~siRXo1 z&L(kuS2G*F>$V#FNe8ZB{qCRSKwzTi)br;WV(%)?(kN@A?h!7)43Zk=9l%u`YJ8!F z`jhxG4%BU_38u!kqPLUTXZsF*UVO; z6@z>u;U9N5pfW6R>k}>nUS=z`kVzrw)k~>ye|ad%%=){KSQqW`AwX?tElt|h&x#ZZ z+-A|KRp$O#jJK~vNPA9xI@dhBY93_j>h!3Sdi5y%7~G=EzZP%BBrcxT@|W`^u!Azc zp+5PhIr!#ct6mY|D6df!=EO$1w(yc6__LU-d|?IP3{puj%)}$7>wch6wmE)9CXoX0ozCI>!N2d; z<$+?BkHAY|^&TArX@?T_Ucv%)VbP#7eN4TW^P70INPWKP#)HPBK)*1j$%;{7&-8xz zM8$((pXD~>u#0SjWN`1s%&~M^!SWdBEjdv;>q#TfzA()3Ze{A~1*`ebEW2Nh1G~~) z^QY!ev1x-R59?$7PMO<_|K;vwwi+O-RvLp#Y(IUxp4Ni5Mau4mOEmS^D415BxC*I8 z=TWKwxenT3{&b=CKzLJN697sPzpA@=pHkiMMX-&FC2)B@Y-IprWV=Acz5LnlD-0XU|r-_C4Qe&^L|efmg}gHO{y-GgttNk_~t z{)KB8P?98&XK_Jw1yQ;>E;-kE70i;YFWkNXJrHqQO~1op^b5|%3^mRE!|1i= zz1+qO3lQkw+`v3v8ag`NdR67 z1@9!^*gk#9ib-RW)xI%m2Gl8Mds1P|Xv+W0b%VJ{+Wp~vA3Lx*myGY^PW;FUjR1hK zbiP|eK3QDpz^SvvsxN<(qsrlq*yYiDm5pvrUM>wc2_)s&3t^1DR0{V^JxIq0w3zC% zAjl9z?k)dwVax?wYH-U%F`o$y zeJ;CFw|}z()9%)_8)^QdMkwv<%?Y{dlGeW_=*;KZZ2Od1evYE=N+3sb&2m#-_c1$kL6()K=*Hr#A zM&_(Td-*2T6{sy;!zYV)l2UU7x|6JIaMi4=NMuBiF;Zm9doYmF>O)TG{7Zb1@MTAr zd1njXbcx_8F3~+w9Y+n-GlgIHjHfW0U#J{x8lr;P+^opE2>;Lu{f-o(*XrzU&vo&) zqBfH~Z?gB;uHgFu;h_>ovH$s$YTO#xS^nq#UFr1izL!zMR(vn2J)nx4_xRHaXnN7n zvTg~2bj{ZPi0`H$N(%qH|kV0hhyTzWg+qb*_W(k8O${b)M>EaC0KHF1RQ5SK@ z5RR?pK-ZBN+19Pf8GfG$%_3EDI+$Pz0hp%tb-YFfJ zyj&iGT3RI`sY(kbW@ZU8rCOs^I@~4}oO>-A+UZ9XeZaQM^ja#Z|7vtWpt{9E2MO}n z;0k}}z>+f@Z#jVmVn4F-LHTXo>6qVc^i-(&HE?#qy#?wQlCni{`P_nrD{DA&;Zp$4kETp z!pnQm_)WUa7U&5h{~2{&252LESxV~Nred+@<$8qgc>mn8DPq7RWxE;SzhfCnj=^lP zl{TH1@K)x@%ziSZB>UJ;Y}9P#4~s4j9ozmiU3RFnjn0k58jb1k97lKwUW&!ak54<_ zr&1^~C-~Xl>1$9bCZx8kWe?=UT11XH{kN0aLp4F+rLPdmevO7ub;~&&%7!3NE`eg_ z3~|Zk{_)SM2$<1XFv4$h+$=e6&SJC%RNC)tc9LY<9zyZsI)1p61&v;L_B`!sb2_v! zLK`5=JThMixBzZy%-ivV<&dk`U&fY^w&|qLJ7=XXxQ>2=Yz)<8w-x?s`E2E(YQU?8 z8gx*mZwP{EauLN&=RBg#|MbNg)OZrMR|PAMyeXT#f`=|Fz^yhBAZ4nGQrIHiw1x-_{b`bkf_aKwKra20z-o zou6><<%{X>@%*J~spV#srR&`W-Q);?xPdmbLdO`j;pL7tz++`mv50K#UlB22$~xa2<$RdZ1so7B za|V$)`y=xyGFdweBpwUQeoOh?`7dzCPlsKD`qkTo;;!c9!H79}LYFREJ#(P`SJMR> zw|im(e6HNo>XZ=<#t6%IUzU$41b$?;Rf@~e@v&l^0C~e-C*UOSzKZvXgiccX2|~M) zyy(Whr+&T;pvc)#ytF+L<*~2AgFS6dCGVTV7?Y%QyAebY*d{2>86F11xEW(rUDPS0 zz1f33E`71k(fyxKPpf{+1wF#kzrvWko9{nht*>cTm`*%Ku z55N6i&CCL|f1cXELJf9;T(ERdPyiy-zBN+h!zkPIWpF4J+% ze2bkZGtvr$+HmUZ+epxkzq)&q^wZkl&&+ z39o6ptWtG>LwmXJK66sY#%X9%mf|YlOV2T*N<_RCC%s@6L(vYYh}a9YrhBp-;yd&ge#>VwV6LrJcJ zTVg6jX{h0|)1&w`kpBr#4|%|~!@_3sT6(3&tgUN3ACn3!5^fPH4;w}tAQuUtlh}J! z4W=0v&6(@9xY>Zc8v$)tI0L>r9w`~rVkh*WKDMidc1ZH!NWZ?o`tSCai?L1QRR?qg zBHGN`7-_|1^z|s!c;3~7CbX01P(6q@{G!9<#S_aK|BFw8hSMyvunuzqF3-a;D zD|+1`i4c<`>)?DZ;e6??!Qib_S)+&%UZ{t`&W{rKP963;V;SD+$7?}USIU;PmNuO_lbAI z7lf1X5~o>4m-qO+H(dH-T!9`4envHe<385t0qtX0-6 zP@~DXkFd~oQ?b|cXf7$Pe7>oprS6mQQl-EHjEoljrIvOkZ|0#wq&8II%CGWA4uHss z$5}BkHIWu1C5j_Ct3HB9IiW})?3$MFNo2t%{*T);Sc5;7!dD9r@eHwu*R{Iyg}xVB zj@d9%d5RGgw>`Ve z14(JOZQ$k3L&>hBU3jTP1wO^{>Q`a(JSD_+pV=uF&2KNJyn8zpGazqt_)rqgMHOU> zp?~fE)+6=&p}P@zp?0UE7kPx^<8z;UPBYArj#4@jmf9hud_#$tPyUGPR4nFCN~+)>-l8afaRRICxcd>T_15j@C1YD(ZVK@1aC$$_fsEPYmgAcl=?MMWb5} z5t5{qzJ;0m1p_@?m|aZHmidErKqrC1?UhX)ay_|WCB8If=atEw*Y03Nt%URH`s(qY zyNT)VgfAbXf5w1#$?|%nsZFV;`MZOY_9IpV+pwd9mIBHf{Kh?0>QgbHCgX0-P<@w3 zv(}{Ws=Bk0%MBG~`kowQDhN-3C~7EDJMP^$P!%;vust^b^(5g-$LLd>FxGVx z+_ZvB&^8()cjiVa{_OfL+ypu_V(pu8`dX;2lx8ZTaA&MB+-Hvu2Hm^W&drSdm8Y8P z#(6kQL5(@J|DCCwvctALp7PzqWRK78bWq+=$&+RM4`HE}8f2dTWb~Ke?!}-f4!Bn4 zgx?8Jd4+B*`~0l^#s`T6i54MK5ZFd|qPJtGo{}JgVOe$25$;@ymy2E;G#q8TaUXUA ztL`kf*}~b(mZs)F&s@aF51OCF+}Vm631p0Sps=+zN7(Y9265?Xw9bjzIp8TuSpJa( z$t(@kJ%*oP)ql?%OG?FWb`a;CEJoi(t1d@*o&53Wf}et7nPuxvtH^R~fp6UJzqN$x za(e*%46s0wT7UG_Rz7Ypk$o9l!Jrex0^7`UU1k*?f*TtK)Et!+u1XUg6+)Wl@A6n9 z&y>It&CO8S{9d23nOL0fG_ekNj$b3(t z3ek8{B7BADF)2Czv7_W_|Boc&!?Dh3f_K__N1P`*02V!Ur9J-G7P-t|;f3lI5&tng zRFs0UD#0%7B#_JvNPkH9Ca43&2_0d#=Da)^3=E$SJnYZrX(2ckyW3zqe|(KG$cia9 z<(HU#6B#08e0z)+y>}feqpZxkDoNzEk^3EFo?Xa6uG^8-ke#b&d{CtQ?I1CVBNCJt z=ywcK%ld8$rTDwe!s?pv$!FeR6N$5yPK=xcssoP+AlxbFWmb8NiB~KGIs5ZQyNd|t zwj=Y-s1_=!QJLLidQGhsap`}qLd0K3WuLmQr(!yq-vV{k6s~$>{Mt=Y*a6`D4CDfz z#gLe8*HuQ{{9g_4dC{{BSebprx-v8|>;Zj9w(wAD84&kO8W(NHy9EhZL@iTRdJAmd z|NI~*mY5oOQx3bFr9cqUUeW0O;%@1!KFa{qWNp( z4!hXqIMch(S5VT_NuSGH{&mR13_+GOuvS<-Vw-3r#plBtug2R@@3(rdB=xpju}o>0 zQFWXm;sSi6h0tx2#(cQaPAfQF(_|xNKAw3d>v@6VZuJ%UxlE}5;-XK`<%YTpVt+P3 zMt}=p_Q}UX%s;9Iu^GI)S(@uApICejHV4rMKl81$Vvm@ zgm%OTG8fnJ!*lowioCwPRsH^D4wi%lrGsDtVc~bsB&+gHf0d5=O+4neUf1>9;51(< z*Qlp@Z$3}qOYU8&94WBg3Jx`yfq^6}%Z#k+4B)CI6_ZnmSY|gD$O0hDMB&8cKxxIvS+ z6;;IA`^z!KgENm^Sou9srNekVal$(-o&|}g3DNySn`gy4aUyRQHu(rj-maVVk2r=gS8ZyLcb7Pt~3DkkpI~c6}*Z z&`a>ygN!iy$~X8cm@`wcvD8bCGnPJ8igU`eJ2yp+T%qeRYDB(#NrmW)IO2JVY>qSj zR8FY~Lo{TMZH6C|2WXopL`I7%+uHj+M!v~AzYJN6DdTUBl#fW_l+o0U^_X1&v&ga7XrHR zFR;Bw=|G}IK}7$N70f*D0Y>-2F}HdOq_8@=w-4`#)tzpw%VKg?@nDl){iqA5C|kxm zBP8-UQ{Ueblw~f-iijCJ3?@$79Hp=~7#)u^V(2fW=vW>xLPcfWJQ8;Zq^Xl{6vhx4 zMmrJ_dVB6nO2S_GxKkJV2nfWu5}G5O-29CZ!#Tv=fo|$XJ8zo*824_$c4`9OzJZGa z!3&h8LszeRAK;vIAuu)a%_z5`LPyOUl}*z2!GIUXT$!)5F^1_5zl^-=*K9!3_h8xw<^dWQiO-(73D3P$D^Np zE-k>AitCIwgs6X)sQj!#WRn0z6O}xLaq|l(?U@mcL<)zHCSvv+w|6AX-Y_o0nfY?z zn;e7_f&y?jyl9j#NzjKgKWJu28&TFr8cK)jiaj&Jr2gkJVvXIF^izEgEiwA%0@4!l z6HX7*YjQ%Ho4)X~B*Hj&MH+{XPv7J^aThF<5F8F&02w5|d5^aK_S444XyrZJoD3^c zHu5Nyi1ylQ?+|I#`)%#gFAY6Bkj+JzH7E~fg@@#r{sNUd^p{4rd$buY^Sq>~;f7{K z^^{bi@?SJ6IUmOw8t#y`PqcDvbl-6zy$l~JiZ%YqL4^9jGmhocW?ecCA7Xe$5xpuJ zGg)+*=0tGg1(pd%?egh;8AO&y!#}udi)HC*H_>VSlkg4BJ=X#G=wC5q@HNzBQO=P{ zFo^`{l3Q)znQSj>C;l3d^06L2a||TU{8Ftzfv`KWLF<-qHh-Ev*VtR7CmAN}zd)mR z?~`H5W@%95F?U$h9kcklzfMYpfA~p*dNkbllra(R<}O@s*_GcT$9KQKX1eOAKh~&m zSeS#AdHYVC`@ozZtr>})w?L|6vGcMClnC)Eo;jAH&&Aw1K4c*ODoOsX#4|W@R-c>M&$0cz~tG(6|O_siE!DN5J85Y5nYmbg1|Tvt=AI=-CtT zQdudJN8_4Eknyu8X9ft)Th{f)z-i3+lpD4@B6Q z>3DPu1PS_MpAY(~KNX0ty6Xr+Q?+i4&)&c3gT~5VrQJl`wD2wCCM;i!uao5d@uI41 z5IQ+Zkyu?Y=JuhcAbceLzyF!R|NdVN|L^~m#XO!Q*WyW8Vt;-MBpZmHmXT)F1^avd E2dqzR#Q*>R literal 0 HcmV?d00001 diff --git a/docs/store/privacy-policy.md b/docs/store/privacy-policy.md new file mode 100644 index 0000000..bc8a78b --- /dev/null +++ b/docs/store/privacy-policy.md @@ -0,0 +1,73 @@ +# SharpClient — Privacy Policy + +**Effective date:** 2026-07-06 +**Applies to:** the SharpClient Android application ("the app") published by the +SharpMUSH project ("we", "us"). + +## Summary + +SharpClient is a client for connecting to text-based multiplayer games (MUD/MUSH +servers). **We do not collect, transmit, or receive any personal data.** The app +has no analytics, no advertising, no tracking, no user accounts with us, and no +third-party SDKs. All data the app stores stays **on your device**. + +## What the app stores on your device + +All of the following is stored only in the app's private storage on your device +and is never sent to us: + +| Data | Where it is stored | Purpose | +| --- | --- | --- | +| Game server addresses (name, host, port) | Local SQLite database (`sharpclient.db`) | So you can reconnect to games you've saved | +| Character names | Local SQLite database | To identify your login on each game | +| Character passwords / connect strings | **OS-encrypted secure storage** (Android Keystore–backed) | To auto-log-in when you choose to save them | +| Triggers and aliases you create | Local SQLite database | Your automation rules | +| Session history / game transcripts | Local SQLite database (full-text index) | So you can scroll back and search what happened | +| Diagnostic and crash logs | Local file in the app's private folder (`logs/sharpclient.log`) | So you can export logs to report a bug | + +The database and logs live in the app's private, sandboxed storage. Automatic +cloud backup is **disabled** (`allowBackup=false`), so this data is not copied to +Google Drive or any other backup service. + +## Data sent over the network + +When you connect to a game, the app opens a direct network connection **to the +server address you entered** and sends what you type — including your character +name and password at login — to **that server**. It does not send anything to us +or to any other party. + +> **Important — connections are unencrypted.** Like virtually all MUD/MUSH +> servers, connections use the Telnet protocol, which is **not encrypted**. Your +> username, password, and everything you send and receive travel in plain text +> between your device and the game server. Only connect to servers you trust, and +> avoid reusing important passwords for game characters. + +We are not the operator of the game servers you connect to. Those servers are +run by independent third parties and have their own privacy practices, which we +do not control. + +## Data sharing + +We do not share your data with anyone, because we never receive it in the first +place. + +## Children's privacy + +The app does not knowingly collect any personal information from anyone, +including children. + +## Deleting your data + +- Delete individual saved games, characters, or history from within the app. +- Uninstalling the app removes all of its local data, including the database, + saved passwords, and logs. + +## Changes to this policy + +If this policy changes, the updated version will be published at the same +location with a new effective date. + +## Contact + +Questions about this policy can be raised via the project's issue tracker: +. diff --git a/docs/store/release-checklist.md b/docs/store/release-checklist.md new file mode 100644 index 0000000..8568d94 --- /dev/null +++ b/docs/store/release-checklist.md @@ -0,0 +1,95 @@ +# First Google Play release — checklist + +End-to-end sequence to get SharpClient onto the Play Store (internal testing +first). Ordered; each step's prerequisites are the steps above it. + +## 0. Prerequisites (one-time) + +- [ ] A Google Play Developer account (one-time US$25 registration). +- [ ] Decide the **package name is final**: `com.sharpmush.sharpclient`. This is + permanent once uploaded and can never be changed. (Renamed from + `…​.sharpclient.app` — see the applicationId change.) + +## 1. Land the code changes + +- [ ] Merge the branch carrying: applicationId rename, `ForegroundScale="0.65"` + icon fix, and `docs/store/` (this checklist, privacy policy, data-safety, + 512 icon). CI (tests + Android head build) must be green. + +## 2. Create the signing keystore + configure secrets ⚠️ REQUIRED before any release + +The release workflow (`.github/workflows/release-apk.yml`) **fails fast** if the +keystore secret is absent — it will never ship an unsigned/debug build. So this +must be done before tagging. Full details in +[`../release-signing.md`](../release-signing.md). + +- [ ] Generate an upload keystore: + ```bash + keytool -genkeypair -v -keystore release.keystore \ + -alias sharpclient -keyalg RSA -keysize 2048 -validity 10000 + ``` +- [ ] Store it + passwords as repository secrets (Settings → Secrets → Actions): + `ANDROID_KEYSTORE_BASE64`, `ANDROID_KEYSTORE_PASSWORD`, `ANDROID_KEY_ALIAS`, + `ANDROID_KEY_PASSWORD`. +- [ ] **Back up the keystore + passwords somewhere safe.** With Play App Signing + (below) a lost *upload* key is recoverable; without it, losing the key means + you can't publish updates under this app identity. + +## 3. Pick the first version and tag + +`release-apk.yml` derives the Android `versionName`/`versionCode` from the release +tag (`vMAJOR.MINOR.PATCH`): +`versionCode = major*100000000 + minor*10000 + patch`. + +- [ ] Choose the first version. **Recommended: `v0.1.0`** for the initial + internal-testing build (versionCode `10000`), leaving room to iterate before + a `v1.0.0` public launch. (`v1.0.0` → versionCode `100000000` is also fine.) + Remember: a Play `versionCode` can never be reused or decreased. +- [ ] Publish a **GitHub Release** with that tag. This triggers the workflow, + which builds and attaches a **signed `.aab`** (for Play) and a signed `.apk` + (for sideloading) to the release. + +## 4. Play Console — create the app + upload + +- [ ] Create the app in Play Console (default language, app name "SharpClient", + app/not game — though it's a game *client*, "App" is fine). +- [ ] Accept **Play App Signing** (recommended): Google holds the app signing + key; your keystore from step 2 is the *upload* key. +- [ ] Create an **Internal testing** release and upload the `.aab` from step 3. + Add tester email addresses. + +## 5. Play Console — required listing content + +- [ ] **App icon:** `docs/store/play-listing-icon-512.png` (512×512). +- [ ] **Feature graphic:** 1024×500 PNG/JPG — *required* for the listing. Not yet + generated; can be produced from the logo on request. +- [ ] **Screenshots:** at least 2 phone screenshots (existing shots live in + `.github/assets/` and may be reused/resized). +- [ ] **Short + full description.** +- [ ] **Privacy policy URL:** host `docs/store/privacy-policy.md` publicly (see + that file / the data-safety doc for options) and paste the URL. +- [ ] **Data safety form:** fill per [`play-data-safety.md`](./play-data-safety.md). +- [ ] **Content rating** questionnaire. +- [ ] **Target audience**, **ads declaration** (no ads), **news/COVID** (no). + +## 6. Submit + +- [ ] Send the internal-testing release for review; once approved, testers can + install via the opt-in link. Promote to closed/open testing → production + when ready. + +--- + +### What's already done in-repo + +- Signed `.aab` + `.apk` CI pipeline (`release-apk.yml`), tag→version derivation. +- Target API 35 (net10 android default), minSdk 24, `allowBackup=false`. +- Final package name `com.sharpmush.sharpclient`. +- Adaptive icon fixed (`ForegroundScale=0.65`) + 512 listing icon. +- Privacy policy + data-safety content. + +### Still needs a human decision / action + +- Keystore generation + secret upload (step 2). +- Version choice + tagging (step 3) — **held pending your confirmation.** +- Play Console account, listing copy, feature graphic, content rating (steps 4–6). From 91325f7c64df9172dcfa9811fd0baa918853849f Mon Sep 17 00:00:00 2001 From: HarryCordewener Date: Mon, 6 Jul 2026 12:49:35 -0500 Subject: [PATCH 3/7] chore(release): align version baseline with the live Obtainium release line The GitHub/Obtainium releases run v0.1..v1.3; v1.3 shipped versionName 1.3 / versionCode 100030000 (tag-derived in release-apk.yml). Update the stale csproj baseline (template 1.0/1) to 1.3 / 100030000 so untagged/dev builds report the real current version, and fix the release checklist to continue the line at v1.4 (-> 100040000) instead of a v0.x reset that would derive a lower code. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01HHCRc5CJ6595iMzEgYYdQp --- docs/store/release-checklist.md | 17 ++++++++++++----- src/SharpClient.App/SharpClient.App.csproj | 11 ++++++++--- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/docs/store/release-checklist.md b/docs/store/release-checklist.md index 8568d94..da69120 100644 --- a/docs/store/release-checklist.md +++ b/docs/store/release-checklist.md @@ -41,10 +41,16 @@ must be done before tagging. Full details in tag (`vMAJOR.MINOR.PATCH`): `versionCode = major*100000000 + minor*10000 + patch`. -- [ ] Choose the first version. **Recommended: `v0.1.0`** for the initial - internal-testing build (versionCode `10000`), leaving room to iterate before - a `v1.0.0` public launch. (`v1.0.0` → versionCode `100000000` is also fine.) - Remember: a Play `versionCode` can never be reused or decreased. +- [ ] Choose the version by **continuing the existing release line**, not + restarting. The Obtainium/GitHub releases run `v0.1 … v1.3`, and v1.3 shipped + `versionName 1.3 / versionCode 100030000`. So the next release is **`v1.4`** + (→ versionCode `100040000`), keeping one coherent version line across + Obtainium and Play. A `v0.x` reset would derive a *lower* code and is wrong. + - Note on the rename: Play tracks versionCodes **per package**, and this is a + brand-new package (`com.sharpmush.sharpclient`), so Play has no prior code to + exceed — but continuing at `v1.4` keeps the human version consistent with the + `…​.app` builds users already have. A Play `versionCode` can never be reused + or decreased *within* a package. - [ ] Publish a **GitHub Release** with that tag. This triggers the workflow, which builds and attaches a **signed `.aab`** (for Play) and a signed `.apk` (for sideloading) to the release. @@ -91,5 +97,6 @@ tag (`vMAJOR.MINOR.PATCH`): ### Still needs a human decision / action - Keystore generation + secret upload (step 2). -- Version choice + tagging (step 3) — **held pending your confirmation.** +- Version choice + tagging (step 3) — next in line is **`v1.4`**; held pending + keystore secrets + your go-ahead. - Play Console account, listing copy, feature graphic, content rating (steps 4–6). diff --git a/src/SharpClient.App/SharpClient.App.csproj b/src/SharpClient.App/SharpClient.App.csproj index cf46dbb..ff3563b 100644 --- a/src/SharpClient.App/SharpClient.App.csproj +++ b/src/SharpClient.App/SharpClient.App.csproj @@ -34,9 +34,14 @@ com.sharpmush.sharpclient - - 1.0 - 1 + + 1.3 + 100030000 None From e465182f72d7bb076bc4a6eef40aca136c3ce577 Mon Sep 17 00:00:00 2001 From: HarryCordewener Date: Mon, 6 Jul 2026 13:08:52 -0500 Subject: [PATCH 4/7] docs(store): add 1024x500 Play feature graphic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Terminal-style feature graphic (option B): green SharpMUSH M on near-black, "> connect any MUD or MUSH" with a block cursor at the end of the line, and a feature strip (telnet · triggers · aliases · reconnect). Built from the real M mark and the app's own brand fonts (Space Grotesk wordmark, JetBrains Mono). Checklist updated to point at the asset. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01HHCRc5CJ6595iMzEgYYdQp --- docs/store/play-feature-graphic-1024x500.png | Bin 0 -> 39395 bytes docs/store/release-checklist.md | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 docs/store/play-feature-graphic-1024x500.png diff --git a/docs/store/play-feature-graphic-1024x500.png b/docs/store/play-feature-graphic-1024x500.png new file mode 100644 index 0000000000000000000000000000000000000000..bb56b1392737c193405956b2bc0c829d48228cc7 GIT binary patch literal 39395 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 literal 0 HcmV?d00001 diff --git a/docs/store/release-checklist.md b/docs/store/release-checklist.md index da69120..52c039c 100644 --- a/docs/store/release-checklist.md +++ b/docs/store/release-checklist.md @@ -67,8 +67,8 @@ tag (`vMAJOR.MINOR.PATCH`): ## 5. Play Console — required listing content - [ ] **App icon:** `docs/store/play-listing-icon-512.png` (512×512). -- [ ] **Feature graphic:** 1024×500 PNG/JPG — *required* for the listing. Not yet - generated; can be produced from the logo on request. +- [ ] **Feature graphic:** `docs/store/play-feature-graphic-1024x500.png` + (1024×500, required) — green M on near-black with a terminal-prompt tagline. - [ ] **Screenshots:** at least 2 phone screenshots (existing shots live in `.github/assets/` and may be reused/resized). - [ ] **Short + full description.** From cdf89f904f3c0b59978792b0dbdb77e54c0831b0 Mon Sep 17 00:00:00 2001 From: HarryCordewener Date: Mon, 6 Jul 2026 13:47:03 -0500 Subject: [PATCH 5/7] docs(store): drop old-package breadcrumbs; fix privacy summary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean start on com.sharpmush.sharpclient (no users yet), so remove the migration cruft: strip the "renamed from …app" note and the "…app builds users already have" version rationale, reframing the version note around the GitHub release-tag line (continue at v1.4). Also resolve the Copilot-flagged contradiction in the privacy summary — "transmit" wrongly implied we never send your input anywhere, so scope it to us/third parties (the app still sends your input to the game server you pick). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01HHCRc5CJ6595iMzEgYYdQp --- docs/store/privacy-policy.md | 8 +++++--- docs/store/release-checklist.md | 18 ++++++------------ 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/docs/store/privacy-policy.md b/docs/store/privacy-policy.md index bc8a78b..60eba6a 100644 --- a/docs/store/privacy-policy.md +++ b/docs/store/privacy-policy.md @@ -7,9 +7,11 @@ SharpMUSH project ("we", "us"). ## Summary SharpClient is a client for connecting to text-based multiplayer games (MUD/MUSH -servers). **We do not collect, transmit, or receive any personal data.** The app -has no analytics, no advertising, no tracking, no user accounts with us, and no -third-party SDKs. All data the app stores stays **on your device**. +servers). **We do not collect or receive any of your personal data.** The app +sends what you type only to the game server you choose to connect to — never to +us or any third party. It has no analytics, no advertising, no tracking, no user +accounts with us, and no third-party SDKs. All data the app stores stays **on +your device**. ## What the app stores on your device diff --git a/docs/store/release-checklist.md b/docs/store/release-checklist.md index 52c039c..2f793e5 100644 --- a/docs/store/release-checklist.md +++ b/docs/store/release-checklist.md @@ -7,8 +7,7 @@ first). Ordered; each step's prerequisites are the steps above it. - [ ] A Google Play Developer account (one-time US$25 registration). - [ ] Decide the **package name is final**: `com.sharpmush.sharpclient`. This is - permanent once uploaded and can never be changed. (Renamed from - `…​.sharpclient.app` — see the applicationId change.) + permanent once uploaded and can never be changed. ## 1. Land the code changes @@ -41,16 +40,11 @@ must be done before tagging. Full details in tag (`vMAJOR.MINOR.PATCH`): `versionCode = major*100000000 + minor*10000 + patch`. -- [ ] Choose the version by **continuing the existing release line**, not - restarting. The Obtainium/GitHub releases run `v0.1 … v1.3`, and v1.3 shipped - `versionName 1.3 / versionCode 100030000`. So the next release is **`v1.4`** - (→ versionCode `100040000`), keeping one coherent version line across - Obtainium and Play. A `v0.x` reset would derive a *lower* code and is wrong. - - Note on the rename: Play tracks versionCodes **per package**, and this is a - brand-new package (`com.sharpmush.sharpclient`), so Play has no prior code to - exceed — but continuing at `v1.4` keeps the human version consistent with the - `…​.app` builds users already have. A Play `versionCode` can never be reused - or decreased *within* a package. +- [ ] Choose the version by **continuing the existing release-tag line**, not + restarting. The GitHub release tags run `v0.1 … v1.3` (v1.3 = + `versionName 1.3 / versionCode 100030000`), so the next release is **`v1.4`** + (→ versionCode `100040000`). A `v0.x` reset would derive a *lower* code and is + wrong. A Play `versionCode` can never be reused or decreased. - [ ] Publish a **GitHub Release** with that tag. This triggers the workflow, which builds and attaches a **signed `.aab`** (for Play) and a signed `.apk` (for sideloading) to the release. From a35a38ef2278e573e40633a9f5a899b6095300d5 Mon Sep 17 00:00:00 2001 From: HarryCordewener Date: Mon, 6 Jul 2026 13:49:34 -0500 Subject: [PATCH 6/7] Revert csproj version bump; the git tag is the sole source of truth release-apk.yml overrides ApplicationDisplayVersion/ApplicationVersion from the tag on every release, so hardcoding 1.3/100030000 was dead config that only added a second, drift-prone version source and made local/dev builds falsely report a real release version. Restore the neutral 1.0/1 dev placeholders and document that the tag is authoritative and these must not be bumped per release. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01HHCRc5CJ6595iMzEgYYdQp --- src/SharpClient.App/SharpClient.App.csproj | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/SharpClient.App/SharpClient.App.csproj b/src/SharpClient.App/SharpClient.App.csproj index ff3563b..2d1387b 100644 --- a/src/SharpClient.App/SharpClient.App.csproj +++ b/src/SharpClient.App/SharpClient.App.csproj @@ -34,14 +34,12 @@ com.sharpmush.sharpclient - - 1.3 - 100030000 + + 1.0 + 1 None From b0dbceb2a04413f637e6acb92f93bf869b13a2ce Mon Sep 17 00:00:00 2001 From: HarryCordewener Date: Mon, 6 Jul 2026 13:52:18 -0500 Subject: [PATCH 7/7] Trim verbose csproj comments to one line each Cut the multi-line version and ForegroundScale notes down to a single line apiece; the detail belongs in the PR/docs, not strewn through the project file. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01HHCRc5CJ6595iMzEgYYdQp --- src/SharpClient.App/SharpClient.App.csproj | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/SharpClient.App/SharpClient.App.csproj b/src/SharpClient.App/SharpClient.App.csproj index 2d1387b..5c4764d 100644 --- a/src/SharpClient.App/SharpClient.App.csproj +++ b/src/SharpClient.App/SharpClient.App.csproj @@ -34,10 +34,7 @@ com.sharpmush.sharpclient - + 1.0 1 @@ -77,14 +74,8 @@ cleanly on it (adaptive icons, Android 8+); the teal base blends into the matching green so the background looks solid. Previously #0b0e12, which put the dark mark on near-black and rendered as "black on grey". - ForegroundScale="0.65": the logo SVG fills its whole viewport (peaks/legs run edge to - edge). Android adaptive icons reserve the outer 18dp of the 108dp layer - for the launcher mask (circle/squircle/rounded-square/teardrop), so a - full-bleed foreground gets its peaks and outer legs clipped. 0.65 is the - stock MAUI/Google template value: it shrinks + centers the foreground - into the safe zone so the whole M survives every mask. MAUI does NOT - apply this inset automatically — omitting it renders full-bleed (the - prior cropping). We never bake the mask shape ourselves; the OS does. + ForegroundScale="0.65" insets the foreground into the adaptive-icon safe zone + (MAUI renders it full-bleed otherwise, so launcher masks crop the mark). -->