22
33import java .io .IOException ;
44import java .io .InputStreamReader ;
5- import java .lang .reflect .ParameterizedType ;
65import java .lang .reflect .Type ;
76import java .net .HttpURLConnection ;
7+ import java .net .URI ;
88import java .net .URL ;
9+ import java .net .http .HttpClient ;
10+ import java .net .http .WebSocket ;
911import java .util .Arrays ;
1012import java .util .HashMap ;
1113
@@ -22,7 +24,7 @@ public class Api {
2224 private boolean tls ;
2325 private String baseURL ;
2426
25- private static Gson json = new GsonBuilder ().setFieldNamingPolicy (FieldNamingPolicy .LOWER_CASE_WITH_UNDERSCORES )
27+ static Gson json = new GsonBuilder ().setFieldNamingPolicy (FieldNamingPolicy .LOWER_CASE_WITH_UNDERSCORES )
2628 .create ();
2729
2830 public Api (String url ) {
@@ -65,10 +67,6 @@ public class GameData {
6567 public String joinSecret ;
6668 }
6769
68- public GameData createGame (boolean makePublic , boolean protect ) throws IOException {
69- return createGame (makePublic , protect , null );
70- }
71-
7270 private class CreateGameRequest {
7371 @ SerializedName ("public" )
7472 public boolean makePublic ;
@@ -78,7 +76,7 @@ private class CreateGameRequest {
7876 public Object config ;
7977 }
8078
81- public GameData createGame (boolean makePublic , boolean protect , Object config ) throws IOException {
79+ GameData createGame (boolean makePublic , boolean protect , Object config ) throws IOException {
8280 var data = new CreateGameRequest ();
8381 data .makePublic = makePublic ;
8482 data .protect = protect ;
@@ -93,7 +91,7 @@ public class PlayerData {
9391 public String secret ;
9492 }
9593
96- public PlayerData createPlayer (String gameId , String username ) throws IOException {
94+ PlayerData createPlayer (String gameId , String username ) throws IOException {
9795 return createPlayer (gameId , username , "" );
9896 }
9997
@@ -104,7 +102,7 @@ private class CreatePlayerRequest {
104102 public String joinSecret ;
105103 }
106104
107- public PlayerData createPlayer (String gameId , String username , String joinSecret ) throws IOException {
105+ PlayerData createPlayer (String gameId , String username , String joinSecret ) throws IOException {
108106 var data = new CreatePlayerRequest ();
109107 data .username = username ;
110108 data .joinSecret = joinSecret ;
@@ -116,28 +114,38 @@ private class FetchUsernameResponse {
116114 public String username ;
117115 }
118116
119- public String fetchUsername (String gameId , String playerId ) throws IOException {
117+ String fetchUsername (String gameId , String playerId ) throws IOException {
120118 return fetchJSON ("/api/games/" + gameId + "/players/" + playerId , FetchUsernameResponse .class ).username ;
121119 }
122120
123- public HashMap <String , String > fetchPlayers (String gameId ) throws IOException {
121+ HashMap <String , String > fetchPlayers (String gameId ) throws IOException {
124122 return fetchJSON ("/api/games/" + gameId + "/players" ,
125123 TypeToken .getParameterized (HashMap .class , String .class , String .class ).getType ());
126124 }
127125
126+ WebSocket connectWebSocket (String endpoint , WSClient .OnMessageCallback onMessage ,
127+ WSClient .OnCloseCallback onClose ) {
128+ return HttpClient .newHttpClient ().newWebSocketBuilder ()
129+ .buildAsync (URI .create (baseURL ("ws" , tls , url + endpoint )),
130+ new WSClient (onMessage , onClose ))
131+ .join ();
132+ }
133+
128134 private <T > T postJSON (String endpoint , Object requestData , Class <T > responseType ) throws IOException {
129135 URL obj = new URL (this .baseURL + endpoint );
130136 HttpURLConnection con = (HttpURLConnection ) obj .openConnection ();
131137 con .setRequestMethod ("POST" );
132138 con .setRequestProperty ("Content-Type" , "application/json" );
133139
134140 var reqData = json .toJson (requestData );
135- System .out .println ("Data: " + reqData );
136141 con .setDoOutput (true );
137142 var os = con .getOutputStream ();
138- os .write (reqData .getBytes ());
139- os .flush ();
140- os .close ();
143+ try {
144+ os .write (reqData .getBytes ());
145+ os .flush ();
146+ } finally {
147+ os .close ();
148+ }
141149
142150 int responseCode = con .getResponseCode ();
143151 if (responseCode != HttpURLConnection .HTTP_OK && responseCode != HttpURLConnection .HTTP_CREATED ) {
@@ -146,8 +154,12 @@ private <T> T postJSON(String endpoint, Object requestData, Class<T> responseTyp
146154 }
147155
148156 InputStreamReader reader = new InputStreamReader (con .getInputStream ());
149- T data = json .fromJson (reader , responseType );
150- return data ;
157+ try {
158+ T data = json .fromJson (reader , responseType );
159+ return data ;
160+ } finally {
161+ reader .close ();
162+ }
151163 }
152164
153165 private <T > T fetchJSON (String endpoint , Class <T > responseType ) throws IOException {
@@ -156,12 +168,18 @@ private <T> T fetchJSON(String endpoint, Class<T> responseType) throws IOExcepti
156168 con .setRequestMethod ("GET" );
157169 con .setRequestProperty ("Accept" , "application/json" );
158170 var reader = new InputStreamReader (con .getInputStream ());
159- int responseCode = con .getResponseCode ();
160- if (responseCode != HttpURLConnection .HTTP_OK )
161- throw new IOException ("Failed to read response from " + endpoint + " endpoint: unexpected response code: "
162- + responseCode );
163- T data = json .fromJson (reader , responseType );
164- return data ;
171+ try {
172+ int responseCode = con .getResponseCode ();
173+ if (responseCode != HttpURLConnection .HTTP_OK ) {
174+ throw new IOException (
175+ "Failed to read response from " + endpoint + " endpoint: unexpected response code: "
176+ + responseCode );
177+ }
178+ T data = json .fromJson (reader , responseType );
179+ return data ;
180+ } finally {
181+ reader .close ();
182+ }
165183 }
166184
167185 private <T > T fetchJSON (String endpoint , Type responseType ) throws IOException {
@@ -170,12 +188,19 @@ private <T> T fetchJSON(String endpoint, Type responseType) throws IOException {
170188 con .setRequestMethod ("GET" );
171189 con .setRequestProperty ("Accept" , "application/json" );
172190 var reader = new InputStreamReader (con .getInputStream ());
173- int responseCode = con .getResponseCode ();
174- if (responseCode != HttpURLConnection .HTTP_OK )
175- throw new IOException ("Failed to read response from " + endpoint + " endpoint: unexpected response code: "
176- + responseCode );
177- T data = json .fromJson (reader , responseType );
178- return data ;
191+ try {
192+ int responseCode = con .getResponseCode ();
193+ if (responseCode != HttpURLConnection .HTTP_OK ) {
194+ reader .close ();
195+ throw new IOException (
196+ "Failed to read response from " + endpoint + " endpoint: unexpected response code: "
197+ + responseCode );
198+ }
199+ T data = json .fromJson (reader , responseType );
200+ return data ;
201+ } finally {
202+ reader .close ();
203+ }
179204 }
180205
181206 static String trimURL (String url ) {
@@ -198,10 +223,17 @@ static boolean isTLS(String trimmedURL) {
198223 try {
199224 var url = new URL (baseURL ("http" , true , trimmedURL ) + "/api/info" );
200225 var connection = (HttpsURLConnection ) url .openConnection ();
201- connection .getInputStream ();
202- if (connection .getSSLSession ().isEmpty ())
226+ var stream = connection .getInputStream ();
227+ if (connection .getSSLSession ().isEmpty ()) {
228+ stream .close ();
229+ return false ;
230+ }
231+ if (!connection .getSSLSession ().get ().isValid ()) {
232+ stream .close ();
203233 return false ;
204- return connection .getSSLSession ().get ().isValid ();
234+ }
235+ stream .close ();
236+ return true ;
205237 } catch (IOException e ) {
206238 return false ;
207239 }
0 commit comments