|
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.StrCallback; |
|
11 import org.hedgewars.hedgeroid.netplay.JnaFrontlib.StrStrCallback; |
|
12 |
|
13 import com.sun.jna.Pointer; |
|
14 |
|
15 import android.content.Context; |
|
16 import android.util.Log; |
|
17 |
|
18 /** |
|
19 * Java-wrapper for the C netconn type. Apart from turning netconn into a more Java-like |
|
20 * object with methods, this also handles some of the problems of C <-> Java interop (e.g. |
|
21 * ensuring that callback objects don't get garbage collected). |
|
22 */ |
|
23 public class Netconn { |
|
24 private static final JnaFrontlib FLIB = Flib.INSTANCE; |
|
25 private static final String DEFAULT_SERVER = "140.247.62.101"; |
|
26 private static final int DEFAULT_PORT = 46631; |
|
27 |
|
28 private NetconnPtr conn; |
|
29 private String playerName; |
|
30 |
|
31 public final PlayerList playerList = new PlayerList(); |
|
32 public final MessageLog lobbyLog; |
|
33 public final MessageLog roomLog; |
|
34 |
|
35 private StrCallback lobbyJoinCb = new StrCallback() { |
|
36 public void callback(Pointer context, String arg1) { |
|
37 playerList.addPlayer(arg1); |
|
38 lobbyLog.appendPlayerJoin(arg1); |
|
39 } |
|
40 }; |
|
41 |
|
42 private StrStrCallback lobbyLeaveCb = new StrStrCallback() { |
|
43 public void callback(Pointer context, String name, String msg) { |
|
44 playerList.removePlayer(name); |
|
45 lobbyLog.appendPlayerLeave(name, msg); |
|
46 } |
|
47 }; |
|
48 |
|
49 private StrStrCallback chatCb = new StrStrCallback() { |
|
50 public void callback(Pointer context, String name, String msg) { |
|
51 getCurrentLog().appendChat(name, msg); |
|
52 } |
|
53 }; |
|
54 |
|
55 private IntStrCallback messageCb = new IntStrCallback() { |
|
56 public void callback(Pointer context, int type, String msg) { |
|
57 getCurrentLog().appendMessage(type, msg); |
|
58 } |
|
59 }; |
|
60 |
|
61 /** |
|
62 * Connect to the official Hedgewars server. |
|
63 * |
|
64 * @throws IOException if the metascheme file can't be read or the connection to the server fails |
|
65 */ |
|
66 public Netconn(Context context, String playerName) throws IOException { |
|
67 this(context, playerName, DEFAULT_SERVER, DEFAULT_PORT); |
|
68 } |
|
69 |
|
70 /** |
|
71 * Connect to the server with the given hostname and port |
|
72 * |
|
73 * @throws IOException if the metascheme file can't be read or the connection to the server fails |
|
74 */ |
|
75 public Netconn(Context context, String playerName, String host, int port) throws IOException { |
|
76 if(playerName == null) { |
|
77 playerName = "Player"; |
|
78 } |
|
79 this.playerName = playerName; |
|
80 this.lobbyLog = new MessageLog(context); |
|
81 this.roomLog = new MessageLog(context); |
|
82 |
|
83 MetaschemePtr meta = null; |
|
84 File dataPath = Utils.getDataPathFile(context); |
|
85 try { |
|
86 String metaschemePath = new File(dataPath, "metasettings.ini").getAbsolutePath(); |
|
87 meta = FLIB.flib_metascheme_from_ini(metaschemePath); |
|
88 if(meta == null) { |
|
89 throw new IOException("Missing metascheme"); |
|
90 } |
|
91 conn = FLIB.flib_netconn_create(playerName, meta, dataPath.getAbsolutePath(), host, port); |
|
92 if(conn == null) { |
|
93 throw new IOException("Unable to connect to the server"); |
|
94 } |
|
95 FLIB.flib_netconn_onLobbyJoin(conn, lobbyJoinCb, null); |
|
96 FLIB.flib_netconn_onLobbyLeave(conn, lobbyLeaveCb, null); |
|
97 FLIB.flib_netconn_onChat(conn, chatCb, null); |
|
98 FLIB.flib_netconn_onMessage(conn, messageCb, null); |
|
99 } finally { |
|
100 FLIB.flib_metascheme_release(meta); |
|
101 } |
|
102 } |
|
103 |
|
104 public void disconnect() { |
|
105 if(conn != null) { |
|
106 FLIB.flib_netconn_send_quit(conn, "User quit"); |
|
107 FLIB.flib_netconn_destroy(conn); |
|
108 conn = null; |
|
109 } |
|
110 } |
|
111 |
|
112 public void tick() { |
|
113 FLIB.flib_netconn_tick(conn); |
|
114 } |
|
115 |
|
116 public void sendChat(String s) { |
|
117 FLIB.flib_netconn_send_chat(conn, s); |
|
118 if(FLIB.flib_netconn_is_in_room_context(conn)) { |
|
119 roomLog.appendChat(playerName, s); |
|
120 } else { |
|
121 lobbyLog.appendChat(playerName, s); |
|
122 } |
|
123 } |
|
124 |
|
125 private MessageLog getCurrentLog() { |
|
126 if(FLIB.flib_netconn_is_in_room_context(conn)) { |
|
127 return roomLog; |
|
128 } else { |
|
129 return lobbyLog; |
|
130 } |
|
131 } |
|
132 |
|
133 public void sendNick(String nick) { FLIB.flib_netconn_send_nick(conn, nick); } |
|
134 public void sendPassword(String password) { FLIB.flib_netconn_send_password(conn, password); } |
|
135 public void sendQuit(String message) { FLIB.flib_netconn_send_quit(conn, message); } |
|
136 |
|
137 public boolean isConnected() { |
|
138 return conn != null; |
|
139 } |
|
140 |
|
141 @Override |
|
142 protected void finalize() throws Throwable { |
|
143 if(conn != null) { |
|
144 FLIB.flib_netconn_destroy(conn); |
|
145 Log.e("Netconn", "Leaked Netconn object"); |
|
146 } |
|
147 } |
|
148 } |