Skip to content

Commit 24fe884

Browse files
committed
Added some configuration options + clean up
1 parent ceac759 commit 24fe884

6 files changed

Lines changed: 91 additions & 18 deletions

File tree

conf.properties

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,9 @@ auth.password=
1212
## Spotify authentication blob (BLOB)
1313
auth.blob=
1414
## Cache enabled
15-
cache.enabled=false
15+
cache.enabled=false
16+
# Zeroconf
17+
## Listen on all interfaces (overrides `zeroconf.interfaces`)
18+
zeroconf.listenAll=true
19+
## Listen on this interfaces (comma separated list of names)
20+
zeroconf.interfaces=

core/src/main/java/xyz/gianlu/librespot/AbsConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
import org.jetbrains.annotations.Nullable;
44
import xyz.gianlu.librespot.core.AuthConfiguration;
55
import xyz.gianlu.librespot.core.Session;
6+
import xyz.gianlu.librespot.core.ZeroconfAuthenticator;
67
import xyz.gianlu.librespot.player.CacheManager;
78
import xyz.gianlu.librespot.player.Player;
89

910
/**
1011
* @author Gianlu
1112
*/
12-
public abstract class AbsConfiguration implements Player.PlayerConfiguration, CacheManager.CacheConfiguration, AuthConfiguration {
13+
public abstract class AbsConfiguration implements Player.PlayerConfiguration, CacheManager.CacheConfiguration, AuthConfiguration, ZeroconfAuthenticator.Configuration {
1314

1415
@Nullable
1516
public abstract String deviceName();

core/src/main/java/xyz/gianlu/librespot/DefaultConfiguration.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,14 @@ public Session.DeviceType deviceType() {
8383
public Strategy strategy() {
8484
return Strategy.ZEROCONF;
8585
}
86+
87+
@Override
88+
public boolean zeroconfListenAll() {
89+
return true;
90+
}
91+
92+
@Override
93+
public @NotNull String[] zeroconfInterfaces() {
94+
return new String[0];
95+
}
8696
}

core/src/main/java/xyz/gianlu/librespot/FileConfiguration.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ private <E extends Enum<E>> E getEnum(@NotNull Class<E> clazz, @NotNull String k
7373
}
7474
}
7575

76+
@NotNull
77+
private String[] getStringArray(@NotNull String key, @NotNull String[] fallback) {
78+
String str = properties.getProperty(key, null);
79+
if (str == null) return fallback;
80+
else if ((str = str.trim()).isEmpty()) return new String[0];
81+
else return Utils.split(str, ',');
82+
}
83+
7684
@Override
7785
public boolean cacheEnabled() {
7886
return getBoolean("cache.enabled", defaults.cacheEnabled());
@@ -133,4 +141,15 @@ public float normalisationPregain() {
133141
public Strategy strategy() {
134142
return getEnum(Strategy.class, "auth.strategy", defaults.strategy());
135143
}
144+
145+
@Override
146+
public boolean zeroconfListenAll() {
147+
return getBoolean("zeroconf.listenAll", defaults.zeroconfListenAll());
148+
}
149+
150+
@NotNull
151+
@Override
152+
public String[] zeroconfInterfaces() {
153+
return getStringArray("zeroconf.interfaces", defaults.zeroconfInterfaces());
154+
}
136155
}

core/src/main/java/xyz/gianlu/librespot/core/Session.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,9 +405,12 @@ public static class Builder {
405405
private final Inner inner;
406406
private Authentication.LoginCredentials loginCredentials = null;
407407
private AuthConfiguration authConf;
408+
private ZeroconfAuthenticator.Configuration zeroconfConf;
408409

409410
public Builder(@NotNull DeviceType deviceType, @NotNull String deviceName, @NotNull AbsConfiguration configuration) {
410411
this.inner = new Inner(deviceType, deviceName, configuration);
412+
this.authConf = configuration;
413+
this.zeroconfConf = configuration;
411414
}
412415

413416
public Builder(@NotNull AbsConfiguration configuration) {
@@ -421,6 +424,7 @@ public Builder(@NotNull AbsConfiguration configuration) {
421424

422425
this.inner = new Inner(deviceType, deviceName, configuration);
423426
this.authConf = configuration;
427+
this.zeroconfConf = configuration;
424428
}
425429

426430
public Builder facebook() throws IOException {
@@ -433,7 +437,7 @@ public Builder facebook() throws IOException {
433437
}
434438

435439
public Builder zeroconf() throws IOException {
436-
try (ZeroconfAuthenticator authenticator = new ZeroconfAuthenticator(inner)) {
440+
try (ZeroconfAuthenticator authenticator = new ZeroconfAuthenticator(inner, zeroconfConf)) {
437441
loginCredentials = authenticator.lockUntilCredentials();
438442
return this;
439443
} catch (InterruptedException ex) {

core/src/main/java/xyz/gianlu/librespot/core/ZeroconfAuthenticator.java

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,35 +62,62 @@ public class ZeroconfAuthenticator implements Closeable {
6262
private final Session.Inner session;
6363
private final DiffieHellman keys;
6464

65-
ZeroconfAuthenticator(Session.Inner session) throws IOException {
65+
ZeroconfAuthenticator(Session.Inner session, Configuration conf) throws IOException {
6666
this.session = session;
6767
this.keys = new DiffieHellman(session.random);
6868
this.mDnsService = new MulticastDNSService();
6969

7070
int port = session.random.nextInt((MAX_PORT - MIN_PORT) + 1) + MIN_PORT;
7171
new Thread(this.runner = new HttpRunner(port)).start();
72-
ArrayList<InetAddress> addressArrayList = new ArrayList<>();
73-
Enumeration<NetworkInterface> networkInterfaces= NetworkInterface.getNetworkInterfaces();
74-
while(networkInterfaces.hasMoreElements()){
75-
NetworkInterface networkInterface = networkInterfaces.nextElement();
76-
Enumeration<InetAddress> interfaceAddresses = networkInterface.getInetAddresses();
77-
if(!networkInterface.isLoopback()) {
78-
while (interfaceAddresses.hasMoreElements()) {
79-
InetAddress address = interfaceAddresses.nextElement();
80-
if(!address.isLoopbackAddress())
81-
addressArrayList.add(address);
82-
}
72+
73+
InetAddress[] bound;
74+
if (conf.zeroconfListenAll()) {
75+
bound = getAllInterfacesAddresses();
76+
} else {
77+
String[] interfaces = conf.zeroconfInterfaces();
78+
if (interfaces.length == 0) {
79+
bound = new InetAddress[]{InetAddress.getLoopbackAddress()};
80+
} else {
81+
List<InetAddress> list = new ArrayList<>();
82+
for (String str : interfaces) addAddressForInterfaceName(list, str);
83+
bound = list.toArray(new InetAddress[0]);
8384
}
8485
}
85-
InetAddress[] addressArray = addressArrayList.toArray(new InetAddress[addressArrayList.size()]);
86-
addressArrayList.add(InetAddress.getByName(InetAddress.getLocalHost().getCanonicalHostName()));
87-
ServiceInstance service = new ServiceInstance(new ServiceName("librespot._spotify-connect._tcp.local."), 0, 0, port, Name.fromString("local."), addressArray, "VERSION=1.0", "CPath=/");
86+
87+
LOGGER.debug("Registering service on " + Arrays.toString(bound));
88+
89+
ServiceInstance service = new ServiceInstance(new ServiceName("librespot._spotify-connect._tcp.local."), 0, 0, port, Name.fromString("local."), bound, "VERSION=1.0", "CPath=/");
8890
spotifyConnectService = mDnsService.register(service);
8991
if (spotifyConnectService == null)
9092
throw new IOException("Failed registering SpotifyConnect service!");
9193
LOGGER.info("SpotifyConnect service registered successfully!");
9294
}
9395

96+
private static void addAddressForInterfaceName(List<InetAddress> list, @NotNull String name) throws SocketException {
97+
NetworkInterface nif = NetworkInterface.getByName(name);
98+
if (nif == null) {
99+
LOGGER.warn(String.format("Interface %s doesn't exists.", name));
100+
return;
101+
}
102+
103+
addAddressOfInterface(list, nif);
104+
}
105+
106+
private static void addAddressOfInterface(List<InetAddress> list, @NotNull NetworkInterface nif) {
107+
LOGGER.trace(String.format("Adding addresses of %s (displayName: %s)", nif.getName(), nif.getDisplayName()));
108+
Enumeration<InetAddress> ias = nif.getInetAddresses();
109+
while (ias.hasMoreElements())
110+
list.add(ias.nextElement());
111+
}
112+
113+
@NotNull
114+
private static InetAddress[] getAllInterfacesAddresses() throws SocketException {
115+
List<InetAddress> list = new ArrayList<>();
116+
Enumeration<NetworkInterface> is = NetworkInterface.getNetworkInterfaces();
117+
while (is.hasMoreElements()) addAddressOfInterface(list, is.nextElement());
118+
return list.toArray(new InetAddress[0]);
119+
}
120+
94121
@Override
95122
public void close() throws IOException {
96123
mDnsService.unregister(spotifyConnectService);
@@ -204,6 +231,13 @@ Authentication.LoginCredentials lockUntilCredentials() throws InterruptedExcepti
204231
}
205232
}
206233

234+
public interface Configuration {
235+
boolean zeroconfListenAll();
236+
237+
@NotNull
238+
String[] zeroconfInterfaces();
239+
}
240+
207241
private class HttpRunner implements Runnable, Closeable {
208242
private final ServerSocket serverSocket;
209243
private volatile boolean shouldStop = false;

0 commit comments

Comments
 (0)