Skip to content

Commit 483baad

Browse files
Add files via upload
1 parent 61a4993 commit 483baad

23 files changed

Lines changed: 2069 additions & 5 deletions
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
package com.luneruniverse.simplepacketlibrary;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.net.InetSocketAddress;
6+
import java.net.Socket;
7+
import java.net.URISyntaxException;
8+
import java.net.UnknownHostException;
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
import java.util.concurrent.ConcurrentLinkedQueue;
12+
13+
import javax.net.ssl.SSLContext;
14+
15+
import com.luneruniverse.simplepacketlibrary.accessors.RawSocketAccess;
16+
import com.luneruniverse.simplepacketlibrary.accessors.ClientWebSocketAccess;
17+
import com.luneruniverse.simplepacketlibrary.listeners.ErrorHandler;
18+
import com.luneruniverse.simplepacketlibrary.listeners.PacketListener;
19+
import com.luneruniverse.simplepacketlibrary.packets.Packet;
20+
21+
/**
22+
* Connects to a {@link Server}
23+
*/
24+
public class Client extends Connection {
25+
26+
private final String ip;
27+
private final int port;
28+
private final List<ErrorHandler<Client>> errorHandlers;
29+
30+
private int connectTimeout;
31+
private boolean useWebSocket;
32+
private SSLContext ssl;
33+
34+
/**
35+
* Create a client <br>
36+
* Will not start the client <br>
37+
* Will not check if the ip or port is open
38+
* @param ip The ip to connect to
39+
* @param port The port to connect to
40+
* @see #start()
41+
*/
42+
public Client(String ip, int port) {
43+
super(new ConcurrentLinkedQueue<>());
44+
this.ip = ip;
45+
this.port = port;
46+
this.errorHandlers = new ArrayList<>();
47+
this.connectTimeout = 5000;
48+
useWebSocket(false);
49+
}
50+
/**
51+
* Create a client <br>
52+
* Will not start the client <br>
53+
* Will not check if the port is open <br>
54+
* Connects to localhost
55+
* @param port The port to connect to
56+
* @see #start()
57+
*/
58+
public Client(int port) throws UnknownHostException, IOException {
59+
this(null, port);
60+
}
61+
62+
/**
63+
* Get the ip
64+
* @return ip
65+
*/
66+
public String getIp() {
67+
return ip;
68+
}
69+
/**
70+
* Get the port
71+
* @return port
72+
*/
73+
public int getPort() {
74+
return port;
75+
}
76+
77+
/**
78+
* Set the connect timeout, which defaults to 5000 (or 5 seconds)
79+
* @param connectTimeout The timeout, or 0 if {@link #start()} should block indefinitely
80+
* @see #getConnectTimeout()
81+
* @see #setTimeout(int)
82+
*/
83+
public void setConnectTimeout(int connectTimeout) {
84+
this.connectTimeout = connectTimeout;
85+
}
86+
/**
87+
* Get the connect timeout
88+
* @return The timeout, or 0 if {@link #start()} will block indefinitely
89+
* @see #setConnectTimeout(int)
90+
* @see #getTimeout()
91+
*/
92+
public int getConnectTimeout() {
93+
return connectTimeout;
94+
}
95+
96+
/**
97+
* Specify whether or not this should use a WebSocket rather than a normal Socket <br>
98+
* The server must also be in the same mode <br>
99+
* A WebSocket allows communication with the JavaScript variant of this library
100+
* @param useWebSocket
101+
* @return this
102+
* @see #isWebSocket()
103+
* @see Server#useWebSocket(boolean)
104+
*/
105+
public Client useWebSocket(boolean useWebSocket) {
106+
this.useWebSocket = useWebSocket;
107+
return this;
108+
}
109+
110+
/**
111+
* @return If this uses a WebSocket
112+
* @see #useWebSocket(boolean)
113+
*/
114+
public boolean isWebSocket() {
115+
return useWebSocket;
116+
}
117+
118+
/**
119+
* <strong>ONLY WORKS WHEN IN WEBSOCKET MODE</strong> <br>
120+
* Allows for wss:// connections, instead of just ws://
121+
* @param ssl The SSLContext, or null to disable SSL
122+
* @return this
123+
* @see #generateSSLContext(File, String, String, String, String)
124+
* @see #isSecure()
125+
* @see #useWebSocket(boolean)
126+
*/
127+
public Client setSecure(SSLContext ssl) {
128+
this.ssl = ssl;
129+
return this;
130+
}
131+
132+
/**
133+
* <strong>ONLY WORKS WHEN IN WEBSOCKET MODE</strong> <br>
134+
* This function returns as if this socket is in websocket mode <br>
135+
* This checks if the last supplied SSLContext was not null
136+
* @return If SSL is enabled
137+
* @see #setSecure(SSLContext)
138+
* @see #useWebSocket(boolean)
139+
*/
140+
public boolean isSecure() {
141+
return this.ssl != null;
142+
}
143+
144+
/**
145+
* The listener is called when a {@link Packet} is received <br>
146+
* Calling this twice will cause the listener to be called twice
147+
* @param listener
148+
* @return this
149+
* @see #removePacketListener(PacketListener)
150+
*/
151+
public Client addPacketListener(PacketListener listener) {
152+
packetListeners.add(listener);
153+
return this;
154+
}
155+
156+
/**
157+
* The listener will stop being called <br>
158+
* If {@link #addPacketListener(PacketListener)} was called twice, it will still be called once
159+
* @param listener
160+
* @return If the listener was registered
161+
* @see #addPacketListener(PacketListener)
162+
*/
163+
public boolean removePacketListener(PacketListener listener) {
164+
return packetListeners.remove(listener);
165+
}
166+
167+
/**
168+
* Connect the client <br>
169+
* @return this
170+
* @throws UnknownHostException If the IP address of the host could not be determined
171+
* @throws IOException If an I/O error occurs when creating the socket
172+
*/
173+
public Client start() throws UnknownHostException, IOException {
174+
if (isAlive())
175+
return this;
176+
177+
String ip = (this.ip == null ? "localhost" : this.ip);
178+
try {
179+
if (useWebSocket)
180+
start(new ClientWebSocketAccess(this, ip, port, connectTimeout, ssl));
181+
else {
182+
Socket socket = new Socket();
183+
socket.connect(new InetSocketAddress(ip, port), connectTimeout);
184+
start(new RawSocketAccess(socket));
185+
}
186+
return this;
187+
} catch (URISyntaxException e) {
188+
throw new UnknownHostException(e.getInput());
189+
}
190+
}
191+
192+
/**
193+
* You can start a client after it has been stopped
194+
* @return If the client is connected
195+
* @see #start()
196+
* @see #close()
197+
*/
198+
@Override
199+
public boolean isAlive() {
200+
return super.isAlive();
201+
}
202+
203+
204+
/**
205+
* The handler is called when an error occurs <br>
206+
* Calling this twice will cause the handler to be called twice
207+
* @param handler
208+
* @return this
209+
* @see #removeErrorHandler(ErrorHandler)
210+
*/
211+
public Client addErrorHandler(ErrorHandler<Client> handler) {
212+
errorHandlers.add(handler);
213+
return this;
214+
}
215+
/**
216+
* The handler will stop being called <br>
217+
* If {@link #addErrorHandler(ErrorHandler)} was called twice, it will still be called once
218+
* @param handler
219+
* @return If the handler was registered
220+
* @see #addErrorHandler(ErrorHandler)
221+
*/
222+
public boolean removeErrorHandler(ErrorHandler<Client> handler) {
223+
return errorHandlers.remove(handler);
224+
}
225+
226+
@Override
227+
public void onError(Exception e, Connection obj, Error error) {
228+
if (errorHandlers.isEmpty()) {
229+
System.err.println("Client error: " + error);
230+
e.printStackTrace();
231+
} else {
232+
for (ErrorHandler<Client> errorHandler : errorHandlers)
233+
errorHandler.onError(e, (Client) obj, error);
234+
}
235+
}
236+
237+
}

0 commit comments

Comments
 (0)