/** * Warlock, the open-source cross-platform game client * * Copyright 2008, Warlock LLC, and individual contributors as indicated * by the @authors tag. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ /* * Created on Jan 15, 2005 */ package cc.warlock.core.client.internal; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import cc.warlock.core.client.ICommand; import cc.warlock.core.client.ICommandHistory; import cc.warlock.core.client.ICompass; import cc.warlock.core.client.IProperty; import cc.warlock.core.client.IRoomListener; import cc.warlock.core.client.IStream; import cc.warlock.core.client.IStreamListener; import cc.warlock.core.client.IWarlockClient; import cc.warlock.core.client.IWarlockClientListener; import cc.warlock.core.client.IWarlockClientViewer; import cc.warlock.core.client.WarlockClientRegistry; import cc.warlock.core.client.logging.IClientLogger; import cc.warlock.core.client.logging.LoggingConfiguration; import cc.warlock.core.client.logging.SimpleLogger; import cc.warlock.core.client.settings.IClientSettings; import cc.warlock.core.network.IConnection; import cc.warlock.core.util.Pair; /** * @author Marshall */ public abstract class WarlockClient implements IWarlockClient { protected IConnection connection; protected IWarlockClientViewer viewer; protected IWarlockClientListener listener; protected ICommandHistory commandHistory = new CommandHistory(); protected String streamPrefix; private Collection<IRoomListener> roomListeners = Collections.synchronizedCollection(new ArrayList<IRoomListener>()); protected Property<ICompass> compass = new Property<ICompass>(null); protected IClientLogger logger; protected HashMap<String, IStream> streams = new HashMap<String, IStream>(); protected ArrayList<Pair<String, IStreamListener>> potentialListeners = new ArrayList<Pair<String, IStreamListener>>(); public WarlockClient () { streamPrefix = "client:" + hashCode() + ":"; if (LoggingConfiguration.instance().getLogFormat().equals(LoggingConfiguration.LOG_FORMAT_TEXT)) { logger = new SimpleLogger(this); } listener = new WarlockClientListener() { @Override public void clientDisconnected(IWarlockClient client) { if (client == WarlockClient.this && logger != null) { logger.flush(); } } @Override public void clientActivated(IWarlockClient client) {} @Override public void clientConnected(IWarlockClient client) {} @Override public void clientRemoved(IWarlockClient client) {} @Override public void clientSettingsLoaded(IWarlockClient client) {} }; WarlockClientRegistry.addWarlockClientListener(listener); } public void dispose() { // Disconnect if we havn't already. if (this.getConnection() != null && this.getConnection().isConnected()) { try { this.getConnection().disconnect(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // Flush Logger logger.flush(); // Remove ourselves from the list of active clients. WarlockClientRegistry.removeWarlockClientListener(listener); } // IWarlockClient methods public ICommandHistory getCommandHistory() { return commandHistory; } public abstract void connect(String server, int port, String key) throws IOException; public void send(ICommand command) { getDefaultStream().sendCommand(command); try { if(connection != null) connection.send(command.getCommand()); } catch(IOException e) { e.printStackTrace(); } } public void setViewer(IWarlockClientViewer viewer) { this.viewer = viewer; } public IWarlockClientViewer getViewer() { return viewer; } public IStream getDefaultStream() { return getStream(IWarlockClient.DEFAULT_STREAM_NAME); } public IStream getStream(String streamName) { synchronized(streams) { return streams.get(streamName); } } public Collection<IStream> getStreams() { return streams.values(); } public IConnection getConnection() { return connection; } public void flushStreams() { synchronized(streams) { for(IStream stream : streams.values()) { stream.flush(); } } } public void addRoomListener(IRoomListener roomListener) { synchronized(roomListeners) { roomListeners.add(roomListener); } } public void removeRoomListener(IRoomListener roomListener) { synchronized(roomListeners) { roomListeners.remove(roomListener); } } public void nextRoom() { synchronized(roomListeners) { for(IRoomListener listener : roomListeners) listener.nextRoom(); } } public IProperty<ICompass> getCompass() { return compass; } public abstract IClientSettings getClientSettings(); public IClientLogger getLogger() { return logger; } public void playSound(InputStream stream) { viewer.playSound(stream); } public abstract IStream createStream(String streamName); public void addStreamListener(String streamName, IStreamListener listener) { IStream stream = streams.get(streamName); if(stream != null) stream.addStreamListener(listener); else potentialListeners.add(new Pair<String, IStreamListener>(streamName, listener)); } public void removeStreamListener(String streamName, IStreamListener listener) { IStream stream = streams.get(streamName); if(stream != null) { stream.removeStreamListener(listener); } else { for(Iterator<Pair<String, IStreamListener>> iter = potentialListeners.iterator(); iter.hasNext(); ) { Pair<String, IStreamListener> pair = iter.next(); if(pair.first().equals(streamName) && pair.second() == listener) { iter.remove(); break; } } } } }