1 package org.hedgewars.hedgeroid.netplay; |
|
2 |
|
3 import java.io.File; |
|
4 import java.io.IOException; |
|
5 |
|
6 import org.hedgewars.hedgeroid.Utils; |
|
7 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.IntStrCallback; |
|
8 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.MetaschemePtr; |
|
9 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.NetconnPtr; |
|
10 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.RoomArrayPtr; |
|
11 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.RoomCallback; |
|
12 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.RoomListCallback; |
|
13 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.RoomPtr; |
|
14 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.StrCallback; |
|
15 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.StrRoomCallback; |
|
16 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.StrStrCallback; |
|
17 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.VoidCallback; |
|
18 |
|
19 import com.sun.jna.Pointer; |
|
20 |
|
21 import android.content.Context; |
|
22 import android.util.Log; |
|
23 |
|
24 /** |
|
25 * Java-wrapper for the C netconn type. Apart from turning netconn into a more Java-like |
|
26 * object with methods, this also handles some of the problems of C <-> Java interop (e.g. |
|
27 * ensuring that callback objects don't get garbage collected). |
|
28 */ |
|
29 public class Netconn { |
|
30 private static final JnaFrontlib FLIB = Flib.INSTANCE; |
|
31 private static final String DEFAULT_SERVER = "140.247.62.101"; |
|
32 private static final int DEFAULT_PORT = 46631; |
|
33 |
|
34 private NetconnPtr conn; |
|
35 private String playerName; |
|
36 private boolean joined; // True once we have been admitted to the lobby |
|
37 |
|
38 public final PlayerList playerList = new PlayerList(); |
|
39 public final RoomList roomList = new RoomList(); |
|
40 public final MessageLog lobbyChatlog; |
|
41 public final MessageLog roomChatlog; |
|
42 |
|
43 private StrCallback lobbyJoinCb = new StrCallback() { |
|
44 public void callback(Pointer context, String arg1) { |
|
45 playerList.addPlayerWithNewId(arg1); |
|
46 lobbyChatlog.appendPlayerJoin(arg1); |
|
47 } |
|
48 }; |
|
49 |
|
50 private StrStrCallback lobbyLeaveCb = new StrStrCallback() { |
|
51 public void callback(Pointer context, String name, String msg) { |
|
52 playerList.removePlayer(name); |
|
53 lobbyChatlog.appendPlayerLeave(name, msg); |
|
54 } |
|
55 }; |
|
56 |
|
57 private StrStrCallback chatCb = new StrStrCallback() { |
|
58 public void callback(Pointer context, String name, String msg) { |
|
59 getCurrentLog().appendChat(name, msg); |
|
60 } |
|
61 }; |
|
62 |
|
63 private IntStrCallback messageCb = new IntStrCallback() { |
|
64 public void callback(Pointer context, int type, String msg) { |
|
65 getCurrentLog().appendMessage(type, msg); |
|
66 } |
|
67 }; |
|
68 |
|
69 private RoomCallback roomAddCb = new RoomCallback() { |
|
70 public void callback(Pointer context, RoomPtr roomPtr) { |
|
71 roomList.addRoomWithNewId(roomPtr); |
|
72 } |
|
73 }; |
|
74 |
|
75 private StrRoomCallback roomUpdateCb = new StrRoomCallback() { |
|
76 public void callback(Pointer context, String name, RoomPtr roomPtr) { |
|
77 roomList.updateRoom(name, roomPtr); |
|
78 } |
|
79 }; |
|
80 |
|
81 private StrCallback roomDeleteCb = new StrCallback() { |
|
82 public void callback(Pointer context, String name) { |
|
83 roomList.removeRoom(name); |
|
84 } |
|
85 }; |
|
86 |
|
87 private VoidCallback connectedCb = new VoidCallback() { |
|
88 public void callback(Pointer context) { |
|
89 // TODO I guess more needs to happen here... |
|
90 joined = true; |
|
91 FLIB.flib_netconn_send_request_roomlist(conn); |
|
92 } |
|
93 }; |
|
94 |
|
95 private RoomListCallback roomlistCb = new RoomListCallback() { |
|
96 public void callback(Pointer context, RoomArrayPtr arg1, int count) { |
|
97 roomList.updateList(arg1.getRooms(count)); |
|
98 } |
|
99 }; |
|
100 |
|
101 private IntStrCallback disconnectCb = new IntStrCallback() { |
|
102 public void callback(Pointer context, int arg1, String arg2) { |
|
103 FLIB.flib_netconn_destroy(conn); |
|
104 conn = null; |
|
105 } |
|
106 }; |
|
107 |
|
108 /** |
|
109 * Connect to the official Hedgewars server. |
|
110 * |
|
111 * @throws IOException if the metascheme file can't be read or the connection to the server fails |
|
112 */ |
|
113 public Netconn(Context context, String playerName) throws IOException { |
|
114 this(context, playerName, DEFAULT_SERVER, DEFAULT_PORT); |
|
115 } |
|
116 |
|
117 /** |
|
118 * Connect to the server with the given hostname and port |
|
119 * |
|
120 * @throws IOException if the metascheme file can't be read or the connection to the server fails |
|
121 */ |
|
122 public Netconn(Context context, String playerName, String host, int port) throws IOException { |
|
123 if(playerName == null) { |
|
124 playerName = "Player"; |
|
125 } |
|
126 this.playerName = playerName; |
|
127 this.lobbyChatlog = new MessageLog(context); |
|
128 this.roomChatlog = new MessageLog(context); |
|
129 |
|
130 MetaschemePtr meta = null; |
|
131 File dataPath = Utils.getDataPathFile(context); |
|
132 try { |
|
133 String metaschemePath = new File(dataPath, "metasettings.ini").getAbsolutePath(); |
|
134 meta = FLIB.flib_metascheme_from_ini(metaschemePath); |
|
135 if(meta == null) { |
|
136 throw new IOException("Missing metascheme"); |
|
137 } |
|
138 conn = FLIB.flib_netconn_create(playerName, meta, dataPath.getAbsolutePath(), host, port); |
|
139 if(conn == null) { |
|
140 throw new IOException("Unable to connect to the server"); |
|
141 } |
|
142 FLIB.flib_netconn_onLobbyJoin(conn, lobbyJoinCb, null); |
|
143 FLIB.flib_netconn_onLobbyLeave(conn, lobbyLeaveCb, null); |
|
144 FLIB.flib_netconn_onChat(conn, chatCb, null); |
|
145 FLIB.flib_netconn_onMessage(conn, messageCb, null); |
|
146 FLIB.flib_netconn_onRoomAdd(conn, roomAddCb, null); |
|
147 FLIB.flib_netconn_onRoomUpdate(conn, roomUpdateCb, null); |
|
148 FLIB.flib_netconn_onRoomDelete(conn, roomDeleteCb, null); |
|
149 FLIB.flib_netconn_onConnected(conn, connectedCb, null); |
|
150 FLIB.flib_netconn_onRoomlist(conn, roomlistCb, null); |
|
151 FLIB.flib_netconn_onDisconnected(conn, disconnectCb, null); |
|
152 } finally { |
|
153 FLIB.flib_metascheme_release(meta); |
|
154 } |
|
155 } |
|
156 |
|
157 public void disconnect() { |
|
158 if(conn != null) { |
|
159 FLIB.flib_netconn_send_quit(conn, "User quit"); |
|
160 FLIB.flib_netconn_destroy(conn); |
|
161 conn = null; |
|
162 } |
|
163 } |
|
164 |
|
165 public void tick() { |
|
166 FLIB.flib_netconn_tick(conn); |
|
167 } |
|
168 |
|
169 public void sendChat(String s) { |
|
170 FLIB.flib_netconn_send_chat(conn, s); |
|
171 if(FLIB.flib_netconn_is_in_room_context(conn)) { |
|
172 roomChatlog.appendChat(playerName, s); |
|
173 } else { |
|
174 lobbyChatlog.appendChat(playerName, s); |
|
175 } |
|
176 } |
|
177 |
|
178 private MessageLog getCurrentLog() { |
|
179 if(FLIB.flib_netconn_is_in_room_context(conn)) { |
|
180 return roomChatlog; |
|
181 } else { |
|
182 return lobbyChatlog; |
|
183 } |
|
184 } |
|
185 |
|
186 public void sendNick(String nick) { FLIB.flib_netconn_send_nick(conn, nick); } |
|
187 public void sendPassword(String password) { FLIB.flib_netconn_send_password(conn, password); } |
|
188 public void sendQuit(String message) { FLIB.flib_netconn_send_quit(conn, message); } |
|
189 public void sendRoomlistRequest() { if(joined) FLIB.flib_netconn_send_request_roomlist(conn); } |
|
190 public void sendPlayerInfoQuery(String name) { FLIB.flib_netconn_send_playerInfo(conn, name); } |
|
191 |
|
192 public boolean isConnected() { |
|
193 return conn != null; |
|
194 } |
|
195 |
|
196 @Override |
|
197 protected void finalize() throws Throwable { |
|
198 if(conn != null) { |
|
199 FLIB.flib_netconn_destroy(conn); |
|
200 Log.e("Netconn", "Leaked Netconn object"); |
|
201 } |
|
202 } |
|
203 |
|
204 } |
|