package NET.worlds.network; import NET.worlds.console.Console; import NET.worlds.core.IniFile; import NET.worlds.core.Std; import NET.worlds.scape.Room; import NET.worlds.scape.RoomSubscribeInfo; import NET.worlds.scape.World; public class NetworkRoom implements NetworkObject, ConnectionWaiter { private static final int STATE_DISCONNECTED = 0; private static final int STATE_CONNECTING = 1; private static final int STATE_GETTINGROOMID = 2; private static final int STATE_CONNECTED = 3; private static final int STATE_SUBSCRIBED = 4; private static int _debugLevel = IniFile.gamma().getIniInt("roomdebug", 0); Room _room; String _worldName; String _roomName; String _longID; Galaxy _galaxy; String _debug1; String _debug2; private RoomSubscribeInfo _lastRSInfo = null; private URL _serverURL = null; private WorldServer _server = null; private int _roomID = 0; private boolean _wantsToBeSubscribed = false; private int _serverState = 0; static { if (_debugLevel > 0) { System.out.println("ROOM DEBUGGING LEVEL = " + _debugLevel); } } public NetworkRoom(Room room) { this._room = room; this._debug1 = ""; this._debug2 = ""; this._galaxy = room.getGalaxy(); this.initNames(); this.register(); } synchronized void initNames() { this._roomName = this._room.getName(); World world = this._room.getWorld(); this._worldName = world.getName(); Galaxy galaxy = this._room.getGalaxy(); String channel = galaxy.getChannel(); if (channel.length() != 0) { channel = "<" + channel + ">"; } this._longID = this._worldName + "#" + this._roomName + channel; } public Room getRoom() { return this._room; } public synchronized void setName(String newName) { assert newName != this._roomName; this.unregister(); this.initNames(); this.register(); } void unregister() { Galaxy tmpGalaxy = this._room.getGalaxy(); assert tmpGalaxy != null; assert this._galaxy == tmpGalaxy; tmpGalaxy.delObject(this._longID); if (this._roomID != 0) { tmpGalaxy.delRoomID(this._roomID, this); } this._debug2 = ""; this._roomID = 0; } public synchronized void detach() { this.unregister(); this._galaxy = null; this._room = null; } @Override public String getLongID() { return this._longID; } public int getRoomID() { return this._roomID; } public boolean isServed() { return this._serverState == 4; } public synchronized void serverRedirect(WorldServer serv, String roomName, ServerURL serverURL) { if (this._server != null) { if (serv.getGalaxy() == this._server.getGalaxy()) { if (roomName.equals(this._longID)) { if ((_debugLevel & 2) > 0) { System.out.println(this._room.getName() + ": serverRedirect(" + serverURL + ")"); } this._serverState = 3; int tmpRoomID = this._roomID; this.disconnect(); assert this._server == null; this._roomID = tmpRoomID; this._debug2 = this._debug2 + "; [" + Std.getRealTime() + "]: serverDirect(" + serv + ")"; this._serverURL = URL.make(serverURL.toString()); if (this._roomID != 0) { this._room.getGalaxy().setRoomID(this._roomID, this); } if (this._wantsToBeSubscribed) { this.acquireServer(); } } } } } public synchronized void setRoomID(WorldServer serv, int roomID, String roomName, boolean willRedirect) { assert serv != null; if ((_debugLevel & 2) > 0) { System.out.println(this._longID + ": setRoomID(" + serv + ", " + roomID + ", " + roomName + ", " + willRedirect + ")"); System.out.println("last request made: " + this._debug1); } if (serv.getGalaxy() != this._server.getGalaxy()) { System.out.println(this._longID + ": setRoomID(" + serv + ", " + roomID + ", " + roomName + ", " + willRedirect + ")"); System.out.println("\twas expecting server " + this._server); System.out.println("last request made: " + this._debug1); new Exception().printStackTrace(System.out); } if (serv.getGalaxy() == this._server.getGalaxy()) { if (roomName.equals(this._longID)) { if (roomID == 0) { this._serverState = 0; this.reacquireServer(serv); } else { if (this._roomID == 0) { this._roomID = roomID; this._debug2 = this._debug2 + "; [" + Std.getRealTime() + "]: setRoomID(" + serv + ", " + willRedirect + ")"; } assert this._roomID == roomID; this._serverState = 3; if (!willRedirect) { if (this._wantsToBeSubscribed) { assert this._lastRSInfo != null; this.subscribe(); } else { this.disconnect(); } } } } } } public synchronized void subscribe(RoomSubscribeInfo info) { assert this._galaxy == this._room.getGalaxy(); if ((_debugLevel & 1) > 0) { System.out.println(this._room.getName() + ": subscribe(Info)"); } assert this._room.getWorld() != null; assert this._serverState != 4; this._lastRSInfo = info; this._wantsToBeSubscribed = true; switch (this._serverState) { case 0: this.acquireServer(); case 1: case 2: default: break; case 3: this.subscribe(); } } private void subscribe() { if ((_debugLevel & 1) > 0) { System.out.println(this._room.getName() + ": subscribe()"); } assert this._server != null; assert this._wantsToBeSubscribed; assert this._lastRSInfo != null; assert this._roomID != 0; assert this._serverState == 3; assert this._room.getWorld() != null; this._serverState = 4; this.sendNetworkMsg(new SubscribeRoomCmd(this._lastRSInfo, this._roomID)); } private void sendNetworkMsg(netPacket msg) { assert this._server != null; try { this._server.sendNetworkMsg(msg); } catch (InfiniteWaitException var3) { this.disconnect(); } catch (PacketTooLargeException var4) { assert false; } } public synchronized void subscribeDist(RoomSubscribeInfo info) { this._lastRSInfo = info; assert this._wantsToBeSubscribed; assert this._room.getWorld() != null; if (this._serverState == 4) { this.sendNetworkMsg(new SubscribeDistCmd(info.d, this._roomID)); } } public synchronized void unsubscribe() { if ((_debugLevel & 1) > 0) { System.out.println(this._room.getName() + ": unsubscribe()"); } assert this._wantsToBeSubscribed; this._wantsToBeSubscribed = false; this._lastRSInfo = null; switch (this._serverState) { case 0: case 3: default: break; case 1: assert this._server != null; this._server.abortWaitForConnection(this); this.disconnect(); break; case 2: this.disconnect(); break; case 4: this.sendNetworkMsg(new UnsubscribeRoomCmd(this._roomID)); this.disconnect(); } } private synchronized void disconnect() { if ((_debugLevel & 2) > 0) { System.out.println(this._room.getName() + ": disconnect()"); } switch (this._serverState) { case 2: this._server.delRoomRequest(this._longID); if (this._debug1 == null) { this._debug1 = ""; } this._debug1 = this._debug1 + "; [" + Std.getRealTime() + "]: deleted request for " + this._longID; default: this._serverURL = null; if (this._server != null && this._roomID != 0) { this._server.delRoomID(this._roomID, this); } this._roomID = 0; this._debug2 = ""; if (this._server != null) { this._server.decRefCnt(this); this._server = null; this._serverState = 0; } assert this._serverState == 0; } } private synchronized void acquireServer() { if ((_debugLevel & 2) > 0) { System.out.println(this._room.getName() + ": acquireServer() - " + this._serverURL); } assert this._serverState == 0; if (this._server == null) { World world = this._room.getWorld(); assert world != null; Galaxy galaxy = world.getConsole().getGalaxy(); assert galaxy != null; if (this._serverURL == null) { this._serverURL = world.getConsole().getGalaxyURL(); if (this._serverURL == null) { return; } } try { this._server = galaxy.getServer(this._serverURL); } catch (InvalidServerURLException var4) { Console.println(">> " + var4.getMessage()); this._serverURL = null; return; } if (this._server == null) { return; } this._server.incRefCnt(this); } this._serverState = 1; this._server.waitForConnection(this); } @Override public void connectionCallback(Object caller, boolean connected) { if (caller instanceof WorldServer) { WorldServer serv = (WorldServer)caller; if ((_debugLevel & 2) > 0) { System.out.println(this._room.getName() + ": connectionCallback(" + serv + ", connected=" + connected + ") _server=" + this._server); } if (this._server == serv) { if (!connected) { this.disconnect(); } else { if (this._roomID == 0) { synchronized (this) { this._serverState = 2; serv.requestRoomID(this._longID, this); this._debug1 = "[" + Std.getRealTime() + "] " + serv + ": requested roomID for " + this._longID; } } else { this.setRoomID(serv, this._roomID, this._longID, false); } } } } } @Override public void property(OldPropertyList propList) { for (int i = 0; i < propList.size(); i++) { netProperty p = propList.elementAt(i); byte[] data = new byte[p.value().length()]; p.value().getBytes(0, p.value().length(), data, 0); this._room.getSharer().setFromNetData(p.property(), data); } } @Override public void propertyUpdate(PropertyList propList) { for (int i = 0; i < propList.size(); i++) { net2Property p = propList.elementAt(i); this._room.getSharer().setFromNetData(p.property(), p.data()); } } @Override public WorldServer getServer() { return this._server; } @Override public void register() { if ((_debugLevel & 2) > 0) { System.out.println(this._room.getName() + ": register()"); } assert this._room.getWorld() != null; Galaxy tmpGalaxy = this._room.getGalaxy(); assert tmpGalaxy != null; tmpGalaxy.regObject(this._longID, this); this._galaxy = tmpGalaxy; if (this._serverState != 0) { this.disconnect(); } this._serverURL = null; if (this._wantsToBeSubscribed) { this.acquireServer(); } } @Override public void galaxyDisconnected() { if ((_debugLevel & 2) > 0) { System.out.println(this._room.getName() + ": galaxyDisconnected()"); } synchronized (this) { if (this._server != null) { this.reacquireServer(this._server); } } } @Override public void reacquireServer(WorldServer oldServ) { if (this._debug1 == null) { this._debug1 = ""; } this._debug1 = this._debug1 + "; [" + Std.getRealTime() + "]: reacquireServer(" + this._server + ", " + oldServ + ")"; if (this._server == oldServ) { if ((_debugLevel & 2) > 0) { System.out.println(this._room.getName() + ": reacquireServer()"); } this.disconnect(); if (this._wantsToBeSubscribed) { this.acquireServer(); } } } @Override public synchronized void changeChannel(Galaxy tmpGalaxy, String oldChannel, String newChannel) { if ((_debugLevel & 2) > 0) { System.out.println(this._room.getName() + ": changeChannel(" + oldChannel + " -> " + newChannel + ")"); } boolean wantsToBeSubscribed = this._wantsToBeSubscribed; RoomSubscribeInfo lastRSInfo = this._lastRSInfo; if (wantsToBeSubscribed) { this.unsubscribe(); } tmpGalaxy.delObject(this._longID); this.initNames(); this.register(); if (wantsToBeSubscribed) { this.subscribe(lastRSInfo); } } @Override public String toString() { return "NetworkRoom[" + this._room.getName() + "]"; } public String debugStuff() { return this + ": debug1 = " + this._debug1 + "\n\tdebug2 = " + this._debug2; } }