1 package net.sourceforge.simplegamenet.framework.transport;
2
3 import java.io.IOException;
4 import java.io.ObjectInputStream;
5 import java.io.ObjectOutputStream;
6 import java.net.InetAddress;
7 import java.net.Socket;
8 import net.sourceforge.simplegamenet.framework.GameFactoryManager;
9 import net.sourceforge.simplegamenet.framework.model.SimpleGameNetSettings;
10 import net.sourceforge.simplegamenet.specs.model.GameFactory;
11 import net.sourceforge.simplegamenet.specs.to.Version;
12
13 public class ClientLoginHandler implements PacketCodes {
14
15 private static final int CONNECTION_TIME_OUT_TIME = 30000;
16
17 public ClientLoginHandler() {
18 }
19
20 public ClientConnectionData connect(InetAddress hostInetAddress, int port, String nickname)
21 throws IOException {
22 Socket socket = new Socket(hostInetAddress, port);
23 try {
24 ObjectOutputStream objectOutputStream = new ObjectOutputStream(
25 socket.getOutputStream());
26 ObjectInputStream objectInputStream = new GamesObjectInputStream(
27 socket.getInputStream(),
28 GameFactoryManager.getInstance().getGamesClassLoader());
29 socket.setSoTimeout(CONNECTION_TIME_OUT_TIME);
30 objectOutputStream.writeObject(new Packet(CON_CLIENT_CON_OPEN,
31 new Integer(0x00000001)));
32 Packet packet = (Packet) objectInputStream.readObject();
33 if (packet.getPacketCode() == E_CON_BANNED) {
34 throw new ClientLoginException(ClientLoginException.BANNED);
35 } else if (packet.getPacketCode() != CON_SERVER_CON_OPEN) {
36 throw new ClientLoginException(ClientLoginException.PROTOCOL_VIOLATION);
37 }
38 objectOutputStream.writeObject(new Packet(CON_SGN_VERSION,
39 SimpleGameNetSettings.getInstance().getVersion()));
40 packet = (Packet) objectInputStream.readObject();
41 if (packet.getPacketCode() == E_CON_CLIENT_SGN_VERSION) {
42 throw new ClientLoginException(ClientLoginException.CLIENT_SGN_VERSION);
43 } else if (packet.getPacketCode() == E_CON_SERVER_SGN_VERSION) {
44 throw new ClientLoginException(ClientLoginException.SERVER_SGN_VERSION);
45 } else if (packet.getPacketCode() != GAME_OPEN) {
46 throw new ClientLoginException(ClientLoginException.PROTOCOL_VIOLATION);
47 }
48 GameIdentification gameIdentification = (GameIdentification) packet.getData();
49 GameFactory gameFactory = GameFactoryManager.getInstance().getGameFactory(
50 gameIdentification);
51 if (gameFactory == null) {
52 objectOutputStream.writeObject(new Packet(E_GAME_NOT_FOUND, null));
53 throw new ClientLoginException(ClientLoginException.GAME_NOT_FOUND);
54 }
55 Version gameVersion = gameFactory.getVersion();
56 if (gameVersion.compareTo(gameIdentification.getVersion()) < 0) {
57 objectOutputStream.writeObject(new Packet(E_GAME_CLIENT_GAME_VERSION,
58 gameVersion));
59 throw new ClientLoginException(ClientLoginException.CLIENT_GAME_VERSION);
60 } else if (gameVersion.compareTo(gameIdentification.getVersion()) > 0) {
61 objectOutputStream.writeObject(new Packet(E_GAME_SERVER_GAME_VERSION,
62 gameVersion));
63 throw new ClientLoginException(ClientLoginException.SERVER_GAME_VERSION);
64 }
65 objectOutputStream.writeObject(new Packet(CON_LOGIN_NICKNAME, nickname));
66 packet = (Packet) objectInputStream.readObject();
67 if (packet.getPacketCode() == E_CON_LOGIN) {
68 throw new ClientLoginException(ClientLoginException.LOGIN_NOT_ACCEPTED);
69 } else if (packet.getPacketCode() != CON_LOGIN_DATA) {
70 throw new ClientLoginException(ClientLoginException.PROTOCOL_VIOLATION);
71 }
72 socket.setSoTimeout(0);
73 LoginData loginData = (LoginData) packet.getData();
74 return new ClientConnectionData(socket, objectInputStream, objectOutputStream,
75 loginData, gameFactory);
76 } catch (ClassNotFoundException exception) {
77 try {
78 socket.close();
79 } catch (IOException innerException) {
80 innerException.printStackTrace();
81 }
82 throw new ClientLoginException(ClientLoginException.PROTOCOL_VIOLATION);
83 } catch (ClassCastException exception) {
84 try {
85 socket.close();
86 } catch (IOException innerException) {
87 innerException.printStackTrace();
88 }
89 throw new ClientLoginException(ClientLoginException.PROTOCOL_VIOLATION);
90 } catch (IOException exception) {
91 try {
92 socket.close();
93 } catch (IOException innerException) {
94 innerException.printStackTrace();
95 }
96 if (exception instanceof ClientLoginException) {
97 throw exception;
98 } else {
99 throw new ClientLoginException(ClientLoginException.PROTOCOL_VIOLATION);
100 }
101 }
102 }
103
104 }