summaryrefslogtreecommitdiff
path: root/NET/worlds/network/WorldServer.java
diff options
context:
space:
mode:
Diffstat (limited to 'NET/worlds/network/WorldServer.java')
-rw-r--r--NET/worlds/network/WorldServer.java1319
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++;
+ }
+ }
+}