diff options
| author | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
| commit | c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch) | |
| tree | df9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/network/WorldServer.java | |
| download | worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip | |
Initial commit
Diffstat (limited to 'NET/worlds/network/WorldServer.java')
| -rw-r--r-- | NET/worlds/network/WorldServer.java | 1319 |
1 files changed, 1319 insertions, 0 deletions
diff --git a/NET/worlds/network/WorldServer.java b/NET/worlds/network/WorldServer.java new file mode 100644 index 0000000..e71e6d6 --- /dev/null +++ b/NET/worlds/network/WorldServer.java @@ -0,0 +1,1319 @@ +package NET.worlds.network; + +import NET.worlds.console.Console; +import NET.worlds.console.Main; +import NET.worlds.console.MainCallback; +import NET.worlds.console.MainTerminalCallback; +import NET.worlds.core.Std; +import NET.worlds.scape.Drone; +import NET.worlds.scape.WObject; +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.Socket; +import java.text.MessageFormat; +import java.util.Enumeration; +import java.util.Vector; + +public class WorldServer implements MainCallback, MainTerminalCallback, NetworkObject { + protected int _serverProtocolVersion; + protected ServerURL _serverURL = null; + protected String _clientVersion = Std.getClientVersion(); + protected WSConnecting _connectThread; + protected OutputStream _ostr = null; + protected Socket _sock = null; + protected netPacketReader _reader = null; + private WaitList _waiters; + protected int _refCnt = 0; + protected int _tmpRefCnt = 0; + protected boolean _isMainRegistered = false; + protected ObjectMgr _objTable = null; + protected Galaxy _galaxy = null; + protected SMState _state; + protected boolean _firstLogon = false; + protected boolean _requestOffline = false; + private int _lastAccessTime = 0; + protected int _retriesLeft = 5; + protected VarErrorException _lastError = null; + protected int _retryTimeout = 60000; + private int _lastMsgProcCnt = 5; + protected PropertyList _propList = null; + protected int _updateTime = 2000; + Vector<WorldServer.BackupServer> _backupServers; + String _currentBackupServer; + private static final int STATE_DEAD = -1; + protected static final int STATE_PRECONNECTED = 0; + private static final int STATE_AUTHPROMPT = 1; + private static final int STATE_AUTHREPLY = 2; + protected static final int STATE_INITIALIZING = 3; + private static final int STATE_CONNECTING = 4; + private static final int STATE_XMIT_PROPREQ = 5; + private static final int STATE_RCV_PROPS = 6; + protected static final int STATE_XMIT_SI = 7; + static final int STATE_RCV_SI_ACK = 8; + static final int STATE_XMIT_AI = 9; + static final int STATE_RCV_AI_ACK = 10; + static final int STATE_XMIT_PROPS = 11; + static final int STATE_MAINLOOP = 12; + private static final int STATE_XMIT_AE = 13; + private static final int STATE_RCV_AE_ACK = 14; + private static final int STATE_XMIT_SE = 15; + static final int STATE_RCV_SE_ACK = 16; + static final int STATE_DETACHING = 17; + static final int STATE_DISCONNECTED = 18; + static final int STATE_SLEEPING = 19; + private Vector<Object> _referrerList = new Vector<Object>(); + private String _scriptServer; + private String _smtpServer; + private String _mailDomain; + private int _lastWhisperTick = 0; + private int _whisperCnt = 0; + private Vector<NetworkObject> zombies; + + protected WorldServer() { + this._serverProtocolVersion = 24; + this._state = new SMState(this, 0); + this._currentBackupServer = null; + this._backupServers = new Vector<WorldServer.BackupServer>(); + } + + public void regShortID(int shortObjID, String longObjID) { + assert shortObjID < 253; + + this._objTable.regShortID(shortObjID, longObjID); + } + + public NetworkObject getObject(ObjID objID) { + return this._objTable.getObject(objID); + } + + public void delObject(ObjID objID) { + this._objTable.delObject(objID); + } + + public void regObject(ObjID objID, NetworkObject obj) { + this._objTable.regObject(objID, obj); + } + + public void regObject(String longid, NetworkObject obj) { + this._objTable.regObject(new ObjID(longid), obj); + } + + public String getLongID(ObjID objID) { + return this._objTable.getLongID(objID); + } + + public InetAddress getLocalAddress() { + return this._sock != null ? this._sock.getLocalAddress() : null; + } + + public Galaxy getGalaxy() { + return this._galaxy; + } + + ServerURL getServerURL() { + return this._serverURL; + } + + void initInstance(Galaxy galaxy, ServerURL serverURL) { + this._galaxy = galaxy; + this._serverURL = serverURL; + this._objTable = new ObjectMgr(this._galaxy); + this._waiters = new WaitList(this); + } + + public net2Property getProperty(int propID) { + return this._propList.getProperty(propID); + } + + public int getUpdateTime() { + return this._updateTime; + } + + void setUsername(String newUsername) { + if ((getDebugLevel() & 4) > 0) { + System.out.println(this + ": Server requested username change to " + newUsername); + } + + this._galaxy.setChatname(newUsername); + this.regShortID(1, newUsername); + } + + public synchronized void printReferrers() { + System.out.println("[" + Std.getRealTime() + "] " + this + ": Referrer list -"); + + for (int i = this._referrerList.size() - 1; i >= 0; i--) { + Object ref = this._referrerList.elementAt(i); + System.out.println("\t" + ref); + } + + System.out.println(this + ": Referrer list complete."); + } + + public synchronized Vector<String> printDroneReferrers() { + Vector<String> list = new Vector<String>(); + + for (int i = this._referrerList.size() - 1; i >= 0; i--) { + Object ref = this._referrerList.elementAt(i); + if (ref.toString().startsWith("!")) { + list.addElement(ref.toString()); + } + } + + return list; + } + + public synchronized void incRefCnt(Object referrer) { + if (this._refCnt == 0 && !this._isMainRegistered) { + Main.register(this); + this._isMainRegistered = true; + } + + this._lastAccessTime = Std.getFastTime(); + this._refCnt++; + + assert !this._referrerList.removeElement(referrer); + + this._referrerList.addElement(referrer); + if ((getDebugLevel() & 4096) > 0) { + System.out.println(this + ": incRefCnt to " + this._refCnt + " by " + referrer); + } + } + + public synchronized void tmpRefCnt(Object referrer) { + this._tmpRefCnt++; + boolean existed = this._referrerList.removeElement(referrer); + + assert existed; + } + + public synchronized void decRefCnt(Object referrer) { + this._refCnt--; + boolean existed = this._referrerList.removeElement(referrer); + + assert existed; + + if ((getDebugLevel() & 4096) > 0) { + System.out.println(this + ": decRefCnt to " + this._refCnt + " by " + referrer); + } + + assert this._refCnt >= 0; + } + + int getRefCnt() { + return this._refCnt; + } + + public int getVersion() { + return this._serverProtocolVersion; + } + + public void setVersion(int ver) { + this._galaxy.setProtocol(ver); + this._serverProtocolVersion = ver; + if (this._reader != null) { + this._reader.setVersion(ver); + } + + if (ver < 18) { + System.out.println(this + ": WARNING: Old server running protocol #17!"); + } + } + + public static int getDebugLevel() { + return Galaxy.getDebugLevel(); + } + + public void sendNetworkMsg(netPacket msg) throws InfiniteWaitException, PacketTooLargeException { + synchronized (this._state) { + assert this._refCnt != 0 || this._state.getState() != -1; + + if (this._state.getState() != 12) { + throw new InfiniteWaitException(); + } else { + this.sendNetMsg(msg); + } + } + } + + public int getServerType() { + if (this._propList == null) { + return 1; + } else { + net2Property stProp = this._propList.getProperty(15); + int servType = 0; + + try { + servType = Integer.parseInt(stProp.value()); + } catch (NumberFormatException var4) { + assert false; + } + + return servType; + } + } + + private void setScriptServer(String server) { + if (!server.endsWith("/")) { + server = server + "/"; + } + + this._scriptServer = server; + } + + public String getScriptServer() { + return this._scriptServer; + } + + private void setSmtpServer(String server) { + this._smtpServer = server; + } + + public String getSmtpServer() { + return this._smtpServer; + } + + private void setMailDomain(String domain) { + this._mailDomain = domain; + } + + public String getMailDomain() { + return this._mailDomain; + } + + void sendNetMsg(netPacket msg) throws PacketTooLargeException { + assert msg != null; + + if ((getDebugLevel() & 128) > 0) { + System.out.println("[" + Std.getRealTime() + "] " + this + ": send(" + msg.toString(this) + ")"); + } + + if (this._ostr != null) { + try { + ByteArrayOutputStream rostr = new ByteArrayOutputStream(256); + ServerOutputStream ostr = new ServerOutputStream(rostr, this.getVersion()); + msg.send(ostr); + if ((getDebugLevel() & 1024) > 0) { + byte[] byteArray = rostr.toByteArray(); + int size = byteArray[0] & 255; + synchronized (System.out) { + System.out.print(this + ": send["); + + for (int i = 0; i < size; i++) { + System.out.print(Integer.toString(byteArray[i] & 255, 16) + " "); + } + + System.out.println("]"); + } + } + + synchronized (this._ostr) { + rostr.writeTo(this._ostr); + } + + this._lastAccessTime = Std.getFastTime(); + } catch (PacketTooLargeException var10) { + throw var10; + } catch (IOException var11) { + VarErrorException ve = new VarErrorException(101); + if (this._lastError == null) { + this._lastError = ve; + } + + assert this._connectThread == null; + + this._state.setState(17); + } + } + } + + public void sendText(String input) { + this.sendText(null, input); + } + + private void _sendText(String who, String msg) { + if (msg.length() > 200) { + Object[] arguments = new Object[]{new Integer(msg.length())}; + Console.println(MessageFormat.format(Console.message("msg-too-long"), arguments)); + msg = msg.substring(0, 199); + } + + msg.trim(); + if (msg.length() >= 1) { + if (who == null) { + try { + this.sendNetworkMsg(new textCmd(msg)); + } catch (InfiniteWaitException var4) { + if (!msg.startsWith("&|+")) { + Console.println(Console.message("not-connected")); + } + } catch (PacketTooLargeException var5) { + assert false; + } + } else { + if (!msg.startsWith("&|+")) { + Console.printOwnWhisper(who, msg); + } + + if (!msg.startsWith("&|+trade>") && !who.equalsIgnoreCase("trade")) { + int timeNow = Std.getRealTime(); + if (timeNow - this._lastWhisperTick > 60000) { + this._whisperCnt = 0; + this._lastWhisperTick = timeNow; + } + + this._whisperCnt++; + if (this._whisperCnt > 15) { + Console.println(Console.message("whisper-too-fast")); + return; + } + } + + try { + this.sendNetworkMsg(new whisperCmd(who, msg)); + } catch (PacketTooLargeException var6) { + assert false; + } catch (InfiniteWaitException var7) { + if (!msg.startsWith("&|+")) { + Console.println(Console.message("not-connected")); + } + } + } + } + } + + public void sendText(String who, String msg) { + if ((getDebugLevel() & 1) > 0) { + System.out.println("[" + Std.getRealTime() + "] " + this + ": sendText(" + msg + ")"); + } + + msg = msg.trim(); + if (msg.length() > 200) { + Console.println(Console.message("converting-long")); + int i1 = 0; + int i2 = 0; + + while (msg.length() - i1 > 200) { + i2 = msg.lastIndexOf(32, i1 + 200); + if (i2 <= i1) { + i2 = i1 + 200; + } + + this._sendText(who, msg.substring(i1, i2)); + i1 = i2 + 1; + } + + this._sendText(who, msg.substring(i1)); + } else { + this._sendText(who, msg); + } + } + + public int getState() { + return this._state.getState(); + } + + void setState(int state) { + this._state.setState(state); + } + + public void waitForConnection() throws InfiniteWaitException { + this._state.waitForState(12); + } + + public void requestRoomID(String roomName, NetworkRoom room) { + this._galaxy.addRoomRequest(roomName, room); + if (this._state.getState() == 12) { + try { + this.sendNetworkMsg(new roomIDReqCmd(roomName)); + } catch (PacketTooLargeException var4) { + assert false; + } catch (InfiniteWaitException var5) { + } + } + } + + public void delRoomRequest(String roomName) { + this._galaxy.delRoomRequest(roomName); + } + + public void delRoomID(int roomID, NetworkRoom room) { + this._galaxy.delRoomID(roomID, room); + } + + void regRoomID(int roomID, String roomName, boolean willRedirect) { + NetworkRoom room = this._galaxy.regRoomID(roomID, roomName); + if (room != null) { + room.setRoomID(this, roomID, roomName, willRedirect); + } + } + + public void redirectRoom(String roomName, ServerURL serverURL) { + NetworkRoom room = (NetworkRoom)this._galaxy.getObject(roomName); + if (room != null) { + room.serverRedirect(this, roomName, serverURL); + } + } + + NetworkRoom getNetworkRoom(int roomID) { + return this._galaxy.getRoom(roomID); + } + + public final boolean isConnected() { + return this._state.getState() == 12; + } + + void startConnect() { + synchronized (this._state) { + int state = this._state.getState(); + switch (state) { + case 0: + assert this._connectThread == null; + + this._state.setState(3); + break; + case 18: + this._retriesLeft = 5; + + assert this._connectThread == null; + + this._state.setState(3); + case 19: + } + } + + this._lastAccessTime = Std.getFastTime(); + } + + void forceOffline() { + this._retriesLeft = 0; + this._lastError = new VarErrorException(205); + this._requestOffline = true; + } + + void goOnline() { + this._requestOffline = false; + this.startConnect(); + } + + protected void perFrame(int timeNow) { + synchronized (this._state) { + int ServerState = this._state.getState(); + switch (ServerState) { + case -1: + this.state_Dead(timeNow); + case 0: + case 4: + default: + break; + case 1: + case 2: + assert false; + break; + case 3: + this.state_Initializing(); + break; + case 5: + this.state_XMIT_PROPREQ(); + break; + case 6: + case 8: + case 16: + if (timeNow - this._lastAccessTime > 30000) { + if (getDebugLevel() > 0) { + System.out.println("[" + timeNow + "] " + this + ": Messaging timeout. (state=" + ServerState + ")"); + } + + if (this._lastError == null) { + this._lastError = new VarErrorException(106); + } + + switch (ServerState) { + case 6: + case 16: + this._state.setState(17); + return; + case 8: + this._state.setState(15); + } + } else { + try { + this.processMsgs(ServerState, timeNow); + } catch (VarErrorException var10) { + if (getDebugLevel() > 0) { + System.out.println("[" + timeNow + "] " + this + ": VarError#" + var10.getErrorNum()); + System.out.println(this + ": " + var10.getMsg()); + } + + if (this._lastError == null) { + this._lastError = var10; + } + + this._state.setState(17); + } catch (EOFException var11) { + EOFException e = var11; + VarErrorException ve = new VarErrorException(100); + if (this._lastError == null) { + this._lastError = ve; + } + + if (getDebugLevel() > 0) { + synchronized (System.out) { + e.printStackTrace(System.out); + } + } + + this._state.setState(17); + } catch (IOException var12) { + IOException ex = var12; + VarErrorException vex = new VarErrorException(102); + if (this._lastError == null) { + this._lastError = vex; + } + + synchronized (System.out) { + System.out.println("[" + timeNow + "] " + this + ": Read error:"); + if (getDebugLevel() > 0) { + ex.printStackTrace(System.out); + } + } + + this._state.setState(17); + } catch (Exception var13) { + Exception ex = var13; + VarErrorException vex = new VarErrorException(103); + if (this._lastError == null) { + this._lastError = vex; + } + + synchronized (System.out) { + System.out.println("[" + timeNow + "] " + this + ": Unexpected error:"); + ex.printStackTrace(System.out); + } + + this._state.setState(17); + } + } + break; + case 7: + this.state_XMIT_SI(); + break; + case 9: + this.state_XMIT_AI(); + break; + case 10: + assert false; + break; + case 11: + this.state_XMIT_Props(); + break; + case 12: + this.state_Mainloop(timeNow); + break; + case 13: + this.state_XMIT_AE(); + break; + case 14: + assert false; + break; + case 15: + this.state_XMIT_SE(); + break; + case 17: + this.state_Detaching(); + break; + case 18: + this.state_Disconnected(timeNow); + break; + case 19: + this.state_Sleeping(timeNow); + } + } + } + + private void processMsgs(int state, int timeNow) throws Exception { + int msgsInQueue = this._reader.count(); + if (msgsInQueue > 0) { + int msgsToProcess = (int)Math.sqrt(this._lastMsgProcCnt * msgsInQueue); + if ((getDebugLevel() & 2) > 0 && msgsInQueue > 30) { + synchronized (System.out) { + System.out.println(this + ": msgs on incoming queue = " + msgsInQueue); + System.out.println(" processed approx " + this._lastMsgProcCnt + " messages on last round."); + System.out.println(" processing " + msgsToProcess + " messages."); + } + } + + if (5 > msgsToProcess) { + this._lastMsgProcCnt = 5; + } else { + this._lastMsgProcCnt = msgsToProcess; + } + + if (msgsInQueue < msgsToProcess) { + msgsToProcess = msgsInQueue; + } + + msgsToProcess = Math.min(msgsToProcess, msgsInQueue); + + while (this._state.getState() == state && msgsToProcess-- != 0) { + receivedNetPacket p = this._reader.get(); + + assert p != null; + + if ((getDebugLevel() & 64) > 0) { + System.out.println(this + ": recv(" + p.toString(this) + ")"); + } + + p.process(this); + } + + this._lastAccessTime = timeNow; + } + } + + protected void state_Initializing() { + if (this._requestOffline) { + this._state.setState(-1); + } else if (this._serverURL.getHost().equals("0.0.0.0:0")) { + System.out.println(this + ": DOA"); + this._state.setState(-1); + } else { + this._objTable.regShortID(255, this.getLongID()); + this._objTable.regObject(this.getLongID(), this); + this._lastError = null; + this._firstLogon = false; + String host = this._serverURL.getHost(); + int port = 5100; + + assert host != null; + + int cindx = this._serverURL.getHost().lastIndexOf(58); + if (cindx >= 0) { + try { + port = Integer.parseInt(this._serverURL.getHost().substring(cindx + 1)); + } catch (NumberFormatException var8) { + NumberFormatException e = var8; + synchronized (System.out) { + System.out.println("######DEBUGGING######"); + System.out.println(" server: " + this._serverURL.getHost()); + System.out.println(" message: " + e.getMessage()); + e.printStackTrace(System.out); + System.out.println("#####################"); + } + + VarErrorException ve = new VarErrorException(103); + if (this._lastError == null) { + this._lastError = ve; + } + + System.out.println("Error in server URL format: " + this._serverURL.getHost()); + this._state.setState(17); + return; + } + + host = this._serverURL.getHost().substring(0, cindx); + } + + this._lastAccessTime = Std.getFastTime(); + if (this._currentBackupServer != null) { + if (this._sock != null) { + try { + this._sock.close(); + } catch (Exception var7) { + } + + this._sock = null; + } + + host = this._currentBackupServer; + } + + if (this._sock == null) { + this._state.setState(4); + + assert this._connectThread == null; + + this._connectThread = new WSConnecting(this, host, port, 15); + } else if (this._propList == null) { + this._state.setState(5); + } else { + this._state.setState(7); + } + } + } + + protected void setSocket(Socket sock, VarErrorException ve, String host) { + Vector<String> resolvedHosts = this._connectThread.getBackupHosts(); + Enumeration<String> en = resolvedHosts.elements(); + + while (en.hasMoreElements()) { + WorldServer.BackupServer bs = new WorldServer.BackupServer(en.nextElement()); + Enumeration<WorldServer.BackupServer> en2 = this._backupServers.elements(); + boolean unique = true; + + while (en2.hasMoreElements()) { + if (en2.nextElement().GetHost().equals(bs.GetHost())) { + unique = false; + break; + } + } + + if (unique) { + this._backupServers.addElement(bs); + } + + if (host != null && host.equals(bs.GetHost())) { + bs.IncTries(); + } + } + + this._connectThread = null; + if (this._state.getState() == 4) { + if (sock != null) { + this._sock = sock; + + try { + this._ostr = this._sock.getOutputStream(); + this._reader = new netPacketReader(this, new ServerInputStream(this._sock.getInputStream())); + this._reader.setVersion(this.getVersion()); + } catch (Exception var9) { + ve = new VarErrorException(105); + if (this._lastError == null) { + this._lastError = ve; + } + + System.out.println(this + ": Error opening I/O streams."); + this._state.setState(17); + return; + } + + this._reader.setDaemon(true); + this._reader.start(); + this._state.setState(5); + } else { + assert ve != null; + + if (this._lastError == null) { + this._lastError = ve; + } + + this._state.setState(17); + } + } + } + + protected void state_XMIT_PROPREQ() { + if (this._requestOffline) { + this._state.setState(17); + } else { + propReqCmd propReq = new propReqCmd(new ObjID(255)); + if (NetUpdate.isInternalVersion()) { + propReq.addProp(1); + propReq.addProp(3); + propReq.addProp(15); + propReq.addProp(29); + propReq.addProp(25); + propReq.addProp(26); + propReq.addProp(27); + } + + try { + this.sendNetMsg(propReq); + } catch (PacketTooLargeException var3) { + assert false; + } + + this._state.setState(6); + } + } + + protected void state_XMIT_SI() { + assert false; + + if (this._requestOffline) { + this._state.setState(17); + } else { + this._galaxy.addPendingServer(this); + this._state.setState(8); + } + } + + protected void state_XMIT_AI() { + assert false; + + if (this._requestOffline) { + this._state.setState(17); + } else { + this._state.setState(11); + } + } + + protected void state_XMIT_Props() { + if (this._requestOffline) { + this._state.setState(15); + } else { + this._state.setState(12); + this._galaxy.addActiveServer(this); + } + } + + protected void state_Mainloop(int timeNow) { + this.killZombies(); + if (this._requestOffline) { + this._state.setState(15); + } else if (timeNow - this._lastAccessTime > 120000) { + if (getDebugLevel() > 0) { + System.out.println(this + ": Timeout during connection."); + } + + System.out.println("[" + timeNow + "] " + this + ": Timeout during connection."); + System.out.println("\t_lastAccessTime = " + this._lastAccessTime); + System.out.println("\t timeNow = " + timeNow); + this._retriesLeft = 0; + this._state.setState(15); + } else { + this._waiters.notify(true); + + try { + this.processMsgs(12, timeNow); + } catch (VarErrorException var8) { + assert false; + + this._state.setState(17); + } catch (EOFException var9) { + EOFException e = var9; + VarErrorException ve = new VarErrorException(100); + if (this._lastError == null) { + this._lastError = ve; + } + + synchronized (System.out) { + System.out.println("[" + timeNow + "] " + this + ": Server has shut down connection."); + if (getDebugLevel() > 0) { + e.printStackTrace(System.out); + } + } + + this._state.setState(17); + } catch (IOException var10) { + IOException e = var10; + VarErrorException ve = new VarErrorException(100); + if (this._lastError == null) { + this._lastError = ve; + } + + synchronized (System.out) { + System.out.println("[" + timeNow + "] " + this + ": Error reading from network."); + if (getDebugLevel() > 0) { + e.printStackTrace(System.out); + } + } + + this._state.setState(17); + } catch (Exception var11) { + Exception e = var11; + VarErrorException ve = new VarErrorException(103); + if (this._lastError == null) { + this._lastError = ve; + } + + synchronized (System.out) { + System.out.println("[" + timeNow + "] " + this + ": Unexpected error."); + e.printStackTrace(System.out); + } + + this._state.setState(17); + } + } + } + + protected void state_XMIT_AE() { + assert false; + + this._state.setState(14); + this._state.setState(15); + } + + protected void state_XMIT_SE() { + boolean sendVAR_LOGONOFF = this._galaxy.addClosingServer(this); + OldPropertyList propList = new OldPropertyList(); + if (sendVAR_LOGONOFF) { + propList.addProperty(new netProperty(12, "1")); + } + + try { + this.sendNetMsg(new sessionExitCmd(propList)); + } catch (PacketTooLargeException var4) { + assert false; + } + + this._state.setState(16); + } + + protected void reuseConnection(WorldServer src) { + this._reader = src._reader; + src._reader = null; + this._ostr = src._ostr; + src._ostr = null; + this._sock = src._sock; + src._sock = null; + this._backupServers = (Vector<WorldServer.BackupServer>)src._backupServers.clone(); + } + + public boolean useBackupServer() { + Enumeration<WorldServer.BackupServer> enums = this._backupServers.elements(); + + while (enums.hasMoreElements()) { + WorldServer.BackupServer bs = enums.nextElement(); + if (bs.tries == 0) { + bs.IncTries(); + this._currentBackupServer = bs.GetHost(); + return true; + } + } + + this._currentBackupServer = null; + return false; + } + + private void addZombies() { + Enumeration<NetworkObject> enums = this._objTable.objects(); + + while (enums.hasMoreElements()) { + NetworkObject no = enums.nextElement(); + if (no instanceof WObject) { + if (this.zombies == null) { + this.zombies = new Vector<NetworkObject>(); + } + + this.zombies.addElement(no); + } else if (no instanceof Drone) { + ((Drone)no).disappear(); + } + } + + this._objTable.clear(); + } + + public void killZombies() { + if (this.zombies != null) { + int i = this.zombies.size(); + + while (--i >= 0) { + NetworkObject no = this.zombies.elementAt(i); + this._objTable.regObject(no.getLongID(), no); + if (no instanceof Drone) { + ((Drone)no).disappear(); + } + } + + this.zombies = null; + } + } + + private void cleanup() { + assert this._objTable != null; + + if (this._lastError != null && !this._lastError.getStatusFlag()) { + this.addZombies(); + } else { + this.killZombies(); + Enumeration<NetworkObject> enums = this._objTable.objects(); + + while (enums.hasMoreElements()) { + NetworkObject no = enums.nextElement(); + if (no instanceof Drone) { + ((Drone)no).disappear(); + } + } + + this._objTable.clear(); + } + + if (this._reader != null) { + if (this._reader.isAlive()) { + this._reader.stop(); + } + + this._reader = null; + } + + if (this._ostr != null) { + try { + this._ostr.close(); + } catch (Exception var4) { + } + + this._ostr = null; + } + + if (this._sock != null) { + try { + this._sock.close(); + } catch (Exception var3) { + } + + this._sock = null; + } + + assert this._connectThread == null; + } + + protected void state_Detaching_helper() { + if (this._galaxy != null) { + this._galaxy.addClosingServer(this); + this._galaxy.markClosedServer(this); + } + + this.cleanup(); + this._retryTimeout = 60000; + if (this._galaxy != null) { + this._galaxy.noteServerDeath(this._lastError); + } + } + + protected void state_Detaching() { + this._state.setState(18); + this.state_Detaching_helper(); + if (this._lastError != null) { + System.out.println("[" + Std.getRealTime() + "] " + this + ": lastError=" + this._lastError); + this._lastError = null; + this._galaxy.reacquireServer(this); + } else if (this._refCnt - this._tmpRefCnt > 0) { + this.startConnect(); + } + } + + protected void state_Sleeping(int timeNow) { + if (this._requestOffline) { + this._state.setState(-1); + } else { + if (timeNow - this._lastAccessTime > this._retryTimeout) { + if (this._refCnt == 0) { + this._state.setState(18); + } else { + this._state.setState(3); + } + } + } + } + + protected void state_Disconnected(int timeNow) { + this._waiters.notify(false); + if (timeNow - this._lastAccessTime > 1800000) { + synchronized (this) { + if (this._refCnt == 0) { + assert this._isMainRegistered; + + Main.unregister(this); + this._isMainRegistered = false; + if (this._galaxy != null) { + this._galaxy.killServer(this); + } + } + } + } else { + this._lastAccessTime = timeNow; + } + } + + protected void state_Dead(int timeNow) { + this.killZombies(); + this.state_Disconnected(timeNow); + } + + @Override + public void mainCallback() { + int t = Std.getRealTime(); + this.perFrame(t); + if ((getDebugLevel() & 4096) > 0 && this._tmpRefCnt > 0) { + System.out.println(this + ": tmpRefCnt cleanup of " + this._tmpRefCnt + " refs."); + } + + synchronized (this) { + this._refCnt = this._refCnt - this._tmpRefCnt; + this._tmpRefCnt = 0; + } + + assert this._refCnt >= 0; + } + + @Override + public void terminalCallback() { + synchronized (this) { + if (this._isMainRegistered) { + Main.unregister(this); + } + + Galaxy.forceOffline(false); + if (this._lastError == null) { + this._lastError = new VarErrorException(201); + } + + this._retriesLeft = 0; + int state = this._state.getState(); + this._state.setState(-1); + switch (state) { + case 4: + this._connectThread = null; + case 7: + case 16: + case 17: + if ((getDebugLevel() & 512) > 0) { + System.out.println(this + ": terminalCallback(): Detach"); + } + + this.state_Detaching(); + break; + case 5: + case 6: + case 13: + case 14: + default: + if ((getDebugLevel() & 512) > 0) { + System.out.println(this + ": terminalCallback(): no operation"); + } + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 15: + if ((getDebugLevel() & 512) > 0) { + System.out.println(this + ": terminalCallback(): XMIT_SE, Detach"); + } + + this.state_XMIT_SE(); + this.state_Detaching(); + } + } + } + + public void waitForConnection(ConnectionWaiter cw) { + this._waiters.addWaiter(cw); + } + + public void abortWaitForConnection(ConnectionWaiter cw) { + this._waiters.abortWait(cw); + } + + @Override + public String toString() { + return this.getLongID(); + } + + @Override + public void property(OldPropertyList propList) { + assert false; + } + + @Override + public void propertyUpdate(PropertyList propList) { + this._propList = propList; + net2Property protocol = this._propList.getProperty(3); + if (protocol != null) { + int ver; + try { + ver = Integer.parseInt(protocol.value()); + } catch (NumberFormatException var9) { + System.err.println(this + ": Error converting protocol value: " + protocol.value()); + ver = 18; + } + + int oldVer = this.getVersion(); + this.setVersion(ver < oldVer ? ver : oldVer); + } + + net2Property update = this._propList.getProperty(8); + if (update != null) { + try { + this._updateTime = Integer.parseInt(update.value()); + this._updateTime /= 1000; + } catch (NumberFormatException var8) { + System.err.println(this + ": Error converting update value: " + update.value()); + } + } + + net2Property http = this._propList.getProperty(24); + if (http == null) { + http = this._propList.getProperty(29); + } + + if (http != null) { + NetUpdate.setUpgradeServerURL(http.value()); + } + + net2Property script = this._propList.getProperty(25); + if (script != null) { + this.setScriptServer(script.value()); + } + + net2Property smtp = this._propList.getProperty(26); + if (smtp != null) { + this.setSmtpServer(smtp.value()); + } + + net2Property domain = this._propList.getProperty(27); + if (domain != null) { + this.setMailDomain(domain.value()); + } + + if (this._state.getState() == 6) { + this._state.setState(7); + } + } + + @Override + public WorldServer getServer() { + return this; + } + + @Override + public String getLongID() { + return this._serverURL.getHost(); + } + + @Override + public void register() { + assert false; + } + + @Override + public void galaxyDisconnected() { + assert false; + } + + @Override + public void reacquireServer(WorldServer oldServer) { + } + + @Override + public void changeChannel(Galaxy g, String oldChannel, String newChannel) { + } + + protected class BackupServer { + protected String hostName; + protected int tries; + + public BackupServer() { + this.hostName = ""; + this.tries = 0; + } + + public BackupServer(String host) { + this.hostName = host; + this.tries = 0; + } + + public String GetHost() { + return this.hostName; + } + + public void IncTries() { + this.tries++; + } + } +} |