/* SubspaceMobile - A subspace/continuum client for mobile phones Copyright (C) 2010 Kingsley Masters Email: kshade2001 at users.sourceforge.net This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. REVISIONS: */ package com.subspace.network; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import android.content.Context; import android.util.Log; /** * * @author Kingsley */ public class NetworkDirectory extends NetworkSubspace implements INetworkCallback { static final String TAG = "Subspace"; static int SUBSPACE_DIRECTORY_PORT = 4990; static int RESPONSE_TIMEOUT = 30000; // 30s boolean responseReceieved; ArrayList<DirectoryZone> result; public NetworkDirectory(Context context) { super(context); this.setCallback(this); } public ArrayList<DirectoryZone> Download(String host) throws IOException { responseReceieved = false; result = null; try { if (this.SSConnect(host, SUBSPACE_DIRECTORY_PORT)) { this.SSSendReliable(NetworkPacket.CreateZoneListRequest()); synchronized (this) { this.wait(); // this.wait(RESPONSE_TIMEOUT); } this.SSDisconnect(); //if no response received return null if (!responseReceieved) { return null; } } } catch (InterruptedException ie) { Log.d(TAG, Log.getStackTraceString(ie)); } return result; } public ByteBuffer Recv(ByteBuffer data, boolean decrypt) { //decrypt data = super.Recv(data, decrypt); //analyse if (data != null) { if(LOG_CORE_PACKETS) { Log.v(TAG,"Zone Download Stream " + Util.ToHex(data)); } try { if (data.get(0) == NetworkPacket.DIRECTORY_REQUEST) { //its saved in the array file result = new ArrayList<DirectoryZone>(); int p = 1; while (p < data.limit()) { StringBuffer ipsb = new StringBuffer(15); ipsb.append(data.get(p) & 0xFF); p++; ipsb.append("."); ipsb.append(data.get(p) & 0xFF); p++; ipsb.append("."); ipsb.append(data.get(p) & 0xFF); p++; ipsb.append("."); ipsb.append(data.get(p) & 0xFF); p++; //switch byte order data.order(ByteOrder.LITTLE_ENDIAN); int port = (int)(data.getShort(p) & 0xFFFF); p += 2; short playerCount = (short) (data.getShort(p) & 0xFFFF); p += 2; byte billing = data.get(p); p += 1; byte hopcount = data.get(p); p += 1; int version = data.getInt(p); p += 4; String name = Util.GetString(data, p, 64, NetworkSubspace.CHAR_ENCODING); p += 64; int startPosition = p; while (data.get(p) != 0) { p++; } String description = Util.GetString(data, startPosition, p - startPosition, NetworkSubspace.CHAR_ENCODING); p++; DirectoryZone dzi = new DirectoryZone( ipsb.toString(), port, playerCount, billing != 0, hopcount, version, name, description); Log.v(TAG, "Zone Listing Downloaded: " + dzi.toString()); result.add(dzi); } //notify completion of task synchronized (this) { responseReceieved = true; this.notify(); } } } catch (Exception e) { Log.e(TAG, Log.getStackTraceString(e)); } } return null; } }