/* * This file is part of the Haven & Hearth game client. * Copyright (C) 2009 Fredrik Tolf <fredrik@dolda2000.com>, and * Björn Johannessen <johannessen.bjorn@gmail.com> * * Redistribution and/or modification of this file is subject to the * terms of the GNU Lesser General Public License, version 3, as * published by the Free Software Foundation. * * 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. * * Other parts of this source tree adhere to other copying * rights. Please see the file `COPYING' in the root directory of the * source tree for details. * * A copy the GNU Lesser General Public License is distributed along * with the source tree of which this file is a part in the file * `doc/LPGL-3'. If it is missing for any reason, please see the Free * Software Foundation's website at <http://www.fsf.org/>, or write * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ package haven; import java.net.*; import java.util.*; public class Bootstrap implements UI.Receiver, UI.Runner { Session sess; String hostname; int port; final Queue<Message> msgs = new LinkedList<Message>(); String inituser = null; byte[] initcookie = null; public static class Message { int id; String name; Object[] args; public Message(int id, String name, Object... args) { this.id = id; this.name = name; this.args = args; } } public Bootstrap(String hostname, int port) { Config.server = hostname; this.hostname = hostname; this.port = port; } public void setinitcookie(String username, byte[] cookie) { inituser = username; initcookie = cookie; } private String getpref(String name, String def) { return(Utils.getpref(name + "@" + hostname, def)); } private void setpref(String name, String val) { Utils.setpref(name + "@" + hostname, val); } public Session run(UI ui) throws InterruptedException { ui.setreceiver(this); ui.bind(new LoginScreen(ui.root), 1); String loginname = getpref("loginname", ""); boolean savepw = false; byte[] token = null; String tokenhex = getpref("savedtoken", ""); if(tokenhex.length() == 64) token = Utils.hex2byte(tokenhex); String authserver = (Config.authserv == null)?hostname:Config.authserv; int authport = Config.authport; retry: do { byte[] cookie; String acctname, tokenname; if(initcookie != null) { acctname = inituser; cookie = initcookie; initcookie = null; } else if((token != null) && ((tokenname = getpref("tokenname", null)) != null)) { savepw = true; ui.uimsg(1, "token", loginname, tokenhex); while(true) { Message msg; synchronized(msgs) { while((msg = msgs.poll()) == null) msgs.wait(); } if(msg.id == 1) { if(msg.name == "login") { loginname = tokenname = (String) msg.args[0]; tokenhex = (String) msg.args[1]; token = Utils.hex2byte(tokenhex); break; } else if(msg.name == "forget") { token = null; setpref("savedtoken", ""); continue retry; } } } ui.uimsg(1, "prg", "Authenticating..."); try { AuthClient auth = new AuthClient(authserver, authport); try { if((acctname = auth.trytoken(tokenname, token)) == null) { token = null; setpref("savedtoken", ""); ui.uimsg(1, "error", "Invalid save"); continue retry; } cookie = auth.getcookie(); } finally { auth.close(); } } catch(java.io.IOException e) { ui.uimsg(1, "error", e.getMessage()); continue retry; } } else { AuthClient.Credentials creds; ui.uimsg(1, "passwd", loginname, savepw); while(true) { Message msg; synchronized(msgs) { while((msg = msgs.poll()) == null) msgs.wait(); } if(msg.id == 1) { if(msg.name == "login") { if(msg.args[0] instanceof String && msg.args[1] instanceof String) { loginname = tokenname = (String) msg.args[0]; tokenhex = (String) msg.args[1]; token = Utils.hex2byte(tokenhex); setpref("savedtoken", tokenhex); setpref("tokenname", tokenname); continue retry; } else { creds = (AuthClient.Credentials) msg.args[0]; savepw = (Boolean) msg.args[1]; loginname = creds.name(); } break; } } } ui.uimsg(1, "prg", "Authenticating..."); try { AuthClient auth = new AuthClient(authserver, authport); try { try { acctname = creds.tryauth(auth); } catch(AuthClient.Credentials.AuthException e) { ui.uimsg(1, "error", e.getMessage()); continue retry; } cookie = auth.getcookie(); if(savepw) { String hex = Utils.byte2hex(auth.gettoken()); setpref("savedtoken", hex); setpref("tokenname", acctname); Config.storeAccount(acctname, hex); } } finally { auth.close(); } } catch(UnknownHostException e) { ui.uimsg(1, "error", "Could not locate server"); continue retry; } catch(java.io.IOException e) { ui.uimsg(1, "error", e.getMessage()); continue retry; } } ui.uimsg(1, "prg", "Connecting..."); try { sess = new Session(new InetSocketAddress(InetAddress.getByName(hostname), port), acctname, cookie); } catch(UnknownHostException e) { ui.uimsg(1, "error", "Could not locate server"); continue retry; } Thread.sleep(100); while(true) { if(sess.state == "") { setpref("loginname", loginname); ui.destroy(1); break retry; } else if(sess.connfailed != 0) { String error; switch(sess.connfailed) { case 1: error = "Invalid authentication token"; break; case 2: error = "Already logged in"; break; case 3: error = "Could not connect to server"; break; case 4: error = "This client is too old"; break; case 5: error = "Authentication token expired"; break; default: error = "Connection failed"; break; } ui.uimsg(1, "error", error); sess = null; continue retry; } synchronized(sess) { sess.wait(); } } } while(true); haven.error.ErrorHandler.setprop("usr", sess.username); return(sess); //(new RemoteUI(sess, ui)).start(); } public void rcvmsg(int widget, String msg, Object... args) { synchronized(msgs) { msgs.add(new Message(widget, msg, args)); msgs.notifyAll(); } } }