package NET.worlds.scape; import NET.worlds.console.AdPart; import NET.worlds.console.BBAnimateDroneCommand; import NET.worlds.console.BBMoveDroneCommand; import NET.worlds.console.BBTeleportCommand; import NET.worlds.console.BlackBox; import NET.worlds.console.Console; import NET.worlds.console.FramePart; import NET.worlds.console.RenderCanvas; import NET.worlds.core.Std; import NET.worlds.network.Galaxy; import NET.worlds.network.InfiniteWaitException; import NET.worlds.network.NetworkObject; import NET.worlds.network.OldPropertyList; import NET.worlds.network.PacketTooLargeException; import NET.worlds.network.PropertyList; import NET.worlds.network.PropertySetCmd; import NET.worlds.network.URL; import NET.worlds.network.WorldServer; import NET.worlds.network.longLocCmd; import NET.worlds.network.net2Property; import NET.worlds.network.netPacket; import NET.worlds.network.roomChangeCmd; import NET.worlds.network.teleportCmd; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Vector; public abstract class Pilot extends WObject implements NetworkObject, BumpHandler { static Vector visibleRooms = new Vector(); static Vector visibleRoomInfo = new Vector(); int lastUpdateTime; private static Vector nextVisibleRooms = new Vector(); private static Vector nextVisibleRoomInfo = new Vector(); int positionSentTime; short lastx; short lasty; short lastz; short lastdir; Room lastroom; Room lastFrameRoom; private static Vector subscribers = new Vector(); private static int lastWarning; private static Pilot active; protected int cameraMode = 0; protected int cameraSpeed = 0; private static World lastWorld = null; private Camera lastCam; protected Console console; private static Object classCookie = new Object(); static { nativeInit(); } public static native void nativeInit(); public float animate(String action) { action = action.toLowerCase(); BlackBox.getInstance().submitEvent(new BBAnimateDroneCommand("@Pilot", action)); if (action.equals("sleep") || action.equals("s")) { Console console = Console.getActive(); if (console != null) { console.goToSleep(); } } else if (this == getActive()) { sendText("&|+action>" + action); } return 0.0F; } public Vector getAnimationList() { Vector v = new Vector(); v.addElement("sleep"); return v; } public void setSleepMode(String mode) { } public static void load(URL url, WobLoaded callback) { if (!url.endsWith(".mov") && !url.endsWith(".rwx") && !url.endsWith(".rwg")) { String s = url.getInternal(); if (s.endsWith(".drone")) { s = s.substring(0, s.length() - 6) + ".pilot"; } else if (!s.endsWith(".pilot")) { s = s + ".pilot"; } new WobLoader(URL.make(s), callback); } else { callback.wobLoaded(null, new HoloPilot(url)); } } public void addInventory(WObject child) throws ClassCastException { assert child.isDynamic(); this.add(child); } public void addInSlot(WObject child, int slot) { assert child.isDynamic(); Sharer s = this.getSharer(); if (s.getAttribute(slot) != null) { System.out.println("Attempting to add a second object (" + child.getName() + ") to slot number " + slot); } else { s.moveToSlot(child, slot); } } @Override public void add(WObject w) { super.add(w); } public float distToVisibleObject(WObject w) { return this.distToVisiblePoint(w.getRoom(), w.getWorldPosition()); } public void aboutToDraw() { } public float distToVisiblePoint(Room r, Point3Temp pos) { if (r == null) { return 0.0F; } else { int i = visibleRooms.indexOf(r); if (i == -1) { return 0.0F; } else { RoomSubscribeInfo rsi = visibleRoomInfo.elementAt(i); return rsi.d == 0.0F ? pos.minus(this.getWorldPosition()).length() : pos.minus(Point3Temp.make(rsi.x, rsi.y, rsi.z)).length() + rsi.d; } } } public static void addVisibleRoom(Room r, float x, float y, float z, float d) { r.noteRef(); int i = nextVisibleRooms.indexOf(r); if (i == -1) { nextVisibleRooms.addElement(r); nextVisibleRoomInfo.addElement(new RoomSubscribeInfo(x, y, z, d)); } else { RoomSubscribeInfo info = nextVisibleRoomInfo.elementAt(i); if (d < info.d) { info.x = x; info.y = y; info.z = z; info.d = d; } } } public void generateFrameEvents(FrameEvent f) { Room currentRoom = this.getRoom(); if (currentRoom != null) { addVisibleRoom(currentRoom, 0.0F, 0.0F, 0.0F, 0.0F); } synchronized (visibleRooms) { Vector t = visibleRoomInfo; visibleRoomInfo = nextVisibleRoomInfo; nextVisibleRoomInfo = t; Vector j = nextVisibleRooms; nextVisibleRooms = visibleRooms; visibleRooms = j; } Vector prevVisibleRooms = nextVisibleRooms; Object oldEventSource = f.source; f.source = this; int i = visibleRooms.size(); while (--i >= 0) { Room r = visibleRooms.elementAt(i); r.generateFrameEvents(f); prevVisibleRooms.removeElement(r); } i = prevVisibleRooms.size(); while (--i >= 0) { prevVisibleRooms.elementAt(i).generateFrameEvents(f); } nextVisibleRooms.removeAllElements(); nextVisibleRoomInfo.removeAllElements(); i = f.time - this.lastUpdateTime; if (i > 500) { this.subscribeRooms(); boolean hasMoved = this.pilotUpdate(f.time); this.subscriptionUpdate(hasMoved); this.updateUnsubscribes(); this.lastUpdateTime = f.time; } this.touchSubscribers(); f.source = oldEventSource; } public static void sendText(String msg) { sendText(null, msg); } public static boolean containsWord(String word, String msg) { int i = -1; while ((i = msg.indexOf(word, i + 1)) >= 0) { if (i == 0 || !Character.isLetter(msg.charAt(i - 1))) { int end = i + word.length(); if (end >= msg.length() || !Character.isLetter(msg.charAt(end))) { return true; } } } return false; } public static void sendText(String who, String msg) { WorldServer server = active.getServer(); if (server != null) { if (msg.contains("&|+action>")) { PropertyList propList = new PropertyList(); String strUrl = getActive().getSourceURL().getAbsolute(); strUrl = strUrl + "#" + msg.substring(msg.indexOf(">") + 1, msg.length()); propList.addProperty(new net2Property(5, 64, 1, strUrl)); try { server.sendNetworkMsg(new PropertySetCmd(propList)); } catch (PacketTooLargeException var7) { } catch (InfiniteWaitException var8) { } } server.sendText(who, msg); if ((containsWord("brb", msg) || containsWord("ggp", msg)) && Console.getActive() != null) { Console.getActive().goToSleep(); } int i = msg.indexOf(42); int next; while (i >= 0 && (next = msg.indexOf(42, i + 1)) > i) { int space = msg.indexOf(32, i); if (next > i + 1 && (space == -1 || space > next)) { String act = msg.substring(i + 1, next).toLowerCase(); if (who == null && active != null) { active.animate(act); } else { sendText(who, "&|+action>" + act); } } i = next; } } else if (!msg.startsWith("&|+")) { Console.println(Console.message("No-server-connect")); } } private static float round(float x, float mul) { return mul * Math.round(x / mul); } public String getWorldRoomChannel(Room room) { if (room == null) { return null; } else { World world = room.getWorld(); if (world == null) { return null; } else { URL url = world.getSourceURL(); if (url == null) { return null; } else { String newURL = url.getAbsolute(); Galaxy g = room.getGalaxy(); String channelPart = g.getChannel(); return newURL + "#" + room.getName() + "<" + channelPart + ">"; } } } } public String getURL() { Room room = this.getRoom(); String newURL = this.getWorldRoomChannel(room); if (newURL == null) { return null; } else { Point3Temp pos = this.getPosition(); float val = round(pos.x, 1.0F); newURL = newURL + "@" + val; val = round(pos.y, 1.0F); newURL = newURL + "," + val; val = round(pos.z, 1.0F); newURL = newURL + "," + val; Point3Temp camAxis = Point3Temp.make(); val = round(this.getSpin(camAxis), 1.0F); newURL = newURL + "," + val; val = round(camAxis.x, 0.001F); newURL = newURL + "," + val; val = round(camAxis.y, 0.001F); newURL = newURL + "," + val; val = round(camAxis.z, 0.001F); return newURL + "," + val; } } public String getTeleportURL() { Camera tester = new Camera(); Room room = this.getRoom(); if (room == null) { return null; } else { room.add(tester); tester.yaw(220.0F); tester.post(this); boolean pBumpable = this.getBumpable(); this.setBumpable(false); Transform t = tester.getObjectToWorldMatrix(); tester.moveThrough(Point3Temp.make(0.0F, -170.0F, 0.0F).times(t).minus(t.getPosition())); t.recycle(); this.setBumpable(pBumpable); room = tester.getRoom(); tester.detach(); String wrc = this.getWorldRoomChannel(room); if (wrc == null) { return null; } else { Point3Temp pos = tester.getPosition(); return wrc + "@" + (int)pos.x + "," + (int)pos.y + "," + (int)pos.z + "," + (int)tester.getYaw(); } } } public Room getLastServedRoom() { return this.lastroom; } public float getFootHeight() { return 0.0F; } private static void sendToRoom(Room r, netPacket msg) { if (r != null) { synchronized (r) { WorldServer s = r.getServer(); if (s != null) { try { s.sendNetworkMsg(msg); } catch (InfiniteWaitException var5) { } catch (PacketTooLargeException var6) { } } } } } private boolean validRoom(Room r) { return r == null || r.getNetworkRoom().getRoomID() != 0; } public boolean pilotUpdate(int t) { Point3Temp pos = this.getPosition(); short x = (short)pos.x; short y = (short)pos.y; short z = (short)this.getFootHeight(); short dir = (short)(-this.getYaw() + 90.0F); dir = (short)(dir % 360); while (dir < 0) { dir = (short)(dir + 360); } Room room = this.getRoom(); if (room != this.lastFrameRoom) { BlackBox.getInstance().submitEvent(new BBTeleportCommand(this.getURL())); this.lastFrameRoom = this.getRoom(); } if (room != null && !room.getNetworkRoom().isServed()) { room = null; } if (this.lastroom != null && !this.lastroom.getNetworkRoom().isServed()) { this.lastroom = null; } int diffTime = t - this.positionSentTime; if (x == this.lastx && y == this.lasty && z == this.lastz && dir == this.lastdir && diffTime <= 40000 && room == this.lastroom) { return false; } else { BlackBox.getInstance().submitEvent(new BBMoveDroneCommand("@Pilot", x, y, z, dir)); if (room != this.lastroom && this.validRoom(room) && this.validRoom(this.lastroom)) { Galaxy lrGalaxy = null; Galaxy rGalaxy = null; if (room != null) { rGalaxy = room.getGalaxy(); } if (this.lastroom != null) { lrGalaxy = this.lastroom.getGalaxy(); } if (rGalaxy != lrGalaxy) { if (room != null) { sendToRoom(room, new teleportCmd(room, (byte)0, (byte)1, x, y, z, dir)); BlackBox.getInstance().submitEvent(new BBTeleportCommand(this.getURL())); } if (this.lastroom != null) { sendToRoom(this.lastroom, new teleportCmd(null, (byte)1, (byte)0, x, y, z, dir)); } BlackBox.getInstance().submitEvent(new BBTeleportCommand(this.getURL())); } else if (room.getServer() != this.lastroom.getServer()) { if (room != null) { sendToRoom(room, new teleportCmd(room, (byte)0, (byte)1, x, y, z, dir)); BlackBox.getInstance().submitEvent(new BBTeleportCommand(this.getURL())); } if (this.lastroom != null) { sendToRoom(this.lastroom, new teleportCmd(null, (byte)1, (byte)0, x, y, z, dir)); } } else { sendToRoom(this.lastroom, new roomChangeCmd(room, x, y, z, dir)); BlackBox.getInstance().submitEvent(new BBTeleportCommand(this.getURL())); } this.lastroom = room; } else if (room != null) { sendToRoom(room, new longLocCmd(x, y, z, dir)); } this.positionSentTime = t; this.lastx = x; this.lasty = y; this.lastz = z; this.lastdir = dir; return true; } } private void updateUnsubscribes() { int i = subscribers.size(); while (--i >= 0) { if (!visibleRooms.contains(subscribers.elementAt(i))) { subscribers.elementAt(i).unsubscribe(); subscribers.removeElementAt(i); } } } public void subscribeRooms() { int i = visibleRooms.size(); while (--i >= 0) { Room r = visibleRooms.elementAt(i); if (!subscribers.contains(r)) { RoomSubscribeInfo newInfo = visibleRoomInfo.elementAt(i); r.subscribe(newInfo); } } } public boolean removeSubscribedRoom(Room suspect) { int i = subscribers.size(); while (--i >= 0) { if (subscribers.elementAt(i) == suspect) { subscribers.removeElementAt(i); return true; } } return false; } public void touchSubscribers() { int i = subscribers.size(); while (--i >= 0) { subscribers.elementAt(i).noteRef(); } } private void subscriptionUpdate(boolean hasMoved) { Room camRoom = this.getRoom(); int i = visibleRooms.size(); while (--i >= 0) { Room r = visibleRooms.elementAt(i); assert r.getNetworkRoom() != null; RoomSubscribeInfo newInfo = visibleRoomInfo.elementAt(i); if (!subscribers.contains(r)) { subscribers.addElement(r); } else if (hasMoved && r.getNetworkRoom().isServed() && r != camRoom) { r.subscribeDist(newInfo); } } } @Override public void property(OldPropertyList propList) { } @Override public void propertyUpdate(PropertyList propList) { } @Override public void register() { } @Override public void galaxyDisconnected() { } @Override public void reacquireServer(WorldServer oldServ) { } @Override public void changeChannel(Galaxy g, String oldChannel, String newChannel) { sendToRoom(this.lastroom, new teleportCmd(null, (byte)1, (byte)0, this.lastx, this.lasty, this.lastz, this.lastdir)); BlackBox.getInstance().submitEvent(new BBTeleportCommand(this.getURL())); this.lastroom = null; } @Override public WorldServer getServer() { Room r = this.getLastServedRoom(); if (r != null) { return r.getServer(); } else { return this.console == null ? null : this.console.getServerNew(); } } @Override public String getLongID() { return this.console != null ? this.console.getGalaxy().getChatname() : null; } @Override public WObject changeRoom(Room newRoom, Transform invPos) { assert this == active; if (newRoom.getVIPOnly() && !newRoom.getWorld().getConsole().getVIP()) { int now = Std.getFastTime(); if (now > lastWarning + 3000) { lastWarning = now; Console.println(Console.message("Only-VIPs-here")); } return null; } else { Room oldRoom = getActiveRoom(); if (oldRoom != null) { oldRoom.removePostrenderHandler(BlackBox.getInstance()); oldRoom.removeFrameHandler(BlackBox.getInstance(), null); } WObject p = changeActiveRoom(newRoom); p.makeIdentity(); p.pre(invPos); if (oldRoom != null) { oldRoom.move(oldRoom, newRoom); } if (newRoom != null) { newRoom.move(oldRoom, newRoom); } return p; } } public static Pilot getActive() { return active; } public void setOutsideCameraMode(int camMode, int camSpeed) { this.cameraMode = camMode; this.cameraSpeed = camSpeed; if (this.getMainCamera() != null) { this.getMainCamera().lookAround.makeIdentity(); } } public int getOutsideCameraMode() { return this.cameraMode; } public int getOutsideCameraSpeed() { return this.cameraSpeed; } public static Room getActiveRoom() { return active == null ? null : active.getRoom(); } public static World getActiveWorld() { return active == null ? null : active.getWorld(); } public abstract void resetAvatarNow(); public static Pilot changeActiveRoom(Room newRoom) { BackgroundLoader.activeRoomChanged(newRoom); Console oldc = Console.getActive(); Console newc = oldc; if (newRoom != null) { newc = newRoom.getWorld().getConsole(); } Pilot p = newc.getPilot(); if (p != active) { p.transferFrom(active); if (newRoom != null && active != null && newRoom == active.getRoom()) { p.makeIdentity().post(active); } } if (oldc != newc) { newc.forPilotOnlyActivate(); } if (oldc != null) { active.detach(); } active = p; p.setUpCameras(newc); if (newRoom != null) { newRoom.add(p); } active.resetAvatarNow(); newc.checkCourtesyVIP(); if (active.getWorld() != lastWorld) { lastWorld = active.getWorld(); newc.displayAds(); WorldScriptManager.getInstance().worldEntered(lastWorld.toString()); } WorldScriptManager.getInstance().roomEntered(newRoom.toString()); newRoom.addPostrenderHandler(BlackBox.getInstance()); newRoom.addFrameHandler(BlackBox.getInstance(), null); return active; } public void changeChannel(String newChannel) { Galaxy g = this.console.getGalaxy(); g.changeChannel(newChannel); } private void setUpCameras(Console c) { Enumeration camList = (Enumeration)this.getContents(); Enumeration e = c.getParts(); while (e.hasMoreElements()) { Object o = e.nextElement(); if (o instanceof RenderCanvas && !(o instanceof AdPart)) { ((RenderCanvas)o).setCamera(getNextCamera(camList)); } } } public Camera getMainCamera() { if (this.lastCam != null) { SuperRoot o = this.lastCam.getOwner(); if (o == this || o != null && o.getOwner() == this) { return this.lastCam; } } return this.lastCam = getNextCamera(new DeepEnumeration((Enumeration)this.getContents())); } private static Camera getNextCamera(Enumeration list) { while (list.hasMoreElements()) { Object o = list.nextElement(); if (o instanceof Camera) { return (Camera)o; } } return null; } protected void transferFrom(Pilot old) { if (old != null) { this.lastx = old.lastx; this.lasty = old.lasty; this.lastz = old.lastz; this.lastdir = old.lastdir; this.lastroom = old.lastroom; this.positionSentTime = old.positionSentTime; Enumeration ehs = this.getHandlers(); while (ehs.hasMoreElements()) { Object eh = ehs.nextElement(); if (eh instanceof MomentumBehavior) { ((MomentumBehavior)eh).transferFrom(old.getHandlers()); } } this.getMainCamera().transferFrom(old.getMainCamera()); } } @Override public boolean handle(BumpEventTemp b) { this.slideBumpHandler(b); return true; } public void slideBumpHandler(BumpEventTemp b) { if (b.receiver == b.source) { Point3Temp bumpNormal = Point3Temp.make(b.bumpNormal).normalize(); b.postBumpPath.minus(Point3Temp.make(bumpNormal).times(b.postBumpPath.dot(bumpNormal))); b.postBumpPath.plus(Point3Temp.make(b.bumpNormal).times(1.0E-6F)); } } @Override public void makeShadow() { } public void setConsole(Console c) { assert this.console == null; this.console = c; copySoul(c.getPilotSoulTemplate(), this); } private static void saveEnum(Saver s, Enumeration e) throws IOException { while (e.hasMoreElements()) { Object o = e.nextElement(); if (o instanceof Persister && !(o instanceof NonPersister)) { s.saveMaybeNull((Persister)o); } } s.saveMaybeNull(null); } public static void copySoul(WObject source, WObject target) { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); try { Saver saver = new Saver(new DataOutputStream(buffer)); saveEnum(saver, source.getContents()); saveEnum(saver, source.getHandlers()); saveEnum(saver, source.getActions()); saveEnum(saver, source.getAttributes()); saver.done(); } catch (Exception var5) { var5.printStackTrace(System.out); throw new Error(var5.toString()); } try { Restorer r = new Restorer(new DataInputStream(new ByteArrayInputStream(buffer.toByteArray()))); Persister p; while ((p = r.restoreMaybeNull()) != null) { target.add((Transform)p); } while ((p = r.restoreMaybeNull()) != null) { target.addHandler((SuperRoot)p); } while ((p = r.restoreMaybeNull()) != null) { target.addAction((Action)p); } while ((p = r.restoreMaybeNull()) != null) { target.addAttribute((Attribute)p); } r.done(); } catch (Exception var6) { var6.printStackTrace(System.out); throw new Error(var6.toString()); } } @Override protected void noteUnadding(SuperRoot child) { if (child instanceof WObject) { WObject w = (WObject)child; w.isDynamic(); } super.noteUnadding(child); } @Override public Object properties(int index, int offset, int mode, Object value) throws NoSuchPropertyException { Object ret = null; switch (index - offset) { case 0: if (mode == 0) { ret = new Property(this, index, "Console"); } else if (mode == 1) { ret = this.console; } break; default: ret = super.properties(index, offset + 1, mode, value); } return ret; } @Override public void saveState(Saver s) throws IOException { if (this.console != null) { System.out.println("Warning: saving pilot " + this.getName() + " with soul, which won't restore correctly!"); } s.saveVersion(0, classCookie); super.saveState(s); } @Override public void restoreState(Restorer r) throws IOException, TooNewException { switch (r.restoreVersion(classCookie)) { case 0: super.restoreState(r); return; default: throw new TooNewException(); } } }