Skip to content

Commit ed87d51

Browse files
Add donor-labeled server presets
Add built-in StormDNS server presets from shared WhiteDNS sources and donor channels. Use donor/source labels as the visible preset names and append stable counters for repeated sources so duplicate donors remain distinguishable in selection UI. Add tests covering non-empty preset data, stable unique IDs, numbered repeated labels, and expected donor/source naming.
1 parent 045fdeb commit ed87d51

2 files changed

Lines changed: 149 additions & 1 deletion

File tree

app/src/main/java/shop/whitedns/client/storm/StormDnsBuiltInPool.kt

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,118 @@ package shop.whitedns.client.storm
33
import shop.whitedns.client.model.StormDnsServerProfile
44

55
object StormDnsBuiltInPool {
6-
val profiles: List<StormDnsServerProfile> = emptyList()
6+
val profiles: List<StormDnsServerProfile> = listOf(
7+
profile("@WhiteDNS", "v.whitedns1.shop", "c8328f9d541860df1637b9b3ed7b990e"),
8+
profile("@WhiteDNS", "v.whitedns2.shop", "7ecd7b6271c47e348f6ab177517ee8fa"),
9+
profile("@WhiteDNS", "v.whitedns3.shop", "9d7aedcaf1f94e784a24fdfc1348a337"),
10+
profile("@WhiteDNS", "v.whitedns4.shop", "0ce14ab71acebbd46b8129e25593155a"),
11+
profile("@WhiteDNS", "v.whitedns5.shop", "2dffd162cb02b278c1ab57ee17fe07ae"),
12+
profile("@WhiteDNS", "v.whitedns6.shop", "e32afdaa30ca36ead696cd90d84ced15"),
13+
profile("@WhiteDNS", "v.whitedns7.shop", "6394eec942238533798ec7524eb7ea66"),
14+
profile("@WhiteDNS", "v.whitedns8.shop", "1c167e9850936655c480e4938b2c5c35"),
15+
profile("@WhiteDNS", "v.whitedns.shop", "b07dc357360d6e6896509136d7097897"),
16+
profile("@WhiteDNS", "v9.whitedns.shop", "a2f3348bfa02170639970f2d63f103dc"),
17+
profile("@WhiteDNS", "v10.whitedns.shop", "1ecd5fdfe351a9313cea39fe1b9c59dd"),
18+
profile("@WhiteDNS", "v11.whitedns.shop", "4c1669326cdbe898cab0965ace3010c0"),
19+
profile("@WhiteDNS", "v12.whitedns.shop", "009c514b2a643ed40cbd7cc619389b0f"),
20+
profile("@WhiteDNS", "v13.whitedns.shop", "e2918870ce88f05547fbfba99aee4ec5"),
21+
profile("@WhiteDNS", "v14.whitedns.shop", "9b8672a352d040489d96be9df97ed966"),
22+
profile("@WhiteDNS", "v15.whitedns.shop", "9aa68e7e9a7c22d91d8f466d64a35dff"),
23+
profile("@WhiteDNS", "v16.whitedns.shop", "592845ca38f19461383d05733c33214c"),
24+
profile("@WhiteDNS", "v17.whitedns.shop", "576550354a7309530b7fa25152dc672f"),
25+
profile("@WhiteDNS", "v18.whitedns.shop", "d0538a3d545a7830b8bb2eb0c3748e95"),
26+
profile("@WhiteDNS", "v.whitedns.space", "bad99364093861634030e96f11fe3132"),
27+
profile("@WhiteDNS", "v.whitedns.site", "bad99364093861634030e96f11fe3132"),
28+
29+
profile("@PersiaTMChannel", "t1.prs612.us", "3e80a0eb3e1fba2bf17e0e0eb5783dc5"),
30+
profile("@PersiaTMChannel", "t2.prs612.us", "afc1bd5e98cd98cde7515adb7295122b"),
31+
profile("@PersiaTMChannel", "t3.prs612.us", "8786a860148e2d4d55403ae3c80ba854"),
32+
profile("@PersiaTMChannel", "t4.prs612.us", "943664f15fd1763e242ce12ba993d9c9"),
33+
profile("@PersiaTMChannel", "t5.prs612.us", "6a9ab24a8bd3937378efbfb3c23e1358"),
34+
profile("@PersiaTMChannel", "t6.prs612.us", "71201fedadfbc0b62189c08961bce651"),
35+
profile("@PersiaTMChannel", "t7.prs612.us", "c4ff91174a79e9e03a4d6727878ada17"),
36+
profile("@PersiaTMChannel", "t8.prs612.us", "ae5db6f03e485214e1fcc9d26a4c0a2f"),
37+
profile("@PersiaTMChannel", "t9.prs612.us", "a01c03a340a3e684a2815961e086eb27"),
38+
profile("@PersiaTMChannel", "t10.prs612.us", "f3a3c5d02bb7ce04f6a4f144fc35e9cb"),
39+
profile("@PersiaTMChannel", "t11.prs612.us", "e7f2db07e778563d31ed1fc80d5fe612"),
40+
41+
profile("Ali / @link_dakheli_app", "te.link-dakheli-app.shop", "TelegramChannel@link_dakheli_app"),
42+
profile("Ali / @link_dakheli_app", "s.o4s.shop", "TelegramChannel@link_dakheli_app"),
43+
profile("Ali / @link_dakheli_app", "s2.o5s.shop", "TelegramChannel@link_dakheli_app"),
44+
45+
profile("@hamedvpns / @Config0plus", "ob.networks.icu", "3947d5ac68015a09a53a0b361bd82999"),
46+
profile("@hamedvpns / @Config0plus", "ts.networks.icu", "e0e71e667e5dcfe3b18e3bce659773d2"),
47+
profile("@hamedvpns / @Config0plus", "zw.networks.icu", "0798c0e8aa05080125e6c65282fd792b"),
48+
49+
profile("Rouh Jangali", "v.0x0.guru", "33815e1bcb88873f2199c735828ea745"),
50+
profile("Rouh Jangali", "v.iranmn.best", "aaed913b8367fce3e20910472d9e3e2d"),
51+
profile("Rouh Jangali", "v.kmjhfilterchi.shop", "4f3d0262ba2bd7cc20b596bdbc77f761"),
52+
53+
profile("Rasoul", "v.eshkaftak.vip", "8705eb75abeedcd99001ef8d01cf9fad"),
54+
profile("Rasoul", "v3.eshkaftak.vip", "8705eb75abeedcd99001ef8d01cf9fad"),
55+
profile("Rasoul", "v4.eshkaftak.vip", "8705eb75abeedcd99001ef8d01cf9fad"),
56+
profile("Rasoul", "v5.eshkaftak.vip", "8705eb75abeedcd99001ef8d01cf9fad"),
57+
profile("Rasoul", "v6.eshkaftak.vip", "8705eb75abeedcd99001ef8d01cf9fad"),
58+
profile("Rasoul", "g1.rmft.tech", "a337e9fa75161c44bebe7d717da36afc"),
59+
profile("Rasoul", "g2.rmft.tech", "a337e9fa75161c44bebe7d717da36afc"),
60+
profile("Rasoul", "g3.rmft.tech", "a337e9fa75161c44bebe7d717da36afc"),
61+
profile("Rasoul", "g4.rmft.tech", "a337e9fa75161c44bebe7d717da36afc"),
62+
profile("Rasoul", "g5.rmft.tech", "a337e9fa75161c44bebe7d717da36afc"),
63+
profile("Rasoul", "g6.rmft.tech", "a337e9fa75161c44bebe7d717da36afc"),
64+
profile("Rasoul", "g7.rmft.tech", "a337e9fa75161c44bebe7d717da36afc"),
65+
66+
profile("@Masir_Sefid", "s.o4s.shop", "Telegram-Channel--->@Masir_Sefid"),
67+
profile("@Masir_Sefid", "s2.o4s.shop", "Telegram-Channel--->@Masir_Sefid"),
68+
profile("@Masir_Sefid", "s3.o4s.shop", "Telegram-Channel--->@Masir_Sefid"),
69+
profile("@Masir_Sefid", "s4.o4s.shop", "Telegram-Channel--->@Masir_Sefid"),
70+
profile("@Masir_Sefid", "s5.o4s.shop", "Telegram-Channel--->@Masir_Sefid"),
71+
profile("@Masir_Sefid", "v1.masir-sefid-1.shop", "Telegram-Channel--->@Masir_Sefid"),
72+
profile("@Masir_Sefid", "v2.masir-sefid-1.shop", "Telegram-Channel--->@Masir_Sefid"),
73+
profile("@Masir_Sefid", "v3.masir-sefid-1.shop", "Telegram-Channel--->@Masir_Sefid"),
74+
profile("@Masir_Sefid", "v4.masir-sefid-1.shop", "Telegram-Channel--->@Masir_Sefid"),
75+
profile("@Masir_Sefid", "v5.masir-sefid-1.shop", "Telegram-Channel--->@Masir_Sefid"),
76+
77+
profile("@pythash", "v1.abolfazlshahi.cloud", "a4c5649c628ac1103ad55c5208e0d74d"),
78+
profile("@pythash", "v2.abolfazlshahi.cloud", "965a568dccef58af7afb86e8ee55eea6"),
79+
).withDonorCounters()
80+
81+
private fun profile(
82+
label: String,
83+
domain: String,
84+
encryptionKey: String,
85+
): StormDnsServerProfile {
86+
return StormDnsServerProfile(
87+
id = "preset-${label.toPresetIdSegment()}-${domain.toPresetIdSegment()}",
88+
label = label,
89+
domain = domain,
90+
encryptionKey = encryptionKey,
91+
encryptionMethod = 1,
92+
)
93+
}
94+
95+
private fun List<StormDnsServerProfile>.withDonorCounters(): List<StormDnsServerProfile> {
96+
val donorCounts = groupingBy { it.label }.eachCount()
97+
val seenDonors = mutableMapOf<String, Int>()
98+
return map { profile ->
99+
val donorTotal = donorCounts.getValue(profile.label)
100+
if (donorTotal == 1) {
101+
profile
102+
} else {
103+
val donorIndex = (seenDonors[profile.label] ?: 0) + 1
104+
seenDonors[profile.label] = donorIndex
105+
val donorCounter = donorIndex.toString().padStart(2, '0')
106+
val numberedLabel = "${profile.label} $donorCounter"
107+
profile.copy(
108+
id = "preset-${profile.label.toPresetIdSegment()}-$donorCounter-${profile.domain.toPresetIdSegment()}",
109+
label = numberedLabel,
110+
)
111+
}
112+
}
113+
}
114+
115+
private fun String.toPresetIdSegment(): String {
116+
return lowercase()
117+
.replace(Regex("[^a-z0-9]+"), "-")
118+
.trim('-')
119+
}
7120
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package shop.whitedns.client.storm
2+
3+
import org.junit.Assert.assertEquals
4+
import org.junit.Assert.assertTrue
5+
import org.junit.Test
6+
7+
class StormDnsBuiltInPoolTest {
8+
@Test
9+
fun builtInServerProfilesHaveStableUniqueIds() {
10+
val profiles = StormDnsBuiltInPool.profiles
11+
12+
assertTrue(profiles.isNotEmpty())
13+
assertEquals(profiles.size, profiles.map { it.id }.distinct().size)
14+
}
15+
16+
@Test
17+
fun repeatedDonorLabelsAreNumbered() {
18+
val whiteDnsProfiles = StormDnsBuiltInPool.profiles
19+
.filter { it.label.startsWith("@WhiteDNS ") }
20+
21+
assertTrue(whiteDnsProfiles.size > 1)
22+
assertEquals("@WhiteDNS 01", whiteDnsProfiles.first().label)
23+
assertTrue(whiteDnsProfiles.any { it.label == "@WhiteDNS 02" })
24+
}
25+
26+
@Test
27+
fun presetLabelsUseDonorNames() {
28+
val labels = StormDnsBuiltInPool.profiles.map { it.label }.toSet()
29+
30+
assertTrue(labels.any { it.startsWith("@PersiaTMChannel ") })
31+
assertTrue(labels.any { it.startsWith("Ali / @link_dakheli_app ") })
32+
assertTrue(labels.any { it.startsWith("@Masir_Sefid ") })
33+
assertTrue(labels.any { it.startsWith("@pythash ") })
34+
}
35+
}

0 commit comments

Comments
 (0)