/* Subspace Mobile - A Android Subspace Client Copyright (C) 2012 Kingsley Masters. All Rights Reserved. kingsley dot masters at gmail dot com 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/>. */ package com.subspace.redemption; import android.app.Activity; import android.app.ProgressDialog; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.preference.PreferenceManager; import android.text.Html; import android.util.Log; import android.view.Display; import android.view.KeyEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.view.View.OnClickListener; import android.view.inputmethod.EditorInfo; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; import com.subspace.android.Information; import com.subspace.android.LVL; import com.subspace.android.NetworkService; import com.subspace.android.News; import com.subspace.network.IGameCallback; import com.subspace.network.ISubspaceCallback; import com.subspace.network.NetworkGame; import com.subspace.network.messages.LvlSettings; import com.subspace.network.messages.Chat; import com.subspace.network.messages.LoginResponse; import com.subspace.network.messages.MapInformation; import com.subspace.network.messages.PlayerEnter; import com.subspace.network.messages.PlayerLeave; import com.subspace.redemption.ZonesActivity.DownloadZonesTask; import com.subspace.redemption.database.DataHelper; import com.subspace.redemption.dataobjects.Zone; public class ConnectActivity extends Activity implements ISubspaceCallback, IGameCallback { static String TAG = "Subspace"; Activity self = this; TextView messageView; NetworkService subspaceService; Zone zone; boolean networkIsBound; DataHelper db; ProgressDialog _dialog; SharedPreferences prefs; ServiceConnection networkServiceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the service object we can use to // interact with the service. Because we have bound to a explicit // service that we know is running in our own process, we can // cast its IBinder to a concrete class and directly access it. subspaceService = ((NetworkService.LocalBinder) service) .getService(); //only connect if we arn't already if(!subspaceService.isConnected()){ SubspaceConnect(); } } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. // Because it is running in our same process, we should never // see this happen. subspaceService = null; UpdateChat("<font color='green'>Network Service Disconnected.</font><br/>"); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); // TODO make full screen a preference /* * getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, * WindowManager.LayoutParams.FLAG_FULLSCREEN); // (NEW) */ setContentView(R.layout.connect_activity); messageView = (TextView) this.findViewById(R.id.messageView); db = new DataHelper(this); int selectedZoneId = getIntent().getIntExtra("SelectedZone", -1); if (selectedZoneId < 0) { Log.e(TAG, "selectedZoneId has not been passed though: " + selectedZoneId); return; } zone = db.getZone(selectedZoneId); // now load information Display display = getWindowManager().getDefaultDisplay(); Information.ScreenWidth = (short) display.getWidth(); Information.ScreenHeight = (short) display.getHeight(); _dialog = new ProgressDialog(this); // hook up chatbox EditText editText = (EditText) findViewById(R.id.chatBox); editText.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView arg0, int actionId, KeyEvent arg2) { boolean handled = false; if (actionId == EditorInfo.IME_ACTION_SEND) { sendMessage(arg0); handled = true; } return handled; } }); //hookup button Button viewArenaButton = (Button) findViewById(R.id.ViewArenaButton); viewArenaButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent gameIntent = new Intent(self, GameActivity.class); startActivity(gameIntent); } }); prefs = PreferenceManager.getDefaultSharedPreferences(this); } protected void sendMessage(TextView textView) { final String message = textView.getText().toString(); textView.setText(""); // write to log messageView.append(Html.fromHtml("<font color='white'>" + prefs.getString("pref_username", "") + ">" + message + "</font><br/>")); // send on background thread new Thread(new Runnable() { @Override public void run() { subspaceService.SendChat(message); } }).start(); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); UpdateChat("<font color='green'>Initialising</font><br/>"); // start startService(new Intent(this, NetworkService.class)); // bind doBindService(); } public void SubspaceConnect() { UpdateChat("<font color='green'>Network Service Connected.</font><br/>"); // lets begin our work now UpdateChat("<font color='green'>Connecting to " + zone.Name + " > " + zone.Ip + ":" + zone.Port + "</font><br/>"); // do a subspace connect please :) subspaceService.Connect(zone.Name, zone.Ip, zone.Port); UpdateChat("<font color='green'>Connected</font><br/>"); // now load subspace connection subspaceService.setDownloadCallback(this); subspaceService.setGameCallback(this); // // lets begin our work now UpdateChat("<font color='green'>Logging in...</font><br/>"); final String username = prefs.getString("pref_username", ""); final String password = prefs.getString("pref_password", ""); // send on background thread new Thread(new Runnable() { @Override public void run() { LoginResponse response = subspaceService.Login(false, username, password); if (response != null) { UpdateChat("<font color='green'>Login Success</font><br/>"); subspaceService.EnterArena(); } else { UpdateChat("<font color='green'>Login Failed</font><br/>"); } } }).start(); } @Override public void DownloadStarted() { Message myMessage = new Message(); myMessage.arg1 = 10; handler.sendMessage(myMessage); } @Override public void DownloadProgressUpdate(int bytesProgress, int bytesTotal) { Message myMessage = new Message(); Bundle resBundle = new Bundle(); float percentage = (float) bytesProgress / (float) bytesTotal * 100f; resBundle.putString("message", "Download Progress " + Math.round(percentage) + "% (" + bytesProgress + "/" + bytesTotal + ")"); myMessage.arg1 = 11; myMessage.setData(resBundle); handler.sendMessage(myMessage); } @Override public void DownloadComplete() { Message myMessage = new Message(); myMessage.arg1 = 12; handler.sendMessage(myMessage); } @Override public void ChatMessageReceived(Chat message) { UpdateChat(message.getFormattedMessage() + "<br/>"); } @Override public void ConsoleMessageReceived(String consoleMessage) { UpdateChat("<font color='red'>" + consoleMessage + "</font><br/>"); } @Override public void NowInGameRecieved() { UpdateChat("<font color='green'>Now in game</font><br/>"); } @Override public void PlayerIdRecieved(int id) { UpdateChat("<font color='green'>PlayerIdRecieved " + id + "</font><br/>"); } @Override public void MapInformationRecieved(MapInformation mapInformation) { UpdateChat("<font color='green'>PlayerIdRecieved " + mapInformation.Filename + " " + mapInformation.CRC32 + "</font><br/>"); } @Override public void NewsReceieved(News news) { UpdateChat("<font color='green'>News Received</font><br/>" + news.getDocument() + "<br/>"); } @Override public void MapReceived(LVL currentLVL) { UpdateChat("<font color='green'>Map Received + " + currentLVL.Filename + "</font><br/>"); } private void UpdateChat(String msg) { // update chat Message myMessage = new Message(); Bundle resBundle = new Bundle(); resBundle.putString("message", msg); myMessage.arg1 = 0; myMessage.setData(resBundle); handler.sendMessage(myMessage); } private Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { if (msg.arg1 == 0) { messageView.append(Html.fromHtml( msg.getData().getString("message"), null, null)); } else if (msg.arg1 == 10) { // TODO Auto-generated method stub _dialog.setMessage("Download Started"); _dialog.show(); } else if (msg.arg1 == 11) { _dialog.setMessage(msg.getData().getString("message")); } else if (msg.arg1 == 12) { // TODO Auto-generated method stub if (_dialog.isShowing()) { _dialog.dismiss(); } } return true; } }); void doBindService() { // Establish a connection with the service. We use an explicit // class name because we want a specific service implementation that // we know will be running in our own process (and thus won't be // supporting component replacement by other applications). bindService(new Intent(this, NetworkService.class), networkServiceConnection, Context.BIND_AUTO_CREATE); networkIsBound = true; } void doUnbindService() { if (networkIsBound) { // Detach our existing connection. unbindService(networkServiceConnection); networkIsBound = false; } } @Override protected void onDestroy() { super.onDestroy(); doUnbindService(); } @Override public void PlayerEntering(PlayerEnter playerEntering) { // TODO Auto-generated method stub } @Override public void PlayerLeaving(PlayerLeave playerLeaving) { // TODO Auto-generated method stub } @Override public void LvlSettingsReceived(LvlSettings arenaSettings) { // TODO Auto-generated method stub } }