+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.connection;
-
-import com.jme3.network.events.ConnectionListener;
-import com.jme3.network.events.MessageListener;
-import com.jme3.network.message.ClientRegistrationMessage;
-import com.jme3.network.message.DisconnectMessage;
-import com.jme3.network.message.DiscoverHostMessage;
-import com.jme3.network.message.Message;
-import com.jme3.network.queue.MessageQueue;
-import com.jme3.network.serializing.Serializer;
-import com.jme3.network.service.ServiceManager;
-import java.io.IOException;
-import java.net.*;
-import java.nio.ByteBuffer;
-import java.nio.channels.CancelledKeyException;
-import java.nio.channels.DatagramChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * @deprecated Use {@link com.jme3.network.Client} from {@link com.jme3.network.Network} instead.
- */
-@Deprecated
-public class Client extends ServiceManager {
- protected Logger log = Logger.getLogger(Client.class.getName());
-
- protected static int clientIDCounter = 0;
- protected int clientID;
- protected long playerID = -1;
- protected String label;
-
- protected boolean isConnected;
- protected TCPConnection tcp;
- protected UDPConnection udp;
-
- protected ConnectionRunnable
- thread;
-
- protected MessageQueue messageQueue;
-
- // Client (connector) related.
- protected SocketChannel tcpChannel;
- protected DatagramChannel udpChannel;
-
- protected SocketAddress udpTarget;
-
- protected boolean isConnector;
-
- protected ClientObserver listener = new ClientObserver();
-
- /**
- * Constructs this client.
- * @deprecated Call createClient() on {@link com.jme3.network.Network} instead.
- */
- @Deprecated
- public Client() {
- this(false);
- }
-
- /**
- * Construct this client, either as a server connector, or
- * a real client. Internal method.
- *
- * @param connector Whether this client is a connector or not.
- */
- Client(boolean connector) {
- super(ServiceManager.CLIENT);
- clientID = ++clientIDCounter;
- this.label = "Client#" + clientID;
-
- isConnector = connector;
- if (connector) {
- isConnected = true;
- } else {
- if (tcp == null) tcp = new TCPConnection(label);
- if (udp == null) udp = new UDPConnection(label);
- }
-
- messageQueue = new MessageQueue();
- }
-
- /**
- * Constructor providing custom instances of the clients and its addresses.
- *
- * @param tcp The TCPConnection instance to manage.
- * @param udp The UDPConnection instance to manage.
- * @param tcpAddress The TCP address to connect to.
- * @param udpAddress The UDP address to connect to.
- * @throws java.io.IOException When a connect error has occurred.
- */
- public Client(TCPConnection tcp, UDPConnection udp, SocketAddress tcpAddress, SocketAddress udpAddress) throws IOException {
- this();
-
- this.tcp = tcp;
- tcp.connect(tcpAddress);
-
- this.udp = udp;
- udp.connect(udpAddress);
- isConnected = true;
-
- registerInternalListeners();
- }
-
- /**
- * Constructor for providing a TCP client instance. UDP will be disabled.
- *
- * @param tcp The TCPConnection instance.
- * @param tcpAddress The address to connect to.
- * @throws IOException When a connection error occurs.
- */
- public Client(TCPConnection tcp, SocketAddress tcpAddress) throws IOException {
- this();
-
- this.tcp = tcp;
- tcp.connect(tcpAddress);
- isConnected = true;
-
- registerInternalListeners();
- }
-
- /**
- * Constructor for providing a UDP client instance. TCP will be disabled.
- *
- * @param udp The UDP client instance.
- * @param updAddress The address to connect to.
- * @throws IOException When a connection error occurs.
- */
- public Client(UDPConnection udp, SocketAddress updAddress) throws IOException {
- this();
-
- this.udp = udp;
- udp.connect(updAddress);
- isConnected = true;
-
- registerInternalListeners();
- }
-
- /**
- * Simple constructor for providing TCP port and UDP port. Will bind using on
- * all interfaces, on given ports.
- *
- * @param ip The IP address where the server are located.
- * @param tcpPort The TCP port to use.
- * @param udpPort The UDP port to use.
- * @throws IOException When a connection error occurs.
- * @deprecated Call connectToServer() on {@link com.jme3.network.Network} instead.
- */
- @Deprecated
- public Client(String ip, int tcpPort, int udpPort) throws IOException {
- this();
-
- tcp = new TCPConnection(label);
- tcp.connect(new InetSocketAddress(ip, tcpPort));
-
- udp = new UDPConnection(label);
- udp.connect(new InetSocketAddress(ip, udpPort));
- isConnected = true;
-
- registerInternalListeners();
- }
-
- /**
- * Connect method for when the no arg constructor was used.
- *
- * @param ip The IP address to connect to.
- * @param tcpPort The TCP port to use. To turn off, use -1.
- * @param udpPort The UDP port to use. To turn off, use -1.
- * @throws IllegalArgumentException When an illegal argument was given.
- * @throws java.io.IOException When a connection error occurs.
- */
- public void connect(String ip, int tcpPort, int udpPort) throws IllegalArgumentException, IOException {
- if (tcpPort == -1 && udpPort == -1) throw new IllegalArgumentException("No point in connect when you want to turn both the connections off.");
-
- if (tcpPort != -1) {
- tcp.connect(new InetSocketAddress(ip, tcpPort));
- }
- if (udpPort != -1) {
- udp.connect(new InetSocketAddress(ip, udpPort));
- }
- registerInternalListeners();
- isConnected = true;
- }
-
- private void registerInternalListeners() {
- if (tcp != null) {
- tcp.addConnectionListener(listener);
- tcp.socketChannel.keyFor(tcp.selector).attach(this);
- }
- addMessageListener(listener, DisconnectMessage.class);
- }
-
- /**
- * Send a message. Whether it's over TCP or UDP is determined by the message flag.
- *
- * @param message The message to send.
- * @throws IOException When a writing error occurs.
- */
- public void send(Message message) throws IOException {
- if (!isConnected) throw new IOException("Not connected yet. Use connect() first.");
-
- try {
- if (message.isReliable()) {
- messageQueue.add(message);
- if (!isConnector) {
- tcp.socketChannel.keyFor(tcp.selector).interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
- } else {
- tcpChannel.keyFor(tcp.selector).interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
- }
- } else {
- udp.sendObject(message);
- }
- } catch (CancelledKeyException e) {
- // Client was disconnected.
- }
- }
-
- /**
- * Disconnect from the server.
- *
- * @param type See DisconnectMessage for the available types.
- * @throws IOException When a disconnection error occurs.
- */
- public void disconnect(String type) throws IOException {
- if (isConnector) return;
- // Send a disconnect message to the server.
- DisconnectMessage msg = new DisconnectMessage();
- msg.setType(type);
- tcp.sendObject(msg);
- udp.sendObject(msg);
-
- // We can disconnect now.
- thread.setKeepAlive(false);
-
- // GC it.
- thread = null;
-
- log.log(Level.INFO, "[{0}][???] Disconnected.", label);
- isConnected = false;
- }
-
- /**
- * Disconnect from the server.
- *
- * @param msg The custom DisconnectMessage to use.
- * @throws IOException When a disconnection error occurs.
- */
- public void disconnect(DisconnectMessage msg) throws IOException {
- if (isConnector) return;
- // Send a disconnect message to the server.
- tcp.sendObject(msg);
- udp.sendObject(msg);
-
- // We can disconnect now.
- thread.setKeepAlive(false);
-
- // GC it.
- thread = null;
-
- log.log(Level.INFO, "[{0}][???] Disconnected.", label);
- isConnected = false;
- }
-
- /**
- * Disconnect from the server with the default disconnection type:
- * USER_REQUESTED.
- *
- * @throws IOException When a disconnection error occurs.
- */
- public void disconnect() throws IOException {
- disconnect(DisconnectMessage.USER_REQUESTED);
- }
-
- /**
- * Kick this client from the server, with given kick reason.
- *
- * @param reason The reason this client was kicked.
- * @throws IOException When a writing error occurs.
- */
- public void kick(String reason) throws IOException {
- if (!isConnector) return;
- DisconnectMessage message = new DisconnectMessage();
- message.setType(DisconnectMessage.KICK);
- message.setReason(reason);
- message.setReliable(true);
- send(message);
-
- tcp.addToDisconnectionQueue(this);
-
- log.log(Level.INFO, "[Server#?][???] {0} got kicked with reason: {1}.", new Object[]{this, reason});
- }
-
- /**
- * Kick this client from the server, with given kick reason.
- *
- * @param message The custom disconnect message.
- * @throws IOException When a writing error occurs.
- */
- public void kick(DisconnectMessage message) throws IOException {
- if (!isConnector) return;
- message.setReliable(true);
- send(message);
-
- tcp.addToDisconnectionQueue(this);
-
- log.log(Level.INFO, "[Server#?][???] {0} got kicked with reason: {1}.", new Object[]{this, message.getReason()});
- }
-
- private void disconnectInternal(DisconnectMessage message) throws IOException {
- DisconnectMessage dcMessage = (DisconnectMessage)message;
- String type = dcMessage.getType();
- String reason = dcMessage.getReason();
-
- log.log(Level.INFO, "[{0}][???] We got disconnected from the server ({1}: {2}).", new Object[]{
- label,
- type,
- reason
- });
-
- // We can disconnect now.
- thread.setKeepAlive(false);
-
- // GC it.
- thread = null;
-
- isConnected = false;
- }
-
- public List<InetAddress> discoverHosts(int port, int timeout) throws IOException {
- ArrayList<InetAddress> addresses = new ArrayList<InetAddress>();
-
- DatagramSocket socket = new DatagramSocket();
- ByteBuffer buffer = ByteBuffer.allocate(4);
-
- Serializer.writeClass(buffer, DiscoverHostMessage.class);
-
- buffer.flip();
- byte[] data = new byte[buffer.limit()];
- buffer.get(data);
-
- for (NetworkInterface iface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
- for (InetAddress address : Collections.list(iface.getInetAddresses())) {
- if (address instanceof Inet6Address || address.isLoopbackAddress()) continue;
- byte[] ip = address.getAddress();
- ip[3] = -1;
- socket.send(new DatagramPacket(data, data.length, InetAddress.getByAddress(ip), port));
- ip[2] = -1;
- socket.send(new DatagramPacket(data, data.length, InetAddress.getByAddress(ip), port));
- }
- }
- log.log(Level.FINE, "[{0}][UDP] Started discovery on port {1}.", new Object[]{label, port});
-
- long targetTime = System.currentTimeMillis() + timeout;
-
- DatagramPacket packet = new DatagramPacket(new byte[0], 0);
- socket.setSoTimeout(1000);
- while (System.currentTimeMillis() < targetTime) {
- try {
- socket.receive(packet);
- if (addresses.contains(packet.getAddress())) continue;
- addresses.add(packet.getAddress());
- log.log(Level.FINE, "[{0}][UDP] Discovered server on {1}.", new Object[]{label, packet.getAddress()});
- } catch (SocketTimeoutException ste) {
- // Nothing to be done here.
- }
- }
-
- return addresses;
- }
-
- public void setLabel(String label) {
- this.label = label;
- }
-
- ///////////////
-
- // Server client related stuff.
-
- public void setSocketChannel(SocketChannel channel) {
- tcpChannel = channel;
- }
-
- public SocketChannel getSocketChannel() {
- return tcpChannel;
- }
-
- public void setDatagramChannel(DatagramChannel channel) {
- udpChannel = channel;
- }
-
- public DatagramChannel getDatagramChannel() {
- return udpChannel;
- }
-
- public void setDatagramReceiver(SocketAddress address) {
- udpTarget = address;
- }
-
- public SocketAddress getDatagramReceiver() {
- return udpTarget;
- }
-
- public void setTCPConnection(TCPConnection con) {
- tcp = con;
- }
-
- public void setUDPConnection(UDPConnection con) {
- udp = con;
- }
-
- public TCPConnection getTCPConnection() {
- return tcp;
- }
-
- public UDPConnection getUDPConnection() {
- return udp;
- }
-
- public MessageQueue getMessageQueue() {
- return messageQueue;
- }
-
- ///////////////
-
- /**
- * Start this client.
- */
- public void start()
- {
- new Thread(thread = new ConnectionRunnable(tcp, udp)).start();
- }
-
- /**
- * Start this client with given sleep time. Higher sleep times may affect the system's response time
- * negatively, whereas lower values may increase CPU load. Use only when you're certain.
- *
- * @param sleep The sleep time.
- */
- public void start(int sleep) {
- new Thread(thread = new ConnectionRunnable(tcp, udp, sleep)).start();
- }
-
- public int getClientID() {
- return clientID;
- }
-
- public long getPlayerID() {
- return playerID;
- }
-
- public void setPlayerID(long id) {
- playerID = id;
- }
-
- public String toString() {
- return label;
- }
-
- public void addConnectionListener(ConnectionListener listener) {
- if (tcp != null) tcp.addConnectionListener(listener);
- if (udp != null) udp.addConnectionListener(listener);
- }
-
- public void removeConnectionListener(ConnectionListener listener) {
- if (tcp != null) tcp.removeConnectionListener(listener);
- if (udp != null) udp.removeConnectionListener(listener);
- }
-
- public void addMessageListener(MessageListener listener) {
- if (tcp != null) tcp.addMessageListener(listener);
- if (udp != null) udp.addMessageListener(listener);
- }
-
- public void addMessageListener(MessageListener listener, Class... classes) {
- for (Class c : classes) {
- if (tcp != null) tcp.addMessageListener(c, listener);
- if (udp != null) udp.addMessageListener(c, listener);
- }
- }
-
- public void removeMessageListener(MessageListener listener) {
- if (tcp != null) tcp.removeMessageListener(listener);
- if (udp != null) udp.removeMessageListener(listener);
- }
-
- public void removeMessageListener(MessageListener listener, Class... classes) {
- for (Class c : classes) {
- if (tcp != null) tcp.removeMessageListener(c, listener);
- if (udp != null) udp.removeMessageListener(c, listener);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof Client || obj instanceof Integer)) {
- return false;
- } else if (obj instanceof Client){
- return ((Client)obj).getClientID() == getClientID();
- } else if (obj instanceof Integer) {
- return ((Integer)obj).intValue() == getClientID();
- } else {
- return false;
- }
- }
-
- protected class ClientObserver implements MessageListener, ConnectionListener {
-
- public void messageReceived(Message message) {
- try {
- disconnectInternal((DisconnectMessage)message);
- } catch (IOException e) {
- log.log(Level.WARNING, "[{0}][???] Could not disconnect.", label);
- }
- }
-
- public void messageSent(Message message) {
-
- }
-
- public void objectReceived(Object object) {
-
- }
-
- public void objectSent(Object object) {
-
- }
-
- public void clientConnected(Client client) {
- // We are a client. This means that we succeeded in connecting to the server.
- if (!isConnected) return;
- long time = System.currentTimeMillis();
- playerID = time;
- ClientRegistrationMessage message = new ClientRegistrationMessage();
- message.setId(time);
- try {
- message.setReliable(false);
- send(message);
- message.setReliable(true);
- send(message);
- } catch (Exception e) {
- e.printStackTrace();
- log.log(Level.SEVERE, "[{0}][???] Could not sent client registration message. Disconnecting.", label);
- try {
- disconnect(DisconnectMessage.ERROR);
- } catch (IOException ie) {}
- }
- }
-
- public void clientDisconnected(Client client) {
- if (thread != null) {
- // We can disconnect now.
- thread.setKeepAlive(false);
-
- // GC it.
- thread = null;
- }
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.connection;
-
-import com.jme3.network.events.ConnectionListener;
-import com.jme3.network.events.MessageAdapter;
-import com.jme3.network.message.ClientRegistrationMessage;
-import com.jme3.network.message.Message;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.logging.Logger;
-
-/**
- * The ClientManager is an internal class that deals with client registrations and disconnects.
- *
- * @author Lars Wesselius
- */
-public class ClientManager extends MessageAdapter implements ConnectionListener {
- protected Logger log = Logger.getLogger(ClientManager.class.getName());
- private ArrayList<Client> clients = new ArrayList<Client>();
- private Hashtable<Integer, Client> clientsByClientID = new Hashtable<Integer, Client>();
-
- private ArrayList<ClientRegistrationMessage> pendingMessages = new ArrayList<ClientRegistrationMessage>();
-
- private ArrayList<ConnectionListener> connectionListeners = new ArrayList<ConnectionListener>();
-
- private ClientRegistrationMessage findMessage(long playerId) {
- for (ClientRegistrationMessage message : pendingMessages) {
- if (message.getId() == playerId) {
- return message;
- }
- }
- return null;
- }
-
- public List<Client> getConnectors() {
- return Collections.unmodifiableList(clients);
- }
-
- public Client getClient(long playerId) {
- for (Client client : clients) {
- if (client.getPlayerID() == playerId) return client;
- }
- return null;
- }
-
- public Client getClientByClientID(int clientID) {
- return clientsByClientID.get(clientID);
- }
-
- public boolean isClientConnected(Client client) {
- return clients.contains(client);
- }
-
-
- @Override
- public void messageReceived(Message message) {
- ClientRegistrationMessage regMessage = (ClientRegistrationMessage)message;
- ClientRegistrationMessage existingMessage = findMessage(regMessage.getId());
-
- // Check if message exists, if not add this message to the pending queue.
- if (existingMessage == null) {
- pendingMessages.add(regMessage);
- return;
- }
-
- // We've got two messages of which we can construct a client.
- Client client = new Client(true);
-
- Connection conOne = regMessage.getConnection();
- Connection conTwo = existingMessage.getConnection();
-
- if (conOne instanceof TCPConnection) {
- fillInTCPInfo(client, regMessage);
- } else if (conOne instanceof UDPConnection) {
- fillInUDPInfo(client, regMessage);
- }
-
- if (conTwo instanceof TCPConnection) {
- fillInTCPInfo(client, existingMessage);
- } else if (conTwo instanceof UDPConnection) {
- fillInUDPInfo(client, existingMessage);
- }
-
- if (client.getUDPConnection() == null || client.getTCPConnection() == null) {
- // Something went wrong in this registration.
- log.severe("[ClientManager][???] Something went wrong in the client registration process.");
- return;
- }
-
- client.setPlayerID(regMessage.getId());
-
- // Set other clients to this playerID as well.
- regMessage.getClient().setPlayerID(regMessage.getId());
- existingMessage.getClient().setPlayerID(regMessage.getId());
-
-
- fireClientConnected(client);
-
- // Remove pending message.
- pendingMessages.remove(existingMessage);
- clients.add(client);
- clientsByClientID.put(client.getClientID(), client);
- }
-
- private void fillInUDPInfo(Client client, ClientRegistrationMessage msg) {
- client.setUDPConnection((UDPConnection)msg.getConnection());
- client.setDatagramReceiver(msg.getClient().getDatagramReceiver());
- client.setDatagramChannel(msg.getClient().getDatagramChannel());
-
- client.getDatagramChannel().keyFor(msg.getConnection().selector).attach(client);
- }
-
- private void fillInTCPInfo(Client client, ClientRegistrationMessage msg) {
- client.setSocketChannel(msg.getClient().getSocketChannel());
- client.setTCPConnection((TCPConnection)msg.getConnection());
-
- client.getSocketChannel().keyFor(msg.getConnection().selector).attach(client);
- }
-
- public void addConnectionListener(ConnectionListener listener) {
- connectionListeners.add(listener);
- }
-
- public void removeConnectionListener(ConnectionListener listener) {
- connectionListeners.remove(listener);
- }
-
- public void clientConnected(Client client) {
- }
-
- public void clientDisconnected(Client client) {
- if (clients.contains(client)) {
- clients.remove(client);
- fireClientDisconnected(client);
- }
- }
-
- public void fireClientConnected(Client client) {
- for (ConnectionListener listener : connectionListeners) {
- listener.clientConnected(client);
- }
- }
-
- public void fireClientDisconnected(Client client) {
- for (ConnectionListener listener : connectionListeners) {
- listener.clientDisconnected(client);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.connection;
-
-import com.jme3.network.events.ConnectionListener;
-import com.jme3.network.events.MessageListener;
-import com.jme3.network.message.Message;
-import java.io.IOException;
-import java.net.ConnectException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.SocketChannel;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Base class for a connection method. Extend this if you have some other fancy
- * way of dealing with connections. This class provides basic message handling, connection filtering
- * and handles the selector.
- *
- * @author Lars Wesselius
- */
-public abstract class Connection implements Runnable {
- protected String label;
- protected Logger log = Logger.getLogger(Connection.class.getName());
- protected final ArrayList<Client> connections = new ArrayList<Client>();
-
- protected Selector selector;
- protected boolean alive = false;
- protected ArrayList<ConnectorFilter> connectorFilters = new ArrayList<ConnectorFilter>();
-
- protected LinkedList<Client> disconnectionQueue = new LinkedList<Client>();
-
- protected ArrayList<ConnectionListener> connectionListeners = new ArrayList<ConnectionListener>();
- protected ArrayList<MessageListener> messageListeners = new ArrayList<MessageListener>();
- protected HashMap<Class, List<MessageListener>> individualMessageListeners = new HashMap<Class, List<MessageListener>>();
-
- public Connection() {
- try {
- selector = Selector.open();
- } catch (IOException e) {
- log.log(Level.SEVERE, "Could not open selector.", e);
- }
- }
-
- /**
- * Add a connector filter for this connection.
- *
- * @param filter The filter to add.
- */
- public void addConnectorFilter(ConnectorFilter filter) {
- connectorFilters.add(filter);
- }
-
- /**
- * Remove a connector filter for this connection.
- * @param filter The filter to remove.
- */
- public void removeConnectorFilter(ConnectorFilter filter) {
- connectorFilters.remove(filter);
- }
-
- /**
- * Determine whether this connection should be filtered.
- *
- * @param address The address that should be checked.
- * @return The reason if it should be filtered.
- */
- public String shouldFilterConnector(InetSocketAddress address) {
- for (ConnectorFilter filter : connectorFilters) {
- String str = filter.filterConnector(address);
- if (str != null) return str;
- }
- return null;
- }
-
- public void run() {
- if (!alive) alive = true;
- try {
- if (selector.selectNow() > 0) {
- // We've received some keys.
- Set<SelectionKey> keys = selector.selectedKeys();
-
- for (Iterator<SelectionKey> it = keys.iterator(); it.hasNext();) {
- SelectionKey key = it.next();
- it.remove();
-
-
- if (key.isValid() && key.isReadable()) {
- read(key.channel());
- }
- if (key.isValid() && key.isAcceptable()) {
- accept(key.channel());
- }
- if (key.isValid() && key.isWritable()) {
- write(key.channel());
- }
- if (key.isValid() && key.isConnectable()) {
- connect(key.channel());
- }
- }
- }
-
- // Process queue's.
- Client dcClient = disconnectionQueue.poll();
- while (dcClient != null) {
- disconnect(dcClient);
- dcClient = disconnectionQueue.poll();
- }
- } catch (ConnectException ce) {
- log.log(Level.WARNING, "[{0}][???] Connection refused.", label);
- fireClientDisconnected(null);
- } catch (IOException e) {
- log.log(Level.SEVERE, "[{0}][???] Error while selecting. Message: {1}", new Object[]{label, e.getMessage()});
- }
- }
-
- /**
- * Get all the connectors.
- *
- * @return A unmodifiable list with the connectors.
- */
- public List<Client> getLocalConnectors() {
- return Collections.unmodifiableList(connections);
- }
-
- /**
- * Get the combined connectors, meaning TCP and UDP are combined into one client.
- *
- * @return A unmodifiable list with the connectors.
- */
- public List<Client> getConnectors() {
- return Collections.unmodifiableList(connections);
- }
-
- /**
- * Return whether this connection is still alive.
- *
- * @return True if so, false if not.
- */
- public boolean isAlive() { return alive; }
-
- /**
- * Accept an incoming connection.
- *
- * @param channel The channel.
- * @throws IOException When a problem occurs.
- */
- public abstract void accept(SelectableChannel channel) throws IOException;
-
- /**
- * Finish the connection.
- *
- * @param channel The channel.
- * @throws IOException When a problem occurs.
- */
- public abstract void connect(SelectableChannel channel) throws IOException;
-
- /**
- * Read from the channel.
- *
- * @param channel The channel.
- * @throws IOException When a problem occurs.
- */
- public abstract void read(SelectableChannel channel) throws IOException;
-
- /**
- * Write to a channel.
- *
- * @param channel The channel to write to.
- * @throws IOException When a problem occurs.
- */
- public abstract void write(SelectableChannel channel) throws IOException;
-
- /**
- * Connect to a server using this overload.
- *
- * @param address The address to connect to.
- * @throws IOException When a problem occurs.
- */
- public abstract void connect(SocketAddress address) throws IOException;
-
- /**
- * Bind to an address.
- *
- * @param address The address to bind to.
- * @throws IOException When a problem occurs.
- */
- public abstract void bind(SocketAddress address) throws IOException;
-
- /**
- * Send an object to the server. If this is a server, it will be
- * broadcast to all clients.
- *
- * @param object The object to send.
- * @throws IOException When a writing error occurs.
- */
- public abstract void sendObject(Object object) throws IOException;
-
- /**
- * Send an object to the connector. Server method.
- *
- * @param connector The connector to send to.
- * @param object The object to send.
- * @throws IOException When a writing error occurs.
- */
- public abstract void sendObject(Client connector, Object object) throws IOException;
-
- /**
- * Called when the connection implementation should clean up.
- *
- * @throws IOException When a problem occurs.
- */
- public abstract void cleanup() throws IOException;
-
- /////////////////////////////// Connection management //////////////////////////
-
- public void addToDisconnectionQueue(Client client) {
- disconnectionQueue.add(client);
- }
-
- /**
- * Disconnect a client.
- *
- * @param client The client to disconnect.
- * @throws IOException When closing the client's channel has failed.
- */
- private void disconnect(Client client) throws IOException {
- if (client == null) return;
-
- // Find the correct client.
-
- Client localClient = null;
- synchronized (connections){
- for (Client locClient : connections) {
- if (locClient.getPlayerID() == client.getPlayerID()) {
- localClient = locClient;
- break;
- }
- }
- }
-
- if (localClient == null) localClient = client;
-
- SocketChannel chan = localClient.getSocketChannel();
- if (chan != null) {
- SelectionKey key = chan.keyFor(selector);
- if (key != null) key.cancel();
- chan.close();
- }
-
- synchronized (connections){
- connections.remove(localClient);
- }
- fireClientDisconnected(client);
- }
-
-
- /////////////////////////////// Listener related ///////////////////////////////
-
- public void addConnectionListener(ConnectionListener listener) {
- connectionListeners.add(listener);
- }
-
- public void removeConnectionListener(ConnectionListener listener) {
- connectionListeners.remove(listener);
- }
-
- public void addMessageListener(MessageListener listener) {
- messageListeners.add(listener);
- }
-
- public void removeMessageListener(MessageListener listener) {
- messageListeners.remove(listener);
- }
-
- public void addMessageListener(Class messageClass, MessageListener listener) {
- if (individualMessageListeners.containsKey(messageClass)) {
- individualMessageListeners.get(messageClass).add(listener);
- } else {
- List<MessageListener> list = new ArrayList<MessageListener>();
- list.add(listener);
- individualMessageListeners.put(messageClass, list);
- }
- }
-
- public void removeMessageListener(Class messageClass, MessageListener listener) {
- if (individualMessageListeners.containsKey(messageClass)) {
- individualMessageListeners.get(messageClass).remove(listener);
- }
- }
-
- protected void fireMessageReceived(Message message) {
- // Pass to listeners.
- for (MessageListener listener : messageListeners) {
- listener.messageReceived(message);
- }
-
- List<MessageListener> list = individualMessageListeners.get(message.getClass());
- if (list == null) return;
-
- for (MessageListener listener : list) {
- listener.messageReceived(message);
- }
- }
-
- protected void fireMessageSent(Message message) {
- for (MessageListener listener : messageListeners) {
- listener.messageSent(message);
- }
-
- List<MessageListener> list = individualMessageListeners.get(message.getClass());
- if (list == null) return;
-
- for (MessageListener listener : list) {
- listener.messageSent(message);
- }
- }
-
- protected void fireObjectReceived(Object data) {
- for (MessageListener listener : messageListeners) {
- listener.objectReceived(data);
- }
-
- if (data == null) return;
-
- List<MessageListener> list = individualMessageListeners.get(data.getClass());
- if (list == null) return;
-
- for (MessageListener listener : list) {
- listener.objectReceived(data);
- }
- }
-
- protected void fireObjectSent(Object data) {
- for (MessageListener listener : messageListeners) {
- listener.objectSent(data);
- }
-
- List<MessageListener> list = individualMessageListeners.get(data.getClass());
- if (list == null) return;
-
- for (MessageListener listener : list) {
- listener.objectSent(data);
- }
- }
-
- protected void fireClientConnected(Client client) {
- for (ConnectionListener listener : connectionListeners) {
- listener.clientConnected(client);
- }
- }
-
- protected void fireClientDisconnected(Client client) {
- for (ConnectionListener listener : connectionListeners) {
- listener.clientDisconnected(client);
- }
- }
-
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.connection;
-
-import com.jme3.system.JmeSystem;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * The connection runnable takes the UDP and TCP connections
- * and updates them accordingly.
- *
- * @author Lars Wesselius
- */
-public class ConnectionRunnable implements Runnable {
- protected Logger log = Logger.getLogger(Server.class.getName());
-
- private TCPConnection tcp;
- private UDPConnection udp;
- private int delay = 2;
- private boolean keepAlive = true;
- private boolean alive = true;
-
- public ConnectionRunnable(TCPConnection tcp, UDPConnection udp, int delay) {
- this.tcp = tcp;
- this.udp = udp;
- this.delay = delay;
- }
-
- public ConnectionRunnable(TCPConnection tcp, UDPConnection udp) {
- this.tcp = tcp;
- this.udp = udp;
- }
-
- public void setKeepAlive(boolean keepAlive) {
- this.keepAlive = keepAlive;
- }
-
- public boolean isRunning() {
- return alive;
- }
-
- public void run() {
- if (!JmeSystem.isLowPermissions()){
- Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
- public void uncaughtException(Thread thread, Throwable thrown) {
- log.log(Level.SEVERE, "Uncaught exception thrown in "+thread.toString(), thrown);
- }
- });
- }
-
- while (keepAlive)
- {
- // Run while one of the connections is still live.
- tcp.run();
- udp.run();
-
- if (delay > 0) {
- try {
- Thread.sleep(delay);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- } else { Thread.yield(); }
- }
- try
- {
- tcp.cleanup();
- udp.cleanup();
- } catch (IOException e) {
- log.log(Level.WARNING, "[???][???] Could not clean up the connection.", e);
- return;
- }
- alive = false;
- log.log(Level.FINE, "[???][???] Cleaned up TCP/UDP.");
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.connection;
-
-import java.net.InetSocketAddress;
-
-/**
- * A connection filter that can be used by the dev to filter
- * connections based on <code>InetAddress</code>es.
- *
- * @author Lars Wesselius
- */
-public interface ConnectorFilter {
-
- /**
- * Filter a connection based on <code>InetAddress</code>. This is called
- * every time a client, or <code>Client</code>, connects to the server.
- *
- * @param address The address.
- * @return A null string if the connection should be accepted without problems.
- * A non null value indicates the reason of why the client should be dropped.
- */
- public String filterConnector(InetSocketAddress address);
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.connection;
-
-import javax.net.ssl.*;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.SocketChannel;
-import java.security.KeyStore;
-import java.util.ArrayList;
-import java.util.logging.Level;
-
-/**
- * The SSLTCPConnection. Handles all SSL traffic for both client
- * and server. Please do not use this class, as it does not work.
- * Replacement is custom encryption over TCP or UDP, without using SSL.
- *
- * @author Lars Wesselius
- */
-public class SSLTCPConnection extends TCPConnection {
-
- // Incoming data. Encrypted.
- protected ByteBuffer incDataEncrypted;
-
- // Incoming data. Decrypted.
- protected ByteBuffer incDataDecrypted;
-
- // Outgoing data. Encrypted.
- protected ByteBuffer outDataEncrypted;
-
- // Used for operations that don't consume any data.
- protected ByteBuffer dummy;
-
- protected SSLEngine sslEngine;
- protected boolean initialHandshake;
- protected SSLEngineResult.HandshakeStatus
- handshakeStatus;
- protected SSLEngineResult.Status
- status;
-
- protected ArrayList<Client>
- handshakingConnectors = new ArrayList<Client>();
-
- public SSLTCPConnection(String name) {
- label = name;
- createSSLEngine();
-
-
- SSLSession session = sslEngine.getSession();
-
- incDataDecrypted = ByteBuffer.allocateDirect(session.getApplicationBufferSize());
- incDataEncrypted = ByteBuffer.allocateDirect(session.getPacketBufferSize());
- outDataEncrypted = ByteBuffer.allocateDirect(session.getPacketBufferSize());
-
- incDataEncrypted.position(incDataEncrypted.limit());
- outDataEncrypted.position(outDataEncrypted.limit());
- dummy = ByteBuffer.allocate(0);
- }
-
- private void createSSLEngine() {
- try
- {
- KeyStore ks = KeyStore.getInstance("JKS");
- File kf = new File("keystore");
- ks.load(new FileInputStream(kf), "lollercopter".toCharArray());
-
- KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
- kmf.init(ks, "lollercopter".toCharArray());
-
- TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
- tmf.init(ks);
-
- TrustManager[] trustAllCerts = new TrustManager[]
- {
- new X509TrustManager() {
- public java.security.cert.X509Certificate[] getAcceptedIssuers() {
- return null;
- }
-
- public void checkClientTrusted(
- java.security.cert.X509Certificate[] certs, String authType) {
- }
-
- public void checkServerTrusted(
- java.security.cert.X509Certificate[] certs, String authType) {
- }
- }
- };
-
- SSLContext sslContext = SSLContext.getInstance("TLS");
- sslContext.init(kmf.getKeyManagers(), trustAllCerts, null);
-
- sslEngine = sslContext.createSSLEngine();
- } catch (Exception e) {
- log.log(Level.SEVERE, "[{0}][TCP] Could not create SSL engine: {1}", new Object[]{label, e.getMessage()});
- }
- }
-
- private void doHandshake(SocketChannel channel) throws IOException {
- while (true) {
- SSLEngineResult result;
- log.log(Level.FINEST, "[{0}][TCP] Handshake Status is now {1}.", new Object[]{label, handshakeStatus});
- switch (handshakeStatus) {
- case NOT_HANDSHAKING:
- log.log(Level.SEVERE, "[{0}][TCP] We're doing a handshake while we're not handshaking.", label);
- break;
-
- case FINISHED:
- initialHandshake = false;
- channel.keyFor(selector).interestOps(SelectionKey.OP_READ);
-
- return;
-
- case NEED_TASK:
- // TODO: Run this task in another thread or something.
- Runnable task;
- while ((task = sslEngine.getDelegatedTask()) != null) {
- task.run();
- }
- handshakeStatus = sslEngine.getHandshakeStatus();
- break;
-
- case NEED_UNWRAP:
- readAndUnwrap(channel);
-
- if (initialHandshake && status == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
- channel.keyFor(selector).interestOps(SelectionKey.OP_READ);
- return;
- }
-
- break;
-
- case NEED_WRAP:
-
- if (outDataEncrypted.hasRemaining()) {
- log.log(Level.FINE, "[{0}][TCP] We found data that should be written out.", label);
- return;
- }
-
- // Prepare to write
- outDataEncrypted.clear();
- result = sslEngine.wrap(dummy, outDataEncrypted);
- log.log(Level.FINEST, "[{0}][TCP] Wrapping result: {1}.", new Object[]{label, result});
-
- if (result.bytesProduced() == 0) log.log(Level.SEVERE, "[{0}][TCP] No net data produced during wrap.", label);
- if (result.bytesConsumed() != 0) log.log(Level.SEVERE, "[{0}][TCP] App data consumed during handshake wrap.", label);
- handshakeStatus = result.getHandshakeStatus();
- outDataEncrypted.flip();
-
- // Now send the data and come back here only when
- // the data is all sent
- System.out.println("WRITING TO: " + channel + " : " + channel.socket());
- if (!flushData(channel)) {
- // There is data left to be send. Wait for it
- return;
- }
- break;
-
- }
- }
- }
-
- public void connect(SocketAddress address) throws IOException {
- super.connect(address);
- }
-
- public void bind(SocketAddress address) throws IOException {
- super.bind(address);
-
- sslEngine.setUseClientMode(false);
- sslEngine.setNeedClientAuth(false);
- }
-
- public void connect(SelectableChannel channel) throws IOException {
- super.connect(channel);
- initialHandshake = true;
- sslEngine.setUseClientMode(true);
- sslEngine.beginHandshake();
- socketChannel.keyFor(selector).interestOps(SelectionKey.OP_WRITE);
- handshakeStatus = sslEngine.getHandshakeStatus();
- doHandshake(socketChannel);
- }
-
- public void accept(SelectableChannel channel) throws IOException {
- super.accept(channel);
-
- Client con = connections.get(connections.size() - 1);
- handshakingConnectors.add(con);
- //con.getChannel().keyFor(selector).interestOps(SelectionKey.OP_WRITE);
-
- initialHandshake = true;
- sslEngine.beginHandshake();
- handshakeStatus = sslEngine.getHandshakeStatus();
- doHandshake(con.getSocketChannel());
- }
-
- public void read(SelectableChannel channel) throws IOException {
- if (initialHandshake) {
- doHandshake((SocketChannel)channel);
- return;
- }
- super.read(channel);
- }
-
- public void readAndUnwrap(SocketChannel channel) throws IOException {
- incDataEncrypted.flip();
- int bytesRead = channel.read(incDataEncrypted);
-
- if (bytesRead == 0) {
- System.out.println("BUFFER INFO: " + incDataEncrypted);
- }
- if (bytesRead == -1) {
- log.log(Level.FINE, "[{0}][TCP] -1 bytes read, closing stream.", new Object[]{label, bytesRead});
- return;
- }
- log.log(Level.FINE, "[{0}][TCP] Read {1} bytes.", new Object[]{label, bytesRead});
-
- incDataDecrypted.clear();
- incDataEncrypted.flip();
-
- SSLEngineResult result;
- do {
- result = sslEngine.unwrap(incDataEncrypted, incDataDecrypted);
- log.log(Level.FINE, "[{0}][TCP] Unwrap result: {1}.", new Object[]{label, result});
- } while (result.getStatus() == SSLEngineResult.Status.OK &&
- result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP &&
- result.bytesProduced() == 0);
-
- // We could have finished the handshake.
- if (result.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED) {
- initialHandshake = false;
- channel.keyFor(selector).interestOps(SelectionKey.OP_READ);
- }
-
- // Check if we unwrapped everything there is to unwrap.
- if (incDataDecrypted.position() == 0 &&
- result.getStatus() == SSLEngineResult.Status.OK && incDataEncrypted.hasRemaining()) {
- result = sslEngine.unwrap(incDataEncrypted, incDataDecrypted);
- log.log(Level.FINE, "[{0}][TCP] Unwrap result: {1}.", new Object[]{label, result});
- }
-
- // Update statuses
- status = result.getStatus();
- handshakeStatus = result.getHandshakeStatus();
-
- incDataEncrypted.compact();
- incDataDecrypted.flip();
-
- if (handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_TASK ||
- handshakeStatus == SSLEngineResult.HandshakeStatus.NEED_WRAP ||
- handshakeStatus == SSLEngineResult.HandshakeStatus.FINISHED)
- {
- log.log(Level.FINE, "[{0}][TCP] Rehandshaking..", label);
- doHandshake(channel);
- }
-
- }
-
- public void send(Object object) throws IOException {
- super.sendObject(object);
- }
-
- public void send(SocketChannel channel, Object object) throws IOException {
- super.send(channel, object);
- }
-
- public void write(SelectableChannel channel) throws IOException {
- //super.write(channel);
- SocketChannel socketChannel = (SocketChannel)channel;
-
- if (flushData(socketChannel)) {
- if (initialHandshake) {
- doHandshake(socketChannel);
- }
- }
- }
-
- private boolean flushData(SocketChannel channel) throws IOException {
- int written = 0;
- try {
- ///
- while (outDataEncrypted.hasRemaining()) {
- written += channel.write(outDataEncrypted);
- }
- } catch (IOException ioe) {
- outDataEncrypted.position(outDataEncrypted.limit());
- throw ioe;
- }
-
- log.log(Level.FINE, "[{0}][TCP] Wrote {1} bytes to {2}.", new Object[]{label, written, channel.socket().getRemoteSocketAddress()});
- if (outDataEncrypted.hasRemaining()) {
- SelectionKey key = channel.keyFor(selector);
- key.interestOps(SelectionKey.OP_WRITE);
- return false;
- } else {
- return true;
- }
- }
-
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.connection;
-
-import com.jme3.network.events.ConnectionListener;
-import com.jme3.network.events.MessageListener;
-import com.jme3.network.message.ClientRegistrationMessage;
-import com.jme3.network.message.DisconnectMessage;
-import com.jme3.network.message.Message;
-import com.jme3.network.service.ServiceManager;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * The class where your SpiderMonkey adventures start. The server class
- * manages the TCP and UDP servers.
- *
- * Using the constructors where you either provide ports or the instances,
- * they will bind automatically. If you do not want this to happen, use the
- * no arg constructor, and then call bind later on.
- *
- * @author Lars Wesselius
- * @deprecated Use {@link com.jme3.network.Server} from {@link com.jme3.network.Network} instead.
- */
-@Deprecated
-public class Server extends ServiceManager {
- protected Logger log = Logger.getLogger(Server.class.getName());
-
- protected static int serverIDCounter = 0;
- protected TCPConnection tcp = null;
- protected UDPConnection udp = null;
-
- protected String label;
- protected int serverID;
- protected boolean isBound = false;
-
- protected ConnectionRunnable
- thread;
-
- protected SocketAddress lastUDPAddress;
- protected SocketAddress lastTCPAddress;
-
- protected ClientManager clientManager = new ClientManager();
-
- protected MessageListener listener = new ServerMessageObserver();
-
- /**
- * Default constructor. Sets the label to
- * <code>Server#[serverID]</code>
- */
- public Server() {
- super(ServiceManager.SERVER);
- serverID = ++serverIDCounter;
- this.label = "Server#" + serverID;
- }
-
- /**
- * Constructor providing custom instances of the servers and its addresses.
- *
- * @param tcp The TCPConnection instance to manage.
- * @param udp The UDPConnection instance to manage.
- * @param tcpAddress The TCP address to bind to.
- * @param udpAddress The UDP address to bind to.
- * @throws IOException When a bind error has occurred.
- */
- public Server(TCPConnection tcp, UDPConnection udp, SocketAddress tcpAddress, SocketAddress udpAddress) throws IOException {
- this();
-
- this.tcp = tcp;
- tcp.bind(tcpAddress);
- lastTCPAddress = tcpAddress;
-
- this.udp = udp;
- udp.bind(udpAddress);
- lastUDPAddress = udpAddress;
- isBound = true;
-
- registerInternalListeners();
- }
-
- /**
- * Constructor for providing a TCP server instance. UDP will be disabled.
- *
- * @param tcp The TCPConnection instance.
- * @param tcpAddress The address to bind to.
- * @throws IOException When a binding error occurs.
- */
- public Server(TCPConnection tcp, SocketAddress tcpAddress) throws IOException {
- this();
-
- this.tcp = tcp;
- tcp.bind(tcpAddress);
- lastTCPAddress = tcpAddress;
- isBound = true;
-
- registerInternalListeners();
- }
-
- /**
- * Constructor for providing a UDP server instance. TCP will be disabled.
- *
- * @param udp The UDP server instance.
- * @param udpAddress The address to bind to.
- * @throws IOException When a binding error occurs.
- */
- public Server(UDPConnection udp, SocketAddress udpAddress) throws IOException {
- this();
-
- this.udp = udp;
- udp.bind(udpAddress);
- lastUDPAddress = udpAddress;
- isBound = true;
-
- registerInternalListeners();
- }
-
- /**
- * Simple constructor for providing TCP port and UDP port. Will bind using on
- * all interfaces, on given ports.
- *
- * @param tcpPort The TCP port to use.
- * @param udpPort The UDP port to use.
- * @throws IOException When a binding error occurs.
- * @deprecated Call createServer() on {@link com.jme3.network.Network} instead.
- */
- @Deprecated
- public Server(int tcpPort, int udpPort) throws IOException {
- this();
-
- tcp = new TCPConnection(label);
-
- lastTCPAddress = new InetSocketAddress(tcpPort);
- tcp.bind(lastTCPAddress);
-
- lastUDPAddress = new InetSocketAddress(udpPort);
- udp = new UDPConnection(label);
- udp.bind(lastUDPAddress);
- isBound = true;
-
- registerInternalListeners();
- }
-
- private void registerInternalListeners() {
- if (tcp != null) {
- tcp.addMessageListener(DisconnectMessage.class, listener);
- tcp.addMessageListener(ClientRegistrationMessage.class, clientManager);
- tcp.addConnectionListener(clientManager);
- }
- if (udp != null) {
- udp.addMessageListener(DisconnectMessage.class, listener);
- udp.addMessageListener(ClientRegistrationMessage.class, clientManager);
- udp.addConnectionListener(clientManager);
- }
- }
-
- /**
- * Bind method for when the no arg constructor was used.
- *
- * @param tcpPort The TCP port to use. To turn off, use -1.
- * @param udpPort The UDP port to use. To turn off, use -1.
- * @throws IllegalArgumentException When an illegal argument was given.
- * @throws java.io.IOException When a binding error occurs.
- */
- public void bind(int tcpPort, int udpPort) throws IllegalArgumentException, IOException {
- if (tcpPort == -1 && udpPort == -1) throw new IllegalArgumentException("No point in binding when you want to turn both the connections off.");
-
- if (tcpPort != -1) {
- lastTCPAddress = new InetSocketAddress(tcpPort);
- tcp.bind(lastTCPAddress);
- }
- if (udpPort != -1) {
- lastUDPAddress = new InetSocketAddress(udpPort);
- udp.bind(lastUDPAddress);
- }
- registerInternalListeners();
- isBound = true;
- }
-
- /**
- * Broadcast a message.
- *
- * @param message The message to broadcast.
- * @throws IOException When a writing error occurs.
- */
- public void broadcast(Message message) throws IOException {
- if (!isBound) throw new IOException("Not bound yet. Use bind() first.");
- if (message.isReliable()) {
- if (tcp == null) throw new IOException("No TCP server.");
- tcp.sendObject(message);
- } else {
- if (udp == null) throw new IOException("No UDP server.");
- udp.sendObject(message);
- }
- }
-
- /**
- * Broadcast a message, except to the given client.
- *
- * @param except The client to refrain from sending the message to.
- * @param message The message to send.
- * @throws IOException When a writing error occurs.
- */
- public void broadcastExcept(Client except, Message message) throws IOException {
- if (!isBound) throw new IOException("Not bound yet. Use bind() first.");
-
- // We don't have to check for reliable or not here, since client.send does that.
- for (Client con : clientManager.getConnectors()) {
- if (con == except) continue;
- con.send(message);
- }
- }
-
- /**
- * Start this server.
- *
- * @throws IOException When an error occurs.
- */
- public void start() throws IOException {
- if (!isBound) {
- tcp.bind(lastTCPAddress);
- udp.bind(lastUDPAddress);
- }
- new Thread(thread = new ConnectionRunnable(tcp, udp)).start();
- log.log(Level.INFO, "[{0}][???] Started server.", label);
- }
-
- /**
- * Start this server with given sleep time. Higher sleep times may affect the system's response time
- * negatively, whereas lower values may increase CPU load. Use only when you're certain.
- *
- * @param sleep The sleep time.
- * @throws IOException When an error occurs.
- */
- public void start(int sleep) throws IOException {
- if (!isBound) {
- tcp.bind(lastTCPAddress);
- udp.bind(lastUDPAddress);
- }
- new Thread(thread = new ConnectionRunnable(tcp, udp, sleep)).start();
- log.log(Level.INFO, "[{0}][???] Started server.", label);
- }
-
- /**
- * Stop this server. Note that it kicks all clients so that they can
- * gracefully quit.
- *
- * @throws IOException When a writing error occurs.
- */
- public void stop() throws IOException {
- stop(new DisconnectMessage());
- }
-
- /**
- * Stops the server with custom message.
- *
- * @throws IOException When a writing error occurs.
- */
- public void stop(DisconnectMessage message) throws IOException {
- log.log(Level.INFO, "[{0}][???] Server is shutting down..", label);
- if (message.getReason() == null) {
- message.setReason("Server shut down.");
- }
- if (message.getType() == null) {
- message.setType(DisconnectMessage.KICK);
- }
- message.setReliable(true);
-
- broadcast(message);
-
- for (Client client : getConnectors()) {
- tcp.addToDisconnectionQueue(client);
- }
-
- tcp.selector.wakeup();
- log.log(Level.FINE, "[{0}][???] Sent disconnection messages to all clients.", label);
-
- thread.setKeepAlive(false);
- thread = null;
- log.log(Level.INFO, "[{0}][???] Server shut down.", label);
- isBound = false;
- }
-
- public boolean isRunning() {
- return thread != null && thread.isRunning();
- }
-
- public int getServerID() {
- return serverID;
- }
-
- public void setLabel(String label) {
- this.label = label;
- }
-
- public String toString() {
- return label;
- }
-
- /////////////////////////////// Connection management //////////////////////////
-
- /**
- * Get all the connectors for the TCP connection.
- *
- * @return A unmodifiable list with the connectors.
- */
- public List<Client> getTCPConnectors() {
- if (tcp != null) return tcp.getConnectors();
- return null;
- }
-
- /**
- * Get all the connectors for the UDP connection.
- *
- * @return A unmodifiable list with the connectors.
- */
- public List<Client> getUDPConnectors() {
- if (udp != null) return udp.getConnectors();
- return null;
- }
-
- /**
- * Get the combined connectors, meaning TCP and UDP are combined into one client. You should
- * generally use this for clients.
- *
- * @return A unmodifiable list with the connectors.
- */
- public List<Client> getConnectors() {
- return clientManager.getConnectors();
- }
-
- /**
- * Get a specific client based on the provided clientID.
- * @param clientID The clientID identifying the client requested.
- * @return The located client or null if the client was not on the list.
- */
- public Client getClientByID(int clientID) {
- Client c = clientManager.getClientByClientID(clientID);
- return c;
- }
-
- /////////////////////////////// Connector filters //////////////////////////////
-
- public void addConnectorFilter(ConnectorFilter filter) {
- if (tcp != null) tcp.addConnectorFilter(filter);
- if (udp != null) udp.addConnectorFilter(filter);
- }
-
- public void removeConnectorFilter(ConnectorFilter filter) {
- if (tcp != null) tcp.removeConnectorFilter(filter);
- if (udp != null) udp.removeConnectorFilter(filter);
- }
-
- /////////////////////////////// Listener related ///////////////////////////////
-
- public void addLocalConnectionListener(ConnectionListener listener) {
- if (tcp != null) tcp.addConnectionListener(listener);
- if (udp != null) udp.addConnectionListener(listener);
- }
-
- public void removeLocalConnectionListener(ConnectionListener listener) {
- if (tcp != null) tcp.removeConnectionListener(listener);
- if (udp != null) udp.removeConnectionListener(listener);
- }
-
- public void addConnectionListener(ConnectionListener listener) {
- clientManager.addConnectionListener(listener);
- }
-
- public void removeConnectionListener(ConnectionListener listener) {
- clientManager.removeConnectionListener(listener);
- }
-
- public void addMessageListener(MessageListener listener) {
- if (tcp != null) tcp.addMessageListener(listener);
- if (udp != null) udp.addMessageListener(listener);
- }
-
- public void addMessageListener(MessageListener listener, Class... classes) {
- for (Class c : classes) {
- if (tcp != null) tcp.addMessageListener(c, listener);
- if (udp != null) udp.addMessageListener(c, listener);
- }
- }
-
- public void removeMessageListener(MessageListener listener) {
- if (tcp != null) tcp.removeMessageListener(listener);
- if (udp != null) udp.removeMessageListener(listener);
- }
-
- public void removeMessageListener(MessageListener listener, Class... classes) {
- for (Class c : classes) {
- if (tcp != null) tcp.removeMessageListener(c, listener);
- if (udp != null) udp.removeMessageListener(c, listener);
- }
- }
-
- protected class ServerMessageObserver implements MessageListener {
-
- public void messageReceived(Message message) {
- // Right now, this is definitely a DisconnectMessage.
- DisconnectMessage dcMessage = (DisconnectMessage)message;
- Client client = dcMessage.getClient();
-
- if (clientManager.isClientConnected(client)) {
- log.log(Level.INFO, "[{0}][???] Client {1} disconnected ({2}: {3}).", new Object[]{
- label,
- client,
- dcMessage.getType(),
- (dcMessage.getReason() != null) ? dcMessage.getReason() : "No description"
- });
- }
- dcMessage.getConnection().addToDisconnectionQueue(client);
- }
-
- public void messageSent(Message message) {
-
- }
-
- public void objectReceived(Object object) {
-
- }
-
- public void objectSent(Object object) {
-
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.connection;
-
-import com.jme3.network.message.Message;
-import com.jme3.network.queue.MessageQueue;
-import com.jme3.network.serializing.Serializer;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.logging.Level;
-
-/**
- * The <code>TCPConnection</code> handles all traffic regarding TCP client and server.
- *
- * @author Lars Wesselius
- * @see Connection
- */
-public class TCPConnection extends Connection {
- protected SocketChannel socketChannel;
- protected ServerSocketChannel serverSocketChannel;
-
- protected ByteBuffer readBuffer;
- protected ByteBuffer writeBuffer;
- protected ByteBuffer tempWriteBuffer;
-
- protected final Object writeLock = new Object();
-
- private int objectLength = 0;
-
- public TCPConnection(String name)
- {
- label = name;
-
- readBuffer = ByteBuffer.allocateDirect(16228);
- writeBuffer = ByteBuffer.allocateDirect(16228);
- tempWriteBuffer = ByteBuffer.allocateDirect(16228);
- }
-
- public TCPConnection() { }
-
- public void connect(SocketAddress address) throws IOException {
- socketChannel = SocketChannel.open();
- socketChannel.socket().setTcpNoDelay(true);
-
- socketChannel.configureBlocking(false);
- socketChannel.connect(address);
- socketChannel.register(selector, SelectionKey.OP_CONNECT).attach(this);
- log.log(Level.INFO, "[{1}][TCP] Connecting to {0}", new Object[]{address, label});
- }
-
- public void bind(SocketAddress address) throws IOException {
- serverSocketChannel = selector.provider().openServerSocketChannel();
- serverSocketChannel.socket().bind(address);
- serverSocketChannel.configureBlocking(false);
- serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
- log.log(Level.INFO, "[{1}][TCP] Bound to {0}", new Object[]{address, label});
- }
-
- public void connect(SelectableChannel channel) throws IOException {
- ((SocketChannel)channel).finishConnect();
- socketChannel.keyFor(selector).interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
- fireClientConnected(null);
- log.log(Level.INFO, "[{0}][TCP] Connection succeeded.", label);
- }
-
- public void accept(SelectableChannel channel) throws IOException {
- SocketChannel socketChannel = ((ServerSocketChannel)channel).accept();
-
- String reason = shouldFilterConnector((InetSocketAddress)socketChannel.socket().getRemoteSocketAddress());
- if (reason != null) {
- log.log(Level.INFO, "[{2}][TCP] Client with address {0} got filtered with reason: {1}", new Object[]{(InetSocketAddress)socketChannel.socket().getRemoteSocketAddress(), reason, label});
- socketChannel.close();
- return;
- }
-
- socketChannel.configureBlocking(false);
- socketChannel.socket().setTcpNoDelay(true);
-
- Client con = new Client(true);
- con.setTCPConnection(this);
- con.setSocketChannel(socketChannel);
-
- socketChannel.register(selector, SelectionKey.OP_READ, con);
-
- connections.add(con);
-
- log.log(Level.INFO, "[{1}][TCP] A client connected with address {0}", new Object[]{socketChannel.socket().getInetAddress(), label});
- }
-
- public void read(SelectableChannel channel) throws IOException {
- SocketChannel socketChannel = (SocketChannel)channel;
-
- if (socketChannel == null) {
- log.log(Level.WARNING, "[{0}][TCP] Connection was closed before we could read.", label);
- return;
- }
-
- int read = -1;
- readBuffer.compact();
- try {
- read = socketChannel.read(readBuffer);
- } catch (IOException ioe) {
- // Probably a 'remote host closed connection'.
- socketChannel.keyFor(selector).cancel();
-
- if (serverSocketChannel != null) {
- log.log(Level.WARNING, "[{0}][TCP] Connection was forcibly closed before we could read. Disconnected client.", label);
- addToDisconnectionQueue((Client)socketChannel.keyFor(selector).attachment());
- } else {
- log.log(Level.WARNING, "[{0}][TCP] Server forcibly closed connection. Disconnected.", label);
- fireClientDisconnected(null);
- }
- }
-
- if (read != -1) {
- log.log(Level.FINE, "[{1}][TCP] Read {0} bytes.", new Object[]{read, label});
- }
-
- readBuffer.flip();
- if (read == -1) {
- socketChannel.keyFor(selector).cancel();
- if (serverSocketChannel != null) {
- log.log(Level.WARNING, "[{0}][TCP] Connection was closed before we could read. Disconnected client.", label);
- addToDisconnectionQueue((Client)socketChannel.keyFor(selector).attachment());
- } else {
- log.log(Level.WARNING, "[{0}][TCP] Server closed connection. Disconnected.", label);
- fireClientDisconnected(null);
- }
- return;
- }
-
- // Okay, see if we can read the data length.
- while (true) {
- try {
-
- // If we're currently not already reading an object, retrieve the length
- // of the next one.
- if (objectLength == 0) {
- objectLength = readBuffer.getShort();
- }
-
- int pos = readBuffer.position();
- int oldLimit = readBuffer.limit();
-
- int dataLength = objectLength;
- if (dataLength > 0 && readBuffer.remaining() >= dataLength) {
- // We can read a full object.
- if (pos + dataLength + 2 > readBuffer.capacity()) {
- readBuffer.limit(readBuffer.capacity());
- } else {
- readBuffer.limit(pos + dataLength + 2);
- }
- Object obj = Serializer.readClassAndObject(readBuffer);
- readBuffer.limit(oldLimit);
- objectLength = 0;
- if (obj != null) {
- if (obj instanceof Message) {
- Message message = (Message)obj;
-
- Object attachment = socketChannel.keyFor(selector).attachment();
- if (attachment instanceof Client) message.setClient((Client)attachment);
- message.setConnection(this);
- this.fireMessageReceived(message);
- } else {
- this.fireObjectReceived(obj);
- }
- log.log(Level.FINEST, "[{0}][TCP] Read full object: {1}", new Object[]{label, obj});
- }
- } else if (dataLength > readBuffer.remaining()) {
- readBuffer.compact();
- int bytesRead = socketChannel.read(readBuffer);
- log.log(Level.FINEST, "[{0}][TCP] Object won't fit in buffer, so read {1} more bytes in a compacted buffer.", new Object[]{label, bytesRead});
- readBuffer.flip();
- } else {
- objectLength = dataLength;
- }
- } catch (BufferUnderflowException someEx) {
- log.log(Level.FINEST, "[{0}][TCP] Done reading messages.", new Object[]{label});
- break;
- }
- }
-
- }
-
- public void sendObject(Object object) throws IOException {
- if (serverSocketChannel == null) {
- send(socketChannel, object) ;
- } else {
- for (Client connector : connections) {
- send(connector.getSocketChannel(), object);
- }
- }
- }
-
- public void sendObject(Client con, Object object) throws IOException {
- if (object instanceof Message) ((Message)object).setClient(con);
- send(con.getSocketChannel(), object);
- }
-
- public void cleanup() throws IOException {
- if (serverSocketChannel != null) {
- serverSocketChannel.close();
- connections.clear();
- } else {
- socketChannel.close();
- }
- }
-
- protected void send(SocketChannel channel, Object object) throws IOException {
- try {
- synchronized (writeLock) {
- tempWriteBuffer.clear();
- tempWriteBuffer.position(4);
- Serializer.writeClassAndObject(tempWriteBuffer, object);
- tempWriteBuffer.flip();
-
- int dataLength = tempWriteBuffer.limit() - 4;
- tempWriteBuffer.position(0);
- tempWriteBuffer.putInt(dataLength);
- tempWriteBuffer.position(0);
-
- if (dataLength > writeBuffer.capacity()) {
- log.log(Level.WARNING, "[{0}][TCP] Message too big for buffer. Discarded.", label);
- return;
- }
-
- if (writeBuffer.position() > 0) {
- try {
- writeBuffer.put(tempWriteBuffer);
- } catch (BufferOverflowException boe) {
- log.log(Level.WARNING, "[{0}][TCP] Buffer overflow occurred while appending data to be sent later. " +
- "Cleared the buffer, so some data may be lost.", label);
-
- // TODO The fix here is all wrong.
- writeBuffer.clear();
- while (tempWriteBuffer.hasRemaining()) {
- if (channel.write(tempWriteBuffer) == 0) break;
-
- }
- }
- } else {
- int writeLength = 0;
- while (tempWriteBuffer.hasRemaining()) {
- int wrote = channel.write(tempWriteBuffer);
- writeLength += wrote;
- if (wrote == 0) {
- break;
- }
- }
-
- log.log(Level.FINE, "[{1}][TCP] Wrote {0} bytes.", new Object[]{writeLength, label});
-
- try
- {
- if (writeBuffer.hasRemaining()) {
- writeBuffer.put(tempWriteBuffer);
- channel.keyFor(selector).interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
- } else {
- if (object instanceof Message) {
- this.fireMessageSent((Message)object);
- } else {
- this.fireObjectSent(object);
- }
- }
- } catch (BufferOverflowException boe) {
- log.log(Level.WARNING, "[{0}][TCP] Buffer overflow occurred while queuing data to be sent later. " +
- "Cleared the buffer, so some data may be lost. Please note that this exception occurs rarely, " +
- "so if this is shown often, please check your message sizes or contact the developer.", label);
- writeBuffer.clear();
- }
- }
- }
- } catch (IOException ioe) {
- // We're doing some additional handling here, since a client could be reset.
- Client client;
- if (socketChannel == null) {
- client = ((Message)object).getClient();
- } else {
- client = (Client)socketChannel.keyFor(selector).attachment();
- }
- if (client != null) {
- addToDisconnectionQueue(client);
-
- log.log(Level.WARNING, "[{0}][TCP] Disconnected {1} because an error occurred: {2}.", new Object[]{label, client, ioe.getMessage()});
- return;
- }
- throw ioe;
- }
- }
-
- public synchronized void write(SelectableChannel channel) throws IOException {
- SocketChannel socketChannel = (SocketChannel)channel;
- Client client = (Client)socketChannel.keyFor(selector).attachment();
- MessageQueue queue = client.getMessageQueue();
-
- Map<Message, Short> sizeMap = new LinkedHashMap<Message, Short>();
- for (Iterator<Message> it = queue.iterator(); it.hasNext();) {
- Message message = it.next();
- if (!message.isReliable()) continue;
-
- int pos = writeBuffer.position();
- try {
- writeBuffer.position(pos + 2);
- Serializer.writeClassAndObject(writeBuffer, message);
-
-
- short dataLength = (short)(writeBuffer.position() - pos - 2);
-
- writeBuffer.position(pos);
- writeBuffer.putShort(dataLength);
- writeBuffer.position(pos + dataLength + 2);
-
- sizeMap.put(message, dataLength);
-
- it.remove();
- } catch (Exception bfe) {
- // No problem, just write the buffer and be done with it.
- writeBuffer.position(pos);
- break;
- }
- }
-
- writeBuffer.flip();
-
- int written = 0;
- while (writeBuffer.hasRemaining()) {
- int wrote = socketChannel.write(writeBuffer);
- written += wrote;
-
- if (wrote == 0) {
- break;
- }
- }
-
- log.log(Level.FINE, "[{1}][TCP] Wrote {0} bytes.", new Object[]{written, label});
-
- // Check which messages were NOT sent.
- if (writeBuffer.hasRemaining()) {
- for (Iterator<Map.Entry<Message, Short>> it = sizeMap.entrySet().iterator(); it.hasNext();) {
- Map.Entry<Message, Short> entry = it.next();
-
- written -= entry.getValue();
- if (written > 0) {
- it.remove();
- } else {
- // Re add to queue.
- client.getMessageQueue().add(entry.getKey());
- }
- }
- }
-
- if (queue.isEmpty()) {
- channel.keyFor(selector).interestOps(SelectionKey.OP_READ);
- }
- writeBuffer.clear();
- }
-}
+++ /dev/null
-/*\r
- * Copyright (c) 2009-2010 jMonkeyEngine\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are\r
- * met:\r
- *\r
- * * Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- *\r
- * * Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- *\r
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors\r
- * may be used to endorse or promote products derived from this software\r
- * without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-package com.jme3.network.connection;\r
-\r
-import com.jme3.network.message.DiscoverHostMessage;\r
-import com.jme3.network.message.Message;\r
-import com.jme3.network.serializing.Serializer;\r
-import java.io.IOException;\r
-import java.net.InetSocketAddress;\r
-import java.net.SocketAddress;\r
-import java.nio.ByteBuffer;\r
-import java.nio.channels.ClosedChannelException;\r
-import java.nio.channels.DatagramChannel;\r
-import java.nio.channels.SelectableChannel;\r
-import java.nio.channels.SelectionKey;\r
-import java.util.logging.Level;\r
-\r
-/**\r
- * The <code>UDPConnection</code> handles all UDP traffic.\r
- *\r
- * @author Lars Wesselius\r
- */\r
-public class UDPConnection extends Connection {\r
- protected DatagramChannel datagramChannel;\r
-\r
- protected ByteBuffer writeBuffer;\r
- protected ByteBuffer readBuffer;\r
-\r
- protected SocketAddress target = null;\r
-\r
- public UDPConnection(String label) {\r
- this.label = label;\r
-\r
- readBuffer = ByteBuffer.allocateDirect(8192);\r
- writeBuffer = ByteBuffer.allocateDirect(8192);\r
- }\r
-\r
- public void connect(SocketAddress address) throws IOException {\r
- datagramChannel = selector.provider().openDatagramChannel();\r
- datagramChannel.socket().bind(null);\r
- datagramChannel.socket().connect(address);\r
- datagramChannel.configureBlocking(false);\r
-\r
- datagramChannel.register(selector, SelectionKey.OP_READ);\r
- log.log(Level.INFO, "[{1}][UDP] Set target to {0}", new Object[]{address, label});\r
- target = address;\r
- }\r
-\r
- public void bind(SocketAddress address) throws IOException {\r
- datagramChannel = selector.provider().openDatagramChannel();\r
- datagramChannel.socket().bind(address);\r
- datagramChannel.configureBlocking(false);\r
- \r
- datagramChannel.register(selector, SelectionKey.OP_READ);\r
-\r
- log.log(Level.INFO, "[{1}][UDP] Bound to {0}", new Object[]{address, label});\r
- }\r
-\r
- public void connect(SelectableChannel channel) throws IOException {\r
- // UDP is connectionless.\r
- }\r
-\r
- public void accept(SelectableChannel channel) throws IOException {\r
- // UDP is connectionless.\r
- }\r
-\r
- public void read(SelectableChannel channel) throws IOException {\r
- DatagramChannel socketChannel = (DatagramChannel)channel;\r
-\r
- InetSocketAddress address = (InetSocketAddress)datagramChannel.receive(readBuffer);\r
- if (address == null){\r
- //System.out.println("Address is NULL!");\r
- //TODO: Fix disconnection issue\r
- socketChannel.close();\r
-\r
- return;\r
- }\r
-\r
- String reason = shouldFilterConnector(address);\r
- if (reason != null) {\r
- log.log(Level.INFO, "[Server][UDP] Client with address {0} got filtered with reason: {1}", new Object[]{address, reason});\r
- socketChannel.close();\r
- return;\r
- }\r
-\r
- SelectionKey key = socketChannel.keyFor(selector);\r
- if ((key.attachment() == null || ((Client)key.attachment()).getDatagramReceiver() != address) && target == null) {\r
- Client client = new Client(true);\r
- client.setDatagramReceiver(address);\r
- client.setUDPConnection(this);\r
- client.setDatagramChannel(socketChannel);\r
- synchronized (connections){\r
- connections.add(client);\r
- }\r
-\r
- key.attach(client);\r
- }\r
-\r
- readBuffer.flip();\r
-\r
-\r
- Object object = Serializer.readClassAndObject(readBuffer);\r
-\r
- log.log(Level.FINE, "[{0}][UDP] Read full object: {1}", new Object[]{label, object});\r
-\r
- if (object instanceof Message) {\r
- Message message = (Message)object;\r
-\r
- if (message instanceof DiscoverHostMessage) {\r
- synchronized (connections){\r
- connections.remove( (Client) key.attachment() );\r
- }\r
- log.log(Level.FINE, "[{0}][UDP] Responded to a discover host message by {1}.", new Object[]{label, address});\r
- send(address, message);\r
- return;\r
- }\r
-\r
- Object attachment = socketChannel.keyFor(selector).attachment();\r
- if (attachment instanceof Client) message.setClient((Client)attachment);\r
- message.setConnection(this);\r
- this.fireMessageReceived(message);\r
- } else {\r
- this.fireObjectReceived(object);\r
- }\r
-\r
- readBuffer.clear();\r
- }\r
-\r
- protected synchronized void send(SocketAddress dest, Object object) {\r
- try {\r
- Serializer.writeClassAndObject(writeBuffer, object);\r
- writeBuffer.flip();\r
-\r
- if (dest == null)\r
- throw new NullPointerException();\r
-\r
- int bytes = datagramChannel.send(writeBuffer, dest);\r
-\r
- if (object instanceof Message) {\r
- this.fireMessageSent((Message)object);\r
- } else {\r
- this.fireObjectSent(object);\r
- }\r
-\r
- log.log(Level.FINE, "[{0}][UDP] Wrote {1} bytes to {2}.", new Object[]{label, bytes, dest});\r
- writeBuffer.clear();\r
- } catch (ClosedChannelException e) {\r
- } catch (IOException e) {\r
- e.printStackTrace();\r
- }\r
- }\r
-\r
- public void sendObject(Object object) throws IOException {\r
- if (target == null) {\r
- // This is a UDP server.\r
- synchronized (connections){\r
- for (Client connector : connections) {\r
- send(connector.getDatagramReceiver(), object);\r
- }\r
- }\r
- } else {\r
- send(target, object);\r
- }\r
- }\r
-\r
- public void sendObject(Client client, Object object) throws IOException {\r
- if (object instanceof Message) ((Message)object).setClient(client);\r
- send(client.getDatagramReceiver(), object);\r
- }\r
-\r
- public void cleanup() throws IOException {\r
- datagramChannel.close();\r
-\r
- if (target == null) {\r
- synchronized (connections){\r
- connections.clear();\r
- }\r
- }\r
- }\r
-\r
- public void write(SelectableChannel channel) throws IOException {\r
- // UDP is (almost) always ready for data, so send() will do.\r
- }\r
-}\r
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.events;
-
-import com.jme3.network.connection.Client;
-
-/**
- * Server adapter for making it easier to listen for server events.
- *
- * @author Lars Wesselius
- */
-public class ConnectionAdapter implements ConnectionListener {
- public void clientConnected(Client client) {}
- public void clientDisconnected(Client client) {}
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.events;
-
-import com.jme3.network.connection.Client;
-
-/**
- * Listener for server events.
- *
- * @author Lars Wesselius
- * @deprecated Use {@link com.jme3.network.ConnectionListener} instead.
- */
-@Deprecated
-public interface ConnectionListener {
- public void clientConnected(Client client);
- public void clientDisconnected(Client client);
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.events;
-
-import com.jme3.network.message.Message;
-
-/**
- * Message adapter to make it easier to listen to message vents.
- *
- * @author Lars Wesselius
- */
-public class MessageAdapter implements MessageListener {
- public void messageReceived(Message message) {}
- public void messageSent(Message message) {}
- public void objectReceived(Object object) {}
- public void objectSent(Object object) {}
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.events;
-
-import com.jme3.network.message.Message;
-
-/**
- * Listener for messages.
- *
- * @author Lars Wesselius
- * @deprecated Use {@link com.jme3.network.MessageListener} instead.
- */
-@Deprecated
-public interface MessageListener {
- public void messageReceived(Message message);
- public void messageSent(Message message);
-
- public void objectReceived(Object object);
- public void objectSent(Object object);
-}
package com.jme3.network.message;
+import com.jme3.network.AbstractMessage;
import com.jme3.network.serializing.Serializable;
/**
* @author Lars Wesselius
*/
@Serializable()
-public class ClientRegistrationMessage extends Message {
+public class ClientRegistrationMessage extends AbstractMessage {
private long id;
private String gameName;
private int version;
package com.jme3.network.message;
+import com.jme3.network.AbstractMessage;
+import com.jme3.network.Message;
import com.jme3.network.serializing.Serializable;
/**
* @author Lars Wesselius
*/
@Serializable()
-public class CompressedMessage extends Message {
+public class CompressedMessage extends AbstractMessage {
private Message message;
public CompressedMessage() { }
package com.jme3.network.message;
+import com.jme3.network.AbstractMessage;
import com.jme3.network.serializing.Serializable;
/**
* @author Lars Wesselius
*/
@Serializable()
-public class DisconnectMessage extends Message {
+public class DisconnectMessage extends AbstractMessage {
public static final String KICK = "Kick";
public static final String USER_REQUESTED = "User requested";
public static final String ERROR = "Error";
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.message;
-
-import com.jme3.network.serializing.Serializable;
-
-/**
- * The discover host message.
- *
- * @author Lars Wesselius
- */
-@Serializable()
-public class DiscoverHostMessage extends Message {
-}
package com.jme3.network.message;
+import com.jme3.network.Message;
import com.jme3.network.serializing.Serializable;
/**
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.message;
-
-import com.jme3.network.connection.Client;
-import com.jme3.network.connection.Connection;
-import com.jme3.network.serializing.Serializable;
-
-/**
- * Message represents data being sent to the other side. This can be anything,
- * and it will be serialized field by field. Extend this class if you wish to
- * provide objects with common fields to the other side.
- *
- * @author Lars Wesselius
- * @deprecated Message implementations should extend {@linke com.jme3.network.AbstractMessage}
- * instead or use the {@linke com.jme3.network.Message} for referencing.
- */
-@Deprecated
-@Serializable()
-public class Message extends com.jme3.network.AbstractMessage {
- // The connector this message is meant for.
- private transient Client connector;
- private transient Connection connection;
- private transient boolean reliable = true;
-
- public Message() {}
-
- public Message(boolean reliable) {
- this.reliable = reliable;
- }
-
- public boolean isReliable() {
- return reliable;
- }
-
- public Message setReliable(boolean reliable) {
- this.reliable = reliable;
- return this;
- }
-
- /**
- * @deprecated This method always returns null in the new API.
- */
- @Deprecated
- public Client getClient() {
- return connector;
- }
-
- @Deprecated
- public void setClient(Client connector) {
- this.connector = connector;
- }
-
- /**
- * @deprecated This method always returns null in the new API.
- */
- @Deprecated
- public Connection getConnection() {
- return connection;
- }
-
- @Deprecated
- public void setConnection(Connection connection) {
- this.connection = connection;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.message;
-
-import com.jme3.network.serializing.Serializable;
-
-/**
- * Stream message contains the data for the stream.
- *
- * @author Lars Wesselius
- */
-@Serializable()
-public class StreamDataMessage extends StreamMessage {
- private byte[] data;
-
- public StreamDataMessage() { }
-
- public StreamDataMessage(short id) {
- super(id);
- }
-
- public void setData(byte[] data) {
- this.data = data;
- }
-
- public byte[] getData() { return data; }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.message;
-
-import com.jme3.network.serializing.Serializable;
-
-@Serializable()
-public class StreamMessage extends Message {
- private short streamID;
-
- public StreamMessage(short id) {
- streamID = id;
- }
-
- public StreamMessage() {}
-
- public short getStreamID() {
- return streamID;
- }
-
- public void setStreamID(short streamID) {
- this.streamID = streamID;
- }
-}
package com.jme3.network.message;
+import com.jme3.network.Message;
import com.jme3.network.serializing.Serializable;
/**
+++ /dev/null
-package com.jme3.network.queue;
-
-import com.jme3.network.message.Message;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-public class MessageQueue extends ConcurrentLinkedQueue<Message> {
-
-}
registerClass(GZIPCompressedMessage.class, new GZIPSerializer());
registerClass(ZIPCompressedMessage.class, new ZIPSerializer());
- registerClass(Message.class);
registerClass(DisconnectMessage.class);
registerClass(ClientRegistrationMessage.class);
- registerClass(DiscoverHostMessage.class);
- registerClass(StreamDataMessage.class);
- registerClass(StreamMessage.class);
}
/**
* @param type The class to write.
* @return The SerializerRegistration that's registered to the class.
*/
- public static SerializerRegistration writeClass(ByteBuffer buffer, Class type) {
+ public static SerializerRegistration writeClass(ByteBuffer buffer, Class type) throws IOException {
SerializerRegistration reg = getSerializerRegistration(type);
if (reg == null) {
- reg = classRegistrations.get(Message.class);
- //registerClassToSerializer(type, FieldSerializer.class);
+ throw new SerializerException( "Class not registered:" + type );
}
buffer.putShort(reg.getId());
return reg;
package com.jme3.network.serializing.serializers;
-import com.jme3.network.message.Message;
import com.jme3.network.serializing.Serializer;
import com.jme3.network.serializing.SerializerException;
import java.io.IOException;
List<Field> fields = new ArrayList<Field>();
Class processingClass = clazz;
- while (processingClass != Object.class && processingClass != Message.class) {
+ while (processingClass != Object.class ) {
Collections.addAll(fields, processingClass.getDeclaredFields());
processingClass = processingClass.getSuperclass();
}
package com.jme3.network.serializing.serializers;
import com.jme3.network.message.GZIPCompressedMessage;
-import com.jme3.network.message.Message;
+import com.jme3.network.Message;
import com.jme3.network.serializing.Serializer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
package com.jme3.network.serializing.serializers;
-import com.jme3.network.message.Message;
+import com.jme3.network.Message;
import com.jme3.network.message.ZIPCompressedMessage;
import com.jme3.network.serializing.Serializer;
import java.io.ByteArrayInputStream;
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.service;
-
-/**
- * The Service interface. All services should implement this class, to provide a common way to manage service.
- *
- * @author Lars Wesselius
- */
-public interface Service {
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.service;
-
-import com.jme3.network.connection.Client;
-import com.jme3.network.connection.Server;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * A class can extend Service Manager to support services.
- *
- * @author Lars Wesselius
- */
-public class ServiceManager {
- private Logger log = Logger.getLogger(ServiceManager.class.getName());
- private final List<Service> services = new ArrayList<Service>();
-
- private boolean client;
-
- public static final boolean CLIENT = true;
- public static final boolean SERVER = false;
-
- public ServiceManager(boolean client) {
- this.client = client;
- }
-
- public <T> T getService(Class cls) {
- for (Service service : services) {
- if (service.getClass() == cls) return (T)service;
- }
-
- try {
- if (!Service.class.isAssignableFrom(cls))
- return null;
-
- Constructor ctor;
- if (client) {
- try {
- ctor = cls.getConstructor(new Class[]{Client.class});
- } catch (NoSuchMethodException nsme) {
- log.log(Level.WARNING, "[ServiceManager][???] The service {0} does not support client mode.", cls);
- return null;
- }
- } else {
- try {
- ctor = cls.getConstructor(new Class[]{Server.class});
- } catch (NoSuchMethodException nsme) {
- log.log(Level.WARNING, "[ServiceManager][???] The service {0} does not support server mode.", cls);
- return null;
- }
- }
-
- T inst = (T)ctor.newInstance(this);
-
- services.add((Service)inst);
- return inst;
- } catch (Exception e) {
- log.log(Level.SEVERE, "[ServiceManager][???] Instantiaton of service failed.", e);
- }
- return null;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.streaming;
-
-import com.jme3.network.connection.Client;
-import com.jme3.network.events.MessageAdapter;
-import com.jme3.network.message.Message;
-import com.jme3.network.message.StreamDataMessage;
-import com.jme3.network.message.StreamMessage;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class ClientStreamingService extends MessageAdapter {
- private static Logger log = Logger.getLogger(StreamingService.class.getName());
-
- protected ArrayList<StreamListener>
- streamListeners;
-
- protected ArrayList<Stream> streams;
-
- private Client client;
-
-
- public ClientStreamingService(Client client) {
- this.client = client;
- streams = new ArrayList<Stream>();
- streamListeners = new ArrayList<StreamListener>();
- client.addMessageListener(this, StreamDataMessage.class,
- StreamMessage.class);
- }
-
- // Client classes/methods //////////////////////////////////////////////////////////////
-
- public void addStreamListener(StreamListener listener) {
- streamListeners.add(listener);
- }
-
- public void removeStreamListener(StreamListener listener) {
- streamListeners.remove(listener);
- }
-
- public void messageReceived(Message message) {
- if (message instanceof StreamMessage && !(message instanceof StreamDataMessage)) {
- // A stream was offered.
- StreamMessage msg = (StreamMessage)message;
- Stream stream = getStream(msg.getStreamID());
-
- if (stream != null) {
- // This is a completion message.
- for (StreamListener listener : stream.getDataListeners()) {
- listener.streamCompleted(msg);
- }
- } else {
- stream = new Stream();
- stream.setMessage(msg);
- boolean accept = fireStreamOffered(stream, msg);
-
- streams.add(stream);
- if (accept) {
- try {
- client.send(msg);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- } else if (message instanceof StreamDataMessage) {
- StreamDataMessage dataMessage = (StreamDataMessage)message;
- Stream stream = getStream(dataMessage.getStreamID());
- if (stream == null) {
- log.log(Level.WARNING, "[StreamClient][TCP] We've received a data message even though we didn't register to the stream.");
- return;
- }
-
- for (StreamListener listener : stream.getDataListeners()) {
- listener.streamDataReceived(dataMessage);
- }
- }
-
- }
-
- private Stream getStream(short id) {
- for (Stream stream : streams) {
- if (stream.getMessage().getStreamID() == id) return stream;
- }
- return null;
- }
-
- private boolean fireStreamOffered(Stream stream, StreamMessage message) {
- boolean accept = false;
- for (StreamListener listener : streamListeners) {
- if (listener.streamOffered(message)) {
- accept = true;
-
- stream.addDataListener(listener);
- }
- }
- return accept;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.streaming;
-
-import com.jme3.network.connection.Client;
-import com.jme3.network.connection.Server;
-import com.jme3.network.events.MessageAdapter;
-import com.jme3.network.message.Message;
-import com.jme3.network.message.StreamDataMessage;
-import com.jme3.network.message.StreamMessage;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class ServerStreamingService extends MessageAdapter {
- private static Logger log = Logger.getLogger(StreamingService.class.getName());
-
- protected ArrayList<Stream> streams;
-
- private short nextStreamID = Short.MIN_VALUE;
-
- public ServerStreamingService(Server server) {
- streams = new ArrayList<Stream>();
- server.addMessageListener(this, StreamMessage.class);
- }
-
- public void offerStream(Client client, StreamMessage msg, InputStream data) {
- short streamID = ++nextStreamID;
- msg.setStreamID(streamID);
- msg.setReliable(true);
-
- Stream stream = new Stream();
- stream.setData(data);
- stream.setMessage(msg);
- stream.setReceiver(client);
- streams.add(stream);
-
- try {
- client.send(msg);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- private void startStream(Stream stream) {
- Client receiver = stream.getReceiver();
- try
- {
- InputStream data = stream.getData();
-
- byte[] buffer = new byte[1024];
- int length;
-
- StreamDataMessage msg = new StreamDataMessage(stream.getMessage().getStreamID());
- msg.setReliable(true);
-
- while ((length = data.read(buffer)) != -1) {
- byte[] newBuffer = new byte[length];
-
- for (int i = 0; i != length; ++i) {
- newBuffer[i] = buffer[i];
- }
- msg.setData(newBuffer);
- receiver.send(msg);
- }
- data.close();
-
- receiver.send(stream.getMessage());
- } catch (Exception ex) {
- ex.printStackTrace();
- log.log(Level.WARNING, "[StreamSender][TCP] Could not send stream with message {0} to {1}. Reason: {2}.", new Object[]{stream, receiver, ex.getMessage()});
- }
- }
-
- public void messageReceived(Message message) {
- if (message instanceof StreamMessage && !(message instanceof StreamDataMessage)) {
- // A stream was accepted.
- StreamMessage streamMessage = (StreamMessage)message;
- Stream stream = getStream(streamMessage);
-
- if (stream == null) return;
- stream.setAccepted(true);
- startStream(stream);
- }
- }
-
- private Stream getStream(short id) {
- for (Stream stream : streams) {
- if (stream.getMessage().getStreamID() == id) return stream;
- }
- return null;
- }
-
- private Stream getStream(StreamMessage msg) {
- for (Stream stream : streams) {
- if (stream.getMessage().getStreamID() == msg.getStreamID()) return stream;
- }
- return null;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.streaming;
-
-import com.jme3.network.connection.Client;
-import com.jme3.network.message.StreamMessage;
-
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-public class Stream {
- private StreamMessage message;
- private InputStream data;
- private Client receiver;
-
- private ArrayList<StreamListener> listeners = new ArrayList<StreamListener>();
-
- private boolean accepted = false;
-
- public StreamMessage getMessage() {
- return message;
- }
-
- public void setMessage(StreamMessage message) {
- this.message = message;
- }
-
- public InputStream getData() {
- return data;
- }
-
- public void setData(InputStream data) {
- this.data = data;
- }
-
- public boolean isAccepted() {
- return accepted;
- }
-
- public void setAccepted(boolean accepted) {
- this.accepted = accepted;
- }
-
- public Client getReceiver() {
- return receiver;
- }
-
- public void setReceiver(Client receiver) {
- this.receiver = receiver;
- }
-
- public void addDataListener(StreamListener listener) {
- listeners.add(listener);
- }
-
- public void removeDataListener(StreamListener listener) {
- listeners.remove(listener);
- }
-
- public List<StreamListener> getDataListeners() {
- return listeners;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.streaming;
-
-import com.jme3.network.message.StreamDataMessage;
-import com.jme3.network.message.StreamMessage;
-
-/**
- * Used for stream sending/receiving.
- *
- * @author Lars Wesselius
- */
-public interface StreamListener {
- public boolean streamOffered(StreamMessage message);
- public void streamDataReceived(StreamDataMessage message);
- public void streamCompleted(StreamMessage message);
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.streaming;
-
-import com.jme3.network.connection.Client;
-import com.jme3.network.connection.Server;
-import com.jme3.network.events.MessageAdapter;
-import com.jme3.network.message.StreamMessage;
-import com.jme3.network.service.Service;
-
-import java.io.InputStream;
-
-/**
- * Streaming service handles all kinds of streaming to clients. It can be instantiated by
- * both the client and server, where server will work as sender, and client as receiver.
- *
- * @author Lars Wesselius
- */
-public class StreamingService extends MessageAdapter implements Service {
-
- private ClientStreamingService clientService;
- private ServerStreamingService serverService;
-
- public StreamingService(Client client) {
- clientService = new ClientStreamingService(client);
- }
-
- public StreamingService(Server server) {
- serverService = new ServerStreamingService(server);
- }
-
- public void offerStream(Client client, StreamMessage msg, InputStream data) {
- if (serverService == null) return;
- serverService.offerStream(client, msg, data);
- }
-
- public void addStreamListener(StreamListener listener) {
- if (clientService == null) return;
- clientService.addStreamListener(listener);
- }
-
- public void removeStreamListener(StreamListener listener) {
- if (clientService == null) return;
- clientService.removeStreamListener(listener);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.sync;
-
-import com.jme3.network.connection.Client;
-import com.jme3.network.events.MessageAdapter;
-import com.jme3.network.message.Message;
-import com.jme3.network.service.Service;
-import com.jme3.util.IntMap;
-import com.jme3.util.IntMap.Entry;
-import java.nio.ByteBuffer;
-
-@Deprecated
-public class ClientSyncService extends MessageAdapter implements Service {
-
- private static final ByteBuffer BUFFER = ByteBuffer.wrap(new byte[10000]);
-
- private static class ClientEntityInfo {
- SyncEntity entity;
-
- EntitySyncInfo lastSyncInfo;
- EntitySyncInfo lastCreateInfo;
-
- long lastUpdate = 0;
- long lastExtrapolate = -1;
- long lastUpdateRate;
- long lastLatencyDelta = Long.MAX_VALUE;
- }
-
-// private final ArrayList<EntitySyncInfo> syncQueue =
-// new ArrayList<EntitySyncInfo>();
-
- private final IntMap<ClientEntityInfo> entities =
- new IntMap<ClientEntityInfo>();
-
- private EntityFactory factory;
- private SyncSerializer serializer = new SyncSerializer();
-
- private long lastSyncMsgTime = 0;
- private int lastHeartbeat;
- private MovingAverage averageLatency = new MovingAverage(20);
-
- public void update(float tpf2){
- long time = System.currentTimeMillis();
- synchronized (entities){
- for (Entry<ClientEntityInfo> entry : entities){
- ClientEntityInfo info = entry.getValue();
-
- if (info.lastSyncInfo != null){
- if (!inLoopApplySyncInfo(entry.getKey(), info))
- continue; // entity was deleted due to this command
- }
-
- long timeSinceUpdate = time - info.lastUpdate;
- if (timeSinceUpdate >= info.lastUpdateRate){
- if (info.lastExtrapolate == -1){
- info.entity.interpolate(1);
- info.lastExtrapolate = info.lastUpdate + info.lastUpdateRate;
- }
-
- long timeSinceExtrapolate = time - info.lastExtrapolate;
- info.lastExtrapolate = time;
- float tpf = timeSinceExtrapolate / 1000f;
- info.entity.extrapolate(tpf);
- }else{
- float blendAmount = (float) timeSinceUpdate / (float)info.lastUpdateRate;
- info.entity.interpolate(blendAmount);
- }
- }
- }
- }
-
- public ClientSyncService(Client client){
- client.addMessageListener(this /*, SyncMessage.class*/ );
- }
-
- public void setEntityFactory(EntityFactory factory){
- this.factory = factory;
- }
-
- public SyncEntity getEntity(int id){
- return entities.get(id).entity;
- }
-
- private void inLoopCreateEntity(int entityId, ClientEntityInfo clientInfo){
- EntitySyncInfo initInfo = clientInfo.lastSyncInfo;
-
- Class<? extends SyncEntity> clazz;
- try {
- clazz = (Class<? extends SyncEntity>) Class.forName(initInfo.className);
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException("Cannot find entity class: " + initInfo.className, ex);
- }
-
- SyncEntity entity;
- if (factory != null){
- entity = factory.createEntity(clazz);
- }else{
- try {
- entity = clazz.newInstance();
- } catch (InstantiationException ex) {
- throw new RuntimeException("Entity class is missing empty constructor", ex);
- } catch (IllegalAccessException ex) {
- throw new RuntimeException(ex);
- }
- }
-
- clientInfo.entity = entity;
- entity.onRemoteCreate();
-
- serializer.read(entity, ByteBuffer.wrap(initInfo.data), true);
-
- clientInfo.lastSyncInfo = null;
- }
-
- private void inLoopSyncEntity(int entityId, ClientEntityInfo entityInfo){
- serializer.read(entityInfo.entity, ByteBuffer.wrap(entityInfo.lastSyncInfo.data), false);
- entityInfo.entity.onRemoteUpdate( entityInfo.lastLatencyDelta / 1000f );
-
- // clear so its not called again
- entityInfo.lastSyncInfo = null;
- entityInfo.lastLatencyDelta = Long.MAX_VALUE;
- }
-
- private void inLoopDeleteEntity(int entityId, ClientEntityInfo clientInfo){
- SyncEntity entity = clientInfo.entity;
- entity.onRemoteDelete();
- entities.remove(entityId);
- }
-
- private boolean inLoopApplySyncInfo(int entityId, ClientEntityInfo clientInfo){
- switch (clientInfo.lastSyncInfo.type){
- case EntitySyncInfo.TYPE_NEW:
- inLoopCreateEntity(entityId, clientInfo);
- return true;
- case EntitySyncInfo.TYPE_SYNC:
- inLoopSyncEntity(entityId, clientInfo);
- return true;
- case EntitySyncInfo.TYPE_DELETE:
- inLoopDeleteEntity(entityId, clientInfo);
- return false;
- default:
- throw new UnsupportedOperationException();
- }
- }
-
- private void createEntity(EntitySyncInfo info){
- ClientEntityInfo entityInfo = new ClientEntityInfo();
- entityInfo.lastUpdate = System.currentTimeMillis();
-
- // forces inLoopCreateEntity to be called later
- entityInfo.lastSyncInfo = info;
-
- entities.put(info.id, entityInfo);
- }
-
- private void syncEntity(EntitySyncInfo info, int latencyDelta){
- ClientEntityInfo entityInfo = entities.get(info.id);
- if (entityInfo == null || entityInfo.entity == null)
- return; // didn't receive init yet.
-
- long time = System.currentTimeMillis();
- entityInfo.lastUpdateRate = time - entityInfo.lastUpdate;
- entityInfo.lastUpdate = time;
- entityInfo.lastExtrapolate = -1;
-
- // forces inLoopSyncEntity to be called later
- entityInfo.lastSyncInfo = info;
- entityInfo.lastLatencyDelta = latencyDelta;
- }
-
- void deleteEntity(EntitySyncInfo info){
- ClientEntityInfo clientInfo = entities.get(info.id);
- clientInfo.lastSyncInfo = info;
- }
-
- private void applySyncInfo(EntitySyncInfo info, int latencyDelta){
- switch (info.type) {
- case EntitySyncInfo.TYPE_NEW:
- createEntity(info);
- break;
- case EntitySyncInfo.TYPE_SYNC:
- syncEntity(info, latencyDelta);
- break;
- case EntitySyncInfo.TYPE_DELETE:
- deleteEntity(info);
- break;
- }
- }
-
- @Override
- public void messageReceived(Message msg) {
- if (!(msg instanceof SyncMessage)) {
- return;
- }
-
- int latencyDelta = 0;
- if (lastSyncMsgTime == 0) {
- // this is the first syncmessage
- lastSyncMsgTime = System.currentTimeMillis();
- } else {
- long time = System.currentTimeMillis();
- long delta = time - lastSyncMsgTime;
- averageLatency.add(delta);
- lastSyncMsgTime = time;
- latencyDelta = (int) (delta - averageLatency.getAverage());
- }
-
- SyncMessage sync = (SyncMessage) msg;
-
- boolean isOldMessage = false;
- int newHeartbeat = sync.heartbeat;
- if (lastHeartbeat > newHeartbeat){
- // check if at the end of heartbeat indices
- // within 1000 heartbeats
- if (lastHeartbeat > Integer.MAX_VALUE - 1000 && newHeartbeat < 1000){
- lastHeartbeat = newHeartbeat;
- }else{
- isOldMessage = true;
- }
- }else{
- lastHeartbeat = newHeartbeat;
- }
-
- for (EntitySyncInfo info : sync.infos) {
- if (info.type == EntitySyncInfo.TYPE_SYNC && isOldMessage)
- continue; // old sync message, ignore.
-
- applySyncInfo(info, latencyDelta);
- }
-
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.sync;
-
-@Deprecated
-public interface EntityFactory {
- public SyncEntity createEntity(Class<? extends SyncEntity> entityType);
-}
+++ /dev/null
-package com.jme3.network.sync;
-
-@Deprecated
-public final class EntitySyncInfo {
-
- public static final byte TYPE_NEW = 0x1,
- TYPE_SYNC = 0x2,
- TYPE_DELETE = 0x3;
-
- /**
- * NEW, SYNC, or DELETE
- */
- public byte type;
- /**
- * Entity ID
- */
- public int id;
- /**
- * Entity Class Name
- */
- public String className;
-
- /**
- * Vars
- */
- public byte[] data;
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.sync;
-
-@Deprecated
-public class MovingAverage {
-
- private long[] samples;
- private long sum;
- private int count, index;
-
- public MovingAverage(int numSamples){
- samples = new long[numSamples];
- }
-
- public void add(long sample){
- sum = sum - samples[index] + sample;
- samples[index++] = sample;
- if (index > count){
- count = index;
- }
- if (index >= samples.length){
- index = 0;
- }
- }
-
- public long getAverage(){
- if (count == 0)
- return 0;
- else
- return (long) ((float) sum / (float) count);
- }
-
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.sync;
-
-import com.jme3.math.FastMath;
-import com.jme3.network.connection.Client;
-import com.jme3.network.connection.Server;
-import com.jme3.network.events.ConnectionAdapter;
-import com.jme3.network.service.Service;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-@Deprecated
-public class ServerSyncService extends ConnectionAdapter implements Service {
-
- private static final ByteBuffer BUFFER = ByteBuffer.wrap(new byte[10000]);
-
- private float updateRate = 0.1f;
- private float packetDropRate = 0;
- private long latency = 0;
- private HashMap<Long, SyncMessage> latencyQueue;
-
- private final Server server;
- private final SyncSerializer serializer = new SyncSerializer();
-// private final ArrayList<Client> connectedClients = new ArrayList<Client>();
- private final ArrayList<SyncEntity> npcs = new ArrayList<SyncEntity>();
- private final HashMap<SyncEntity, Integer> npcToId
- = new HashMap<SyncEntity, Integer>();
-
- private static int nextId = 0;
-
- private int heartbeat = 0;
- private float time = 0;
-
- public ServerSyncService(Server server){
- this.server = server;
- server.addConnectionListener(this);
- }
-
- public void setNetworkSimulationParams(float packetDropRate, long latency){
- if (latencyQueue == null)
- latencyQueue = new HashMap<Long, SyncMessage>();
-
- this.packetDropRate = packetDropRate;
- this.latency = latency;
- }
-
- private EntitySyncInfo generateInitInfo(SyncEntity entity, boolean newId){
- EntitySyncInfo info = new EntitySyncInfo();
- info.className = entity.getClass().getName();
- info.id = newId ? nextId ++ : npcToId.get(entity);
- info.type = EntitySyncInfo.TYPE_NEW;
-
- BUFFER.clear();
- serializer.write(entity, BUFFER, true);
- BUFFER.flip();
- info.data = new byte[BUFFER.limit()];
- BUFFER.get(info.data);
- return info;
- }
-
- private EntitySyncInfo generateSyncInfo(SyncEntity entity){
- EntitySyncInfo info = new EntitySyncInfo();
- info.className = null;
- info.id = npcToId.get(entity);
- info.type = EntitySyncInfo.TYPE_SYNC;
-
- BUFFER.clear();
- serializer.write(entity, BUFFER, false);
- BUFFER.flip();
- info.data = new byte[BUFFER.limit()];
- BUFFER.get(info.data);
- return info;
- }
-
- private EntitySyncInfo generateDeleteInfo(SyncEntity entity){
- EntitySyncInfo info = new EntitySyncInfo();
- info.className = null;
- info.id = npcToId.get(entity);
- info.type = EntitySyncInfo.TYPE_DELETE;
- return info;
- }
-
- public void addNpc(SyncEntity entity){
- EntitySyncInfo info = generateInitInfo(entity, true);
- SyncMessage syncMsg = new SyncMessage();
- syncMsg.setReliable(true);
- syncMsg.heartbeat = heartbeat;
- syncMsg.infos = new EntitySyncInfo[]{ info };
-
- try {
- server.broadcast(syncMsg);
- } catch (IOException ex) {
- ex.printStackTrace();
- }
-
- synchronized (npcs){
- npcs.add(entity);
- npcToId.put(entity, info.id);
- }
- }
-
- public void removeNpc(SyncEntity entity){
- EntitySyncInfo info = generateDeleteInfo(entity);
-
- SyncMessage syncMsg = new SyncMessage();
- syncMsg.setReliable(true);
- syncMsg.heartbeat = heartbeat;
- syncMsg.infos = new EntitySyncInfo[]{ info };
-
- try {
- server.broadcast(syncMsg);
- } catch (IOException ex) {
- ex.printStackTrace();
- }
-
- synchronized (npcs){
- npcs.remove(entity);
- npcToId.remove(entity);
- }
- }
-
- @Override
- public void clientConnected(Client client){
- System.out.println("Server: Client connected: " + client);
- SyncMessage msg = new SyncMessage();
- msg.setReliable(true); // sending INIT information, has to be reliable.
-
- msg.heartbeat = heartbeat;
- EntitySyncInfo[] infos = new EntitySyncInfo[npcs.size()];
- msg.infos = infos;
- synchronized (npcs){
- for (int i = 0; i < npcs.size(); i++){
- SyncEntity entity = npcs.get(i);
- EntitySyncInfo info = generateInitInfo(entity, false);
- infos[i] = info;
- }
-
- try {
- client.send(msg);
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
-
- @Override
- public void clientDisconnected(Client client){
- System.out.println("Server: Client disconnected: " + client);
- }
-
- private void sendDelayedMessages(){
- ArrayList<Long> removeList = new ArrayList<Long>();
- for (Map.Entry<Long, SyncMessage> entry : latencyQueue.entrySet()){
- if (entry.getKey() > System.currentTimeMillis())
- continue;
-
- removeList.add(entry.getKey());
- if (packetDropRate > FastMath.nextRandomFloat())
- continue;
-
- for (Client client : server.getConnectors()){
- try {
- client.send(entry.getValue());
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
- for (Long removeEntry : removeList)
- latencyQueue.remove(removeEntry);
- }
-
- public void update(float tpf){
- if (latencyQueue != null)
- sendDelayedMessages();
-
- if (npcs.size() == 0)
- return;
-
- time += tpf;
- if (time < updateRate){
- return;
- }else{
- time = 0;
- }
-
- SyncMessage msg = new SyncMessage();
- msg.setReliable(false); // Purely SYNC message, reliability not needed
-
- msg.heartbeat = heartbeat;
- synchronized (npcs){
- EntitySyncInfo[] infos = new EntitySyncInfo[npcs.size()];
- msg.infos = infos;
- for (int i = 0; i < npcs.size(); i++){
- SyncEntity entity = npcs.get(i);
- EntitySyncInfo info = generateSyncInfo(entity);
- entity.onLocalUpdate();
- infos[i] = info;
- }
- }
-
- if (latencyQueue != null){
- long latencyTime = (long) (latency + (FastMath.nextRandomFloat()-0.5f) * latency);
- long timeToSend = System.currentTimeMillis() + latencyTime;
- latencyQueue.put(timeToSend, msg);
- }else{
- for (Client client : server.getConnectors()){
- try {
- client.send(msg); // unreliable
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
-
- heartbeat++;
- if (heartbeat < 0){
- // overflow detected
- heartbeat = 0;
- }
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.sync;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Deprecated
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD)
-public @interface Sync {
-
- public enum SyncType { InitOnly, Init, Sync }
-
- boolean smooth() default false;
- SyncType value() default SyncType.Sync;
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.sync;
-
-@Deprecated
-public interface SyncEntity {
-
- public void onRemoteCreate();
- public void onRemoteUpdate(float latencyDelta);
- public void onRemoteDelete();
- public void onLocalUpdate();
-
- public void interpolate(float blendAmount);
- public void extrapolate(float tpf);
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.sync;
-
-import com.jme3.network.message.Message;
-import com.jme3.network.serializing.Serializable;
-
-@Deprecated
-@Serializable
-public class SyncMessage extends Message {
- public int heartbeat;
- public EntitySyncInfo[] infos;
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2010 jMonkeyEngine
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package com.jme3.network.sync;
-
-import com.jme3.network.serializing.Serializer;
-import com.jme3.network.sync.Sync.SyncType;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.lang.reflect.Field;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-@Deprecated
-class SyncSerializer {
-
- static class SyncFieldInfo {
- private Field field;
- private boolean init,sync,smooth;
- }
-
- static class FieldTable extends ArrayList<SyncFieldInfo> {
- }
-
- private HashMap<Class<?>, FieldTable> classFieldTables
- = new HashMap<Class<?>, FieldTable>();
-
- private FieldTable generateFieldTable(Class<?> clazz){
- FieldTable table = new FieldTable();
- while (clazz != null){
- Field[] fields = clazz.getDeclaredFields();
- for (Field field : fields){
- Sync syncAnnot = field.getAnnotation(Sync.class);
- if (syncAnnot == null)
- continue;
-
- SyncFieldInfo info = new SyncFieldInfo();
- field.setAccessible(true);
- info.field = field;
- info.init = syncAnnot.value() == SyncType.Init
- || syncAnnot.value() == SyncType.InitOnly;
- info.sync = syncAnnot.value() != SyncType.InitOnly;
- info.smooth = syncAnnot.smooth();
- table.add(info);
- }
-
- clazz = clazz.getSuperclass();
- }
-
- return table;
- }
-
- private FieldTable getTable(Class<?> clazz){
- FieldTable table = classFieldTables.get(clazz);
- if (table == null){
- table = generateFieldTable(clazz);
- classFieldTables.put(clazz, table);
- }
- return table;
- }
-
- public void read(Object entity, ByteBuffer in, boolean init){
- FieldTable table = getTable(entity.getClass());
- for (SyncFieldInfo fieldInfo : table){
- if ( (init && !fieldInfo.init)
- || (!init && !fieldInfo.sync) )
- continue;
-
- Field field = fieldInfo.field;
- try {
- Object obj = Serializer.readClassAndObject(in);
- field.set(entity, obj);
- } catch (Exception ex){
- ex.printStackTrace();
- }
- }
- }
-
- public void write(Object entity, ByteBuffer out, boolean init){
- FieldTable table = getTable(entity.getClass());
- for (SyncFieldInfo fieldInfo : table){
- if ( (init && !fieldInfo.init)
- || (!init && !fieldInfo.sync) )
- continue;
-
- Field field = fieldInfo.field;
- try {
- Serializer.writeClassAndObject(out, field.get(entity));
- } catch (Exception ex){
- ex.printStackTrace();
- }
- }
- }
-}