project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/netplay/Netconn.java
changeset 7355 5673e95ef647
parent 7352 641f11cdd319
child 7358 57a508884052
equal deleted inserted replaced
7352:641f11cdd319 7355:5673e95ef647
     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 }