package NET.worlds.network; import NET.worlds.console.Console; import NET.worlds.console.DialogReceiver; import NET.worlds.console.InternetConnectionDialog; import NET.worlds.console.LoginWizard; import NET.worlds.core.IniFile; import java.util.Enumeration; import java.util.Hashtable; public class Galaxy implements DialogReceiver { private static Hashtable _galaxyHash = new Hashtable(); private static boolean _globalUserAllowsOnline = true; private boolean _localUserAllowsOnline = true; private ServerURL _serverURL; private int _serverType; private int _worldCount; private Hashtable _nFlongID; private ServerTracker _serverTracker; private RoomMgr _roomTable; private String _channel; private String _username; private String _usernameU; private String _password; private String _serial; private String _newUsername; private String _newPassword; private int _mode; private NetworkMulti _consoleList; private int _retriesLeft = 2; private InternetConnectionDialog _icd; private LoginWizard _wizard; private Object _wizardMutex = new Object(); private static int _debugLevel = IniFile.gamma().getIniInt("netdebug", 0); private WaitList _waiters; private boolean _relogin; private boolean _onlineEnabled; private boolean _online; private boolean sentFriendsList; private int protocolLevel; static { if (_debugLevel > 0) { System.out.println("NETWORK DEBUGGING LEVEL = " + _debugLevel); } } private Galaxy(ServerURL serverURL) { this._serverURL = serverURL; this._serverType = 0; this._nFlongID = new Hashtable(); this._worldCount = 0; this._channel = ""; this._serverTracker = new ServerTracker(this); this._waiters = new WaitList(this); this._username = ""; this._usernameU = ""; this._consoleList = new NetworkMulti(this._username, this); this.regObject(this._username, this._consoleList); if (serverURL == null) { this._onlineEnabled = false; this._online = false; } else { this._onlineEnabled = true; this._online = false; } this.setOnlineState(this._onlineEnabled, this._online); } private synchronized void incWorldCount() { this._worldCount++; } public synchronized void decWorldCount() { this._worldCount--; assert this._worldCount >= 0; if (this._worldCount <= 0) { if (this._serverURL != null) { _galaxyHash.remove(this._serverURL.getHost()); } this._waiters.clear(); this._serverTracker = new ServerTracker(this); } } public static Galaxy getGalaxy(String strServerURL) throws InvalidServerURLException { ServerURL serverURL = new ServerURL(strServerURL); String serverHost = serverURL.getHost(); Galaxy reqGal = _galaxyHash.get(serverHost); if (reqGal == null) { reqGal = new Galaxy(serverURL); _galaxyHash.put(serverHost, reqGal); } assert reqGal != null; reqGal.incWorldCount(); return reqGal; } public static Galaxy getGalaxy(URL serverURL) throws InvalidServerURLException { return getGalaxy(serverURL.unalias()); } public static Galaxy getAnonGalaxy() { Galaxy reqGal = new Galaxy(null); reqGal.incWorldCount(); return reqGal; } public boolean isAnonymous() { return this._serverURL == null; } public WorldServer getServer(String StrServerURL) throws InvalidServerURLException { if (this._serverURL == null) { return null; } else if (!_globalUserAllowsOnline) { return null; } else if (!this._localUserAllowsOnline) { return null; } else if (this._icd != null) { return null; } else { synchronized (this._wizardMutex) { if (this._wizard != null && !this._wizard.waitingForConnection() && !this._wizard.safeToQueryServer()) { return null; } } return this._serverTracker.getServer(StrServerURL); } } public WorldServer getServer(URL serverURL) throws InvalidServerURLException { return this.getServer(serverURL.unalias()); } public boolean isActive() { return this._serverTracker.isActive(); } protected boolean addPendingServer(WorldServer ws) { assert ws != null; boolean firstOnline = this._serverTracker.addPendingServer(ws); if (firstOnline) { this._retriesLeft = 2; this.setOnlineState(true, true); synchronized (this) { this._roomTable = new RoomMgr(); } } return firstOnline; } void addActiveServer(WorldServer ws) { boolean firstActive = this._serverTracker.addActiveServer(ws); if (firstActive) { this._waiters.notify(true); if (this._wizard != null) { System.out.println("LWDB: calling " + this._wizard + " setConnected"); this._wizard.setConnected(); } } } boolean addClosingServer(WorldServer ws) { assert this._nFlongID != null; assert ws != null; boolean lastActive = this._serverTracker.addClosingServer(ws); if (lastActive) { this.forceDisconnect(); } return lastActive; } void markClosedServer(WorldServer ws) { this._serverTracker.markClosedServer(ws); } void killServer(WorldServer serv) { this._serverTracker.killServer(serv); } protected void noteServerDeath(VarErrorException lastError) { synchronized (this._serverTracker) { if (!this._serverTracker.isActive()) { synchronized (this) { this._roomTable = null; } this.setOnlineState(false, false); if (this.getProtocol() == 0) { this._icd = new InternetConnectionDialog(this, lastError); } else { if (lastError != null && (!lastError.getStatusFlag() || this._relogin)) { _globalUserAllowsOnline = true; boolean tryBackup = false; synchronized (this._serverTracker) { Enumeration list = this._serverTracker.getAllServers(); while (list.hasMoreElements()) { WorldServer ws = list.nextElement(); if (ws.useBackupServer()) { tryBackup = true; } } } if (tryBackup) { System.out.println("Server death noted, trying alternate."); this.setChatname(this._username); this.goOnline(); } else { System.out.println("Server death noted, no more alternates. How sad."); if (this._retriesLeft <= 0 || !this._relogin && !lastError.getRetryFlag()) { this.setChatname(""); this.killZombies(); if (this._wizard == null) { this._wizard = new LoginWizard(this, this.getIniSection(), lastError.getMsg()); System.out.println("LWDB: brought up " + this._wizard + " error " + lastError.getMsg()); } else { System.out.println("LWDB: reporting error " + lastError.getMsg() + " to " + this._wizard); this._wizard.loginError(lastError.getMsg()); } } else { System.out.println(this + ": doing retry on " + lastError); this._retriesLeft = this._retriesLeft - lastError.getRetryCount(); this.setChatname(this._username); this.goOnline(); } } this._relogin = false; } else { this.setOnlineState(true, false); } } } } } public void waitForConnection(ConnectionWaiter cw) { this._waiters.addWaiter(cw); } public void goOffline(boolean relogin) { this._relogin = relogin; if (!this._serverTracker.isActive()) { this._relogin = false; } synchronized (this._serverTracker) { Enumeration list = this._serverTracker.getAllServers(); while (list.hasMoreElements()) { WorldServer ws = list.nextElement(); ws.forceOffline(); } } } private void killZombies() { synchronized (this._serverTracker) { Enumeration list = this._serverTracker.getAllServers(); while (list.hasMoreElements()) { list.nextElement().killZombies(); } } } void goOnline() { synchronized (this._serverTracker) { Enumeration list = this._serverTracker.getAllServers(); while (list.hasMoreElements()) { WorldServer ws = list.nextElement(); ws.goOnline(); } } this.reacquireServer(null); } public static synchronized void forceOffline(boolean relogin) { if (_globalUserAllowsOnline) { _globalUserAllowsOnline = false; synchronized (_galaxyHash) { Enumeration list = _galaxyHash.elements(); while (list.hasMoreElements()) { Galaxy g = list.nextElement(); g.goOffline(relogin); } } } } public void localForceOnline() { _globalUserAllowsOnline = true; this._relogin = false; if (!this.isActive()) { this.setOnlineState(false, false); this._localUserAllowsOnline = true; if (this.getGalaxyType() != 0) { this.setChatname(""); this._wizard = new LoginWizard(this, this.getIniSection()); System.out.println("LWDB: brought up " + this._wizard + " in localForceOnline"); } else { this.reacquireServer(null); } } } public static int getDebugLevel() { return _debugLevel; } public static void printDebugging() { System.out.println("----GALAXY DEBUGGING-------"); Enumeration e = _galaxyHash.elements(); while (e.hasMoreElements()) { Galaxy g = e.nextElement(); System.out.println(g + " : "); System.out.println(g._serverTracker); } System.out.println("---------------------------"); } public String getChannel() { return this._channel; } void setChannel(String channel) { this.changeChannel(channel, false); } public void changeChannel(String channel) { if (channel == null) { channel = ""; } channel = channel.replace(' ', '_'); channel = channel.replace('<', '{'); channel = channel.replace('>', '}'); this.changeChannel(channel, true); } private void changeChannel(String channel, boolean sendMsg) { if (!channel.equals(this._channel)) { String oldChannel = this._channel; this._channel = channel; Hashtable tmpIDtable = (Hashtable)this._nFlongID.clone(); Enumeration e = tmpIDtable.elements(); while (e.hasMoreElements()) { NetworkObject no = e.nextElement(); assert no != null; no.changeChannel(this, oldChannel, this._channel); } if (sendMsg) { WorldServer ws = this._serverTracker.getActive(this); if (ws != null) { ws.tmpRefCnt(this); try { ws.sendNetworkMsg(new ChannelCmd(channel)); } catch (PacketTooLargeException var8) { assert false; } catch (InfiniteWaitException var9) { } } } } } public ServerURL getServerURL() { return this._serverURL; } @Override public String toString() { return this._serverURL == null ? "AnonGalaxy=" + super.toString() : "Galaxy[" + this._serverURL + "]"; } void swapServer(WorldServer oldServ, WorldServer newServ) { if ((_debugLevel & 8192) > 0) { System.out.println(this + ".swapServer(" + oldServ + ", " + newServ + ")"); } this._serverTracker.swapServer(oldServ, newServ); this.reacquireServer(oldServ); } void reacquireServer(WorldServer oldServ) { if ((_debugLevel & 8192) > 0) { System.out.println(this + ".reacquireServer(" + oldServ + ")"); } Enumeration e = this._nFlongID.elements(); while (e.hasMoreElements()) { e.nextElement().reacquireServer(oldServ); } } public void regObject(String longID, NetworkObject obj) { if ((_debugLevel & 8192) > 0) { System.out.println(this + ".regObject(" + longID + ", " + obj + ")"); } this._nFlongID.put(longID, obj); } public NetworkObject getObject(String longID) { return this._nFlongID.get(longID); } public void delObject(String longID) { if ((_debugLevel & 8192) > 0) { System.out.println(this + ".delObject(" + longID + ")"); } this._nFlongID.remove(longID); } public void forceObjectRereg() { if ((_debugLevel & 8192) > 0) { System.out.println(this + ".forceObjectRereg()"); } Hashtable oldTable = this._nFlongID; this._nFlongID = new Hashtable(); Enumeration e = oldTable.elements(); while (e.hasMoreElements()) { e.nextElement().register(); } } private void forceDisconnect() { if ((_debugLevel & 8192) > 0) { System.out.println(this + ".forceDisconnect()"); } Enumeration e = this._nFlongID.elements(); while (e.hasMoreElements()) { NetworkObject no = e.nextElement(); assert no != null; no.galaxyDisconnected(); } } void addRoomRequest(String roomName, NetworkRoom room) { assert this._roomTable != null; this._roomTable.addRequest(roomName, room); } void delRoomRequest(String roomName) { if (this._roomTable != null) { this._roomTable.delRequest(roomName); } } NetworkRoom regRoomID(int roomID, String roomName) { assert this._roomTable != null; NetworkRoom room = this._roomTable.getRequest(roomName); if (roomID != 0 && room != null) { this._roomTable.regRoomID(roomID, room); } return room; } public void setRoomID(int roomID, NetworkRoom room) { assert this._roomTable != null; assert roomID != 0; assert room != null; this._roomTable.regRoomID(roomID, room); } void delRoomID(int roomID, NetworkRoom room) { if (this._roomTable != null) { this._roomTable.delRoomID(roomID, room); } } NetworkRoom getRoom(int roomID) { return this._roomTable == null ? null : this._roomTable.getRoom(roomID); } void setGalaxyType(int type) { this._serverType = type; if (_globalUserAllowsOnline) { this.setOnlineState(false, this._online); this.setChatname(""); this._wizard = new LoginWizard(this, this.getIniSection()); System.out.println("LWDB: brought up " + this._wizard + " in setGalaxyType"); } } public int getGalaxyType() { return this._serverType; } public synchronized void setAuthInfo(String usernm, String newUsernm, String passwd, String newPasswd, String serial, int mode) { _globalUserAllowsOnline = true; this._localUserAllowsOnline = true; assert this._serverType != 0; this.setUsernameU(usernm); this.setChatname(usernm); this._newUsername = newUsernm; this._password = passwd; this._newPassword = newPasswd; this._serial = serial; this._mode = mode; switch (this._serverType) { case 1: switch (this._mode) { case 1: default: break; case 2: this._serial = null; break; case 3: this._password = null; this._serial = null; } assert this._mode != 4; break; case 3: assert false; break; case 4: assert this._mode == 2; case 2: assert this._mode != 1; assert this._mode != 4; if (this._password != null && this._password.length() != 0) { System.out.println(this + ": Password shouldn't be specified."); } this._password = null; if (this._serial != null && this._serial.length() != 0) { System.out.println(this + ": Serial number shouldn't be specified."); } this._serial = null; } this.goOnline(); } public String getSerialNum() { return this._serial; } public String getPassword() { return this._password; } String getNewPassword() { return this._newPassword; } public String getChatname() { return this._username; } String getNewChatname() { return this._newUsername; } String getGuestExpiration() { assert false; return null; } public int getLoginMode() { return this._mode; } void setOnlineState(boolean enabled, boolean online) { synchronized (this) { this._onlineEnabled = enabled; this._online = online; } synchronized (this._consoleList) { Enumeration cList = this.getConsoles(); while (cList.hasMoreElements()) { Console c = (Console)cList.nextElement(); c.setOnlineState(enabled, online); } } } public boolean getOnlineEnabled() { return this._onlineEnabled; } public boolean getOnline() { return this._online; } void setPassword(String password) { this._password = password; } void setNewPassword(String password) { this._newPassword = password; } void setNewChatname(String chatname) { this._newUsername = chatname; } void setSerialNum(String sn) { this._serial = sn; } public void setUsernameU(String username) { this._usernameU = username; } public String getUsernameU() { return this._usernameU; } void setChatname(String newname) { synchronized (this) { this._consoleList = new NetworkMulti(newname, this._consoleList, this); if (this._username != null) { this.delObject(this._username); } this.regObject(newname, this._consoleList); this._username = newname; } synchronized (this._consoleList) { Enumeration cList = this.getConsoles(); while (cList.hasMoreElements()) { Console c = (Console)cList.nextElement(); c.setChatname(this._username); } } synchronized (this._serverTracker) { Enumeration list = this._serverTracker.getAllServers(); while (list.hasMoreElements()) { WorldServer ws = list.nextElement(); ws.regShortID(1, this._username); } } } public IniFile getIniSection() { if (this._serverURL == null) { return new IniFile("UNSHARED"); } else { if (this._serverURL.getHost().equals("www.3dcd.com:6650")) { IniFile i = new IniFile("209.240.84.122:6650"); if (i.getIniString("User0", "").length() != 0) { return i; } } return new IniFile(this._serverURL.getHost()); } } @Override public void dialogDone(Object who, boolean confirmed) { if (who instanceof LoginWizard) { synchronized (this._wizardMutex) { System.out.println("LWDB: setting who " + who + " wiz " + this._wizard + " to null"); this._wizard = null; } if (!confirmed) { this.setOnlineState(true, false); this._localUserAllowsOnline = false; } else { this._localUserAllowsOnline = true; _globalUserAllowsOnline = true; } } else if (who instanceof InternetConnectionDialog) { this._icd = null; if (!confirmed) { this.setOnlineState(true, false); this._localUserAllowsOnline = false; } else { this._localUserAllowsOnline = true; _globalUserAllowsOnline = true; this.reacquireServer(null); } } else { assert false; } } public void addConsole(Console c) { assert this._consoleList != null; this._consoleList.addObject(c); this.setOnlineState(this._onlineEnabled, this._online); } public void delConsole(Console c) { assert this._consoleList != null; this._consoleList.delObject(c); } public Enumeration getConsoles() { return this._consoleList.elements(); } public void sentFriendsList(boolean state) { this.sentFriendsList = state; } public boolean sentFriendsList() { return this.sentFriendsList; } public int getProtocol() { return this.protocolLevel; } void setProtocol(int level) { this.protocolLevel = level; } }