package jrummikub.server; import java.net.BindException; import java.net.InetAddress; import org.apache.vysper.mina.TCPEndpoint; import org.apache.vysper.storage.OpenStorageProviderRegistry; import org.apache.vysper.xmpp.addressing.Entity; import org.apache.vysper.xmpp.authorization.UserAuthorization; import org.apache.vysper.xmpp.modules.extension.xep0045_muc.MUCModule; import org.apache.vysper.xmpp.modules.extension.xep0045_muc.storage.InMemoryOccupantStorageProvider; import org.apache.vysper.xmpp.modules.extension.xep0045_muc.storage.InMemoryRoomStorageProvider; import org.apache.vysper.xmpp.modules.roster.persistence.MemoryRosterManager; import org.apache.vysper.xmpp.server.XMPPServer; /** * Implements a simple XMPP server with a global server password */ public class DedicatedServer { private volatile String serverPassword; private String hostName; /** * Creates a new dedicated server with the specified password * * @param serverPassword * the password */ public DedicatedServer(String serverPassword) { this.serverPassword = serverPassword; try { InetAddress addr = InetAddress.getLocalHost(); hostName = addr.getCanonicalHostName(); } catch (Exception e) { hostName = "localhost"; } } /** * Change the current server password * * @param password * the new server password */ public void setServerPassword(String password) { serverPassword = password; } /** * Get the current server password * * @return the current server password */ public String getServerPassword() { return serverPassword; } /** * Getter for host name * * @return host name */ public String getHostName() { return hostName; } /** * Result of server startup attempt */ public enum ServerStatus { /** Server successfully started */ STARTED, /** Server already running on this machine */ ALREADY_RUNNING, /** Other error */ ERROR } /** * Start the server * * @return Whether we could start the server */ public ServerStatus start() { try { XMPPServer server = new XMPPServer(hostName); OpenStorageProviderRegistry providerRegistry = new OpenStorageProviderRegistry(); providerRegistry.add(new ServerPasswordAuthorization()); providerRegistry.add(new MemoryRosterManager()); providerRegistry.add(new InMemoryRoomStorageProvider()); providerRegistry.add(new InMemoryOccupantStorageProvider()); server.setStorageProviderRegistry(providerRegistry); server.addEndpoint(new TCPEndpoint()); server.setTLSCertificateInfo( getClass().getResource( "/jrummikub/resource/bogus_mina_tls.cert") .openStream(), "boguspw"); server.start(); MUCModule muc = new MUCModule("play"); server.addModule(muc); return ServerStatus.STARTED; } catch (BindException e) { return ServerStatus.ALREADY_RUNNING; } catch (Exception e) { e.printStackTrace(); return ServerStatus.ERROR; } } /** * Allow authorization using a single password for all users */ public class ServerPasswordAuthorization implements UserAuthorization { @Override public boolean verifyCredentials(Entity entity, String password, Object credentials) { return password.equals(serverPassword); } @Override public boolean verifyCredentials(String entity, String password, Object credentials) { return password.equals(serverPassword); } } /** * Main for a simple command line dedicated server * * @param args * first argument specifies the server password, it is * "jrummikub" when none is specified */ public static void main(String[] args) { DedicatedServer server = new DedicatedServer(args.length >= 1 ? args[0] : "jrummikub"); System.out.println("Server hostname is " + server.getHostName()); try { switch (server.start()) { case ALREADY_RUNNING: System.out.println("Server already running"); // fall through case ERROR: System.exit(1); } } catch (Exception e) { e.printStackTrace(); } } }