diff options
Diffstat (limited to 'NET/worlds/console')
194 files changed, 27063 insertions, 0 deletions
diff --git a/NET/worlds/console/AboutDialog.java b/NET/worlds/console/AboutDialog.java new file mode 100644 index 0000000..4fea336 --- /dev/null +++ b/NET/worlds/console/AboutDialog.java @@ -0,0 +1,100 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.core.Std; +import NET.worlds.network.NetUpdate; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Component; +import java.awt.Event; +import java.awt.Font; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextArea; +import java.util.Enumeration; +import java.util.Vector; + +public class AboutDialog extends PolledDialog { + private static final long serialVersionUID = -2810306367601133331L; + public static final String JavaVersion = "1890a40"; + Button okButton = new Button(Console.message("OK")); + private static Font font = new Font(Console.message("ConsoleFont"), 0, 12); + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + String apptitle; + + AboutDialog(String apptitle, Frame frame) { + super(frame, null, Console.message("About") + Std.getProductName(), true); + this.apptitle = apptitle; + this.ready(); + } + + private Component setConstraints(GridBagLayout gbag, Component comp, GridBagConstraints c) { + gbag.setConstraints(comp, c); + return comp; + } + + @Override + protected void build() { + this.setBackground(Color.white); + this.setLayout(new BorderLayout()); + this.add("North", new Filler(10, 10)); + this.add("South", new Filler(10, 10)); + this.add("East", new Filler(10, 10)); + this.add("West", new Filler(10, 10)); + GridBagLayout gbag = new GridBagLayout(); + Panel p = new Panel(gbag); + p.setFont(font); + GridBagConstraints c = new GridBagConstraints(); + c.fill = 0; + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 0; + c.gridheight = 1; + String logo = IniFile.override().getIniString("AboutLogo", Console.message("wlogo.gif")); + p.add(this.setConstraints(gbag, new ImageCanvas(logo), c)); + c.weightx = 0.0; + c.weighty = 0.0; + p.add(this.setConstraints(gbag, new Label(this.apptitle), c)); + if (Gamma.getShaper() != null) { + p.add(this.setConstraints(gbag, new Label(Console.message("about-box-build-date") + " " + Std.getBuildInfo() + ":" + "1890a40"), c)); + } else { + p.add(this.setConstraints(gbag, new Label(Console.message("about-box-rev") + " " + Std.getVersion() + " : " + "1890a40"), c)); + } + + Vector<String> worlds = NetUpdate.aboutWorlds(); + TextArea worldList = new TextArea(10, 40); + worldList.setEditable(false); + p.add(this.setConstraints(gbag, worldList, c)); + Enumeration<String> e = worlds.elements(); + + while (e.hasMoreElements()) { + worldList.append(e.nextElement() + "\n"); + } + + p.add(this.setConstraints(gbag, new Label(Console.message("about-box-1")), c)); + p.add(this.setConstraints(gbag, new Label(Console.message("about-box-2")), c)); + this.okButton.setFont(bfont); + p.add(this.setConstraints(gbag, this.okButton, c)); + this.add("Center", p); + } + + @Override + public boolean action(Event event, Object what) { + return event.target == this.okButton ? this.done(true) : false; + } + + @Override + public boolean keyDown(Event event, int key) { + return key != 27 && key != 10 ? super.keyDown(event, key) : this.done(true); + } + + @Override + public void show() { + super.show(); + this.okButton.requestFocus(); + } +} diff --git a/NET/worlds/console/ActionDialog.java b/NET/worlds/console/ActionDialog.java new file mode 100644 index 0000000..93deea2 --- /dev/null +++ b/NET/worlds/console/ActionDialog.java @@ -0,0 +1,150 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.core.ServerTableManager; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Event; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.Point; +import java.util.Vector; + +class ActionDialog extends PolledDialog implements ImageButtonsCallback { + private static final long serialVersionUID = -1190930869038557992L; + BorderLayout overall = new BorderLayout(); + static Point lastWindowLocation = null; + private Vector<TextImageButtons> hunks = new Vector<TextImageButtons>(); + private Vector<String> names = new Vector<String>(); + private static final int buttonsPerHunk = 1; + private static final int buttonWidth = 72; + private static final int[] buttonHeights = new int[]{16}; + private static final int[] xText = new int[]{22}; + private static final String topImageName = IniFile.override().getIniString("actionsTopGif", Console.message("actt.gif")); + private static final String buttonImageName = IniFile.override().getIniString("actionsButtonGif", "actm.gif"); + private static final String bottomImageName = IniFile.override().getIniString("actionsBottomGif", "actb.gif"); + + ActionDialog(Vector<String> inNames) { + super(Console.getFrame(), null, Console.message("Actions"), false); + String[] hiddenActions = ServerTableManager.instance().getTable("hiddenActions"); + String[] actionAliases = ServerTableManager.instance().getTable("actionAliases"); + if (IniFile.gamma().getIniInt("HideActions", 1) == 0) { + hiddenActions = (String[])null; + } + + this.names = new Vector<String>(); + + for (int i = 0; i < inNames.size(); i++) { + boolean hide = false; + if (hiddenActions != null) { + String inStr = inNames.elementAt(i); + inStr = inStr.toLowerCase(); + + for (int j = 0; j < hiddenActions.length; j++) { + if (inStr.equals(hiddenActions[j])) { + hide = true; + } + } + } + + if (!hide) { + String prettyName = inNames.elementAt(i); + if (actionAliases != null) { + String var11 = prettyName.toLowerCase(); + + for (int jx = 0; jx < actionAliases.length; jx += 2) { + if (var11.equals(actionAliases[jx])) { + prettyName = actionAliases[jx + 1]; + } + } + } + + this.names.addElement(upperFirst(prettyName)); + } + } + + this.setResizable(false); + this.setAlignment(2); + this.setLayout(this.overall); + this.ready(); + } + + @Override + protected boolean done(boolean confirmed) { + ActionsPart.showDialog = false; + lastWindowLocation = this.getLocation(); + return super.done(confirmed); + } + + private static String upperFirst(String text) { + String ret = text.substring(0, 1).toUpperCase(); + if (text.length() > 1) { + ret = ret + text.substring(1); + } + + return ret.replace('_', ' '); + } + + @Override + public synchronized Object imageButtonsCallback(Component who, int which) { + int whichHunk = this.hunks.indexOf(who); + if (whichHunk == -1) { + return null; + } else { + Console.wake(); + ActionsPart.actionToPerform = whichHunk * 1 + which; + return null; + } + } + + @Override + protected void build() { + int numHunks = (this.names.size() + 1 - 1) / 1; + int numRows = (numHunks + 1) / 2; + numHunks = numRows * 2; + Panel hunky = new Panel(new GridLayout(numRows, 2)); + hunky.setBackground(Color.black); + int nextNameIndex = 0; + + for (int i = 0; i < numHunks; i++) { + String[] strings = new String[1]; + + for (int s = 0; s < 1; nextNameIndex++) { + if (nextNameIndex < this.names.size()) { + strings[s] = this.names.elementAt(nextNameIndex); + } + + s++; + } + + TextImageButtons hunk = new TextImageButtons(buttonImageName, 72, buttonHeights, xText, strings, this); + this.hunks.addElement(hunk); + hunky.add(hunk); + } + + this.add("North", new ImageCanvas(topImageName)); + this.add("Center", hunky); + this.add("South", new ImageCanvas(bottomImageName)); + } + + @Override + protected void initialSize(int width, int height) { + if (lastWindowLocation == null) { + super.initialSize(width, height); + } else { + this.setLocation(lastWindowLocation); + this.setSize(width, height); + } + } + + @Override + public boolean handleEvent(Event event) { + if (event.id == 1004) { + Console.getFrame().requestFocus(); + return true; + } else { + return super.handleEvent(event); + } + } +} diff --git a/NET/worlds/console/ActionsPart.java b/NET/worlds/console/ActionsPart.java new file mode 100644 index 0000000..aed4c7c --- /dev/null +++ b/NET/worlds/console/ActionsPart.java @@ -0,0 +1,122 @@ +package NET.worlds.console; + +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.InventoryAction; +import NET.worlds.scape.InventoryItem; +import NET.worlds.scape.InventoryManager; +import NET.worlds.scape.Pilot; +import java.awt.Container; +import java.awt.Event; +import java.util.Vector; + +public class ActionsPart implements FramePart { + static int actionToPerform = -1; + private Pilot curPilot; + private Vector<String> curAnimations; + private int numPilotAnims; + private static ActionsPart activePart; + private static ActionDialog dialog; + static boolean showDialog; + + public void present() { + showDialog = true; + this.curPilot = null; + } + + @Override + public void activate(Console c, Container f, Console prev) { + } + + @Override + public void deactivate() { + } + + @Override + public boolean action(Event event, Object what) { + return false; + } + + public static boolean listEquals(Vector<String> a, Vector<String> b) { + if (a != null && b != null) { + if (a.size() != b.size()) { + return false; + } else { + int i = a.size(); + + while (--i >= 0) { + Object ao = a.elementAt(i); + Object bo = b.elementAt(i); + if (ao == null || bo == null) { + if (ao != null || bo != null) { + return false; + } + } else if (!ao.equals(bo)) { + return false; + } + } + + return true; + } + } else { + return a == null == (b == null); + } + } + + public static void updateActionDialog() { + if (activePart != null && dialog != null && showDialog && dialog.isVisible()) { + Main.register(new MainCallback() { + @Override + public void mainCallback() { + ActionsPart.activePart.regenActionDialog(); + Main.unregister(this); + } + }); + } + } + + public void regenActionDialog() { + Vector<String> newAnimations = this.curPilot.getAnimationList(); + this.numPilotAnims = newAnimations.size(); + Vector<InventoryItem> specials = InventoryManager.getInventoryManager().getInventoryActionList(); + + for (int i = 0; i < specials.size(); i++) { + InventoryAction act = (InventoryAction)specials.elementAt(i); + newAnimations.addElement(act.getItemName()); + } + + if (dialog != null) { + boolean showWas = showDialog; + if (showWas && dialog.isVisible() && listEquals(newAnimations, this.curAnimations)) { + return; + } + + dialog.done(true); + showDialog = showWas; + } + + this.curAnimations = newAnimations; + if (showDialog) { + dialog = new ActionDialog(this.curAnimations); + } + } + + @Override + public synchronized boolean handle(FrameEvent f) { + Pilot pilot = Pilot.getActive(); + if (pilot != this.curPilot) { + this.curPilot = pilot; + activePart = this; + this.regenActionDialog(); + } else if (actionToPerform != -1 && actionToPerform < this.curAnimations.size()) { + String act = this.curAnimations.elementAt(actionToPerform); + if (actionToPerform < this.numPilotAnims) { + pilot.animate(act); + } else { + InventoryManager.getInventoryManager().doInventoryAction(act); + } + } + + actionToPerform = -1; + return true; + } +} diff --git a/NET/worlds/console/ActiveX.java b/NET/worlds/console/ActiveX.java new file mode 100644 index 0000000..19b59e3 --- /dev/null +++ b/NET/worlds/console/ActiveX.java @@ -0,0 +1,147 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import java.io.IOException; +import java.util.Vector; + +public class ActiveX implements MainCallback, MainTerminalCallback { + private static boolean disabled = IniFile.gamma().getIniInt("DISABLEACTIVEX", 0) != 0; + private static ActiveX _instance; + private static int _references; + private static Vector<IUnknown> _referrers = new Vector<IUnknown>(); + private static int _serverLocks; + private static int _activeComponents; + private static int _debugLevel = IniFile.gamma().getIniInt("oledebug", 0); + public int _shutdownCounter = 0; + + static { + if (_debugLevel > 0) { + System.out.println("OLE DEBUGGING LEVEL = " + _debugLevel); + } + } + + public static int getDebugLevel() { + return _debugLevel; + } + + public static ActiveX getInstance() { + if (_instance == null) { + _instance = new ActiveX(); + } + + return _instance; + } + + private ActiveX() { + Main.register(this); + } + + @Override + public void mainCallback() { + this.winProc(); + } + + @Override + public void terminalCallback() { + assert this == _instance; + + if (_serverLocks <= 0 && _activeComponents <= 0) { + synchronized (this) { + assert _references == _referrers.size(); + + while (_references > 0) { + for (int i = _referrers.size() - 1; i >= 0; i--) { + IUnknown pUnk = _referrers.elementAt(i); + + try { + pUnk.Release(); + } catch (OLEInvalidObjectException var5) { + var5.printStackTrace(System.out); + System.out.println("ActiveX: misbehaved object detected: " + pUnk); + _referrers.removeElementAt(i); + } + } + + if (_referrers.size() > 0) { + System.out.println("ActiveX: bad referrers found:"); + + for (int i = _referrers.size() - 1; i >= 0; i--) { + IUnknown pUnk = _referrers.elementAt(i); + System.out.println("\t" + pUnk); + } + } + } + + assert _references == 0; + + Main.unregister(this); + } + } else { + this._shutdownCounter++; + if (this._shutdownCounter == 10) { + this._shutdownCounter = 0; + System.out.println("Shutdown ignored: _serverLocks = " + _serverLocks + ", _activeComponents = " + _activeComponents); + Exception e = new Exception(); + e.printStackTrace(System.out); + } + } + } + + public static void init(IUnknown referrer) throws IOException { + synchronized (getInstance()) { + assert !_referrers.contains(referrer); + + if (_references == 0) { + initActiveX(); + } + + _references++; + _referrers.addElement(referrer); + if ((_debugLevel & 1) > 0) { + System.out.println("ActiveX.init() - refCnt = " + _references); + } + } + } + + public static void uninit(IUnknown referrer) { + synchronized (getInstance()) { + assert _references > 0; + + assert _referrers.contains(referrer); + + _references--; + if (_references == 0) { + uninitActiveX(); + } + + _referrers.removeElement(referrer); + if ((_debugLevel & 1) > 0) { + System.out.println("ActiveX.uninit() - refCnt = " + _references); + } + } + } + + public static synchronized void incServerLocks(int amt) { + _serverLocks += amt; + + assert _serverLocks >= 0; + } + + public static synchronized void incActiveComponents(int amt) { + _activeComponents += amt; + + assert _activeComponents >= 0; + } + + private static native void initActiveX() throws IOException; + + private static native void uninitActiveX(); + + public static native int getClassFClsID(String var0, String var1) throws IOException; + + public static native int getClassFProgID(String var0, String var1) throws IOException; + + private static native int getClass(int var0, String var1) throws IOException; + + private native void winProc(); +} diff --git a/NET/worlds/console/AdBanner.java b/NET/worlds/console/AdBanner.java new file mode 100644 index 0000000..c4e8e63 --- /dev/null +++ b/NET/worlds/console/AdBanner.java @@ -0,0 +1,37 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; + +public class AdBanner { + private WebControl wc = null; + + public AdBanner(int width, int height, String url) { + if (IniFile.gamma().getIniInt("NoAdBanners", 0) != 1) { + Console c = Console.getActive(); + if (c != null && c instanceof DefaultConsole) { + DefaultConsole dc = (DefaultConsole)c; + + try { + RenderCanvas canvas = dc.getRender(); + if (canvas == null) { + return; + } + + this.wc = new WebControl(canvas, width, height, false, true, true); + this.wc.activate(); + this.wc.setURL(url); + } catch (NoWebControlException var7) { + System.out.println("Error creating IE control; " + var7.toString()); + } + } + } + } + + public void detach() { + if (this.wc != null) { + this.wc.detach(); + } + + this.wc = null; + } +} diff --git a/NET/worlds/console/AdPart.java b/NET/worlds/console/AdPart.java new file mode 100644 index 0000000..bf7c02e --- /dev/null +++ b/NET/worlds/console/AdPart.java @@ -0,0 +1,221 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.core.Std; +import NET.worlds.network.URL; +import NET.worlds.scape.BGLoaded; +import NET.worlds.scape.BackgroundLoader; +import NET.worlds.scape.Camera; +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.LoadedURLSelf; +import NET.worlds.scape.Material; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Rect; +import NET.worlds.scape.Room; +import NET.worlds.scape.SendURLAction; +import NET.worlds.scape.SuperRoot; +import NET.worlds.scape.Transform; +import NET.worlds.scape.URLSelf; +import NET.worlds.scape.WObject; +import NET.worlds.scape.World; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Point; +import java.io.File; +import java.text.MessageFormat; + +public class AdPart extends RenderCanvas implements LoadedURLSelf, BGLoaded { + private static final long serialVersionUID = 4290496811864911807L; + private static World world; + private static Room room; + private static Material[] faces = new Material[4]; + private static WObject cube; + private static Transform cubeStart; + private float angle; + private int currentFace = -1; + private int lastAd = -1; + private boolean lastAdIsRemote = false; + private boolean initialized; + URL image0; + int nextAdNumber; + int nextLoadTime; + int lastFrame; + static boolean cycleAds = IniFile.gamma().getIniInt("CYCLEADS", 1) == 1; + + public AdPart(URL defaultImage) { + super(new Dimension(130, 130)); + this.image0 = defaultImage; + } + + private void init() { + if (!this.initialized) { + if (world == null) { + World.load(URL.make("home:ad.world"), this, true); + } else { + this.initCamera(); + } + } + } + + private void initCamera() { + this.setCamera(new Camera()); + room.add(this.getCamera()); + this.getCamera().moveTo(room.getDefaultPosition()).spin(room.getDefaultOrientationAxis(), room.getDefaultOrientation()); + } + + @Override + public synchronized void loadedURLSelf(URLSelf o, URL url, String err) { + if (world != null) { + this.initCamera(); + } else if (o == null) { + Object[] arguments = new Object[]{new String("" + url)}; + Console.println(MessageFormat.format(Console.message("Error-ad"), arguments)); + } else { + world = (World)o; + room = world.getRoom(world.getDefaultRoomName()); + this.initCamera(); + cube = (WObject)SuperRoot.nameSearch(room.getContents(), "Cube"); + if (cube != null) { + cubeStart = cube.getTransform(); + + for (int i = 0; i < 4; i++) { + Rect r = (Rect)SuperRoot.nameSearch(cube.getContents(), "Rect" + (i + 1)); + if (r != null) { + faces[i] = r.getMaterial(); + } + } + } + } + } + + private String getAdBaseURL() { + World world = Pilot.getActiveWorld(); + return world == null ? "ads/ad" : world.getAdCubeBaseURL(); + } + + @Override + public boolean action(Event event, Object what) { + return false; + } + + @Override + public boolean mouseDown(Event e, int x, int y) { + World w = Pilot.getActiveWorld(); + if (w == null || !w.getHasClickableAdCube()) { + return false; + } else if ((e.modifiers & 12) != 0) { + return false; + } else { + if (this.nextAdNumber > 1 && this.getAdBaseURL() != null) { + new SendURLAction(this.getAdBaseURL() + (this.nextAdNumber - 1) + ".html").startBrowser(); + } else { + new SendURLAction(w.getDefaultAdCubeURL()).startBrowser(); + } + + return true; + } + } + + @Override + public Object asyncBackgroundLoad(String localName, URL remoteURL) { + return localName; + } + + @Override + public boolean syncBackgroundLoad(Object obj, URL remoteURL) { + String localName = (String)obj; + if (remoteURL != null != this.lastAdIsRemote) { + this.lastAd = -1; + } + + this.lastAdIsRemote = remoteURL != null; + if (localName != null && new File(localName).exists()) { + remoteURL = URL.make(localName); + } else { + this.lastAd = this.nextAdNumber; + this.nextAdNumber = 0; + remoteURL = this.image0; + } + + if (++this.currentFace > 3) { + this.currentFace = 0; + } + + Material m = faces[this.currentFace]; + if (m != null) { + m.loadTexture(remoteURL); + } + + if (++this.nextAdNumber == this.lastAd) { + this.nextAdNumber = 0; + } + + this.nextLoadTime = Std.getFastTime() + 10000; + return false; + } + + @Override + public Room getBackgroundLoadRoom() { + return null; + } + + @Override + public synchronized boolean handle(FrameEvent f) { + if (this.getCamera() != null && cube != null) { + int now = Std.getRealTime(); + if (now >= this.nextLoadTime) { + if (this.nextAdNumber == 0) { + this.syncBackgroundLoad(null, null); + } else if (cycleAds) { + String extension = ".cmp"; + World w = Pilot.getActiveWorld(); + if (w != null && w.getAdCubeFormatIsGif()) { + extension = ".gif"; + } + + String name = this.getAdBaseURL() + this.nextAdNumber + extension; + BackgroundLoader.get(this, URL.make(name)); + this.nextLoadTime = now + 10000; + } + } else { + float targetAngle = (float) (Math.PI / 2) * this.currentFace; + if (targetAngle != this.angle) { + int duration = now - this.lastFrame; + float rot = (float) (Math.PI / 4) * (duration / 1000.0F); + if (targetAngle == 0.0F) { + targetAngle = (float) (Math.PI * 2); + } + + float dist = targetAngle - this.angle; + if (rot >= dist) { + this.angle = (float) (Math.PI / 2) * this.currentFace; + } else { + this.angle += rot; + } + + cube.setTransform(cubeStart); + cube.spin(0.0F, 0.0F, -1.0F, this.angle * 180.0F / (float) Math.PI); + } + } + + this.lastFrame = now; + if (this.checkForWindow(false)) { + Point pt = this.getLocationOnScreen(); + Dimension dim = this.getSize(); + this.getWindow().reShape(pt.x, pt.y, dim.width, dim.height); + this.getCamera().renderToCanvas(); + } + + return true; + } else { + return true; + } + } + + @Override + public void activate(Console c, Container f, Console prev) { + super.activate(c, f, prev); + this.init(); + } +} diff --git a/NET/worlds/console/AddHandler.java b/NET/worlds/console/AddHandler.java new file mode 100644 index 0000000..ef9287c --- /dev/null +++ b/NET/worlds/console/AddHandler.java @@ -0,0 +1,90 @@ +package NET.worlds.console; + +import NET.worlds.scape.BumpEventTemp; +import NET.worlds.scape.BumpHandler; +import NET.worlds.scape.NoSuchPropertyException; +import NET.worlds.scape.Portal; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Room; +import NET.worlds.scape.Saver; +import NET.worlds.scape.SuperRoot; +import NET.worlds.scape.TooNewException; +import NET.worlds.scape.VectorProperty; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; + +public class AddHandler extends SuperRoot implements BumpHandler { + private Vector<SuperRoot> handlers = new Vector<SuperRoot>(1); + private static Object classCookie = new Object(); + + public AddHandler() { + } + + public AddHandler(SuperRoot newhandler) { + this.handlers.addElement(newhandler); + } + + @Override + public boolean handle(BumpEventTemp e) { + Room sc = ((Portal)e.target).farSide().getRoom(); + + assert sc instanceof Staircase || sc instanceof Stair; + + Enumeration<SuperRoot> enh = this.handlers.elements(); + + while (enh.hasMoreElements()) { + sc.addHandler(enh.nextElement()); + } + + return true; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(2, classCookie); + super.saveState(s); + s.saveVector(this.handlers); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + switch (r.restoreVersion(classCookie)) { + case 1: + super.restoreState(r); + case 0: + if (r.restoreBoolean()) { + this.handlers.addElement((SuperRoot)r.restore()); + } + break; + case 2: + super.restoreState(r); + this.handlers = r.restoreVectorSuperRoot(); + break; + default: + throw new TooNewException(); + } + } + + @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 VectorProperty(this, index, "Handlers to Add"); + } else if (mode == 1) { + ret = this.handlers.clone(); + } else if (mode == 4) { + this.handlers.removeElement(value); + } else if (mode == 3) { + this.handlers.addElement((SuperRoot)value); + } + break; + default: + ret = super.properties(index, offset + 1, mode, value); + } + + return ret; + } +} diff --git a/NET/worlds/console/AddNameDialog.java b/NET/worlds/console/AddNameDialog.java new file mode 100644 index 0000000..79615e1 --- /dev/null +++ b/NET/worlds/console/AddNameDialog.java @@ -0,0 +1,85 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; + +class AddNameDialog extends PolledDialog { + private static final long serialVersionUID = -6679739808485406091L; + private TextField nameField; + private Button okButton = new Button(Console.message("OK")); + private Button cancelButton = new Button(Console.message("Cancel")); + private String newName; + private static Font font = new Font(Console.message("ButtonFont"), 0, 12); + + AddNameDialog(EditNamesDialog parent, String title) { + super(parent, parent, title, true); + this.ready(); + } + + @Override + protected void build() { + this.nameField = new TextField("", 40); + this.nameField.setFont(font); + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.fill = 0; + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 2; + c.gridheight = 1; + this.add(gbag, new Label(Console.message("Name")), c); + c.gridwidth = 0; + c.fill = 2; + this.add(gbag, this.nameField, c); + Panel buttons = new Panel(); + this.okButton.setFont(font); + this.cancelButton.setFont(font); + buttons.add(this.okButton); + buttons.add(this.cancelButton); + c.gridwidth = 0; + c.fill = 0; + this.add(gbag, buttons, c); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.okButton && this.mayConfirm()) { + return this.done(true); + } else { + return target == this.cancelButton ? this.done(false) : false; + } + } + + @Override + public String getName() { + return this.newName; + } + + private boolean mayConfirm() { + return FriendsListPart.isValidUserName(this.newName = this.nameField.getText().trim()); + } + + @Override + public boolean keyDown(Event event, int key) { + if (key == 27) { + return this.done(false); + } else { + return key == 10 && this.mayConfirm() ? this.done(true) : super.keyDown(event, key); + } + } + + @Override + public void show() { + super.show(); + this.nameField.requestFocus(); + this.nameField.selectAll(); + } +} diff --git a/NET/worlds/console/AnimationButton.java b/NET/worlds/console/AnimationButton.java new file mode 100644 index 0000000..22b1aa8 --- /dev/null +++ b/NET/worlds/console/AnimationButton.java @@ -0,0 +1,123 @@ +package NET.worlds.console; + +import NET.worlds.scape.FrameEvent; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Graphics; + +public class AnimationButton extends ImageCanvas implements MainCallback, FramePart, DialogDisabled { + private static final long serialVersionUID = 5605353426438467905L; + private static final int frameInterval = 33; + private String movieName; + private int frameCount; + private int curFrame; + private int width; + private int height; + private boolean playVideoNext; + private int videoHandle = -1; + private boolean isDialogDisabled; + + public AnimationButton(String imageName, int frameCount, String movieName) { + super(imageName); + this.frameCount = frameCount; + this.movieName = movieName; + } + + @Override + public void paint(Graphics g) { + g.clipRect(0, 0, this.width, this.height); + g.drawImage(this.image_, -this.width * this.curFrame, 0, null); + } + + @Override + public Dimension preferredSize() { + Dimension d = super.preferredSize(); + return new Dimension(this.width = d.width / this.frameCount, this.height = d.height); + } + + @Override + public Dimension minimumSize() { + return this.preferredSize(); + } + + @Override + public void mainCallback() { + if (this.videoHandle == -1) { + this.videoHandle = Window.playVideoClip(this, this.movieName); + if (this.videoHandle == -1) { + this.videoHandle = Window.playVideoClip(this, "..\\" + this.movieName); + if (this.videoHandle == -1) { + Main.unregister(this); + } + } + } else if (!Window.isVideoPlaying(this.videoHandle)) { + Main.unregister(this); + this.videoHandle = -1; + this.repaint(); + } + } + + @Override + public boolean mouseDown(Event e, int x, int y) { + if (this.isDialogDisabled) { + return false; + } else { + if (this.playVideoNext) { + Main.register(this); + this.playVideoNext = false; + } else if (this.videoHandle == -1) { + Graphics g = this.getGraphics(); + g.clipRect(0, 0, this.width, this.height); + int nextFrameIncr = this.curFrame == 0 ? 1 : -1; + long startTime = System.currentTimeMillis(); + long frameTime = 0L; + + for (int i = 1; i < this.frameCount; i++) { + this.curFrame += nextFrameIncr; + g.drawImage(this.image_, -this.width * this.curFrame, 0, null); + long elapsedTime = System.currentTimeMillis() - startTime; + frameTime += 33L; + long sleepTime = frameTime - elapsedTime; + if (sleepTime > 0L) { + try { + Thread.sleep(sleepTime); + } catch (InterruptedException var16) { + } + } + } + + if (this.curFrame == this.frameCount - 1) { + this.playVideoNext = true; + } + + g.dispose(); + } + + return true; + } + } + + @Override + public void activate(Console c, Container f, Console prev) { + } + + @Override + public void deactivate() { + } + + @Override + public boolean action(Event event, Object what) { + return false; + } + + @Override + public boolean handle(FrameEvent f) { + return false; + } + + @Override + public void dialogDisable(boolean disable) { + this.isDialogDisabled = disable; + } +} diff --git a/NET/worlds/console/ArmyOfZombies.java b/NET/worlds/console/ArmyOfZombies.java new file mode 100644 index 0000000..5cfb094 --- /dev/null +++ b/NET/worlds/console/ArmyOfZombies.java @@ -0,0 +1,120 @@ +package NET.worlds.console; + +import NET.worlds.scape.DeepEnumeration; +import NET.worlds.scape.Drone; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Point3Temp; +import NET.worlds.scape.Room; +import NET.worlds.scape.SuperRoot; +import NET.worlds.scape.WObject; +import java.util.Enumeration; +import java.util.Hashtable; + +class ArmyOfZombies { + Hashtable<String, Drone> zombies = new Hashtable<String, Drone>(); + private static ArmyOfZombies instance = new ArmyOfZombies(); + + public static ArmyOfZombies instance() { + return instance; + } + + protected ArmyOfZombies() { + } + + public void killZombies() { + Enumeration<Drone> e = this.zombies.elements(); + + while (e.hasMoreElements()) { + Drone id = e.nextElement(); + Enumeration<WObject> en = (Enumeration<WObject>)id.getContents(); + + while (en.hasMoreElements()) { + WObject wob = en.nextElement(); + wob.detach(); + } + + id.detach(); + id.discard(); + } + + this.zombies.clear(); + } + + public void addZombie(Drone id) { + String name = id.getName(); + if (name.charAt(0) == '!') { + name = name.substring(1); + } + + this.zombies.put(name, id); + } + + public void replaceZombie(String name, Drone id) { + Drone oldId = this.get(name); + if (oldId != id) { + this.zombies.remove(name); + this.addZombie(id); + id.makeTag(true); + } + } + + public void killZombie(String name) { + Drone id = this.get(name); + if (id != null) { + this.zombies.remove(name); + id.detach(); + } + } + + public void zombify() { + if (Pilot.getActive() != null) { + if (Pilot.getActive().getRoom() != null) { + if (Pilot.getActive().getRoom().getWorld() != null) { + Enumeration<Object> rooms = Pilot.getActive().getRoom().getWorld().getRooms(); + + while (rooms.hasMoreElements()) { + Room r = (Room)rooms.nextElement(); + if (r != null) { + DeepEnumeration<Object> de = new DeepEnumeration<Object>(); + r.getChildren(de); + + while (de.hasMoreElements()) { + Object o = de.nextElement(); + if (o instanceof Drone) { + Drone d = (Drone)o; + Point3Temp pos = d.getPosition(); + short dir = (short)(-d.getYaw() + 90.0F); + dir = (short)(dir % 360); + + while (dir < 0) { + dir = (short)(dir + 360); + } + + SuperRoot wobj = d.getOwner(); + if (wobj != null) { + Room rm = wobj.getRoom(); + if (rm != null && d.getName() != null) { + BlackBox.getInstance() + .submitEvent(new BBAppearDroneCommand(r.getRoom().toString(), d.getName(), (short)pos.x, (short)pos.y, (short)pos.z, dir)); + if (d.getCurrentURL() != null) { + BlackBox.getInstance().submitEvent(new BBDroneBitmapCommand(d.getName(), d.getCurrentURL().toString())); + } + } + } + } + } + } + } + } + } + } + } + + Drone get(String name) { + if (name.charAt(0) == '!') { + name = name.substring(1); + } + + return this.zombies.get(name); + } +} diff --git a/NET/worlds/console/AttributeList.java b/NET/worlds/console/AttributeList.java new file mode 100644 index 0000000..25292a7 --- /dev/null +++ b/NET/worlds/console/AttributeList.java @@ -0,0 +1,38 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.scape.PropList; +import java.awt.List; +import java.util.Vector; + +class AttributeList extends List { + private static final long serialVersionUID = 4867320900648345562L; + + public AttributeList(int numVisibleRows) { + super(numVisibleRows); + Vector<String> sortOrder = new Vector<String>(); + int numUserPreferences = IniFile.gamma().getIniInt("PropertyOrderCount", -1); + if (numUserPreferences >= 0) { + sortOrder = new Vector<String>(numUserPreferences); + + for (int i = 0; i < numUserPreferences; i++) { + sortOrder.addElement(IniFile.gamma().getIniString("PropertyOrder" + i, "")); + } + } + + for (int idx = 0; idx < sortOrder.size(); idx++) { + String attToAdd = sortOrder.elementAt(idx); + this.add(attToAdd); + } + } + + public void save() { + int numProperties = this.getItemCount(); + PropList.setPreferences(this.getItems()); + IniFile.gamma().setIniInt("PropertyOrderCount", numProperties); + + for (int i = 0; i < numProperties; i++) { + IniFile.gamma().setIniString("PropertyOrder" + i, this.getItem(i)); + } + } +} diff --git a/NET/worlds/console/AttributeSortPanel.java b/NET/worlds/console/AttributeSortPanel.java new file mode 100644 index 0000000..6856e7b --- /dev/null +++ b/NET/worlds/console/AttributeSortPanel.java @@ -0,0 +1,160 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Point; +import java.awt.TextField; + +public class AttributeSortPanel extends Frame implements MainCallback, MainTerminalCallback { + private static final long serialVersionUID = -7230661745931320369L; + private AttributeList list; + private Button addButton = new Button("Add"); + private Button deleteButton = new Button("Delete"); + private Button moveUpButton = new Button("MoveUp"); + private Button moveDownButton = new Button("MoveDown"); + private Button okButton = new Button("Ok"); + private Button cancelButton = new Button("Cancel"); + private Button clearButton = new Button("Clear"); + private TextField attNameField = new TextField(32); + private Label attNameLabel = new Label("Attribute Name: "); + + public AttributeSortPanel(java.awt.Window parent) { + super("Attribute Sorting"); + this.list = new AttributeList(10); + GridBagLayout gbag = new GridBagLayout(); + GridBagConstraints c = new GridBagConstraints(); + this.setLayout(gbag); + this.setBackground(Color.gray); + c.gridx = 1; + c.gridy = 1; + c.gridheight = 7; + c.gridwidth = 3; + c.anchor = 18; + gbag.setConstraints(this.list, c); + this.add(this.list); + c.gridx = 4; + c.gridy = 1; + c.gridwidth = 1; + c.gridheight = 1; + gbag.setConstraints(this.moveUpButton, c); + this.add(this.moveUpButton); + c.gridx = 4; + c.gridy = 2; + c.gridwidth = 1; + c.gridheight = 1; + gbag.setConstraints(this.moveDownButton, c); + this.add(this.moveDownButton); + c.gridx = 4; + c.gridy = 5; + c.gridheight = 1; + c.gridwidth = 3; + gbag.setConstraints(this.attNameLabel, c); + this.add(this.attNameLabel); + c.gridy = 6; + c.gridheight = 1; + c.gridwidth = 3; + gbag.setConstraints(this.attNameField, c); + this.add(this.attNameField); + c.gridx = 7; + c.gridy = 6; + c.gridheight = 1; + c.gridwidth = 1; + gbag.setConstraints(this.addButton, c); + this.add(this.addButton); + c.gridx = 7; + c.gridy = 1; + c.gridwidth = 1; + c.gridheight = 1; + gbag.setConstraints(this.deleteButton, c); + this.add(this.deleteButton); + c.gridx = 7; + c.gridy = 2; + gbag.setConstraints(this.clearButton, c); + this.add(this.clearButton); + c.gridx = 5; + c.gridy = 8; + gbag.setConstraints(this.okButton, c); + this.add(this.okButton); + c.gridx = 7; + gbag.setConstraints(this.cancelButton, c); + this.add(this.cancelButton); + this.pack(); + Point loc = parent.location(); + Dimension size = parent.getSize(); + this.reshape(loc.x + (size.width - 512) / 2, loc.y + (size.height - 240) / 2, 512, 240); + this.show(); + Main.register(this); + } + + @Override + public boolean handleEvent(Event ev) { + switch (ev.id) { + case 201: + this.dispose(); + return true; + default: + return super.handleEvent(ev); + } + } + + @Override + public boolean action(Event e, Object o) { + if (e.target == this.addButton) { + String attToAdd = this.attNameField.getText(); + if (attToAdd != "") { + this.list.add(attToAdd); + } + + this.attNameField.setText(""); + return true; + } else if (e.target == this.deleteButton) { + this.list.remove(this.list.getSelectedIndex()); + return true; + } else if (e.target == this.moveUpButton) { + int index = this.list.getSelectedIndex(); + if (index > 0) { + String toPutBack = this.list.getItem(index - 1); + this.list.remove(index - 1); + this.list.add(toPutBack, index); + } + + return true; + } else if (e.target == this.moveDownButton) { + int index = this.list.getSelectedIndex(); + if (index < this.list.getItemCount()) { + String toPutBack = this.list.getItem(index + 1); + this.list.remove(index + 1); + this.list.add(toPutBack, index); + } + + return true; + } else if (e.target == this.cancelButton) { + this.dispose(); + return true; + } else if (e.target == this.clearButton) { + this.list.removeAll(); + return true; + } else if (e.target == this.okButton) { + this.list.save(); + this.dispose(); + return true; + } else { + return false; + } + } + + @Override + public void mainCallback() { + } + + @Override + public void terminalCallback() { + Main.unregister(this); + } +} diff --git a/NET/worlds/console/AvMenu.java b/NET/worlds/console/AvMenu.java new file mode 100644 index 0000000..e406673 --- /dev/null +++ b/NET/worlds/console/AvMenu.java @@ -0,0 +1,508 @@ +package NET.worlds.console; + +import NET.worlds.network.URL; +import NET.worlds.scape.HoloDrone; +import NET.worlds.scape.InventoryAvatar; +import NET.worlds.scape.InventoryItem; +import NET.worlds.scape.InventoryManager; +import NET.worlds.scape.PosableShape; +import NET.worlds.scape.SelectAvatarAction; +import NET.worlds.scape.WearAction; +import java.awt.Event; +import java.awt.Font; +import java.awt.Menu; +import java.awt.MenuItem; +import java.net.MalformedURLException; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.StringTokenizer; +import java.util.Vector; + +public class AvMenu extends Menu implements AvatarDialogCallback { + private static final long serialVersionUID = 333613242466644876L; + DefaultConsole defcon; + Menu articMenuAF; + Menu articMenuGO; + Menu articMenuPZ; + Menu specialGuestMenu; + public MenuItem customize; + static AvatarDialog avDialog; + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + Vector<AvMenuItem> articulatedAvatarItemsAF; + Vector<AvMenuItem> articulatedAvatarItemsGO; + Vector<AvMenuItem> articulatedAvatarItemsPZ; + Vector<AvMenuItem> holographicAvatarItemsAL; + Vector<AvMenuItem> holographicAvatarItemsMZ; + Vector<AvMenuItem> specialGuestAvatarItems; + private static Vector<String> parts = new Vector<String>(); + private static Vector<String> sizes = new Vector<String>(); + private static Vector<String> colors = new Vector<String>(); + private static Vector<String> faceTypes = new Vector<String>(); + private static Vector<String> headTypes = new Vector<String>(); + + static { + parts.addElement(Console.message("Head")); + parts.addElement(Console.message("Head-size")); + parts.addElement(Console.message("Face")); + parts.addElement(Console.message("Hair")); + parts.addElement(Console.message("Skin")); + parts.addElement(Console.message("Shirt")); + parts.addElement(Console.message("Coat")); + parts.addElement(Console.message("Dress")); + parts.addElement(Console.message("Pants")); + parts.addElement(Console.message("Left-glove")); + parts.addElement(Console.message("Right-glove")); + parts.addElement(Console.message("Left-shoe")); + parts.addElement(Console.message("Right-shoe")); + sizes.addElement(Console.message("m30")); + sizes.addElement(Console.message("m20")); + sizes.addElement(Console.message("m10")); + sizes.addElement(Console.message("standard")); + sizes.addElement(Console.message("p10")); + sizes.addElement(Console.message("p20")); + sizes.addElement(Console.message("p30")); + colors.addElement(Console.message("Original")); + colors.addElement(Console.message("Black")); + colors.addElement(Console.message("Blue")); + colors.addElement(Console.message("Tan")); + colors.addElement(Console.message("Red-orange")); + colors.addElement(Console.message("Pale-pink")); + colors.addElement(Console.message("Bright-green")); + colors.addElement(Console.message("Green")); + colors.addElement(Console.message("Dark-blue")); + colors.addElement(Console.message("Blue-purple")); + colors.addElement(Console.message("Light-blue")); + colors.addElement(Console.message("Dark-pink")); + colors.addElement(Console.message("Light-green")); + colors.addElement(Console.message("Pale-orange")); + colors.addElement(Console.message("Dark-grey")); + colors.addElement(Console.message("Orange")); + colors.addElement(Console.message("Pink")); + colors.addElement(Console.message("Purple")); + colors.addElement(Console.message("Red")); + colors.addElement(Console.message("Burgundy")); + colors.addElement(Console.message("Brown")); + colors.addElement(Console.message("Light-grey")); + colors.addElement(Console.message("Violet")); + colors.addElement(Console.message("White")); + colors.addElement(Console.message("Golden-yellow")); + colors.addElement(Console.message("Medium-yellow")); + colors.addElement(Console.message("Light-yellow")); + headTypes.addElement(Console.message("Original")); + addProperCasedEntries(headTypes, PosableShape.getPermittedNames()); + faceTypes.addElement(Console.message("Original")); + addProperCasedEntries(faceTypes, PosableShape.getFaceNames()); + } + + AvMenu(DefaultConsole d, URL lastPilotRequested) { + super(Console.message("choose-av")); + this.defcon = d; + URL url = URL.getAvatar(); + String curAvatar = ""; + if (lastPilotRequested != null) { + curAvatar = lastPilotRequested.getAbsolute(); + String avaStr = url.getAbsolute(); + if (curAvatar.startsWith(avaStr)) { + curAvatar = curAvatar.substring(avaStr.length()); + } + } + + this.articMenuAF = new Menu(Console.message("Articulated-A-F")); + this.articMenuGO = new Menu(Console.message("Articulated-G-O")); + this.articMenuPZ = new Menu(Console.message("Articulated-P-Z")); + this.articMenuAF.setFont(font); + this.articMenuGO.setFont(font); + this.articMenuPZ.setFont(font); + this.add(this.articMenuAF); + this.add(this.articMenuGO); + this.add(this.articMenuPZ); + this.addAvatars(url, "abcdef", "bod", this.articMenuAF, curAvatar, this.articulatedAvatarItemsAF = new Vector<AvMenuItem>()); + this.addAvatars(url, "ghijklmno", "bod", this.articMenuGO, curAvatar, this.articulatedAvatarItemsGO = new Vector<AvMenuItem>()); + this.addAvatars(url, "0123456789pqrstuvwxyz", "bod", this.articMenuPZ, curAvatar, this.articulatedAvatarItemsPZ = new Vector<AvMenuItem>()); + Menu holoMenuAL = new Menu(Console.message("Holographic-A-L")); + Menu holoMenuMZ = new Menu(Console.message("Holographic-M-Z")); + holoMenuAL.setFont(font); + holoMenuMZ.setFont(font); + this.add(holoMenuAL); + this.add(holoMenuMZ); + this.addAvatars("abcdefghijkl", holoMenuAL, curAvatar, this.holographicAvatarItemsAL = new Vector<AvMenuItem>()); + this.addAvatars("0123456789mnopqrstuvwxyz", holoMenuMZ, curAvatar, this.holographicAvatarItemsMZ = new Vector<AvMenuItem>()); + this.specialGuestMenu = null; + this.specialGuestAvatarItems = new Vector<AvMenuItem>(); + this.buildSpecialGuestMenu(); + this.customize = new MenuItem(Console.message("customize-av")); + } + + public void rebuildVIPMenu() { + this.articMenuAF.removeAll(); + this.articulatedAvatarItemsAF.removeAllElements(); + this.articMenuGO.removeAll(); + this.articulatedAvatarItemsGO.removeAllElements(); + this.articMenuPZ.removeAll(); + this.articulatedAvatarItemsPZ.removeAllElements(); + URL url = URL.getAvatar(); + this.addAvatars(url, "abcdef", "bod", this.articMenuAF, null, this.articulatedAvatarItemsAF); + this.addAvatars(url, "ghijklmno", "bod", this.articMenuGO, null, this.articulatedAvatarItemsGO); + this.addAvatars(url, "0123456789pqrstuvwxyz", "bod", this.articMenuPZ, null, this.articulatedAvatarItemsPZ); + } + + public void buildSpecialGuestMenu() { + Vector<InventoryItem> specialGuests = InventoryManager.getInventoryManager().getInventoryAvatars(); + if (specialGuests != null && specialGuests.size() > 0) { + if (this.specialGuestMenu != null) { + this.specialGuestMenu.removeAll(); + this.specialGuestAvatarItems.removeAllElements(); + } else { + this.specialGuestMenu = new Menu(Console.message("special-av")); + this.add(this.specialGuestMenu); + } + + Enumeration<InventoryItem> e = specialGuests.elements(); + + while (e.hasMoreElements()) { + InventoryAvatar invItem = (InventoryAvatar)e.nextElement(); + String fullName = invItem.getItemName(); + StringTokenizer tok = new StringTokenizer(fullName); + if (tok.countTokens() < 1) { + System.out.println("ERROR: Special avatar inventory item " + fullName + " does not conform to the form \"<name> avatar\""); + } else { + String finalName = ""; + String raw = tok.nextToken(); + if (raw.length() > 1) { + finalName = raw.substring(0, 1).toUpperCase() + raw.substring(1); + AvMenuItem item = new AvMenuItem(finalName, false); + item.intAvatar = "_vv" + raw + ".rwg"; + this.specialGuestAvatarItems.addElement(item); + this.specialGuestMenu.add(item); + } + } + } + } + } + + private void addAvatars(URL url, String initChar, String ext, Menu menu, String curAvatar, Vector<AvMenuItem> menuItems) { + if (curAvatar != null) { + curAvatar = SelectAvatarAction.getPrettyAvatarName(curAvatar); + } + + Vector<String> names = PosableShape.getPermittedNames(); + Vector<AvMenuItem> menuItemList = new Vector<AvMenuItem>(); + int count = names.size(); + + for (int i = 0; i < count; i++) { + String name = names.elementAt(i); + if (!name.substring(0, 1).equals("_")) { + String properName = SelectAvatarAction.getPrettyAvatarName(name); + if (initChar.indexOf(properName.toLowerCase().substring(0, 1)) >= 0) { + AvMenuItem item = new AvMenuItem(properName, false); + item.intAvatar = AvMenuItem.avify(name, ".rwg"); + item.setFont(font); + menuItemList.addElement(item); + } + } + } + + try { + this.SortMenu(menuItemList, menu, menuItems); + } catch (NoClassDefFoundError var14) { + count = menuItemList.size(); + + for (int ix = 0; ix < count; ix++) { + AvMenuItem item = menuItemList.elementAt(ix); + menuItems.addElement(item); + menu.add(item); + } + } + } + + private void SortMenu(Vector<AvMenuItem> menuItemList, Menu menu, Vector<AvMenuItem> menuItems) throws NoClassDefFoundError { + Vector<AvMenuItemSortable> sortableArray = new Vector<AvMenuItemSortable>(); + int count = menuItemList.size(); + + for (int i = 0; i < count; i++) { + AvMenuItem item = menuItemList.elementAt(i); + sortableArray.add(new AvMenuItemSortable(item)); + } + + Object[] itemList = sortableArray.toArray(); + Arrays.sort(itemList); + count = itemList.length; + + for (int i = 0; i < count; i++) { + AvMenuItem item = ((AvMenuItemSortable)itemList[i]).menuItem; + menuItems.addElement(item); + menu.add(item); + } + } + + private void addAvatars(String initChar, Menu menu, String curAvatar, Vector<AvMenuItem> menuItems) { + curAvatar = SelectAvatarAction.getPrettyAvatarName(curAvatar); + String[] list = HoloDrone.getPermittedList(); + Vector<AvMenuItem> menuItemList = new Vector<AvMenuItem>(); + + for (String name : list) { + if (!name.substring(0, 1).equals("_")) { + String properName = SelectAvatarAction.getPrettyAvatarName(name); + if (initChar.indexOf(properName.toLowerCase().substring(0, 1).toLowerCase()) >= 0) { + AvMenuItem item = new AvMenuItem(properName, false); + item.intAvatar = AvMenuItem.avify(name, ".mov"); + item.setFont(font); + menuItemList.addElement(item); + } + } + } + + try { + this.SortMenu(menuItemList, menu, menuItems); + } catch (NoClassDefFoundError var12) { + int var14 = menuItemList.size(); + + for (int i = 0; i < var14; i++) { + AvMenuItem item = menuItemList.elementAt(i); + menuItems.addElement(item); + menu.add(item); + } + } + } + + public boolean action(Event event, Object what) { + if (this.articulatedAvatarItemsAF == null + || !this.articulatedAvatarItemsAF.contains(event.target) + && !this.articulatedAvatarItemsGO.contains(event.target) + && !this.articulatedAvatarItemsPZ.contains(event.target)) { + if (this.holographicAvatarItemsAL == null + || !this.holographicAvatarItemsAL.contains(event.target) && !this.holographicAvatarItemsMZ.contains(event.target)) { + if (event.target == this.customize && this.customize != null) { + if (avDialog != null) { + avDialog.closeWin(); + } + + avDialog = new AvatarDialog(Console.getFrame(), null, Console.message("customize-av"), this); + } else { + if (this.specialGuestAvatarItems == null || !this.specialGuestAvatarItems.contains(event.target)) { + return false; + } + + AvMenuItem item = (AvMenuItem)event.target; + this.changeAvatar(item, "rwg", URL.make(URL.getAvatar(), "_vv" + item.getLabel().toLowerCase() + ".rwg")); + } + } else { + this.changeAvatar((AvMenuItem)event.target, "mov", null); + } + } else { + this.changeAvatar((AvMenuItem)event.target, "rwg", null); + } + + return true; + } + + public void notifyOfChange() { + if (avDialog != null) { + avDialog.setChangeCheck(); + } + } + + @Override + public Vector<String> getChoices(int index) { + switch (index) { + case 0: + return headTypes; + case 1: + return sizes; + case 2: + return faceTypes; + default: + return colors; + } + } + + private static void addProperCasedEntries(Vector<String> dest, Vector<String> source) { + for (int i = 0; i < source.size(); i++) { + String s = source.elementAt(i); + if (s.charAt(0) != '_') { + dest.addElement(s.substring(0, 1).toUpperCase() + s.substring(1)); + } + } + } + + public static void rebuildHeadList() { + headTypes.removeAllElements(); + headTypes.addElement(Console.message("Original")); + addProperCasedEntries(headTypes, PosableShape.getPermittedNames()); + } + + @Override + public Vector<String> getComponents() { + return parts; + } + + public static int findIndex(Vector<String> v, String match) { + int end = v.size(); + + for (int i = 0; i < end; i++) { + String s = v.elementAt(i); + if (s.equalsIgnoreCase(match)) { + return i; + } + } + + return -1; + } + + @Override + public int getCurrentSelection(int index) { + String str = PosableShape.getCurrentAvCustomizable(); + if (str == null) { + return 0; + } else { + int pos = str.indexOf(".", 7); + String bodyType = str.substring(7, pos).toLowerCase(); + int result = -1; + switch (index) { + case 0: + int p = str.lastIndexOf("NS"); + if (p >= 0 && str.charAt(p + 5) == 'G') { + result = findIndex(headTypes, PosableShape.readName(str, p + 6)); + if (result >= 0) { + return result; + } + } + + result = findIndex(headTypes, bodyType); + return result < 0 ? 0 : result; + case 1: + int p = str.lastIndexOf("NS"); + if (p >= 0) { + result = "qhd0DHQ".indexOf(str.charAt(p + 2)); + } + + return result < 0 ? 3 : result; + case 2: + int head = str.lastIndexOf("NS"); + int p = str.lastIndexOf("DgT"); + if (p > head) { + p += 3; + + while (str.charAt(p) >= '0' && str.charAt(p) <= '9') { + p++; + } + + String texName = PosableShape.readName(str, p); + Vector<String> v = faceTypes; + int i = v.size(); + + while (--i >= 1) { + String s = v.elementAt(i); + if (s.regionMatches(true, 0, texName, 0, s.length())) { + result = i; + break; + } + } + + if (result < 0) { + result = findIndex(faceTypes, bodyType); + } + + if (result > 0 && faceTypes.elementAt(result).equals(headTypes.elementAt(this.getCurrentSelection(0)))) { + result = 0; + } + } else { + result = 0; + } + + return result < 0 ? 0 : result; + default: + int p = PosableShape.getMatPosition(str, "fabcdeOVKY".charAt(index - 3)); + if (p >= 0 && str.charAt(p) == 'C' && str.charAt(p + 1) == '_') { + char letter = str.charAt(p + 2); + if (letter >= 'A' && letter <= 'Z') { + result = 1 + (letter - 'A'); + } + } + + return result < 0 ? 0 : result; + } + } + } + + @Override + public void setCurrentSelection(int index, int choice) { + String str = PosableShape.getCurrentAvCustomizable(); + if (str != null) { + String val; + char limb; + if (index >= 3) { + limb = "fabcdeOVKY".charAt(index - 3); + + assert choice >= 0; + + assert choice <= PosableShape.colorTable.length; + + val = choice == 0 ? null : "C_" + (char)(65 + choice - 1); + } else if (index == 1) { + char scale = "qhd0DHQ".charAt(choice); + char[] scaleStr = new char[]{scale, scale, scale}; + limb = 'Q'; + val = new String(scaleStr); + } else { + limb = (char)(index == 0 ? 72 : 69); + Vector<String> choices = index == 0 ? headTypes : faceTypes; + val = choice == 0 ? null : choices.elementAt(choice).toLowerCase(); + } + + WearAction.setAvLimb(limb, val); + } + } + + private void changeAvatar(AvMenuItem item, String ext, URL url) { + if (url == null) { + try { + url = new URL(URL.getAvatar(), item.intAvatar); + } catch (MalformedURLException var5) { + Console.println(Console.message("invalid-URL") + " " + var5); + return; + } + } + + this.defcon.setNextAvatar(url, item); + } + + private AvMenuItem findAvatar(Vector<AvMenuItem> items, String name) { + if (items != null) { + int count = items.size(); + + for (int i = 0; i < count; i++) { + AvMenuItem item = items.elementAt(i); + if (item.getLabel().equals(name)) { + return item; + } + } + } + + return null; + } + + public AvMenuItem findMenuItem(URL url) { + String prefix = URL.getAvatar().getAbsolute(); + String name = url.getAbsolute().substring(prefix.length()); + String pname = SelectAvatarAction.getPrettyAvatarName(name); + String suffix = name.substring(name.lastIndexOf(46) + 1); + AvMenuItem item; + return ( + !suffix.equalsIgnoreCase("rwg") + || this.articulatedAvatarItemsAF == null + || (item = this.findAvatar(this.articulatedAvatarItemsAF, pname)) == null + ) + && (item = this.findAvatar(this.articulatedAvatarItemsGO, pname)) == null + && (item = this.findAvatar(this.articulatedAvatarItemsPZ, pname)) == null + && (item = this.findAvatar(this.specialGuestAvatarItems, pname)) == null + && ( + !suffix.equalsIgnoreCase("mov") + || this.holographicAvatarItemsAL == null + || (item = this.findAvatar(this.holographicAvatarItemsAL, pname)) == null + && (item = this.findAvatar(this.holographicAvatarItemsMZ, pname)) == null + ) + ? null + : item; + } +} diff --git a/NET/worlds/console/AvMenuItem.java b/NET/worlds/console/AvMenuItem.java new file mode 100644 index 0000000..2be2470 --- /dev/null +++ b/NET/worlds/console/AvMenuItem.java @@ -0,0 +1,19 @@ +package NET.worlds.console; + +import java.awt.CheckboxMenuItem; + +class AvMenuItem extends CheckboxMenuItem { + private static final long serialVersionUID = 8358406033091883856L; + public String intAvatar; + public String prettyAvatar; + + AvMenuItem(String s, boolean b) { + super(s, b); + this.prettyAvatar = s; + } + + public static String avify(String in, String ext) { + int idx = in.indexOf(46); + return idx != -1 ? in.substring(0, idx).toLowerCase() + ext : in.toLowerCase() + ext; + } +} diff --git a/NET/worlds/console/AvMenuItemSortable.java b/NET/worlds/console/AvMenuItemSortable.java new file mode 100644 index 0000000..49cae0e --- /dev/null +++ b/NET/worlds/console/AvMenuItemSortable.java @@ -0,0 +1,15 @@ +package NET.worlds.console; + +class AvMenuItemSortable implements Comparable<Object> { + public AvMenuItem menuItem; + + AvMenuItemSortable(AvMenuItem i) { + this.menuItem = i; + } + + @Override + public int compareTo(Object o) { + AvMenuItemSortable b = (AvMenuItemSortable)o; + return this.menuItem.prettyAvatar.compareTo(b.menuItem.prettyAvatar); + } +} diff --git a/NET/worlds/console/AvatarDialog.java b/NET/worlds/console/AvatarDialog.java new file mode 100644 index 0000000..6e50502 --- /dev/null +++ b/NET/worlds/console/AvatarDialog.java @@ -0,0 +1,164 @@ +package NET.worlds.console; + +import NET.worlds.scape.EventQueue; +import java.awt.Button; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.Point; +import java.util.Vector; + +public class AvatarDialog extends PolledDialog { + private static final long serialVersionUID = 8661992825430619335L; + private Button okButton = new Button(Console.message("Close")); + private AvatarDialogCallback callback; + private Vector<Choice> choices = new Vector<Choice>(); + private Vector<int[]> changes = new Vector<int[]>(); + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + private int checkChanges; + static Point lastWindowLocation = null; + + public AvatarDialog(java.awt.Window parent, DialogReceiver receiver, String title, AvatarDialogCallback callback) { + super(parent, receiver, title, false); + this.callback = callback; + this.setResizable(false); + this.setAlignment(3); + this.ready(); + } + + public void setChangeCheck() { + this.checkChanges = 2; + } + + @Override + protected void build() { + Vector<String> headings = this.callback.getComponents(); + int rows = headings.size(); + Panel top = new Panel(new GridLayout(rows, 2, 2, 2)); + top.setFont(font); + top.setBackground(Color.black); + + for (int i = 0; i < rows; i++) { + Label label = new Label(headings.elementAt(i), 2); + label.setForeground(Color.white); + label.setFont(font); + top.add(label); + Choice choice = new Choice(); + choice.setForeground(Color.white); + choice.setBackground(Color.black); + choice.setFont(font); + top.add(choice); + this.choices.addElement(choice); + Vector<String> items = this.callback.getChoices(i); + int count = items.size(); + + for (int j = 0; j < count; j++) { + choice.add(items.elementAt(j)); + } + + choice.select(this.callback.getCurrentSelection(i)); + } + + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.weightx = 1.0; + c.weighty = 1.0; + c.gridheight = rows; + c.gridwidth = 0; + c.fill = 0; + this.add(gbag, top, c); + Panel bottom = new Panel(); + this.okButton.setFont(bfont); + bottom.add(this.okButton); + bottom.setBackground(Color.black); + c.gridheight = 1; + c.weightx = 0.0; + c.weighty = 0.0; + c.fill = 1; + this.add(gbag, bottom, c); + this.okButton.setBackground(Color.black); + this.okButton.setForeground(Color.white); + } + + @Override + public boolean handleEvent(Event event) { + if (EventQueue.redirectDrivingKeys(event)) { + return true; + } else { + return event.id == 201 ? this.done(false) : super.handleEvent(event); + } + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.okButton) { + return this.done(true); + } else { + int count = this.choices.size(); + + for (int i = 0; i < count; i++) { + Choice choice = this.choices.elementAt(i); + if (target == choice) { + int[] change = new int[]{i, choice.getSelectedIndex()}; + this.changes.addElement(change); + return true; + } + } + + return false; + } + } + + @Override + public boolean done(boolean confirmed) { + lastWindowLocation = this.getLocation(); + return super.done(confirmed); + } + + public void closeWin() { + if (lastWindowLocation == null) { + this.done(true); + } + } + + @Override + protected void initialSize(int width, int height) { + if (lastWindowLocation == null) { + super.initialSize(width, height); + } else { + this.setLocation(lastWindowLocation); + lastWindowLocation = null; + this.setSize(width, height); + } + } + + @Override + protected void activeCallback() { + if (this.checkChanges > 0 && --this.checkChanges == 0) { + for (int i = 0; i < this.choices.size(); i++) { + this.choices.elementAt(i).select(this.callback.getCurrentSelection(i)); + } + } + + while (this.changes.size() != 0) { + int[] change = this.changes.elementAt(0); + this.callback.setCurrentSelection(change[0], change[1]); + this.checkChanges = 1; + this.changes.removeElementAt(0); + } + } + + @Override + public boolean keyDown(Event event, int key) { + return key == 27 ? this.done(false) : super.keyDown(event, key); + } +} diff --git a/NET/worlds/console/AvatarDialogCallback.java b/NET/worlds/console/AvatarDialogCallback.java new file mode 100644 index 0000000..03efa25 --- /dev/null +++ b/NET/worlds/console/AvatarDialogCallback.java @@ -0,0 +1,13 @@ +package NET.worlds.console; + +import java.util.Vector; + +public interface AvatarDialogCallback { + Vector<String> getComponents(); + + Vector<String> getChoices(int var1); + + int getCurrentSelection(int var1); + + void setCurrentSelection(int var1, int var2); +} diff --git a/NET/worlds/console/AvatarDialogTest.java b/NET/worlds/console/AvatarDialogTest.java new file mode 100644 index 0000000..4587c87 --- /dev/null +++ b/NET/worlds/console/AvatarDialogTest.java @@ -0,0 +1,43 @@ +package NET.worlds.console; + +import java.util.Vector; + +public class AvatarDialogTest implements AvatarDialogCallback { + private static final String[] components = new String[]{"Color", "Weather", "Height", "Shape"}; + private static final String[] colors = new String[]{"Red", "Orange", "Yellow", "Green", "Blue", "Violet"}; + private static final String[] weather = new String[]{"Sunny", "Cloudy", "Raining", "Snowing"}; + private static final String[] heights = new String[]{"Short", "Medium", "Tall"}; + private static final String[] shapes = new String[]{"Circle", "Rectangle", "Triangle"}; + private static final String[][] items = new String[][]{colors, weather, heights, shapes}; + private static int[] settings = new int[components.length]; + + @Override + public Vector<String> getComponents() { + return stringsToVector(components); + } + + @Override + public Vector<String> getChoices(int index) { + return stringsToVector(items[index]); + } + + @Override + public int getCurrentSelection(int index) { + return settings[index]; + } + + @Override + public void setCurrentSelection(int index, int choice) { + settings[index] = choice; + } + + private static Vector<String> stringsToVector(String[] strings) { + Vector<String> v = new Vector<String>(); + + for (int i = 0; i < strings.length; i++) { + v.addElement(strings[i]); + } + + return v; + } +} diff --git a/NET/worlds/console/BBAnimateDroneCommand.java b/NET/worlds/console/BBAnimateDroneCommand.java new file mode 100644 index 0000000..347edfb --- /dev/null +++ b/NET/worlds/console/BBAnimateDroneCommand.java @@ -0,0 +1,54 @@ +package NET.worlds.console; + +import NET.worlds.scape.Drone; +import NET.worlds.scape.Pilot; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class BBAnimateDroneCommand extends BlackBoxCommand { + private String animation; + private String droneName; + + public BBAnimateDroneCommand() { + this.commandType = 9; + } + + public BBAnimateDroneCommand(String drone, String cmd) { + this(); + this.animation = new String(cmd); + this.droneName = new String(drone); + } + + @Override + public boolean execute() { + if (this.droneName.equals("@Pilot")) { + Pilot p = Pilot.getActive(); + if (p != null) { + p.animate(this.animation); + } + } else { + Drone d = ArmyOfZombies.instance().get(this.droneName); + if (d != null) { + d.animate(this.animation); + } + } + + this.doCallback(true); + return true; + } + + @Override + public void save(DataOutputStream dos) throws IOException { + super.save(dos); + dos.writeUTF(this.animation); + dos.writeUTF(this.droneName); + } + + @Override + public void load(DataInputStream dis) throws IOException { + super.load(dis); + this.animation = new String(dis.readUTF()); + this.droneName = new String(dis.readUTF()); + } +} diff --git a/NET/worlds/console/BBAppearDroneCommand.java b/NET/worlds/console/BBAppearDroneCommand.java new file mode 100644 index 0000000..1a12af4 --- /dev/null +++ b/NET/worlds/console/BBAppearDroneCommand.java @@ -0,0 +1,70 @@ +package NET.worlds.console; + +import NET.worlds.scape.HoloDrone; +import NET.worlds.scape.Room; +import NET.worlds.scape.World; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class BBAppearDroneCommand extends BlackBoxCommand { + private short x; + private short y; + private short z; + private short dir; + private String room; + private String name; + + public BBAppearDroneCommand(String roomName, String pName, short px, short py, short pz, short pdir) { + this(); + this.x = px; + this.y = py; + this.z = pz; + this.dir = pdir; + this.room = new String(roomName); + this.name = new String(pName); + } + + public BBAppearDroneCommand() { + this.commandType = 5; + } + + @Override + public boolean execute() { + HoloDrone d = new HoloDrone(null, null); + d.setName(this.name); + Room r = World.findRoomByName(this.room); + if (r != null) { + d.appear(r, this.x, this.y, this.z, this.dir); + d.makeTag(true); + ArmyOfZombies.instance().addZombie(d); + this.doCallback(true); + } else { + this.doCallback(false); + } + + return true; + } + + @Override + public void save(DataOutputStream dos) throws IOException { + super.save(dos); + dos.writeShort(this.x); + dos.writeShort(this.y); + dos.writeShort(this.z); + dos.writeShort(this.dir); + dos.writeUTF(this.room); + dos.writeUTF(this.name); + } + + @Override + public void load(DataInputStream dis) throws IOException { + super.load(dis); + this.x = dis.readShort(); + this.y = dis.readShort(); + this.z = dis.readShort(); + this.dir = dis.readShort(); + this.room = new String(dis.readUTF()); + this.name = new String(dis.readUTF()); + } +} diff --git a/NET/worlds/console/BBChatCommand.java b/NET/worlds/console/BBChatCommand.java new file mode 100644 index 0000000..2fc6c61 --- /dev/null +++ b/NET/worlds/console/BBChatCommand.java @@ -0,0 +1,37 @@ +package NET.worlds.console; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class BBChatCommand extends BlackBoxCommand { + private String chatLine; + + public BBChatCommand(String line) { + this(); + this.chatLine = new String(line); + } + + public BBChatCommand() { + this.commandType = 0; + } + + @Override + public boolean execute() { + Console.println(this.chatLine); + this.doCallback(true); + return true; + } + + @Override + public void save(DataOutputStream dos) throws IOException { + super.save(dos); + dos.writeUTF(this.chatLine); + } + + @Override + public void load(DataInputStream dis) throws IOException { + super.load(dis); + this.chatLine = new String(dis.readUTF()); + } +} diff --git a/NET/worlds/console/BBDisappearDroneCommand.java b/NET/worlds/console/BBDisappearDroneCommand.java new file mode 100644 index 0000000..eb302b7 --- /dev/null +++ b/NET/worlds/console/BBDisappearDroneCommand.java @@ -0,0 +1,37 @@ +package NET.worlds.console; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class BBDisappearDroneCommand extends BlackBoxCommand { + private String name; + + public BBDisappearDroneCommand(String pName) { + this(); + this.name = new String(pName); + } + + public BBDisappearDroneCommand() { + this.commandType = 6; + } + + @Override + public boolean execute() { + ArmyOfZombies.instance().killZombie(this.name); + this.doCallback(true); + return true; + } + + @Override + public void save(DataOutputStream dos) throws IOException { + super.save(dos); + dos.writeUTF(this.name); + } + + @Override + public void load(DataInputStream dis) throws IOException { + super.load(dis); + this.name = new String(dis.readUTF()); + } +} diff --git a/NET/worlds/console/BBDroneBitmapCommand.java b/NET/worlds/console/BBDroneBitmapCommand.java new file mode 100644 index 0000000..48e2412 --- /dev/null +++ b/NET/worlds/console/BBDroneBitmapCommand.java @@ -0,0 +1,55 @@ +package NET.worlds.console; + +import NET.worlds.network.URL; +import NET.worlds.scape.Drone; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class BBDroneBitmapCommand extends BlackBoxCommand { + private String name; + private String bitmap; + + public BBDroneBitmapCommand(String pName, String pBitmap) { + this(); + this.name = new String(pName); + this.bitmap = new String(pBitmap); + } + + public BBDroneBitmapCommand() { + this.commandType = 7; + } + + @Override + public boolean execute() { + Drone id = ArmyOfZombies.instance().get(this.name); + if (id != null) { + Drone newDrone = id.handleVAR_BITMAP(this.bitmap); + ArmyOfZombies.instance().replaceZombie(this.name, newDrone); + } else if (this.name.equals("@Pilot")) { + Console c = Console.getActive(); + if (c != null) { + c.setAvatar(URL.make(this.bitmap)); + } + } else { + System.out.println("Couldn't find drone " + this.name + " for bitmap command."); + } + + this.doCallback(true); + return true; + } + + @Override + public void save(DataOutputStream dos) throws IOException { + super.save(dos); + dos.writeUTF(this.name); + dos.writeUTF(this.bitmap); + } + + @Override + public void load(DataInputStream dis) throws IOException { + super.load(dis); + this.name = new String(dis.readUTF()); + this.bitmap = new String(dis.readUTF()); + } +} diff --git a/NET/worlds/console/BBDroneDeltaPosCommand.java b/NET/worlds/console/BBDroneDeltaPosCommand.java new file mode 100644 index 0000000..09cfdf0 --- /dev/null +++ b/NET/worlds/console/BBDroneDeltaPosCommand.java @@ -0,0 +1,71 @@ +package NET.worlds.console; + +import NET.worlds.scape.Drone; +import NET.worlds.scape.HoloPilot; +import NET.worlds.scape.Pilot; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class BBDroneDeltaPosCommand extends BlackBoxCommand { + private byte dx; + private byte dy; + private byte dyaw; + private String droneID; + + public BBDroneDeltaPosCommand() { + this.commandType = 8; + } + + public BBDroneDeltaPosCommand(String pdroneID, byte pdx, byte pdy, byte pdyaw) { + this(); + this.droneID = pdroneID; + this.dx = pdx; + this.dy = pdy; + this.dyaw = pdyaw; + } + + @Override + public boolean execute() { + Drone id = null; + if (this.droneID.equals("@Pilot")) { + Pilot p = Pilot.getActive(); + if (p != null && p instanceof HoloPilot) { + HoloPilot hp = (HoloPilot)p; + Drone d = hp.getInternalDrone(); + if (d != null && d instanceof Drone) { + id = d; + } + } + } else { + id = ArmyOfZombies.instance().get(this.droneID); + } + + if (id != null) { + id.shortLoc(this.dx, this.dy, this.dyaw); + this.doCallback(true); + return true; + } else { + this.doCallback(true); + return true; + } + } + + @Override + public void save(DataOutputStream dos) throws IOException { + super.save(dos); + dos.writeUTF(this.droneID); + dos.writeByte(this.dx); + dos.writeByte(this.dy); + dos.writeByte(this.dyaw); + } + + @Override + public void load(DataInputStream dis) throws IOException { + super.load(dis); + this.droneID = dis.readUTF(); + this.dx = dis.readByte(); + this.dy = dis.readByte(); + this.dyaw = dis.readByte(); + } +} diff --git a/NET/worlds/console/BBMoveDroneCommand.java b/NET/worlds/console/BBMoveDroneCommand.java new file mode 100644 index 0000000..464bd12 --- /dev/null +++ b/NET/worlds/console/BBMoveDroneCommand.java @@ -0,0 +1,75 @@ +package NET.worlds.console; + +import NET.worlds.scape.Drone; +import NET.worlds.scape.HoloPilot; +import NET.worlds.scape.Pilot; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class BBMoveDroneCommand extends BlackBoxCommand { + private short x; + private short y; + private short z; + private short dir; + private String droneID; + + public BBMoveDroneCommand() { + this.commandType = 3; + } + + public BBMoveDroneCommand(String pdroneID, short px, short py, short pz, short pdir) { + this(); + this.droneID = pdroneID; + this.x = px; + this.y = py; + this.z = pz; + this.dir = pdir; + } + + @Override + public boolean execute() { + Drone id = null; + if (this.droneID.equals("@Pilot")) { + Pilot p = Pilot.getActive(); + if (p != null && p instanceof HoloPilot) { + HoloPilot hp = (HoloPilot)p; + id = hp.getInternalDrone(); + } + } else { + id = ArmyOfZombies.instance().get(this.droneID); + } + + if (id != null) { + short _dir = this.dir; + _dir = (short)(90 - _dir); + _dir = (short)(360 - _dir); + id.longLoc(this.x, this.y, this.z, _dir); + this.doCallback(true); + return true; + } else { + this.doCallback(true); + return true; + } + } + + @Override + public void save(DataOutputStream dos) throws IOException { + super.save(dos); + dos.writeUTF(this.droneID); + dos.writeShort(this.x); + dos.writeShort(this.y); + dos.writeShort(this.z); + dos.writeShort(this.dir); + } + + @Override + public void load(DataInputStream dis) throws IOException { + super.load(dis); + this.droneID = dis.readUTF(); + this.x = dis.readShort(); + this.y = dis.readShort(); + this.z = dis.readShort(); + this.dir = dis.readShort(); + } +} diff --git a/NET/worlds/console/BBTeleportCommand.java b/NET/worlds/console/BBTeleportCommand.java new file mode 100644 index 0000000..620e9c4 --- /dev/null +++ b/NET/worlds/console/BBTeleportCommand.java @@ -0,0 +1,82 @@ +package NET.worlds.console; + +import NET.worlds.scape.Drone; +import NET.worlds.scape.HoloPilot; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Point3Temp; +import NET.worlds.scape.TeleportAction; +import NET.worlds.scape.TeleportStatus; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class BBTeleportCommand extends BlackBoxCommand implements TeleportStatus { + private String location; + + public BBTeleportCommand() { + this.commandType = 1; + } + + public BBTeleportCommand(String pLocation) { + this(); + if (pLocation != null) { + this.location = new String(pLocation); + } + } + + @Override + public boolean execute() { + if (this.location != null) { + TeleportAction.teleport(this.location, this); + } + + return true; + } + + @Override + public void save(DataOutputStream dos) throws IOException { + super.save(dos); + if (this.location == null) { + dos.writeUTF(""); + } else { + dos.writeUTF(this.location); + } + } + + @Override + public void load(DataInputStream dis) throws IOException { + super.load(dis); + this.location = dis.readUTF(); + if (this.location.equals("")) { + this.location = null; + } + } + + @Override + public void teleportStatus(String err, String targetURL) { + Pilot p = Pilot.getActive(); + if (p instanceof HoloPilot) { + HoloPilot hp = (HoloPilot)p; + Drone d = hp.getInternalDrone(); + if (d != null) { + short dir = (short)(-p.getYaw() + 90.0F); + dir = (short)(dir % 360); + + while (dir < 0) { + dir = (short)(dir + 360); + } + + dir = (short)(90 - dir); + dir = (short)(360 - dir); + Point3Temp pos = p.getPosition(); + d.reset((short)pos.x, (short)pos.y, (short)p.getFootHeight(), dir); + } + } + + if (err == null) { + this.doCallback(true); + } else { + this.doCallback(false); + } + } +} diff --git a/NET/worlds/console/BBWObjClickedCommand.java b/NET/worlds/console/BBWObjClickedCommand.java new file mode 100644 index 0000000..e0d93b7 --- /dev/null +++ b/NET/worlds/console/BBWObjClickedCommand.java @@ -0,0 +1,82 @@ +package NET.worlds.console; + +import NET.worlds.scape.DeepEnumeration; +import NET.worlds.scape.MouseDownEvent; +import NET.worlds.scape.MouseDownHandler; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Room; +import NET.worlds.scape.SuperRoot; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public class BBWObjClickedCommand extends BlackBoxCommand { + private String objUrl; + int x; + int y; + char key; + + public BBWObjClickedCommand() { + this.commandType = 4; + } + + public BBWObjClickedCommand(String obj, char pkey, int px, int py) { + this(); + this.objUrl = new String(obj); + this.key = pkey; + this.x = px; + this.y = py; + } + + @Override + public boolean execute() { + MouseDownHandler target = null; + if (Pilot.getActive() == null) { + return false; + } else { + Room r = Pilot.getActive().getRoom(); + if (r == null) { + return false; + } else { + DeepEnumeration de = new DeepEnumeration(); + r.getChildren(de); + + while (de.hasMoreElements()) { + Object o = de.nextElement(); + if (o instanceof MouseDownHandler && ((SuperRoot)o).getName().equals(this.objUrl)) { + target = (MouseDownHandler)o; + break; + } + } + + if (target == null) { + this.doCallback(false); + return false; + } else { + MouseDownEvent e = new MouseDownEvent(0, null, this.key, this.x, this.y); + target.handle(e); + this.doCallback(true); + return true; + } + } + } + } + + @Override + public void save(DataOutputStream dos) throws IOException { + super.save(dos); + dos.writeInt(this.x); + dos.writeInt(this.y); + dos.writeChar(this.key); + dos.writeUTF(this.objUrl); + } + + @Override + public void load(DataInputStream dis) throws IOException { + super.load(dis); + this.x = dis.readInt(); + this.y = dis.readInt(); + this.key = dis.readChar(); + this.objUrl = dis.readUTF(); + } +} diff --git a/NET/worlds/console/BackButton.java b/NET/worlds/console/BackButton.java new file mode 100644 index 0000000..6d5c386 --- /dev/null +++ b/NET/worlds/console/BackButton.java @@ -0,0 +1,11 @@ +package NET.worlds.console; + +import java.awt.Button; + +class BackButton extends Button { + private static final long serialVersionUID = -3040398427896332517L; + + public BackButton(String name) { + super(name); + } +} diff --git a/NET/worlds/console/BlackBox.java b/NET/worlds/console/BlackBox.java new file mode 100644 index 0000000..8ab5868 --- /dev/null +++ b/NET/worlds/console/BlackBox.java @@ -0,0 +1,389 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.core.Std; +import NET.worlds.network.Galaxy; +import NET.worlds.network.URL; +import NET.worlds.scape.Camera; +import NET.worlds.scape.Drone; +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.FrameHandler; +import NET.worlds.scape.HoloPilot; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Postrenderable; +import NET.worlds.scape.Sound; +import NET.worlds.scape.SoundPlayer; +import NET.worlds.scape.WMPSoundPlayer; +import NET.worlds.scape.WavSoundPlayer; +import java.awt.FileDialog; +import java.awt.Frame; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.Enumeration; +import java.util.Properties; +import java.util.Vector; + +public class BlackBox implements BlackBoxCallback, FrameHandler, Postrenderable { + private static BlackBox instance = new BlackBox(); + private boolean disable = IniFile.gamma().getIniInt("disableRecorder", 0) == 1; + private String autoFile = null; + private SoundPlayer autoSound = null; + static final int PLAYING = 0; + static final int RECORDING = 1; + static final int STOPPED = 2; + private int state = 2; + static final int CHATCMD = 0; + static final int TELEPORTCMD = 1; + static final int ACTORLISTCMD = 2; + static final int MOVEDRONECMD = 3; + static final int OBJCLICKEDCMD = 4; + static final int APPEARDRONECMD = 5; + static final int DISAPPEARDRONECMD = 6; + static final int DRONEBITMAPCMD = 7; + static final int DRONEDELTACMD = 8; + static final int ANIMATECMD = 9; + public static final String PilotID = "@Pilot"; + private Vector<BlackBoxCommand> commandList = new Vector<BlackBoxCommand>(); + private int commandIdx; + private long basetime; + static final int NOCMD = 0; + static final int PLAYCMD = 1; + static final int RECCMD = 2; + static final int STOPCMD = 3; + private int pendingCommand = 0; + static final int FILE_VERSION = 1; + + public static BlackBox getInstance() { + return instance; + } + + private BlackBox() { + this.autoFile = IniFile.override().getIniString("AutoPlaybackFile", ""); + if (!this.autoFile.equals("")) { + this.play(); + } else { + this.autoFile = null; + } + + String soundFile = IniFile.override().getIniString("AutoPlaybackSound", ""); + if (!soundFile.equals("")) { + Sound owner = new Sound(URL.make(soundFile)); + if (soundFile.toLowerCase().endsWith(".wav")) { + this.autoSound = new WavSoundPlayer(owner); + } else { + this.autoSound = new WMPSoundPlayer(owner); + } + } + } + + @Override + public void finalize() { + this.stop(); + } + + @Override + public void postrender(Camera cam) { + if (!this.disable) { + if (Std.getSynchronizedTime() % 2 != 0) { + if (this.isPlaying()) { + cam.nDrawText(Console.message("PLAY"), 10, 10, 18, 16711680); + } else if (this.isRecording()) { + cam.nDrawText(Console.message("REC"), 10, 10, 18, 16711680); + } + } + } + } + + public synchronized void record() { + this.pendingCommand = 2; + } + + private boolean doRecord() { + if (this.state != 2) { + this.stop(); + } + + this.commandList.removeAllElements(); + this.basetime = Std.getFastTime(); + String url = ""; + Pilot pilot = Pilot.getActive(); + if (pilot == null) { + return false; + } else { + url = pilot.getURL(); + this.state = 1; + this.submitEvent(new BBTeleportCommand(url)); + URL avatar = Console.getActive().getAvatarName(); + if (avatar != null) { + this.submitEvent(new BBDroneBitmapCommand("@Pilot", avatar.toString())); + } + + ArmyOfZombies.instance().zombify(); + return true; + } + } + + public synchronized void play() { + this.pendingCommand = 1; + } + + public synchronized void play(URL recFile) { + this.autoFile = recFile.unalias(); + this.pendingCommand = 1; + } + + private void doPlay() { + if (this.state != 2) { + this.stop(); + } + + if (this.restore()) { + Galaxy.forceOffline(false); + Console.getActive().setChatname(""); + Pilot p = Pilot.getActive(); + if (p instanceof HoloPilot) { + HoloPilot hp = (HoloPilot)p; + hp.removeSmoothDriver(); + } + + if (this.autoSound != null) { + this.autoSound.start(1); + this.autoSound = null; + } + + this.commandIdx = 0; + this.basetime = Std.getFastTime(); + this.state = 0; + } + } + + @Override + public void commandCompleted(BlackBoxCommand c, boolean ok) { + if (ok) { + this.commandIdx++; + } else { + System.out.println("Failed command!"); + this.stop(); + } + } + + @Override + public boolean handle(FrameEvent e) { + if (this.disable) { + return false; + } else { + switch (this.pendingCommand) { + case 1: + this.doPlay(); + this.pendingCommand = 0; + break; + case 2: + this.doRecord(); + this.pendingCommand = 0; + break; + case 3: + this.doStop(); + this.pendingCommand = 0; + } + + if (this.isPlaying()) { + if (this.commandIdx >= this.commandList.size()) { + this.stop(); + return false; + } + + long elapsedTime = Std.getFastTime() - this.basetime; + BlackBoxCommand c = this.commandList.elementAt(this.commandIdx); + if (c.startTime <= elapsedTime) { + c.execute(this); + } + + Pilot p = Pilot.getActive(); + if (p instanceof HoloPilot) { + HoloPilot hp = (HoloPilot)p; + Drone d = hp.getInternalDrone(); + if (d != null) { + d.interpolate(e.time, 2000, p); + p.setZ(p.getPosition().z + hp.getSmoothDriver().getEyeHeight()); + } + } + } + + return false; + } + } + + public boolean isRecording() { + return this.state == 1; + } + + public boolean isPlaying() { + return this.state == 0; + } + + public void submitEvent(BlackBoxCommand c) { + if (!this.disable) { + if (this.isRecording()) { + c.timestamp(this.basetime); + this.commandList.addElement(c); + } + } + } + + public synchronized void stop() { + this.pendingCommand = 3; + } + + private void doStop() { + if (this.state != 2) { + if (this.isRecording()) { + this.save(); + } + + if (this.isPlaying()) { + ArmyOfZombies.instance().killZombies(); + Pilot p = Pilot.getActive(); + if (p instanceof HoloPilot) { + HoloPilot hp = (HoloPilot)p; + hp.returnSmoothDriver(); + } + + Console c = Console.getActive(); + if (c instanceof DefaultConsole) { + DefaultConsole dc = (DefaultConsole)c; + dc.getGalaxy().localForceOnline(); + dc.getGalaxy().waitForConnection(dc); + } + } + + this.state = 2; + } + } + + private void save() { + Frame parent = Console.getFrame(); + Properties p = System.getProperties(); + String oldDir = p.getProperty("user.dir"); + FileDialog fd = new FileDialog(parent, Console.message("Save-recording"), 1); + fd.setFile("record.rec"); + fd.show(); + String fname = fd.getFile(); + String path = fd.getDirectory(); + p.remove("user.dir"); + p.put("user.dir", oldDir); + System.setProperties(p); + if (fname != null) { + File f = new File(path, fname); + + try { + FileOutputStream fos = new FileOutputStream(f); + DataOutputStream dos = new DataOutputStream(fos); + dos.writeInt(1); + Enumeration<BlackBoxCommand> e = this.commandList.elements(); + + while (e.hasMoreElements()) { + BlackBoxCommand cmd = e.nextElement(); + cmd.save(dos); + } + + dos.close(); + fos.close(); + } catch (Exception var12) { + System.out.println(var12); + } + } + } + + private boolean restore() { + if (this.autoFile != null) { + this.restoreFile(new File(this.autoFile)); + this.autoFile = null; + return true; + } else { + Frame parent = Console.getFrame(); + Properties p = System.getProperties(); + String oldDir = p.getProperty("user.dir"); + FileDialog fd = new FileDialog(parent, Console.message("Load-recording"), 0); + fd.show(); + String filename = fd.getFile(); + String directory = fd.getDirectory(); + p.remove("user.dir"); + p.put("user.dir", oldDir); + System.setProperties(p); + if (filename == null) { + return false; + } else { + File f = new File(directory, filename); + this.restoreFile(f); + return true; + } + } + } + + private void restoreFile(File f) { + this.commandList.removeAllElements(); + + try { + FileInputStream fis = new FileInputStream(f); + DataInputStream dis = new DataInputStream(fis); + int version = dis.readInt(); + if (version != 1) { + Console.println("Invalid recorder file."); + return; + } + + try { + while (true) { + int cmdId = dis.readInt(); + BlackBoxCommand cmd = null; + switch (cmdId) { + case 0: + cmd = new BBChatCommand(); + break; + case 1: + cmd = new BBTeleportCommand(); + break; + case 2: + default: + System.out.println("Error! Unknown command type."); + break; + case 3: + cmd = new BBMoveDroneCommand(); + break; + case 4: + cmd = new BBWObjClickedCommand(); + break; + case 5: + cmd = new BBAppearDroneCommand(); + break; + case 6: + cmd = new BBDisappearDroneCommand(); + break; + case 7: + cmd = new BBDroneBitmapCommand(); + break; + case 8: + cmd = new BBDroneDeltaPosCommand(); + break; + case 9: + cmd = new BBAnimateDroneCommand(); + } + + if (cmd != null) { + cmd.load(dis); + this.commandList.addElement(cmd); + } + } + } catch (EOFException var7) { + dis.close(); + fis.close(); + } + } catch (Exception var8) { + System.out.println(var8); + } + } +} diff --git a/NET/worlds/console/BlackBoxCallback.java b/NET/worlds/console/BlackBoxCallback.java new file mode 100644 index 0000000..37e9c97 --- /dev/null +++ b/NET/worlds/console/BlackBoxCallback.java @@ -0,0 +1,5 @@ +package NET.worlds.console; + +public interface BlackBoxCallback { + void commandCompleted(BlackBoxCommand var1, boolean var2); +} diff --git a/NET/worlds/console/BlackBoxCommand.java b/NET/worlds/console/BlackBoxCommand.java new file mode 100644 index 0000000..bfafc43 --- /dev/null +++ b/NET/worlds/console/BlackBoxCommand.java @@ -0,0 +1,48 @@ +package NET.worlds.console; + +import NET.worlds.core.Std; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +public abstract class BlackBoxCommand { + int commandType; + long startTime; + BlackBoxCallback callback; + boolean waiting = false; + + void timestamp(long basetime) { + this.startTime = Std.getFastTime() - basetime; + } + + public boolean execute(BlackBoxCallback c) { + if (this.waiting) { + return false; + } else { + this.callback = c; + if (c != null) { + this.waiting = true; + } + + return this.execute(); + } + } + + abstract boolean execute(); + + void save(DataOutputStream dos) throws IOException { + dos.writeInt(this.commandType); + dos.writeLong(this.startTime); + } + + void load(DataInputStream dis) throws IOException { + this.startTime = dis.readLong(); + } + + void doCallback(boolean ok) { + if (this.callback != null) { + this.waiting = false; + this.callback.commandCompleted(this, ok); + } + } +} diff --git a/NET/worlds/console/BlockingDialog.java b/NET/worlds/console/BlockingDialog.java new file mode 100644 index 0000000..b32b5b8 --- /dev/null +++ b/NET/worlds/console/BlockingDialog.java @@ -0,0 +1,47 @@ +package NET.worlds.console; + +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class BlockingDialog extends Dialog implements ActionListener { + private static final long serialVersionUID = 8379457384966170912L; + boolean stillWaiting = true; + + public BlockingDialog(Frame parent, String title, boolean modal) { + super(parent, title, modal); + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + BlockingDialog.this.finish(); + } + }); + } + + @Override + public void actionPerformed(ActionEvent e) { + this.finish(); + } + + public void finish() { + this.responded(); + this.setVisible(false); + } + + public synchronized void waitForResponse() { + try { + while (this.stillWaiting) { + this.wait(); + } + } catch (Exception var2) { + } + } + + public synchronized void responded() { + this.stillWaiting = false; + this.notifyAll(); + } +} diff --git a/NET/worlds/console/BookmarkAddDialog.java b/NET/worlds/console/BookmarkAddDialog.java new file mode 100644 index 0000000..f2ad3d2 --- /dev/null +++ b/NET/worlds/console/BookmarkAddDialog.java @@ -0,0 +1,36 @@ +package NET.worlds.console; + +class BookmarkAddDialog implements MainCallback, DialogReceiver { + private java.awt.Window parent; + private DialogReceiver receiver; + private BookmarkEditDialog editor; + + BookmarkAddDialog(java.awt.Window parent, DialogReceiver receiver) { + this.parent = parent; + this.receiver = receiver; + Main.register(this); + } + + @Override + public void mainCallback() { + this.editor = new BookmarkEditDialog( + this.parent, + this, + Console.message("Add-WorldsMark2"), + WorldsMarkPart.getCurrentPositionName(), + Console.message("Add"), + Console.message("Cancel"), + WorldsMarkPart.getCurrentPositionURL(false) + ); + Main.unregister(this); + } + + public BookmarkEditDialog getEditor() { + return this.editor; + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + this.receiver.dialogDone(this, confirmed); + } +} diff --git a/NET/worlds/console/BookmarkDeleteDialog.java b/NET/worlds/console/BookmarkDeleteDialog.java new file mode 100644 index 0000000..c88e8b5 --- /dev/null +++ b/NET/worlds/console/BookmarkDeleteDialog.java @@ -0,0 +1,138 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.List; + +class BookmarkDeleteDialog extends PolledDialog implements DialogReceiver { + private static final long serialVersionUID = 7297733090895837320L; + private List listbox = new List(10); + private Button delButton = new Button(Console.message("Delete")); + private Button cancelButton = new Button(Console.message("Done")); + private WorldsMarkPart bookmarks; + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + + BookmarkDeleteDialog(WorldsMarkPart bookmarks) { + super(Console.getFrame(), null, Console.message("Delete-WorldsMark"), true); + this.bookmarks = bookmarks; + this.ready(); + } + + @Override + protected void build() { + int count = WorldsMarkPart.getBookmarkCount(); + + for (int i = 0; i < count; i++) { + this.listbox.add(WorldsMarkPart.getBookmarkName(i)); + } + + Label caption = new Label(Console.message("Choose-WorldsMark")); + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.fill = 2; + c.gridwidth = 0; + c.gridheight = 1; + c.weightx = 1.0; + c.weighty = 0.0; + caption.setFont(font); + this.add(gbag, caption, c); + c.fill = 1; + c.gridwidth = 0; + c.gridheight = 6; + c.weightx = 1.0; + c.weighty = 1.0; + this.listbox.setFont(font); + this.add(gbag, this.listbox, c); + c.fill = 0; + c.gridwidth = -1; + c.gridheight = 0; + c.anchor = 14; + c.weightx = 0.45; + c.weighty = 0.0; + this.delButton.setFont(bfont); + this.cancelButton.setFont(bfont); + this.add(gbag, this.delButton, c); + c.gridwidth = 0; + c.anchor = 16; + c.weightx = 0.55; + this.add(gbag, this.cancelButton, c); + } + + private void select(boolean state) { + this.delButton.setEnabled(state); + } + + @Override + public void show() { + super.show(); + if (this.listbox.getItemCount() != 0) { + this.listbox.select(0); + this.select(true); + } else { + this.select(false); + } + + this.listbox.requestFocus(); + } + + @Override + public boolean handleEvent(Event event) { + if (event.id == 701) { + this.select(true); + } else if (event.id == 702) { + this.select(false); + } + + return super.handleEvent(event); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.cancelButton) { + return this.done(false); + } else if (target == this.delButton) { + int index = this.listbox.getSelectedIndex(); + if (index != -1) { + this.listbox.remove(index); + this.bookmarks.removeBookmark(index); + int count = this.listbox.getItemCount(); + if (index < count - 1) { + this.listbox.select(index); + } else if (count > 0) { + this.listbox.select(count - 1); + } else { + this.select(false); + this.listbox.requestFocus(); + } + } + + return true; + } else { + return false; + } + } + + @Override + public boolean keyDown(Event event, int key) { + return key != 27 && key != 10 ? super.keyDown(event, key) : this.done(false); + } + + private void add(String name, String target) { + this.bookmarks.addBookmark(name, target); + this.listbox.add(name); + this.listbox.makeVisible(this.listbox.getItemCount() - 1); + this.listbox.select(this.listbox.getItemCount() - 1); + this.select(true); + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + } +} diff --git a/NET/worlds/console/BookmarkEditDialog.java b/NET/worlds/console/BookmarkEditDialog.java new file mode 100644 index 0000000..7d42600 --- /dev/null +++ b/NET/worlds/console/BookmarkEditDialog.java @@ -0,0 +1,146 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; + +class BookmarkEditDialog extends PolledDialog { + private static final long serialVersionUID = 3386024535827699136L; + private TextField nameField; + private TextField URLField; + private Button okButton; + private Button cancelButton; + private String newName; + private String newTarget; + private int index; + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + + BookmarkEditDialog(java.awt.Window parent, DialogReceiver receiver, String title, String name, String url) { + this(parent, receiver, title, name, Console.message("OK"), Console.message("Cancel"), url, -1); + } + + BookmarkEditDialog(java.awt.Window parent, DialogReceiver receiver, String title, String name, String ok, String cancel, String url) { + this(parent, receiver, title, name, ok, cancel, url, -1); + } + + BookmarkEditDialog(java.awt.Window parent, DialogReceiver receiver, String name, String url, int index) { + this(parent, receiver, Console.message("Edit-WorldsMark"), name, Console.message("OK"), Console.message("Cancel"), url, index); + } + + private BookmarkEditDialog(java.awt.Window parent, DialogReceiver receiver, String title, String name, String ok, String cancel, String url, int index) { + super(parent, receiver, title, true); + this.index = index; + this.nameField = new TextField(name, 40); + this.URLField = new TextField(url, 40); + this.okButton = new Button(ok); + this.cancelButton = new Button(cancel); + this.ready(); + } + + @Override + protected void build() { + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.fill = 0; + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 2; + c.gridheight = 1; + Label lName = new Label(Console.message("Name")); + this.add(gbag, lName, c); + c.gridwidth = 0; + c.fill = 2; + this.nameField.setFont(font); + this.URLField.setFont(font); + this.add(gbag, this.nameField, c); + c.fill = 0; + c.gridwidth = 2; + this.add(gbag, new Label("URL:"), c); + c.gridwidth = 0; + c.fill = 2; + this.add(gbag, this.URLField, c); + Panel buttons = new Panel(); + this.okButton.setFont(bfont); + this.cancelButton.setFont(bfont); + buttons.add(this.okButton); + buttons.add(this.cancelButton); + c.gridwidth = 0; + c.fill = 0; + this.add(gbag, buttons, c); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.okButton && this.mayConfirm()) { + return this.done(true); + } else { + return target == this.cancelButton ? this.done(false) : false; + } + } + + @Override + public String getName() { + return this.newName; + } + + public String getTarget() { + return this.newTarget; + } + + public int getIndex() { + return this.index; + } + + private boolean mayConfirm() { + this.newName = this.nameField.getText(); + int i = this.newName.length(); + + do { + i--; + } while (i >= 0 && this.newName.charAt(i) == ' '); + + this.newName = this.newName.substring(0, i + 1); + this.newTarget = this.URLField.getText().trim(); + return this.newName.length() != 0 && this.newTarget.length() != 0; + } + + @Override + public boolean keyDown(Event event, int key) { + if (key == 27) { + return this.done(false); + } else { + if (key == 10) { + if (this.mayConfirm()) { + return this.done(true); + } + } else if (key == 9) { + if (event.target == this.nameField) { + this.URLField.requestFocus(); + this.URLField.selectAll(); + } else if (event.target == this.URLField) { + this.nameField.requestFocus(); + this.nameField.selectAll(); + } + + return true; + } + + return super.keyDown(event, key); + } + } + + @Override + public void show() { + super.show(); + this.nameField.requestFocus(); + this.nameField.selectAll(); + } +} diff --git a/NET/worlds/console/BookmarkListDialog.java b/NET/worlds/console/BookmarkListDialog.java new file mode 100644 index 0000000..e8586d5 --- /dev/null +++ b/NET/worlds/console/BookmarkListDialog.java @@ -0,0 +1,182 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.List; + +class BookmarkListDialog extends PolledDialog implements DialogReceiver { + private static final long serialVersionUID = 2134767291802432777L; + private List listbox = new List(10); + private Button editButton = new Button(Console.message("Edit")); + private Button addButton = new Button(Console.message("Add")); + private Button copyButton = new Button(Console.message("Copy")); + private Button delButton = new Button(Console.message("Delete")); + private Button okButton = new Button(Console.message("Go-To")); + private Button cancelButton = new Button(Console.message("Done")); + private WorldsMarkPart bookmarks; + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + + BookmarkListDialog(WorldsMarkPart bookmarks) { + super(Console.getFrame(), null, Console.message("Edit-WorldsMarkL"), true); + this.bookmarks = bookmarks; + this.ready(); + } + + @Override + protected void build() { + int count = WorldsMarkPart.getBookmarkCount(); + + for (int i = 0; i < count; i++) { + this.listbox.add(WorldsMarkPart.getBookmarkName(i)); + } + + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.fill = 1; + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 2; + c.gridheight = 6; + this.listbox.setFont(font); + this.add(gbag, this.listbox, c); + c.weightx = 0.0; + c.weighty = 0.0; + c.gridwidth = 0; + c.gridheight = 1; + c.fill = 2; + this.editButton.setFont(bfont); + this.addButton.setFont(bfont); + this.delButton.setFont(bfont); + this.okButton.setFont(bfont); + this.cancelButton.setFont(bfont); + this.add(gbag, this.editButton, c); + this.add(gbag, this.addButton, c); + this.add(gbag, this.copyButton, c); + this.add(gbag, this.delButton, c); + c.weighty = 1.0; + c.anchor = 15; + this.add(gbag, this.okButton, c); + c.weighty = 0.0; + this.add(gbag, this.cancelButton, c); + } + + private void select(boolean state) { + this.editButton.setEnabled(state); + this.delButton.setEnabled(state); + this.copyButton.setEnabled(state); + this.okButton.setEnabled(state); + } + + @Override + public void show() { + super.show(); + if (this.listbox.getItemCount() != 0) { + this.listbox.select(0); + this.select(true); + } else { + this.select(false); + } + + this.listbox.requestFocus(); + } + + @Override + public boolean handleEvent(Event event) { + if (event.id == 701) { + this.select(true); + } else if (event.id == 702) { + this.select(false); + } + + return super.handleEvent(event); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.okButton || target == this.listbox) { + WorldsMarkPart.gotoBookmark(this.listbox.getSelectedIndex()); + return this.done(true); + } else if (target == this.cancelButton) { + return this.done(false); + } else if (target == this.delButton) { + int index = this.listbox.getSelectedIndex(); + if (index != -1) { + this.listbox.remove(index); + this.bookmarks.removeBookmark(index); + int count = this.listbox.getItemCount(); + if (index < count - 1) { + this.listbox.select(index); + } else if (count > 0) { + this.listbox.select(count - 1); + } else { + this.select(false); + this.listbox.requestFocus(); + } + } + + return true; + } else if (target == this.copyButton) { + int index = this.listbox.getSelectedIndex(); + if (index != -1) { + this.add(WorldsMarkPart.getBookmarkName(index), WorldsMarkPart.getBookmarkTarget(index)); + } + + return true; + } else if (target == this.addButton) { + new BookmarkAddDialog(this, this); + return true; + } else if (target == this.editButton) { + int index = this.listbox.getSelectedIndex(); + new BookmarkEditDialog(this, this, WorldsMarkPart.getBookmarkName(index), WorldsMarkPart.getBookmarkTarget(index), index); + return true; + } else { + return false; + } + } + + @Override + public boolean keyDown(Event event, int key) { + if (key == 27) { + return this.done(false); + } else if (key == 10) { + WorldsMarkPart.gotoBookmark(this.listbox.getSelectedIndex()); + return this.done(true); + } else { + return super.keyDown(event, key); + } + } + + private void add(String name, String target) { + this.bookmarks.addBookmark(name, target); + this.listbox.add(name); + this.listbox.makeVisible(this.listbox.getItemCount() - 1); + this.listbox.select(this.listbox.getItemCount() - 1); + this.select(true); + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + if (confirmed) { + if (who instanceof BookmarkAddDialog) { + BookmarkAddDialog adder = (BookmarkAddDialog)who; + BookmarkEditDialog editor = adder.getEditor(); + this.add(editor.getName(), editor.getTarget()); + } else if (who instanceof BookmarkEditDialog) { + BookmarkEditDialog edit = (BookmarkEditDialog)who; + int index = edit.getIndex(); + String name = edit.getName(); + String target = edit.getTarget(); + this.bookmarks.changeBookmark(index, name, target); + this.listbox.replaceItem(name, index); + this.listbox.makeVisible(index); + this.listbox.select(index); + } + } + } +} diff --git a/NET/worlds/console/BookmarkMenuItem.java b/NET/worlds/console/BookmarkMenuItem.java new file mode 100644 index 0000000..6108bcf --- /dev/null +++ b/NET/worlds/console/BookmarkMenuItem.java @@ -0,0 +1,53 @@ +package NET.worlds.console; + +import NET.worlds.scape.Persister; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Saver; +import NET.worlds.scape.TooNewException; +import java.awt.MenuItem; +import java.io.IOException; + +public class BookmarkMenuItem extends MenuItem implements Persister { + private static final long serialVersionUID = -6078093402030113754L; + private String target; + private static Object classCookie = new Object(); + + public BookmarkMenuItem(String name, String target) { + super(name); + this.target = target; + } + + public BookmarkMenuItem() { + } + + public String getTarget() { + return this.target; + } + + public void setTarget(String loc) { + this.target = loc; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(1, classCookie); + s.saveString(this.getLabel()); + s.saveString(this.target); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + switch (r.restoreVersion(classCookie)) { + case 1: + this.setLabel(r.restoreString()); + this.target = r.restoreString(); + return; + default: + throw new TooNewException(); + } + } + + @Override + public void postRestore(int version) { + } +} diff --git a/NET/worlds/console/BootDialog.java b/NET/worlds/console/BootDialog.java new file mode 100644 index 0000000..e37de7d --- /dev/null +++ b/NET/worlds/console/BootDialog.java @@ -0,0 +1,83 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; + +public class BootDialog extends PolledDialog { + private static final long serialVersionUID = -4574101262059937239L; + private Label bootLabel = new Label(Console.message("User-to-Boot")); + private Button okButton = new Button(Console.message("OK")); + private Button cancelButton = new Button(Console.message("Cancel")); + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + private TextField bootField = new TextField(""); + + public BootDialog(java.awt.Window parent, DialogReceiver receiver, String title) { + super(parent, receiver, title, true); + this.ready(); + } + + public String getBoot() { + return this.bootField.getText(); + } + + @Override + protected void build() { + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.weightx = 1.0; + c.weighty = 1.0; + c.gridheight = 1; + c.fill = 0; + c.gridwidth = 2; + this.add(gbag, this.bootLabel, c); + c.gridwidth = 0; + c.fill = 2; + this.bootField.setFont(font); + this.add(gbag, this.bootField, c); + Panel buttons = new Panel(); + this.okButton.setFont(bfont); + buttons.add(this.okButton); + this.cancelButton.setFont(bfont); + buttons.add(this.cancelButton); + c.gridwidth = 0; + c.fill = 0; + this.add(gbag, buttons, c); + } + + @Override + public void show() { + this.initialSize(320, 140); + super.show(); + this.bootField.requestFocus(); + } + + @Override + public boolean handleEvent(Event event) { + return event.id == 201 ? this.done(false) : super.handleEvent(event); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.cancelButton) { + this.done(false); + } else if (target == this.okButton) { + this.done(true); + } + + return false; + } + + @Override + public boolean keyDown(Event event, int key) { + return key == 27 ? this.done(false) : super.keyDown(event, key); + } +} diff --git a/NET/worlds/console/CameraConveyor.java b/NET/worlds/console/CameraConveyor.java new file mode 100644 index 0000000..c271e80 --- /dev/null +++ b/NET/worlds/console/CameraConveyor.java @@ -0,0 +1,90 @@ +package NET.worlds.console; + +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.FrameHandler; +import NET.worlds.scape.NoSuchPropertyException; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Point3; +import NET.worlds.scape.Point3Temp; +import NET.worlds.scape.Property; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Saver; +import NET.worlds.scape.SuperRoot; +import NET.worlds.scape.TooNewException; +import NET.worlds.scape.WObject; +import java.io.IOException; +import java.util.Enumeration; + +public class CameraConveyor extends SuperRoot implements FrameHandler { + private Point3 vector; + private static Object classCookie = new Object(); + + public CameraConveyor() { + } + + public CameraConveyor(Point3Temp direction, float speed) { + this.vector = new Point3(direction.normalize().times(speed)); + } + + public CameraConveyor(Point3Temp v) { + this.vector = new Point3(v); + } + + @Override + public boolean handle(FrameEvent e) { + if (e.dt == 0) { + return true; + } else { + Enumeration<WObject> stuff = (Enumeration<WObject>)e.receiver.getContents(); + Point3Temp delta = Point3Temp.make(this.vector); + delta.times(e.dt / 1000.0F); + + while (stuff.hasMoreElements()) { + WObject thing = stuff.nextElement(); + if (thing instanceof Pilot) { + thing.moveThrough(delta); + } + } + + return true; + } + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(1, classCookie); + super.saveState(s); + s.save(this.vector); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + switch (r.restoreVersion(classCookie)) { + case 1: + super.restoreState(r); + case 0: + this.vector = (Point3)r.restore(); + return; + default: + throw new TooNewException(); + } + } + + @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, "Velocity"); + } else if (mode == 1) { + ret = this.vector; + } + break; + default: + ret = super.properties(index, offset + 1, mode, value); + } + + return ret; + } +} diff --git a/NET/worlds/console/ChannelDialog.java b/NET/worlds/console/ChannelDialog.java new file mode 100644 index 0000000..b2df8ac --- /dev/null +++ b/NET/worlds/console/ChannelDialog.java @@ -0,0 +1,84 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; + +public class ChannelDialog extends PolledDialog { + private static final long serialVersionUID = -3677512952231237135L; + private Label channelLabel = new Label(Console.message("New-channel")); + private Button okButton = new Button(Console.message("OK")); + private Button cancelButton = new Button(Console.message("Cancel")); + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private TextField channelField; + + public ChannelDialog(java.awt.Window parent, DialogReceiver receiver, String title, String defChannel) { + super(parent, receiver, title, true); + this.channelField = new TextField(defChannel); + this.ready(); + } + + public String getChannel() { + return this.channelField.getText(); + } + + @Override + protected void build() { + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.weightx = 1.0; + c.weighty = 1.0; + c.gridheight = 1; + c.fill = 0; + c.gridwidth = 2; + this.channelLabel.setFont(font); + this.add(gbag, this.channelLabel, c); + c.gridwidth = 0; + c.fill = 2; + this.channelField.setFont(font); + this.add(gbag, this.channelField, c); + Panel buttons = new Panel(); + buttons.add(this.okButton); + buttons.add(this.cancelButton); + this.okButton.setFont(font); + this.cancelButton.setFont(font); + c.gridwidth = 0; + c.fill = 0; + this.add(gbag, buttons, c); + } + + @Override + public void show() { + this.initialSize(320, 140); + super.show(); + this.channelField.requestFocus(); + } + + @Override + public boolean handleEvent(Event event) { + return event.id == 201 ? this.done(false) : super.handleEvent(event); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.cancelButton) { + this.done(false); + } else if (target == this.okButton) { + this.done(true); + } + + return false; + } + + @Override + public boolean keyDown(Event event, int key) { + return key == 27 ? this.done(false) : super.keyDown(event, key); + } +} diff --git a/NET/worlds/console/ChatArea.java b/NET/worlds/console/ChatArea.java new file mode 100644 index 0000000..a25f1e6 --- /dev/null +++ b/NET/worlds/console/ChatArea.java @@ -0,0 +1,248 @@ +package NET.worlds.console; + +import java.awt.Component; +import java.awt.Event; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.text.DateFormat; +import java.util.Date; +import java.util.Observer; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; + +public class ChatArea extends JScrollPane implements SharedTextArea { + private JTextArea textArea; + private static String sharedText; + private boolean isShared; + private String unsharedText; + private String unaddedText; + private boolean haveFocus; + private PrintWriter logFile; + private String logFileName; + private static final long oneMeg = 1048576L; + private static final long logLengthLimit = 524288L; + private static PublicObservable obsLogFile = new PublicObservable(); + + public ChatArea(int rows, int cols, boolean isShared) { + this.textArea = new JTextArea(rows, cols); + this.isShared = isShared; + this.textArea.setEditable(false); + this.setViewportView(this.textArea); + super.setHorizontalScrollBarPolicy(31); + super.setVerticalScrollBarPolicy(20); + } + + @Override + public Component getComponent() { + return this; + } + + @Override + public void finalize() { + this.disableLogging(); + } + + @Override + public synchronized void validate() { + super.validate(); + String text = this.isShared ? sharedText : this.unsharedText; + if (text != null) { + this.textArea.replaceRange("", 0, this.textArea.getText().length()); + this.textArea.append(text); + } + } + + @Override + public synchronized void enableLogging(String fileName, String title, boolean append) { + if (this.logFile != null) { + if (this.logFileName.equals(fileName)) { + return; + } + + this.logFile.close(); + } + + try { + if (append && new File(fileName).exists()) { + this.truncateIfExceeds(fileName, title, 524288L); + this.logFile = new PrintWriter(new FileWriter(fileName, true)); + } else { + this.logFile = new PrintWriter(new FileWriter(fileName, false)); + obsLogFile.setChanged(true); + this.logFile.println("<html>"); + this.logFile.println("<head>"); + this.logFile.println("<title>" + title + "</title>"); + this.logFile.println("</head>"); + this.logFile.println("<body>"); + } + + this.logFileName = fileName; + this.logFile.println("<hr>"); + this.logFile.println("<h3>Conversation of " + DateFormat.getDateTimeInstance().format(new Date()) + "</h3>"); + this.logFile.flush(); + obsLogFile.notifyObservers(this); + } catch (IOException var5) { + System.out.println("Log file not opened: " + var5); + } + } + + public static void addLogObserver(Observer o) { + obsLogFile.addObserver(o); + } + + public static void deleteLogObserver(Observer o) { + obsLogFile.deleteObserver(o); + } + + private synchronized void truncateIfExceeds(String fileName, String title, long lengthLimit) { + File f = new File(fileName); + if (f.length() > lengthLimit) { + File tf = new File(fileName + ".temp"); + + try { + BufferedReader in = new BufferedReader(new FileReader(f)); + PrintWriter out = new PrintWriter(new FileWriter(tf)); + out.println("<html>"); + out.println("<head>"); + out.println("<title>" + title + "</title>"); + out.println("</head>"); + out.println("<body>"); + in.skip(f.length() - lengthLimit / 2L); + String line = in.readLine(); + + for (String var13 = in.readLine(); var13 != null; var13 = in.readLine()) { + out.println(var13); + } + + in.close(); + out.close(); + f.delete(); + f = new File(fileName); + tf.renameTo(f); + } catch (FileNotFoundException var10) { + System.out.println("DuplexPart fatal: " + var10); + } catch (IOException var11) { + System.out.println("DuplexPart: Unable to write, " + var11); + } + } + } + + @Override + public synchronized void disableLogging() { + if (this.logFile != null) { + this.logFile.close(); + this.logFile = null; + } + } + + @Override + public boolean canAddText() { + return !this.haveFocus; + } + + private String toHtml(String s) { + assert s != null; + + String h = ""; + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '"': + h = h + """; + break; + case '&': + h = h + "&"; + break; + case '<': + h = h + "<"; + break; + case '>': + h = h + ">"; + break; + default: + h = h + c; + } + } + + return h; + } + + @Override + public synchronized void println(String msg) { + if (this.logFile != null && msg != null) { + this.logFile.println(this.toHtml(msg) + "<br>"); + this.logFile.flush(); + } + + if (this.unaddedText == null) { + this.unaddedText = msg; + } else if (msg != null) { + this.unaddedText = this.unaddedText + "\n" + msg; + } + + if (this.unaddedText != null && this.canAddText()) { + if (this.textArea.getText().length() == 0) { + this.textArea.append(this.unaddedText); + } else { + this.textArea.append("\n" + this.unaddedText); + } + + this.unaddedText = null; + String text = this.textArea.getText(); + if (text.length() > 20000) { + int linePos = text.indexOf(10, 10240); + if (linePos >= 0) { + text = text.substring(linePos + 1); + linePos = text.lastIndexOf(10); + if (linePos > 0) { + this.textArea.setText(text.substring(0, linePos)); + this.textArea.append(text.substring(linePos)); + } + } + } + + if (this.isShared) { + sharedText = text; + } else { + this.unsharedText = text; + } + } + } + + @Override + public synchronized void scrollToBottom() { + String text = this.textArea.getText(); + int textlen = text.length(); + this.textArea.select(textlen, textlen); + } + + @Override + public synchronized boolean handleEvent(Event event) { + if (event.id == 1004) { + this.haveFocus = true; + } else if (event.id == 1005) { + this.haveFocus = false; + } + + this.poll(); + return super.handleEvent(event); + } + + @Override + public void poll() { + if (this.unaddedText != null) { + this.println(null); + } + } + + @Override + public boolean isFocusTraversable() { + return false; + } +} diff --git a/NET/worlds/console/ChatDialog.java b/NET/worlds/console/ChatDialog.java new file mode 100644 index 0000000..0f4821e --- /dev/null +++ b/NET/worlds/console/ChatDialog.java @@ -0,0 +1,143 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Choice; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; + +public class ChatDialog extends PolledDialog { + private static final long serialVersionUID = 2346715931784644393L; + private Label fontsizeLabel = new Label(Console.message("Font-Size")); + private Label linesLabel = new Label(Console.message("Chat-Lines")); + private Label chatlengthLabel = new Label(Console.message("Chat-Buffer-Length")); + private Button okButton = new Button(Console.message("OK")); + private Button cancelButton = new Button(Console.message("Cancel")); + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private Choice fontsizeChoice = new Choice(); + private Choice linesChoice = new Choice(); + private TextField chatlengthField; + + public ChatDialog(java.awt.Window parent, DialogReceiver receiver, String title, int defSize, int defLines, int defLength) { + super(parent, receiver, title, true); + this.chatlengthField = new TextField("" + defLength); + + for (int i = 0; i <= 16; i++) { + this.fontsizeChoice.insert(i + 10 + "pt", i); + } + + if (defSize >= 10 && defSize <= 16) { + this.fontsizeChoice.select(defSize - 10); + } else { + this.fontsizeChoice.select(2); + } + + for (int i = 0; i < 24; i++) { + this.linesChoice.insert(i + 6 + " lines", i); + } + + if (defLines >= 6 && defLines <= 30) { + this.linesChoice.select(defLines - 6); + } else { + this.linesChoice.select(0); + } + + this.ready(); + } + + public int getFontsize() { + try { + return this.fontsizeChoice.getSelectedIndex() + 10; + } catch (Exception var2) { + return 12; + } + } + + public int getLines() { + try { + return this.linesChoice.getSelectedIndex() + 6; + } catch (Exception var2) { + return 6; + } + } + + public int getLength() { + try { + return Integer.parseInt(this.chatlengthField.getText()); + } catch (Exception var2) { + return 20000; + } + } + + @Override + protected void build() { + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.weightx = 1.0; + c.weighty = 1.0; + c.gridheight = 1; + c.fill = 0; + c.gridwidth = 2; + this.fontsizeLabel.setFont(font); + this.add(gbag, this.fontsizeLabel, c); + c.gridwidth = 0; + c.fill = 2; + this.add(gbag, this.fontsizeChoice, c); + c.fill = 0; + c.gridwidth = 2; + this.linesLabel.setFont(font); + this.add(gbag, this.linesLabel, c); + c.gridwidth = 0; + c.fill = 2; + this.add(gbag, this.linesChoice, c); + c.gridwidth = 2; + this.chatlengthLabel.setFont(font); + this.add(gbag, this.chatlengthLabel, c); + c.gridwidth = 0; + c.fill = 2; + this.chatlengthField.setFont(font); + this.add(gbag, this.chatlengthField, c); + Panel buttons = new Panel(); + buttons.add(this.okButton); + buttons.add(this.cancelButton); + this.okButton.setFont(font); + this.cancelButton.setFont(font); + c.gridwidth = 0; + c.fill = 0; + this.add(gbag, buttons, c); + } + + @Override + public void show() { + this.initialSize(320, 160); + super.show(); + this.fontsizeChoice.requestFocus(); + } + + @Override + public boolean handleEvent(Event event) { + return event.id == 201 ? this.done(false) : super.handleEvent(event); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.cancelButton) { + this.done(false); + } else if (target == this.okButton) { + this.done(true); + } + + return false; + } + + @Override + public boolean keyDown(Event event, int key) { + return key == 27 ? this.done(false) : super.keyDown(event, key); + } +} diff --git a/NET/worlds/console/ChatPart.java b/NET/worlds/console/ChatPart.java new file mode 100644 index 0000000..dfdf161 --- /dev/null +++ b/NET/worlds/console/ChatPart.java @@ -0,0 +1,72 @@ +package NET.worlds.console; + +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.Pilot; +import java.awt.Container; + +public class ChatPart extends DuplexPart { + private Window renderWindow; + private DefaultConsole console; + private static final String activateVCselfWhisper = "&|+debug<selfWhisperON"; + private static final String deactivateVCselfWhisper = "&|+debug<selfWhisperOFF"; + private static final String VCextraCommand = "&|+debug<VCcommand"; + + @Override + protected void sendText(String s) { + int ii = s.indexOf(92); + if (s.startsWith("&|+debug<")) { + this.triggerLocalDebug(s); + } else if (ii >= 0 && ii < s.length() - 1 && s.charAt(ii + 1) == 'u') { + Pilot.sendText(Console.parseUnicode(s)); + } else { + Pilot.sendText(s); + } + } + + @Override + public void activate(Console c, Container f, Console prev) { + super.activate(c, f, prev); + this.console = (DefaultConsole)c; + } + + @Override + public void deactivate() { + super.deactivate(); + this.renderWindow = null; + this.console = null; + } + + @Override + public synchronized boolean handle(FrameEvent f) { + boolean ret = super.handle(f); + if (this.renderWindow == null && this.console != null) { + RenderCanvas rc = this.console.getRender(); + if (rc != null) { + Window w = rc.getWindow(); + if (w != null) { + try { + w.hookChatLine(this.line); + this.renderWindow = w; + } catch (WindowNotFoundException var6) { + } + } + } + } + + return ret; + } + + private void triggerLocalDebug(String s) { + if (s.startsWith("&|+debug<selfWhisperON")) { + VoiceChat.activateSelfWhisper(); + } + + if (s.startsWith("&|+debug<selfWhisperOFF")) { + VoiceChat.deactivateSelfWhisper(); + } + + if (s.startsWith("&|+debug<VCcommand")) { + VoiceChat.setExtra(s); + } + } +} diff --git a/NET/worlds/console/ClassicSharedTextArea.java b/NET/worlds/console/ClassicSharedTextArea.java new file mode 100644 index 0000000..e571c5a --- /dev/null +++ b/NET/worlds/console/ClassicSharedTextArea.java @@ -0,0 +1,258 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import java.awt.Color; +import java.awt.Component; +import java.awt.Event; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.TextArea; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.text.DateFormat; +import java.util.Date; +import java.util.Observer; + +class ClassicSharedTextArea extends TextArea implements SharedTextArea { + private static final long serialVersionUID = -3315186117230082655L; + private static String sharedText; + private boolean isShared; + private String unsharedText; + private String unaddedText; + private boolean haveFocus; + private int hwnd = 0; + private PrintWriter logFile; + private String logFileName; + private static final long oneMeg = 1048576L; + private static final long logLengthLimit = 524288L; + private static PublicObservable obsLogFile = new PublicObservable(); + public static int chatLengthLimit = IniFile.gamma().getIniInt("ChatLengthLimit", 20000); + + public ClassicSharedTextArea(int rows, int cols, boolean isShared) { + super("", rows, cols, 1); + this.isShared = isShared; + this.setEditable(false); + } + + @Override + public Component getComponent() { + return this; + } + + @Override + public void finalize() { + this.disableLogging(); + } + + @Override + public synchronized void validate() { + super.validate(); + String text = this.isShared ? sharedText : this.unsharedText; + if (text != null) { + this.replaceRange("", 0, this.getText().length()); + this.append(text); + } + + this.hwnd = 0; + } + + @Override + public synchronized void enableLogging(String fileName, String title, boolean append) { + if (this.logFile != null) { + if (this.logFileName.equals(fileName)) { + return; + } + + this.logFile.close(); + } + + try { + if (append && new File(fileName).exists()) { + this.truncateIfExceeds(fileName, title, 524288L); + this.logFile = new PrintWriter(new FileWriter(fileName, true)); + } else { + this.logFile = new PrintWriter(new FileWriter(fileName, false)); + obsLogFile.setChanged(true); + this.logFile.println("<html>"); + this.logFile.println("<head>"); + this.logFile.println("<title>" + title + "</title>"); + this.logFile.println("</head>"); + this.logFile.println("<body>"); + } + + this.logFileName = fileName; + this.logFile.println("<hr>"); + this.logFile.println("<h3>Conversation of " + DateFormat.getDateTimeInstance().format(new Date()) + "</h3>"); + this.logFile.flush(); + obsLogFile.notifyObservers(this); + } catch (IOException var5) { + System.out.println("Log file not opened: " + var5); + } + } + + public static void addLogObserver(Observer o) { + obsLogFile.addObserver(o); + } + + public static void deleteLogObserver(Observer o) { + obsLogFile.deleteObserver(o); + } + + private void truncateIfExceeds(String fileName, String title, long lengthLimit) { + File f = new File(fileName); + if (f.length() > lengthLimit) { + File tf = new File(fileName + ".temp"); + + try { + BufferedReader in = new BufferedReader(new FileReader(f)); + PrintWriter out = new PrintWriter(new FileWriter(tf)); + out.println("<html>"); + out.println("<head>"); + out.println("<title>" + title + "</title>"); + out.println("</head>"); + out.println("<body>"); + in.skip(f.length() - lengthLimit / 2L); + String line = in.readLine(); + + for (String var13 = in.readLine(); var13 != null; var13 = in.readLine()) { + out.println(var13); + } + + in.close(); + out.close(); + f.delete(); + f = new File(fileName); + tf.renameTo(f); + } catch (FileNotFoundException var10) { + System.out.println("DuplexPart fatal: " + var10); + } catch (IOException var11) { + System.out.println("DuplexPart: Unable to write, " + var11); + } + } + } + + @Override + public synchronized void disableLogging() { + if (this.logFile != null) { + this.logFile.close(); + this.logFile = null; + } + } + + @Override + public boolean canAddText() { + return !this.haveFocus ? true : true; + } + + @Override + public synchronized void println(String msg) { + if (this.logFile != null && msg != null) { + this.logFile.println(DuplexPart.toHtml(msg) + "<br>"); + this.logFile.flush(); + } + + if (this.unaddedText == null) { + this.unaddedText = msg; + } else if (msg != null) { + this.unaddedText = this.unaddedText + "\n" + msg; + } + + if (this.unaddedText != null && this.canAddText()) { + if (this.getText().length() == 0) { + this.append(this.unaddedText); + } else { + this.append("\n" + this.unaddedText); + } + + this.unaddedText = null; + String text = this.getText(); + if (text.length() > chatLengthLimit) { + int linePos = text.indexOf(10, chatLengthLimit / 2 - 80); + if (linePos >= 0) { + text = text.substring(linePos + 1); + linePos = text.lastIndexOf(10); + if (linePos > 0) { + this.setText(text.substring(0, linePos)); + this.append(text.substring(linePos)); + } + } + } + + if (this.isShared) { + sharedText = text; + } else { + this.unsharedText = text; + } + } + } + + @Override + public synchronized void scrollToBottom() { + String text = this.getText(); + int textlen = text.length(); + this.select(textlen, textlen); + } + + @Override + public boolean handleEvent(Event event) { + if (event.id == 1004) { + this.haveFocus = true; + } else if (event.id == 1005) { + this.haveFocus = false; + } + + this.poll(); + return super.handleEvent(event); + } + + @Override + public void poll() { + if (this.unaddedText != null) { + this.println(null); + } + } + + @Override + public boolean isFocusTraversable() { + return false; + } + + @Override + public synchronized void paint(Graphics g) { + String[] fulltext = this.getText().split("\n"); + Rectangle r = this.getBounds(); + if (r.height >= 0 && r.width >= 0) { + Point offset = new Point(0, 0); + Image offImage = this.createImage(r.width, r.height); + Graphics offGraphic = offImage.getGraphics(); + offGraphic.setColor(GammaTextArea.getBackgroundColor()); + offGraphic.fillRect(r.x, r.y, r.width, r.height); + offGraphic.setColor(Color.black); + offGraphic.setFont(this.getFont()); + FontMetrics fm = offGraphic.getFontMetrics(this.getFont()); + int windowY = offset.y; + int curY = fm.getHeight(); + int curLine = 0; + int curPos = 0; + int mode = -1; + System.out + .println("paint (" + r.x + "," + r.y + "):" + r.height + "," + r.width + " Offset=" + offset.x + "," + offset.y + " lines=" + fulltext.length); + System.out.println("curLine=" + curLine + " curY=" + curY); + + for (int i = curLine; i < fulltext.length && curY <= windowY + r.height; i++) { + if (mode != 0) { + offGraphic.drawString(fulltext[i], offset.x, curY); + curY += fm.getHeight(); + } + } + } + } +} diff --git a/NET/worlds/console/ColorFiller.java b/NET/worlds/console/ColorFiller.java new file mode 100644 index 0000000..3749678 --- /dev/null +++ b/NET/worlds/console/ColorFiller.java @@ -0,0 +1,41 @@ +package NET.worlds.console; + +import java.awt.Dimension; +import java.awt.Panel; +import java.awt.Rectangle; + +class ColorFiller extends Panel { + private static final long serialVersionUID = 7047615493861713512L; + private int w; + private int h; + + ColorFiller(int width, int height) { + this.w = width; + this.h = height; + } + + public void setHeight(int newH) { + this.h = newH; + } + + public void setWidth(int newW) { + this.w = newW; + } + + @Override + public Dimension preferredSize() { + return new Dimension(this.w, this.h); + } + + @Override + public Dimension getMaximumSize() { + return this.preferredSize(); + } + + @Override + public void setBounds(Rectangle r) { + r.width = this.w; + r.height = this.h; + super.setBounds(r); + } +} diff --git a/NET/worlds/console/ConfirmDialog.java b/NET/worlds/console/ConfirmDialog.java new file mode 100644 index 0000000..f0613e4 --- /dev/null +++ b/NET/worlds/console/ConfirmDialog.java @@ -0,0 +1,40 @@ +package NET.worlds.console; + +import java.awt.GridBagConstraints; +import java.awt.Label; + +public class ConfirmDialog extends OkCancelDialog { + private static final long serialVersionUID = 2839131701328189735L; + private String prompt; + + public ConfirmDialog(java.awt.Window parent, DialogReceiver target, String title, String prompt) { + super(parent, target, title, Console.message("No"), Console.message("Yes")); + this.prompt = prompt; + this.ready(); + } + + public ConfirmDialog(java.awt.Window parent, String title, String prompt) { + this(parent, (DialogReceiver)parent, title, prompt); + } + + @Override + protected void build() { + GridBagConstraints c = new GridBagConstraints(); + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 0; + this.add(this.gbag, new Label(this.prompt), c); + super.build(); + } + + @Override + protected boolean setValue() { + return true; + } + + @Override + public void show() { + super.show(); + this.okButton.requestFocus(); + } +} diff --git a/NET/worlds/console/ConnectionRecord.java b/NET/worlds/console/ConnectionRecord.java new file mode 100644 index 0000000..74e7867 --- /dev/null +++ b/NET/worlds/console/ConnectionRecord.java @@ -0,0 +1,47 @@ +package NET.worlds.console; + +import java.util.Date; +import java.util.Vector; + +class ConnectionRecord { + private static Vector<ConnectionRecord> recordList = new Vector<ConnectionRecord>(); + private String _who = null; + private Date _startDelayTime = null; + + public ConnectionRecord(String who) { + this._who = who; + this._startDelayTime = new Date(); + } + + public boolean isExpired(Date now) { + return now.getTime() - this._startDelayTime.getTime() > 15000L; + } + + public String getWho() { + return this._who; + } + + public static Vector<ConnectionRecord> getList() { + return recordList; + } + + public static synchronized boolean checkList(String w) { + boolean delayed = false; + int i = 0; + Date now = new Date(); + + while (!recordList.isEmpty() && i < recordList.size()) { + ConnectionRecord r = recordList.elementAt(i); + if (r.isExpired(now)) { + recordList.removeElementAt(i); + } else { + i++; + if (r.getWho().equals(w)) { + delayed = true; + } + } + } + + return delayed; + } +} diff --git a/NET/worlds/console/Console.java b/NET/worlds/console/Console.java new file mode 100644 index 0000000..1fc32ab --- /dev/null +++ b/NET/worlds/console/Console.java @@ -0,0 +1,1542 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.core.Std; +import NET.worlds.network.ConnectionWaiter; +import NET.worlds.network.DNSLookup; +import NET.worlds.network.Galaxy; +import NET.worlds.network.InfiniteWaitException; +import NET.worlds.network.InvalidServerURLException; +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.VarErrorException; +import NET.worlds.network.WorldServer; +import NET.worlds.network.net2Property; +import NET.worlds.scape.Attribute; +import NET.worlds.scape.BooleanPropertyEditor; +import NET.worlds.scape.Drone; +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.FrameHandler; +import NET.worlds.scape.HoloDrone; +import NET.worlds.scape.HoloPilot; +import NET.worlds.scape.InventoryManager; +import NET.worlds.scape.LoadedURLSelf; +import NET.worlds.scape.NoSuchPropertyException; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.ProgressiveAdder; +import NET.worlds.scape.PropAdder; +import NET.worlds.scape.Property; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Room; +import NET.worlds.scape.Saver; +import NET.worlds.scape.StringPropertyEditor; +import NET.worlds.scape.SuperRoot; +import NET.worlds.scape.TeleportStatus; +import NET.worlds.scape.TooNewException; +import NET.worlds.scape.URLPropertyEditor; +import NET.worlds.scape.URLSelf; +import NET.worlds.scape.URLSelfLoader; +import NET.worlds.scape.VectorProperty; +import NET.worlds.scape.WObject; +import NET.worlds.scape.WobLoaded; +import NET.worlds.scape.WobLoader; +import NET.worlds.scape.World; +import java.awt.CardLayout; +import java.awt.CheckboxMenuItem; +import java.awt.Container; +import java.awt.Event; +import java.awt.Font; +import java.awt.Menu; +import java.awt.MenuBar; +import java.awt.MenuItem; +import java.awt.MenuShortcut; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.io.File; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URLConnection; +import java.text.MessageFormat; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.Vector; + +public abstract class Console extends SuperRoot implements URLSelf, MainCallback, NetworkObject, WobLoaded, DialogDisabled, ConnectionWaiter { + private static Vector<String> storedLines = new Vector<String>(); + protected boolean disableShaperAccess = false; + protected boolean disableSingleUserAccess = false; + private static Console active; + private Panel myCard; + private static int nameCounter; + private static Font font = new Font(message("MenuFont"), 0, 12); + private URL targetAv; + private static String activeTeleportURL; + private static String lastTeleportURL; + private static FrameEvent frameEvent; + private static int freezeFrameEvents = 0; + private String sleepMode = ""; + private int lastUserAction; + private Vector<FramePart> parts = new Vector<FramePart>(); + private static MenuBar menuBar = new MenuBar(); + protected boolean enableMenu = false; + protected MenuItem exitItem; + private Hashtable<String, Menu> menus = new Hashtable<String, Menu>(); + protected static boolean autoFullVIP = IniFile.override().getIniInt("tieredVIP", 0) == 0; + protected static boolean isRedLightWorld = IniFile.override().getIniString("ProductName", "").equalsIgnoreCase("RedLightWorld") + || IniFile.override().getIniString("ProductName", "").equalsIgnoreCase("RedLightCenter"); + protected static int vip = IniFile.gamma().getIniInt("VIP", 0) != 0 ? (autoFullVIP ? 2 : 1) : 0; + protected static int spguest = IniFile.gamma().getIniInt("SPGUEST", 0) != 0 ? 2 : 0; + private boolean canBroadcast = false; + protected URL lastPilotRequested; + public String pendingPilot = ""; + protected boolean setFromMenu = false; + private String postFix = ""; + public static boolean selfCustom = false; + protected Vector<LoadedURLSelf> callbacks = new Vector<LoadedURLSelf>(); + private String defaultAction = ""; + protected String tempCarAvatar = ""; + protected static String defaultConsole = IniFile.gamma().getIniString("DEFAULTCONSOLE", "NET.worlds.console.DefaultConsole"); + private static Hashtable<URL, Console> defConsoles = new Hashtable<URL, Console>(); + private static Console defaultUnshared; + private int refcnt = 0; + protected Pilot pilotSoulTemplate; + protected Drone droneSoulTemplate; + protected Pilot pilot; + public boolean targetValid = false; + private String sleepStr = message("asleep"); + protected static GammaFrame frame = new GammaFrame(); + protected Galaxy galaxy = null; + protected URL _galaxyURL; + private Cursor cursor = new Cursor(URL.make("system:WAIT_CURSOR")); + private Vector<Object> tempArea = new Vector<Object>(); + private static Object classCookie = new Object(); + + static { + WhisperManager.whisperManager().setParent(frame); + } + + public static synchronized void println(String msg) { + if (active != null) { + active.printLine(msg); + } else { + storedLines.addElement(msg); + } + } + + public static void printWhisper(String from, String msg) { + if (active != null) { + active.printWhisperFrom(from, msg); + } + } + + public static void printOwnWhisper(String to, String msg) { + if (active != null) { + active.printWhisperTo(to, msg); + } + } + + public static void startWhispering(String to) { + if (active != null) { + active.startWhisperingTo(to); + } + } + + public static synchronized String message(String Id) { + Locale currentLocale = Locale.getDefault(); + + try { + String bundlePrefix = IniFile.override().getIniString("BundlePrefix", "MessagesBundle"); + ResourceBundle messages = ResourceBundle.getBundle(bundlePrefix, currentLocale); + String mess = messages.getString(Id); + if (mess.indexOf(123) == -1 && mess.indexOf(125) == -1) { + mess = Std.replaceStr(mess, "''", "'"); + } + + if (mess.lastIndexOf(".gif") > 0 || mess.lastIndexOf(".jpg") > 0 || mess.lastIndexOf(".bmp") > 0) { + File f = new File(mess); + if (!f.exists()) { + return Id; + } + } + + return mess; + } catch (MissingResourceException var6) { + if (Galaxy.getDebugLevel() != 0) { + System.out.println("MRE: " + var6.getClassName() + " " + var6.getKey()); + System.out.println("NO MESSAGE for " + Id); + } + + return Id; + } + } + + public static synchronized String parseUnicode(String s) { + if (s == null) { + return s; + } else { + int idx; + while ((idx = s.indexOf("\\u")) != -1) { + if (idx >= s.length() - 5) { + return s; + } + + String x = s.substring(idx + 2, idx + 6); + char p = (char)Integer.parseInt(x, 16); + String tmp = s.substring(0, idx) + p + s.substring(idx + 6); + s = tmp; + } + + return s; + } + } + + public static synchronized Vector<String> parseUnicode(Vector<String> cc) { + for (int i = 0; i < cc.size(); i++) { + String s = cc.elementAt(i); + String s2 = parseUnicode(s); + cc.setElementAt(s2, i); + } + + return cc; + } + + public static synchronized String parseExtended(String s) { + String uc = ""; + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c > 255) { + int ii = c; + + try { + uc = uc + "\\u" + Integer.toHexString(ii); + } catch (NumberFormatException var6) { + uc = uc + "?"; + } + } else { + uc = uc + c; + } + } + + return uc; + } + + public static boolean wasHttpNoSuchFile(String us) { + java.net.URL u = null; + URLConnection uc = null; + + try { + u = DNSLookup.lookup(new java.net.URL(us)); + uc = u.openConnection(); + } catch (Exception var5) { + return true; + } + + try { + return ((HttpURLConnection)uc).getResponseCode() == 404; + } catch (Exception var4) { + return true; + } + } + + protected void printWhisperFrom(String from, String msg) { + if (!msg.startsWith("&|+")) { + Object[] arguments = new Object[]{new String(from), new String(msg)}; + println(MessageFormat.format(message("whispered"), arguments)); + } + } + + protected void printWhisperTo(String to, String msg) { + if (!msg.startsWith("&|+")) { + Object[] arguments = new Object[]{new String(to), new String(msg)}; + println(MessageFormat.format(message("You-whispered"), arguments)); + } + } + + protected void startWhisperingTo(String to) { + Object[] arguments = new Object[]{new String(to)}; + println(MessageFormat.format(message("You-want-whisp"), arguments)); + } + + public void printLine(String msg) { + System.out.println(msg); + } + + public boolean isShaperAccessDisabled() { + return this.disableShaperAccess; + } + + public boolean isSingleUserAccessDisabled() { + return this.disableSingleUserAccess; + } + + public static Console getActive() { + return active; + } + + public void inventoryChanged() { + } + + public void forPilotOnlyActivate() { + if (active != this) { + this.myCard = new Panel(); + String myCardName = "" + nameCounter++; + Container consoleTile = frame.getConsoleTile(); + consoleTile.add(myCardName, this.myCard); + Console prev = active; + this.activate(this.myCard); + ((CardLayout)consoleTile.getLayout()).show(consoleTile, myCardName); + getFrame().validate(); + if (prev != null) { + consoleTile.remove(prev.myCard); + prev.myCard.removeAll(); + } + } + } + + protected void setEnableMenu(boolean enable) { + this.enableMenu = enable; + if (this == active) { + enable |= Gamma.shaper != null; + boolean enabled = frame.getMenuBar() == menuBar && menuBar != null; + if (enable != enabled) { + frame.setMenuBar(enable ? menuBar : null); + frame.pack(); + } + } + } + + private static synchronized void setActive(Console active) { + Console.active = active; + int sz = storedLines.size(); + if (sz > 0) { + for (int i = 0; i < sz; i++) { + active.printLine(storedLines.elementAt(i)); + } + + storedLines.removeAllElements(); + } + } + + protected void activate(Container c) { + assert this.pilot != null; + + Console prev = active; + if (active != null) { + active.deactivate(); + } + + setActive(this); + Main.register(this); + this.menus.clear(); + menuBar = new MenuBar(); + this.getMenu("File"); + if (Gamma.shaper != null) { + Gamma.shaper.activate(this, c, prev); + } + + int len = this.parts.size(); + + for (int i = 0; i < len; i++) { + this.parts.elementAt(i).activate(this, c, prev); + } + + this.exitItem = this.addMenuItem(message("Exit"), "File"); + if (activeTeleportURL != null) { + teleportNotification("", activeTeleportURL); + } + + this.cursor.activate(); + } + + protected void menuDone() { + this.setEnableMenu(this.enableMenu); + } + + protected void deactivate() { + if (active == this) { + setActive(null); + Main.unregister(this); + int len = this.parts.size(); + + for (int i = 0; i < len; i++) { + this.parts.elementAt(i).deactivate(); + } + + if (Gamma.shaper != null) { + Gamma.shaper.deactivate(); + } + + this.cursor.deactivate(); + frame.deactivate(); + } + } + + public String getActiveTeleportURL() { + return lastTeleportURL == null ? "" : lastTeleportURL; + } + + public static void teleportNotification(String err, String url) { + if (err != null && err.length() == 0) { + activeTeleportURL = url; + lastTeleportURL = url.toString(); + } else { + activeTeleportURL = null; + } + + if (active != null) { + if (active instanceof TeleportStatus) { + ((TeleportStatus)active).teleportStatus(err, url); + } + + int len = active.parts.size(); + + for (int i = 0; i < len; i++) { + Object fp = active.parts.elementAt(i); + if (fp instanceof TeleportStatus) { + ((TeleportStatus)fp).teleportStatus(err, url); + } + } + } + } + + public static void setFreezeFrameEvents(boolean x) { + if (x) { + freezeFrameEvents++; + } else { + freezeFrameEvents--; + + assert freezeFrameEvents >= 0; + } + } + + @Override + public void mainCallback() { + if (frameEvent == null) { + frameEvent = new FrameEvent(null, null); + } + + if (freezeFrameEvents <= 0) { + frameEvent.newFrameTime(); + frameEvent.source = this; + this.generateFrameEvents(frameEvent); + frameEvent.target = null; + frameEvent.receiver = null; + frameEvent.source = null; + } + } + + public void generateFrameEvents(FrameEvent f) { + World.generateFrameEvents(f); + int now = Std.getFastTime(); + if (Window.getAndResetUserActionCount() != 0) { + this.setSleepMode(null); + this.lastUserAction = now; + } else if (now > this.lastUserAction + 300000) { + if (this.lastUserAction == 0) { + this.lastUserAction = now; + } else { + this.goToSleep(); + } + } + + int len = this.parts.size(); + if (Main.profile != 0) { + for (int i = 0; i < len; i++) { + FramePart fp = this.parts.elementAt(i); + int start = Std.getRealTime(); + long startBytes = Runtime.getRuntime().freeMemory(); + fp.handle(f); + int dur = Std.getRealTime() - start; + long used = startBytes - Runtime.getRuntime().freeMemory(); + if (dur > Main.profile) { + System.out.println("Took " + dur + "ms and " + used + " bytes to call framePart " + fp); + } + } + } else { + for (int ix = 0; ix < len; ix++) { + this.parts.elementAt(ix).handle(f); + } + } + + ProgressiveAdder.get().handle(f); + if (this instanceof FrameHandler) { + ((FrameHandler)this).handle(f); + } + + if (this.pilot != null) { + this.pilot.generateFrameEvents(f); + } + } + + public void addPart(FramePart p) { + this.parts.addElement(p); + } + + public Enumeration<FramePart> getParts() { + return this.parts.elements(); + } + + public boolean action(Event event, Object what) { + if (event.target == this.exitItem) { + return maybeQuit(); + } else if (Gamma.shaper != null && Gamma.shaper.action(event, what)) { + return true; + } else { + int len = this.parts.size(); + + for (int i = 0; i < len; i++) { + if (this.parts.elementAt(i).action(event, what)) { + return true; + } + } + + return false; + } + } + + public boolean handleEvent(Event e) { + return e.id == 201 ? maybeQuit() : false; + } + + public boolean okToQuit() { + return true; + } + + public static void quit() { + if (Gamma.getShaper() != null) { + Gamma.getShaper().maybeQuit(); + } else { + GammaFrameState.saveBorder(); + Main.end(); + } + } + + public static boolean maybeQuit() { + Console c = getActive(); + if (c == null || c.okToQuit()) { + quit(); + } + + return true; + } + + public static MenuBar getMenuBar() { + return menuBar; + } + + public Menu getMenu(String name) { + Menu menu = this.menus.get(name); + if (menu == null) { + if (!name.equals("Help") && !name.equals("Options") && !name.equals("VIP")) { + menu = new Menu(name); + menuBar.add(menu); + } else { + menu = new PopupMenu(); + } + + this.menus.put(name, menu); + } + + return menu; + } + + public void addMenuItem(MenuItem item, String menuName) { + this.getMenu(menuName).add(item); + item.setFont(font); + } + + public MenuItem addMenuItem(String itemName, String menuName) { + MenuItem item = new MenuItem(itemName); + this.getMenu(menuName).add(item); + item.setFont(font); + return item; + } + + public MenuItem addMenuItem(String itemName, String menuName, int keyCode, boolean shiftKey) { + MenuItem item = new MenuItem(itemName); + MenuShortcut shortcut = new MenuShortcut(keyCode, shiftKey); + item.setShortcut(shortcut); + this.getMenu(menuName).add(item); + item.setFont(font); + return item; + } + + public CheckboxMenuItem addMenuCheckbox(String itemName, String menuName) { + CheckboxMenuItem item = new CheckboxMenuItem(itemName); + this.getMenu(menuName).add(item); + item.setFont(font); + return item; + } + + @Override + public void dialogDisable(boolean disable) { + int len = this.parts.size(); + + for (int i = 0; i < len; i++) { + FramePart part = this.parts.elementAt(i); + if (part instanceof DialogDisabled) { + ((DialogDisabled)part).dialogDisable(disable); + } + } + } + + public static final native String encrypt(String var0); + + public static final native String decrypt(String var0); + + public static String encode(String password) { + String coded = ""; + if (password != null) { + char[] cryptChars = encrypt(password).toCharArray(); + + for (int i = 0; i < cryptChars.length; i++) { + String hex = Integer.toHexString(cryptChars[i]); + if (hex.length() == 1) { + hex = "0" + hex; + } + + coded = coded + hex; + } + } + + return coded; + } + + public static String decode(String password) { + try { + int length = password.length(); + if (length != 0 && (length & 1) == 0) { + char[] cryptChars = new char[length / 2]; + int j = 0; + + for (int i = 0; i < cryptChars.length; j += 2) { + cryptChars[i] = (char)Integer.parseInt(password.substring(j, j + 2), 16); + i++; + } + + String ret = decrypt(new String(cryptChars)); + if (ret != null && ret.length() != 0) { + return ret; + } + } + } catch (NumberFormatException var5) { + } + + return null; + } + + public static final native int getVolumeInfo(); + + public boolean getVIPAvatars() { + return vip > 0 || isRedLightWorld; + } + + public boolean getVIP() { + return vip > 0; + } + + public void setVIP(boolean vip) { + Console.vip = vip ? 1 : 0; + this.checkCourtesyVIP(); + IniFile.gamma().setIniInt("VIP", Console.vip); + if (autoFullVIP && vip) { + Console.vip = 2; + } + } + + public boolean getFullVIP() { + return vip == 2; + } + + public void setFullVIP(boolean fullVIP) { + if (fullVIP) { + vip = 2; + } + + IniFile.gamma().setIniInt("VIP", vip); + } + + public boolean getSpecialGuest() { + return spguest > 0; + } + + public void setSpecialGuest(boolean spguest) { + if (Console.spguest > 1 != spguest) { + Console.spguest = spguest ? 1 : 0; + IniFile.gamma().setIniInt("SPGUEST", Console.spguest); + Console.spguest = Console.spguest + Console.spguest; + } + } + + public void checkCourtesyVIP() { + int oldVIP = vip; + if (vip < 1) { + World w = this.getPilot().getWorld(); + vip = w != null && w.isHomeWorld() && w.getCourtesyVIP() ? 1 : 0; + } + + if (vip != oldVIP) { + if (vip == 1) { + println(message("You-VIP")); + } else { + println(message("You-no-VIP")); + } + } + + URL av = this.getDefaultAvatarURL(); + if (!av.equals(this.getAvatarName())) { + this.setAvatar(av); + } + } + + public boolean broadcastEnabled() { + return this.canBroadcast; + } + + public void enableBroadcast(boolean enabled) { + this.canBroadcast = enabled; + } + + public abstract URL getAvatarName(); + + public abstract void setChatname(String var1); + + public void serverStatus(WorldServer serv, VarErrorException ve) { + System.out.println("status-- " + serv + ": " + ve.getMsg()); + } + + @Override + public void property(OldPropertyList propList) { + assert false; + } + + @Override + public void propertyUpdate(PropertyList propList) { + assert false; + } + + @Override + public WorldServer getServer() { + URL url = this.getGalaxyURL(); + if (url != null && this.galaxy != null) { + try { + return this.getGalaxy().getServer(url); + } catch (InvalidServerURLException var3) { + println(">>" + var3.getMessage()); + return null; + } + } else { + return null; + } + } + + public WorldServer getServerNew() { + URL url = this.getGalaxyURL(); + if (url != null && this.galaxy != null) { + try { + return this.getGalaxy().getServer(url); + } catch (InvalidServerURLException var3) { + println(">>" + var3.getMessage()); + return null; + } + } else { + return null; + } + } + + @Override + public String getLongID() { + return this.galaxy.getChatname(); + } + + @Override + public void register() { + } + + @Override + public void galaxyDisconnected() { + this.setChatname(""); + this.galaxy.waitForConnection(this); + } + + @Override + public void reacquireServer(WorldServer oldServ) { + } + + @Override + public void changeChannel(Galaxy g, String oldChannel, String newChannel) { + this.pilot.changeChannel(g, oldChannel, newChannel); + } + + protected void handleVAR_BITMAP(String s) { + if (s.charAt(0) == 0) { + s = s.substring(2); + } + + try { + this.loadPilot(new URL(URL.getAvatar(), s)); + } catch (MalformedURLException var3) { + this.loadPilot(URL.make("error:\"" + s + '"')); + } + } + + protected void loadPilot(URL url) { + if (!url.equals(this.lastPilotRequested)) { + this.lastPilotRequested = url; + this.pendingPilot = url.toString(); + Pilot.load(url, this); + this.setFromMenu = false; + } + } + + @Override + public void wobLoaded(WobLoader loader, SuperRoot w) { + String err = null; + if (w == null) { + err = message("no-load-pilot"); + println(err + " " + loader.getWobName()); + } else if (!(w instanceof Pilot)) { + err = message("not-pilot"); + println(loader.getWobName().toString() + " " + err); + } else { + try { + this.setPilot((Pilot)w); + } catch (IllegalPilotException var7) { + err = var7.getMessage(); + } + } + + if (this.pilot == null && err != null && !this.disableSingleUserAccess) { + this.useDefaultPilot(); + err = null; + } + + int end = this.callbacks.size(); + + for (int i = 0; i < end; i++) { + LoadedURLSelf callback = this.callbacks.elementAt(i); + if (err == null) { + callback.loadedURLSelf(this, this.getSourceURL(), null); + } else { + this.decRef(); + callback.loadedURLSelf(null, this.getSourceURL(), err); + } + } + + this.callbacks.removeAllElements(); + } + + public static URL getDefaultURL() { + String defaultAvatar = IniFile.override().getIniString("DefaultAvatar", "avatar:pengo.mov"); + return URL.make(defaultAvatar); + } + + protected void useDefaultPilot() { + try { + this.setPilot(new HoloPilot(getDefaultURL())); + } catch (IllegalPilotException var2) { + assert false; + } + } + + public abstract void setOnlineState(boolean var1, boolean var2); + + @Override + public void connectionCallback(Object caller, boolean connected) { + if (caller instanceof Galaxy) { + if (caller != this.galaxy) { + return; + } + + if (!connected) { + return; + } + + this.setAvatar(this.lastPilotRequested); + this.displayAds(); + } + } + + public void displayAds() { + Pilot p = Pilot.getActive(); + if (p != null) { + World w = p.getWorld(); + if (w != null) { + w.setupAdBanner(); + } + } + } + + public void setDefaultAction(String newda) { + this.defaultAction = newda; + } + + public String getDefaultAction() { + return this.defaultAction; + } + + public URL getDefaultAvatarURL() { + String defAv = getDefaultURL().toString(); + String av = IniFile.gamma().getIniString("AVATAR", defAv); + String vav = IniFile.gamma().getIniString("VIPAVATAR", ""); + boolean isVIPAv = av.toLowerCase().endsWith(".rwg"); + if (vav.equals("")) { + vav = av; + if (isVIPAv) { + IniFile.gamma().setIniString("VIPAVATAR", av); + } + } + + if (this.tempCarAvatar != "") { + av = this.tempCarAvatar; + } else if (this.getVIPAvatars()) { + av = vav; + } else if (isVIPAv) { + av = defAv; + } + + return URL.make(av); + } + + public Console() { + this.add(this.cursor); + this.galaxy = Galaxy.getAnonGalaxy(); + this.regWithGalaxy(); + this.setServerURL(null); + } + + public Console(URL serverURL) { + this.add(this.cursor); + this.galaxy = Galaxy.getAnonGalaxy(); + this.regWithGalaxy(); + this.setServerURL(serverURL); + this.templateInit(); + } + + @Override + public void loadInit() { + this.templateInit(); + this.add(this.cursor); + } + + public void addCursor(Cursor c) { + this.add(c); + } + + private void templateInit() { + this.pilotSoulTemplate = new HoloPilot(); + this.droneSoulTemplate = new HoloDrone(); + this.add(this.pilotSoulTemplate); + this.add(this.droneSoulTemplate); + } + + public static void load(URL url, LoadedURLSelf callback) { + if (url != null && url.endsWith(".console")) { + new ConsoleLoader(url, callback); + } else { + Console c; + if (url == null) { + c = defaultUnshared; + } else { + c = defConsoles.get(url); + } + + if (c != null && c.galaxy == null) { + if (c.getGalaxyURL() == null) { + c.galaxy = Galaxy.getAnonGalaxy(); + } else { + try { + c.galaxy = Galaxy.getGalaxy(c.getGalaxyURL()); + } catch (InvalidServerURLException var5) { + System.out.println("Illegal ServerURL = " + c.getGalaxyURL()); + c.galaxy = Galaxy.getAnonGalaxy(); + c.setServerURL(null); + } + } + + c.regWithGalaxy(); + c.regPilot(); + } + + assert c == null || c.galaxy != null; + + if (c == null) { + try { + Class<?> cl = Class.forName(defaultConsole); + c = (Console)cl.newInstance(); + } catch (Exception var4) { + System.out.println("Can't use class " + defaultConsole + ", using DefaultConsole instead."); + var4.printStackTrace(System.out); + c = new DefaultConsole(); + } + + assert c != null; + + if (c.galaxy == null) { + c.galaxy = Galaxy.getAnonGalaxy(); + c.regWithGalaxy(); + c.regPilot(); + } + + assert c.galaxy != null; + + c.loadInit(); + c.setServerURL(url); + if (url == null) { + c.setName("unshared"); + defaultUnshared = c; + } else { + defConsoles.put(c.getGalaxyURL(), c); + } + } + + c.incRef(); + c.initPilot(url, callback); + } + } + + protected void initPilot(URL pilotURL, LoadedURLSelf callback) { + this.loadPilot(this.getDefaultAvatarURL()); + if (this.pilot == null) { + this.useDefaultPilot(); + } + + callback.loadedURLSelf(this, pilotURL, null); + } + + @Override + public void incRef() { + this.refcnt++; + } + + @Override + public void decRef() { + if (--this.refcnt == 0) { + if (this.galaxy != null) { + this.unregWithGalaxy(); + this.unregPilot(); + this.galaxy.decWorldCount(); + Galaxy oldGalaxy = this.galaxy; + this.galaxy = null; + } + + this.pilot = null; + URL url = this.getSourceURL(); + if (url != null) { + if (url.endsWith(".console")) { + URLSelfLoader.unload(this); + } else { + defConsoles.remove(url); + } + } + } + } + + @Override + public String toString() { + return super.toString() + "[" + this.getSourceURL() + "]"; + } + + public Pilot getPilotSoulTemplate() { + return this.pilotSoulTemplate; + } + + public Drone getDroneSoulTemplate() { + return this.droneSoulTemplate; + } + + public Pilot getPilot() { + return this.pilot; + } + + public boolean isValidAv() { + if (this.targetAv == null) { + return false; + } else if (!InventoryManager.getInventoryManager().inventoryInitialized()) { + return true; + } else { + String av = this.targetAv.getAbsolute(); + int len = av.length(); + + for (int i = 1; i < len; i++) { + if (av.charAt(i - 1) == '_') { + char firstChar = av.charAt(i); + if (Character.isLowerCase(firstChar)) { + StringBuffer item = new StringBuffer(); + item.append(Character.toUpperCase(firstChar)); + + while (++i < len) { + char c = av.charAt(i); + if (!Character.isLowerCase(c)) { + break; + } + + item.append(c); + } + + if (InventoryManager.getInventoryManager().checkInventoryFor(item.toString()) <= 0) { + return false; + } + } + } + } + + return true; + } + } + + public void resetAvatar() { + this.setAvatar(this.targetAv); + } + + public void setAvatar(URL url) { + if (url != null) { + BlackBox.getInstance().submitEvent(new BBDroneBitmapCommand("@Pilot", url.toString())); + this.targetAv = url; + this.targetValid = true; + if (url.getAbsolute().length() > 220) { + println(message("av-too-complex")); + url = URL.make("avatar:holden.mov"); + this.targetValid = false; + } else if (!this.isValidAv()) { + println(message("av-has-inventory")); + url = URL.make("avatar:holden.mov"); + this.targetValid = false; + } + + this.loadPilot(url); + WorldServer serv = this.getServerNew(); + if (serv != null) { + assert serv.getVersion() >= 18; + + PropertyList propList = new PropertyList(); + propList.addProperty(new net2Property(5, 64, 1, url.getAbsolute())); + + try { + serv.sendNetworkMsg(new PropertySetCmd(propList)); + } catch (PacketTooLargeException var5) { + assert url.getAbsolute().length() < 220; + + assert false; + } catch (InfiniteWaitException var6) { + } + } + } + } + + public static void wake() { + if (active != null) { + active.setSleepMode(null); + } + } + + public void goToSleep() { + this.setSleepMode(this.sleepStr); + Window.getAndResetUserActionCount(); + } + + public boolean isSleeping() { + return !this.sleepMode.equals(""); + } + + protected void setSleepMode(String mode) { + if (mode == null) { + mode = ""; + this.lastUserAction = Std.getFastTime(); + } + + if (this.pilot != null) { + this.pilot.setSleepMode(mode); + } + + if (!mode.equals(this.sleepMode)) { + WorldServer serv = this.getServerNew(); + if (serv != null) { + PropertyList propList = new PropertyList(); + propList.addProperty(new net2Property(23, 64, 1, mode)); + + try { + serv.sendNetworkMsg(new PropertySetCmd(propList)); + } catch (PacketTooLargeException var5) { + assert false; + } catch (InfiniteWaitException var6) { + } + + this.sleepMode = mode; + } + } + } + + public void setPilot(Pilot a) throws IllegalPilotException { + assert a != null; + + Room prevRoom = null; + if (this.pilot != null) { + prevRoom = this.pilot.getRoom(); + this.unregPilot(); + } + + this.pilot = a; + this.pilot.getSharer().createDynamicFromNet(); + this.pilot.setConsole(this); + this.regPilot(); + if (active == this) { + Pilot.changeActiveRoom(prevRoom); + } + + this.pilot.setSleepMode(this.sleepMode); + if (this instanceof DefaultConsole) { + ((DefaultConsole)this).resetCamera(); + } + } + + public static GammaFrame getFrame() { + return frame; + } + + public Galaxy getGalaxy() { + assert this.galaxy != null; + + return this.galaxy; + } + + public URL getGalaxyURL() { + return this._galaxyURL; + } + + public void setServerURL(URL serverURL) { + try { + if (serverURL != null) { + this._galaxyURL = URL.make("worldserver://" + getServerHost(serverURL) + "/"); + } + } catch (InvalidServerURLException var5) { + println(">>" + var5.getMessage()); + + assert false; + + this._galaxyURL = null; + } + + Galaxy oldGalaxy = this.galaxy; + this.unregWithGalaxy(); + this.unregPilot(); + if (this._galaxyURL != null) { + try { + this.galaxy = Galaxy.getGalaxy(this._galaxyURL); + } catch (InvalidServerURLException var4) { + println(">>" + var4.getMessage()); + this.galaxy = Galaxy.getAnonGalaxy(); + } + } else { + this.galaxy = Galaxy.getAnonGalaxy(); + } + + assert this.galaxy != null; + + this.regWithGalaxy(); + this.regPilot(); + if (oldGalaxy != null) { + oldGalaxy.decWorldCount(); + if (oldGalaxy != this.galaxy) { + oldGalaxy.forceObjectRereg(); + } + } + } + + private void regWithGalaxy() { + assert this.galaxy != null; + + this.galaxy.addConsole(this); + this.galaxy.waitForConnection(this); + } + + private void unregWithGalaxy() { + assert this.galaxy != null; + + this.galaxy.delConsole(this); + } + + protected void regPilot() { + if (this.pilot != null) { + this.pilot.getSharer().adjustShare(); + } + } + + public static String getServerHost(URL url) throws InvalidServerURLException { + String s = url.unalias(); + int len = s.length(); + if (len > 14 && s.startsWith("worldserver://")) { + if (s.charAt(len - 1) == '/') { + len--; + } + + s = s.substring(14, len); + if (s.equals("209.67.68.214:6650")) { + s = "www.3dcd.com:6650"; + } + + return s; + } else { + throw new InvalidServerURLException("Bad worldserver:// URL format"); + } + } + + public static URL makeServerURL(String host) { + assert host != null && host.length() > 0; + + return URL.make("worldserver://" + host + "/"); + } + + protected void unregPilot() { + if (this.pilot != null) { + this.pilot.getSharer().adjustShare(); + } + } + + public Cursor getCursor() { + return this.cursor; + } + + public String getScriptServer() { + String Fred = "Fred"; + String override = IniFile.override().getIniString("ScriptServer", Fred); + if (!override.equals(Fred)) { + return new String(override); + } else { + WorldServer server = this.getServerNew(); + if (server != null) { + String sname = server.getScriptServer(); + if (sname != null) { + return new String(sname); + } + } + + return new String("http://www-dynamic.us.worlds.net/cgi-bin/"); + } + } + + public String getSmtpServer() { + WorldServer server = this.getServerNew(); + if (server != null) { + String sname = server.getSmtpServer(); + if (sname != null) { + return sname; + } + } + + return "www.3dcd.com:25"; + } + + public String getMailDomain() { + WorldServer server = this.getServerNew(); + if (server != null) { + String dname = server.getMailDomain(); + if (dname != null) { + return dname; + } + } + + return "3dcd.com"; + } + + @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 = URLPropertyEditor.make(new Property(this, index, "Server URL").allowSetNull(), null); + } else if (mode == 1) { + ret = this.getGalaxyURL(); + } else if (mode == 2) { + if (value == null) { + this.setServerURL(null); + } else { + URL u = (URL)value; + if (u != null && !u.unalias().startsWith("worldserver:")) { + println(message("server-URL")); + } else { + this.setServerURL(u); + } + } + } + break; + case 1: + if (mode == 0) { + ret = BooleanPropertyEditor.make(new Property(this, index, "Enable Menu Bar"), "No", "Yes"); + } else if (mode == 1) { + ret = new Boolean(this.enableMenu); + } else if (mode == 2) { + this.setEnableMenu((Boolean)value); + } + break; + case 2: + if (mode == 0) { + ret = BooleanPropertyEditor.make(new Property(this, index, "Disable Shaper Access (irreversible!)"), "No", "Yes"); + } else if (mode == 1) { + ret = new Boolean(this.disableShaperAccess); + } else if (mode == 2) { + this.disableShaperAccess = (Boolean)value; + } + break; + case 3: + if (mode == 0) { + ret = BooleanPropertyEditor.make(new Property(this, index, "Disable Single-user Access"), "No", "Yes"); + } else if (mode == 1) { + ret = new Boolean(this.disableSingleUserAccess); + } else if (mode == 2) { + this.disableSingleUserAccess = (Boolean)value; + } + break; + case 4: + if (mode == 0) { + ret = new Property(this, index, "Pilot Soul Template"); + } else if (mode == 1) { + ret = this.pilotSoulTemplate; + } + break; + case 5: + if (mode == 0) { + ret = new Property(this, index, "Drone Soul Template"); + } else if (mode == 1) { + ret = this.droneSoulTemplate; + } + break; + case 6: + if (mode == 0) { + ret = new Property(this, index, "Cursor"); + } else if (mode == 1) { + ret = this.getCursor(); + } + break; + case 7: + if (mode == 0) { + ret = PropAdder.make(new VectorProperty(this, index, "Temporary Area")); + } else if (mode == 1) { + ret = this.tempArea.clone(); + } else if (mode == 4) { + this.tempArea.removeElement(value); + ((SuperRoot)value).detach(); + } else if (mode == 3) { + this.tempArea.addElement(value); + this.add((SuperRoot)value); + if (value instanceof Console) { + Console c = (Console)value; + if (c.pilotSoulTemplate == null) { + c.loadInit(); + } + } + } else if (mode == 5 && value instanceof SuperRoot && !(value instanceof Room)) { + ret = value; + } + break; + case 8: + if (mode == 0) { + ret = StringPropertyEditor.make(new Property(this, index, "Default Action")); + } else if (mode == 1) { + ret = this.getDefaultAction(); + } else if (mode == 2) { + this.setDefaultAction((String)value); + } + break; + default: + ret = super.properties(index, offset + 9, mode, value); + } + + return ret; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(4, classCookie); + super.saveState(s); + URL.save(s, this.getGalaxyURL()); + s.saveBoolean(this.enableMenu); + s.saveBoolean(this.disableShaperAccess); + s.saveString(this.defaultAction); + s.save(this.pilotSoulTemplate); + s.save(this.droneSoulTemplate); + s.save(this.cursor); + } + + private static URL restoreOldURL(Restorer r) throws IOException { + String s = r.restoreString(); + return s != null && !s.equals("UNSHARED") ? makeServerURL(s) : null; + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + int vers = r.restoreVersion(classCookie); + switch (vers) { + case 0: + case 1: + WObject w = new WObject(); + w.restoreState(r); + this.setName(w.getName()); + this.templateInit(); + Enumeration<Attribute> e = w.getAttributes(); + + while (e.hasMoreElements()) { + Attribute a = e.nextElement(); + a.setAttrID(a.getForwardAttrID()); + } + + Pilot.copySoul(w, this.pilotSoulTemplate); + this.setServerURL(restoreOldURL(r)); + this.enableMenu = r.restoreBoolean(); + this.disableShaperAccess = r.restoreBoolean(); + if (vers == 1) { + this.cursor = (Cursor)r.restore(); + } + break; + case 2: + super.restoreState(r); + this.setServerURL(restoreOldURL(r)); + this.enableMenu = r.restoreBoolean(); + this.disableShaperAccess = r.restoreBoolean(); + this.pilotSoulTemplate = (Pilot)r.restore(); + this.add(this.pilotSoulTemplate); + this.droneSoulTemplate = (Drone)r.restore(); + this.add(this.droneSoulTemplate); + this.cursor = (Cursor)r.restore(); + break; + case 3: + super.restoreState(r); + this.setServerURL(restoreOldURL(r)); + this.enableMenu = r.restoreBoolean(); + this.disableShaperAccess = r.restoreBoolean(); + this.defaultAction = r.restoreString(); + this.pilotSoulTemplate = (Pilot)r.restore(); + this.add(this.pilotSoulTemplate); + this.droneSoulTemplate = (Drone)r.restore(); + this.add(this.droneSoulTemplate); + this.cursor = (Cursor)r.restore(); + break; + case 4: + super.restoreState(r); + this.setServerURL(URL.restore(r)); + this.enableMenu = r.restoreBoolean(); + this.disableShaperAccess = r.restoreBoolean(); + this.defaultAction = r.restoreString(); + this.pilotSoulTemplate = (Pilot)r.restore(); + this.add(this.pilotSoulTemplate); + this.droneSoulTemplate = (Drone)r.restore(); + this.add(this.droneSoulTemplate); + this.cursor = (Cursor)r.restore(); + break; + default: + throw new TooNewException(); + } + + this.add(this.cursor); + } +} diff --git a/NET/worlds/console/ConsoleLoader.java b/NET/worlds/console/ConsoleLoader.java new file mode 100644 index 0000000..5bb2fd8 --- /dev/null +++ b/NET/worlds/console/ConsoleLoader.java @@ -0,0 +1,29 @@ +package NET.worlds.console; + +import NET.worlds.network.URL; +import NET.worlds.scape.LoadedURLSelf; +import NET.worlds.scape.URLSelf; +import NET.worlds.scape.URLSelfLoader; + +class ConsoleLoader implements LoadedURLSelf { + private LoadedURLSelf callback; + + public ConsoleLoader(URL url, LoadedURLSelf callback) { + this.callback = callback; + URLSelfLoader.load(url, this, true); + } + + @Override + public void loadedURLSelf(URLSelf o, URL url, String err) { + Console c = (Console)o; + if (err == null && c.pilot == null) { + if (c.disableSingleUserAccess) { + c.callbacks.addElement(this.callback); + } else { + c.initPilot(url, this.callback); + } + } else { + this.callback.loadedURLSelf(o, url, err); + } + } +} diff --git a/NET/worlds/console/Conveyor.java b/NET/worlds/console/Conveyor.java new file mode 100644 index 0000000..a0e899e --- /dev/null +++ b/NET/worlds/console/Conveyor.java @@ -0,0 +1,60 @@ +package NET.worlds.console; + +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.FrameHandler; +import NET.worlds.scape.Point3; +import NET.worlds.scape.Point3Temp; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Saver; +import NET.worlds.scape.SuperRoot; +import NET.worlds.scape.TooNewException; +import NET.worlds.scape.WObject; +import java.io.IOException; +import java.util.Enumeration; + +public class Conveyor extends SuperRoot implements FrameHandler { + private Point3 vector; + private static Object classCookie = new Object(); + + public Conveyor(Point3Temp direction, float speed) { + this.vector = new Point3(direction.normalize().times(speed)); + } + + public Conveyor(Point3Temp v) { + this.vector = new Point3(v); + } + + @Override + public boolean handle(FrameEvent e) { + Enumeration<WObject> stuff = (Enumeration<WObject>)e.receiver.getContents(); + Point3Temp delta = this.vector; + delta.times(e.dt / 1000.0F); + + while (stuff.hasMoreElements()) { + WObject thing = stuff.nextElement(); + thing.moveThrough(delta); + } + + return true; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(1, classCookie); + super.saveState(s); + s.save(this.vector); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + switch (r.restoreVersion(classCookie)) { + case 1: + super.restoreState(r); + case 0: + this.vector = (Point3)r.restore(); + return; + default: + throw new TooNewException(); + } + } +} diff --git a/NET/worlds/console/Cursor.java b/NET/worlds/console/Cursor.java new file mode 100644 index 0000000..a9c9f3c --- /dev/null +++ b/NET/worlds/console/Cursor.java @@ -0,0 +1,218 @@ +package NET.worlds.console; + +import NET.worlds.network.URL; +import NET.worlds.scape.BGLoaded; +import NET.worlds.scape.BackgroundLoader; +import NET.worlds.scape.NoSuchPropertyException; +import NET.worlds.scape.Property; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Room; +import NET.worlds.scape.Saver; +import NET.worlds.scape.SuperRoot; +import NET.worlds.scape.TooNewException; +import NET.worlds.scape.URLPropertyEditor; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Enumeration; +import java.util.Hashtable; + +public class Cursor extends SuperRoot implements BGLoaded { + private URL url = URL.make("system:DEFAULT_CURSOR"); + private int hCursor; + private static Cursor active; + private static Hashtable<URL, Comparable> sysCursors = new Hashtable<URL, Comparable>(); + private static int defaultCursor = retrieveSystemCursor(addCursor("DEFAULT_CURSOR", "IDC_ARROW")); + private static Object classCookie; + + static { + assert defaultCursor != 0; + + addCursor("CROSSHAIR_CURSOR", "IDC_CROSS"); + addCursor("TEXT_CURSOR", "IDC_IBEAM"); + addCursor("WAIT_CURSOR", "IDC_WAIT"); + addCursor("NE_RESIZE_CURSOR", "IDC_SIZENESW"); + addCursor("SW_RESIZE_CURSOR", "IDC_SIZENESW"); + addCursor("NW_RESIZE_CURSOR", "IDC_SIZENWSE"); + addCursor("SE_RESIZE_CURSOR", "IDC_SIZENWSE"); + addCursor("N_RESIZE_CURSOR", "IDC_SIZENS"); + addCursor("S_RESIZE_CURSOR", "IDC_SIZENS"); + addCursor("W_RESIZE_CURSOR", "IDC_SIZEWE"); + addCursor("E_RESIZE_CURSOR", "IDC_SIZEWE"); + addCursor("HAND_CURSOR", "IDC_UPARROW"); + addCursor("MOVE_CURSOR", "IDC_SIZEALL"); + addCursor("CANNOT_CURSOR", "IDC_NO"); + classCookie = new Object(); + } + + private static URL addCursor(String javaName, String win32Name) { + URL url = URL.make("system:" + javaName); + sysCursors.put(url, win32Name); + return url; + } + + public Cursor() { + } + + public Cursor(URL url) { + this.setURL(url); + } + + public void setURL(URL url) { + this.url = url; + if (!url.unalias().startsWith("system:")) { + BackgroundLoader.get(this, url); + } else { + this.activate(); + } + } + + public static Cursor getActive() { + return active; + } + + public void activate() { + SuperRoot owner = this.getOwner(); + if (owner != null && owner == Console.getActive()) { + int sysCurs = retrieveSystemCursor(this.url); + if (sysCurs != 0) { + Window.setCursor(sysCurs); + this.maybeDestroyCursor(); + this.hCursor = sysCurs; + } else if (this.hCursor != 0) { + Window.setCursor(this.hCursor); + } + + active = this; + } + } + + public void deactivate() { + if (active == this) { + active = null; + } + } + + public URL getURL() { + return this.url; + } + + public static Enumeration<URL> getSysCursorURLs() { + return sysCursors.keys(); + } + + public static native int getSystemCursorWidth(); + + public static native int getSystemCursorHeight(); + + public static native int getSystemCursorDepth(); + + private static native int loadCursor(String var0); + + private static native int loadSystemCursor(String var0); + + private static native void destroyCursor(int var0); + + private static int retrieveSystemCursor(URL url) { + int handle = 0; + Object c = sysCursors.get(url); + if (c != null) { + if (c instanceof String) { + handle = loadSystemCursor((String)c); + sysCursors.put(url, new Integer(handle)); + } else { + handle = (Integer)c; + } + } + + return handle; + } + + private void maybeDestroyCursor() { + if (this.hCursor != 0) { + if (!sysCursors.contains(new Integer(this.hCursor))) { + destroyCursor(this.hCursor); + } + + this.hCursor = 0; + } + } + + @Override + public Object asyncBackgroundLoad(String localName, URL remoteName) { + this.deactivate(); + this.maybeDestroyCursor(); + if (localName == null) { + return null; + } else { + if ((this.hCursor = loadCursor(localName)) != 0) { + this.activate(); + } + + return null; + } + } + + @Override + public boolean syncBackgroundLoad(Object obj, URL remoteURL) { + if (this.hCursor == 0) { + Object[] arguments = new Object[]{new String("" + this.url)}; + Console.println(MessageFormat.format(Console.message("Load-cursor"), arguments)); + } + + return false; + } + + @Override + public Room getBackgroundLoadRoom() { + SuperRoot owner = this.getOwner(); + return owner != null && owner instanceof Console ? ((Console)owner).getPilot().getRoom() : null; + } + + @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 = URLPropertyEditor.make(new Property(this, index, "File"), "cur;ani", getSysCursorURLs()); + } else if (mode == 1) { + ret = this.getURL(); + } else if (mode == 2) { + this.setURL((URL)value); + } + break; + default: + ret = super.properties(index, offset + 1, mode, value); + } + + return ret; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(1, classCookie); + super.saveState(s); + URL.save(s, this.url); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + switch (r.restoreVersion(classCookie)) { + case 0: + r.restoreMaybeNull(); + String s = r.restoreString(); + if (!s.endsWith(".cur") && !s.endsWith(".ani")) { + this.setURL(URL.make("system:" + this.url)); + } else { + this.setURL(URL.restore(r, s, null)); + } + break; + case 1: + super.restoreState(r); + this.setURL(URL.restore(r)); + break; + default: + throw new TooNewException(); + } + } +} diff --git a/NET/worlds/console/DefaultConsole.java b/NET/worlds/console/DefaultConsole.java new file mode 100644 index 0000000..557bd71 --- /dev/null +++ b/NET/worlds/console/DefaultConsole.java @@ -0,0 +1,1999 @@ +package NET.worlds.console; + +import NET.worlds.core.ArchiveMaker; +import NET.worlds.core.IniFile; +import NET.worlds.core.Std; +import NET.worlds.network.Galaxy; +import NET.worlds.network.NetUpdate; +import NET.worlds.network.RemoteFileConst; +import NET.worlds.network.URL; +import NET.worlds.network.WorldServer; +import NET.worlds.scape.BooleanPropertyEditor; +import NET.worlds.scape.CDAudio; +import NET.worlds.scape.CDControl; +import NET.worlds.scape.CDPlayerAction; +import NET.worlds.scape.EquipAction; +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.MusicManager; +import NET.worlds.scape.NoSuchPropertyException; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.PosableShape; +import NET.worlds.scape.Property; +import NET.worlds.scape.RenderWare; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Saver; +import NET.worlds.scape.SelectAvatarAction; +import NET.worlds.scape.SendURLAction; +import NET.worlds.scape.TeleportAction; +import NET.worlds.scape.TooNewException; +import NET.worlds.scape.URLPropertyEditor; +import NET.worlds.scape.VehicleShape; +import NET.worlds.scape.World; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.CheckboxMenuItem; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.Label; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.text.Collator; +import java.text.DateFormat; +import java.text.MessageFormat; +import java.util.Date; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.NoSuchElementException; +import java.util.ResourceBundle; +import java.util.StringTokenizer; +import java.util.Vector; + +public class DefaultConsole extends Console implements DialogReceiver, ImageButtonsCallback, RemoteFileConst { + MenuItem aboutItem; + MenuItem statisticsItem; + MenuItem upgradeItem; + MenuItem channelItem; + MenuItem infoItem; + MenuItem sleepItem; + MenuItem helpItem; + MenuItem gettingStartedItem; + MenuItem serverItem; + MenuItem numVisItem; + MenuItem checkAccountItem; + MenuItem becomeVIPItem; + MenuItem toggleVoiceChatItem; + MenuItem chatItem; + MenuItem shaperHelpItem; + MenuItem inventoryItem; + MenuItem checkInventoryItem; + MenuItem bankItem; + MenuItem ubuItem; + MenuItem proxyServerItem; + MenuItem musicManItem; + MenuItem condenseItem; + MenuItem expandItem; + MenuItem i18nTest; + MenuItem currentLang; + Menu switchLang; + Vector<MenuItem> downItems = null; + Vector<MenuItem> langItems = null; + Vector<MenuItem> fontItems = null; + static final String LANGUAGES = "languages.lst"; + static final String FONTS = "fonts.lst"; + Vector<CheckboxMenuItem> viewItems = null; + Vector<CheckboxMenuItem> camSpeedItems = null; + CheckboxMenuItem currentViewItem; + CheckboxMenuItem currentCamSpeedItem; + ImageButtons driveButton; + ImageButtons quitButton; + ImageButtons exploreButton; + ImageButtons menuButtons; + ImageButtons adCubeButton; + String defaultAd = IniFile.override().getIniString("defaultAd", "home:adworlds.cmp"); + AdPart ad = new AdPart(URL.make(this.defaultAd)); + ColorFiller adFiller; + ChatPart chat = new ChatPart(); + RenderCanvas render = new RenderCanvas(this, new Dimension(560, 360)); + Panel renderAndUniverse; + UniversePanel universe; + CardLayout renderCard; + InventoryPart inventory = new InventoryPart(); + WorldsMarkPart marks = new WorldsMarkPart(); + FriendsListPart friends = new FriendsListPart(); + ActionsPart actions = new ActionsPart(); + MuteListPart mutes = new MuteListPart(); + MapPart map = new MapPart(); + SavedAvPart savedAvs = new SavedAvPart(); + private static Font font = new Font(Console.message("ConsoleFont"), 0, 12); + private static Font mfont = new Font(Console.message("MenuFont"), 0, 12); + private static int chatLines = IniFile.gamma().getIniInt("ChatLines", 6); + private static int maxWebSize = 540; + CDControl cdcontrol; + boolean playedCD; + MenuItem cdPlayerItem; + MenuItem volumeItem; + MenuItem graphicsItem; + MenuItem nametagItem; + MenuItem chatBoxItem; + MenuItem broadcastToRoom; + MenuItem broadcastToAll; + MenuItem bootSomeone; + CheckboxMenuItem orthographicViewItem; + MenuItem recorderPlayItem; + MenuItem recorderRecItem; + MenuItem recorderStopItem; + boolean universeMode; + private static final int[] menuButtonHeights = new int[]{23, 21, 21, 21, 21, 21, 25, -29}; + private Vector<DefaultConsole.CameraView> viewNames; + private Vector<DefaultConsole.CameraSpeed> speedNames; + private static final int HELP = 0; + private static final int OPTIONS = 1; + private static final int WORLDSMAIL = 2; + private static final int WORLDSMARK = 3; + private static final int LETS = 4; + private static final int ACTIONS = 5; + private static final int VIP = 6; + static String loadingString = Console.message("Loading"); + static String arrowKeyMsg = Console.message("Use-arrow-keys"); + String statusMessage = arrowKeyMsg; + String overrideMessage; + String lastStatus = ""; + int lastUpdateTime = 0; + boolean wasTeleporting = false; + private int lastVMCheck; + private int lastVMBigWarning; + Component bottom; + Component top; + Label status = new UnpaddedLabel("", 2); + Label yourName = new UnpaddedLabel("", 0); + static String[] lNames = lpList(); + static int lLength = lNames.length; + static MenuItem[] lLangs = new MenuItem[lLength]; + static Locale[] newLocale = new Locale[lLength]; + static String[][] lCodes = new String[lLength][2]; + Vector<String> lList = new Vector<String>(); + Vector<String> sList = new Vector<String>(); + int[] lSizes = new int[10]; + int dLength = this.dpList(this.lList, this.sList, this.lSizes); + MenuItem[] dLangs = this.dLength == 0 ? null : new MenuItem[this.dLength]; + Locale[] newdLocale = this.dLength == 0 ? null : new Locale[this.dLength]; + Vector<String> flList = new Vector<String>(); + Vector<String> fsList = new Vector<String>(); + int[] fSizes = new int[10]; + int fLength = this.fpList(this.flList, this.fsList, this.fSizes); + MenuItem[] dFonts = this.fLength == 0 ? null : new MenuItem[this.fLength]; + Locale[] newfLocale = this.fLength == 0 ? null : new Locale[this.fLength]; + static boolean wasDelta; + static boolean doDrive; + Panel mapPanel; + private static String signIn = Console.message("Sign-In"); + private static String signOut = Console.message("Sign-Out"); + private static String signingIn = Console.message("Signing-In"); + private static String noMultiUser = Console.message("Network"); + private static String enable3D = Console.message("Enable3D"); + private static String disable3D = Console.message("Disable3D"); + private static String showTags = Console.message("ShowNametags"); + private static String hideTags = Console.message("HideNametags"); + private static String enableClassicChat = Console.message("EnableClassicChat"); + private static String disableClassicChat = Console.message("DisableClassicChat"); + private static String configureChat = Console.message("Config-Chat"); + Menu chatLogMenu; + AvMenu avatarMenu; + private int chooseView = -1; + private int chooseCamSpeed = -1; + private static String sleepStatus = Console.message("Sleeping"); + OkCancelDialog reloginDialog; + private Object nextAvatarMutex = new Object(); + private URL nextAvatar; + private CheckboxMenuItem nextAvatarItem; + private CheckboxMenuItem curAvatarItem; + private static String lastWorldName = ""; + private static String lowVMMsg = Console.message("Low-virt"); + private boolean showedMidWarn; + private static boolean startupMemCheck = true; + public static int physMem; + protected URL avatarURL; + private static Object classCookie = new Object(); + + public UniversePanel getUniversePanel() { + return this.universe; + } + + @Override + public void printLine(String msg) { + this.chat.println(msg); + super.printLine(msg); + } + + @Override + protected void printWhisperFrom(String from, String msg) { + WhisperManager.whisperManager().printFrom(from, msg); + } + + @Override + protected void printWhisperTo(String to, String msg) { + WhisperManager.whisperManager().printTo(to, msg); + } + + @Override + protected void startWhisperingTo(String to) { + WhisperManager.whisperManager().startTo(to); + } + + public DefaultConsole() { + this.init(); + this.loadViewNames(); + this.speedNames = new Vector<DefaultConsole.CameraSpeed>(); + this.speedNames.addElement(new DefaultConsole.CameraSpeed("Slow", 1)); + this.speedNames.addElement(new DefaultConsole.CameraSpeed("Medium", 2)); + this.speedNames.addElement(new DefaultConsole.CameraSpeed("Fast", 3)); + } + + public void loadViewNames() { + this.viewNames = new Vector<DefaultConsole.CameraView>(); + this.viewNames.addElement(new DefaultConsole.CameraView("First-person", 1)); + this.viewNames.addElement(new DefaultConsole.CameraView("Low-first-person", 2)); + this.viewNames.addElement(new DefaultConsole.CameraView("Waist", 3)); + this.viewNames.addElement(new DefaultConsole.CameraView("Shoulder", 4)); + this.viewNames.addElement(new DefaultConsole.CameraView("Head", 5)); + this.viewNames.addElement(new DefaultConsole.CameraView("Overhead", 6)); + this.viewNames.addElement(new DefaultConsole.CameraView("Behind", 7)); + this.viewNames.addElement(new DefaultConsole.CameraView("Wide-shot", 8)); + if (Gamma.getShaper() != null) { + this.viewNames.addElement(new DefaultConsole.CameraView("Orthographic", 9)); + } + } + + public void setOrthoEnabled(boolean in) { + if (this.orthographicViewItem != null) { + this.orthographicViewItem.setEnabled(in); + } + } + + @Override + public void loadInit() { + super.loadInit(); + } + + public void removeUseArrowStatusMsg() { + if (this.statusMessage == arrowKeyMsg) { + this.statusMessage = ""; + } + } + + public void overrideStatusMsg(String msg) { + synchronized (this.status) { + this.overrideMessage = msg; + if (msg != null) { + this.status.setText(msg); + } else { + this.status.setText(this.lastStatus); + } + } + } + + public String message(String Id, Locale currentLocale) { + Locale.setDefault(currentLocale); + Console.println(currentLocale.getDisplayName()); + + try { + ResourceBundle messages = ResourceBundle.getBundle("MessagesBundle", currentLocale); + return messages.getString(Id); + } catch (MissingResourceException var4) { + return "NO MESSAGE for " + Id; + } + } + + private void init() { + this.addPart(this.render); + this.addPart(this.chat); + this.addPart(this.inventory); + this.addPart(this.marks); + this.addPart(this.friends); + this.addPart(this.actions); + this.addPart(this.mutes); + this.addPart(this.ad); + this.addPart(this.map); + this.addPart(this.savedAvs); + Panel drivePanel = new Panel(new FlowLayout(1, 0, 0)); + String driveGif = IniFile.override().getIniString("driveGif", "drive.gif"); + this.addPart(this.driveButton = new ImageButtons(driveGif, 81, 19, this)); + String quitGif = IniFile.override().getIniString("quitGif", Console.message("quit.gif")); + this.addPart(this.quitButton = new ImageButtons(quitGif, 65, 19, this)); + String exploreGif = IniFile.override().getIniString("exploreGif", Console.message("explore.gif")); + this.addPart(this.exploreButton = new ImageButtons(exploreGif, 98, 22, this)); + drivePanel.add(this.driveButton); + this.driveButton.setDownUpHandler(new ImageButtonsCallback() { + @Override + public Object imageButtonsCallback(Component who, int which) { + if (which != -1) { + DefaultConsole.this.startDrive(); + } else { + DefaultConsole.this.driveButton.drawDown(); + } + + return this; + } + }); + Panel mid = new Panel(); + mid.setLayout(new GridLayout(1, 3)); + int bgR = IniFile.override().getIniInt("uiBackgroundRed", 49); + int bgG = IniFile.override().getIniInt("uiBackgroundGreen", 0); + int bgB = IniFile.override().getIniInt("uiBackgroundBlue", 255); + mid.setBackground(new Color(bgR, bgG, bgB)); + mid.add(this.yourName); + mid.add(drivePanel); + mid.add(this.status); + this.chat.line.setBackground(Color.black); + this.chat.line.setForeground(Color.white); + this.chat.line.setFont(font); + Panel chatter = new InsetPanel(new BorderLayout(0, 3), 0, 0, 3, 0); + chatter.add("North", mid); + chatter.add("Center", this.chat.listen.getComponent()); + chatter.add("South", this.chat.line); + this.chat.listen.setBackground(Color.black); + this.chat.listen.setForeground(Color.white); + this.chat.listen.setFont(font); + Panel p = new Panel(new BorderLayout()); + new Panel(new BorderLayout()); + Panel r = new Panel(new BorderLayout()); + Panel s = new Panel(new BorderLayout()); + ColorFiller qBlue1 = new ColorFiller(65, 19); + qBlue1.setBackground(new Color(bgR, bgG, bgB)); + r.add("West", this.quitButton); + r.add("East", qBlue1); + int bgbR = IniFile.override().getIniInt("uiBackground2Red", 0); + int bgbG = IniFile.override().getIniInt("uiBackground2Green", 0); + int bgbB = IniFile.override().getIniInt("uiBackground2Blue", 0); + s.add("North", r); + s.add("Center", this.ad); + if (chatLines > 6) { + int h = chatLines * this.chat.listen.getComponent().getFontMetrics(this.chat.listen.getFont()).getHeight(); + h -= 96; + if (h > 0) { + this.adFiller = new ColorFiller(130, h); + this.adFiller.setBackground(new Color(bgbR, bgbG, bgbB)); + s.add("South", this.adFiller); + } + } + + p.add("West", s); + this.mapPanel = new Panel(new BorderLayout()); + this.mapPanel.add("Center", this.map); + this.mapPanel.setBackground(Color.black); + r = new Panel(new BorderLayout()); + ColorFiller qBlue = new ColorFiller(60, 19); + qBlue.setBackground(new Color(bgR, bgG, bgB)); + r.add("North", qBlue); + ColorFiller qBlack = new ColorFiller(60, 3); + qBlack.setBackground(new Color(bgbR, bgbG, bgbB)); + r.add("South", qBlack); + Panel bgbRx = new Panel(new BorderLayout()); + bgbRx.add("East", this.exploreButton); + bgbRx.add("West", r); + this.mapPanel.add("North", bgbRx); + p.add("East", this.mapPanel); + p.add("Center", chatter); + this.bottom = p; + this.renderCard = new CardLayout(); + this.renderAndUniverse = new Panel(this.renderCard); + this.renderAndUniverse.add("render", this.render); + p = new InsetPanel(new BorderLayout(), 3, 3, 0, 0); + p.add("Center", this.renderAndUniverse); + int bgbRxx = IniFile.override().getIniInt("uiBackground3Red", 0); + int bgbGx = IniFile.override().getIniInt("uiBackground3Green", 0); + int bgbBx = IniFile.override().getIniInt("uiBackground3Blue", 0); + qBlue1 = new ColorFiller(97, 1); + qBlue1.setBackground(new Color(bgbRxx, bgbGx, bgbBx)); + Panel rt = new Panel(new QuantizedStackedLayout(qBlue1)); + String panelGif = IniFile.override().getIniString("rtPanel", Console.message("rtpanel.gif")); + this.addPart(this.menuButtons = new ImageButtons(panelGif, 97, menuButtonHeights, this)); + rt.add(qBlue1); + rt.add(this.menuButtons); + rt.add(this.friends); + p.add("East", rt); + this.top = p; + } + + public void relayoutMap() { + this.mapPanel.invalidate(); + this.mapPanel.validate(); + this.mapPanel.doLayout(); + this.mapPanel.repaint(); + } + + public void startDrive() { + this.statusMessage = Console.message("Drag-mouse"); + doDrive = true; + Window.makeJavaReleaseCapture(); + } + + @Override + public void setOnlineState(boolean enabled, boolean online) { + synchronized (this) { + if (this.serverItem != null) { + this.serverItem.setEnabled(enabled); + if (!enabled) { + Galaxy g = this.getGalaxy(); + if (g != null && !g.isAnonymous()) { + this.serverItem.setLabel(signingIn); + } else { + this.serverItem.setLabel(noMultiUser); + } + } else if (online) { + this.serverItem.setLabel(signOut); + } else { + this.serverItem.setLabel(signIn); + } + } + } + } + + private void handleNametagsItem() { + if (IniFile.gamma().getIniInt("SHOWNAMETAGS", 1) == 0) { + IniFile.gamma().setIniInt("SHOWNAMETAGS", 1); + this.nametagItem.setLabel(hideTags); + } else { + IniFile.gamma().setIniInt("SHOWNAMETAGS", 0); + this.nametagItem.setLabel(showTags); + } + + new OkCancelDialog(getFrame(), null, Console.message("Alert"), null, Console.message("OK"), Console.message("Change-exit"), true); + } + + private void handleGraphicsItem() { + if (IniFile.gamma().getIniInt("UserEnabled3DHardware", 0) == 0) { + IniFile.gamma().setIniInt("UserEnabled3DHardware", 1); + this.graphicsItem.setLabel(disable3D); + } else { + IniFile.gamma().setIniInt("UserEnabled3DHardware", 0); + this.graphicsItem.setLabel(enable3D); + } + + new OkCancelDialog(getFrame(), null, Console.message("Alert"), null, Console.message("OK"), Console.message("Change-exit"), true); + } + + private void handleChatBoxItem() { + if (IniFile.gamma().getIniInt("classicChatBox", 1) == 0) { + IniFile.gamma().setIniInt("classicChatBox", 1); + this.chatBoxItem.setLabel(disableClassicChat); + } else { + IniFile.gamma().setIniInt("classicChatBox", 0); + this.chatBoxItem.setLabel(enableClassicChat); + } + + new OkCancelDialog(getFrame(), null, Console.message("Alert"), null, Console.message("OK"), Console.message("Change-exit"), true); + } + + public AvMenu getAvatarMenu() { + return this.avatarMenu; + } + + @Override + public void inventoryChanged() { + super.inventoryChanged(); + if (this.avatarMenu != null) { + this.avatarMenu.buildSpecialGuestMenu(); + } + } + + public void setMenusWRTVIP() { + if (this.avatarMenu != null) { + this.avatarMenu.setEnabled(this.getVIP()); + this.avatarMenu.customize.setEnabled(this.getVIP()); + } + + if (this.savedAvs != null) { + this.savedAvs.setEnabled(this.getVIP()); + } + + if (this.chatLogMenu != null) { + this.chatLogMenu.setEnabled(this.getVIP()); + } + + if (this.toggleVoiceChatItem != null) { + this.toggleVoiceChatItem.setLabel(this.getVIP() && VoiceChat.voiceChatEnabled ? Console.message("Reject-Voice") : Console.message("Accept-Voice")); + this.toggleVoiceChatItem.setEnabled(this.getVIP() && VoiceChat.voiceChatAvailable()); + } + + if (this.becomeVIPItem != null) { + this.becomeVIPItem.setLabel(vip > 0 ? (vip > 1 ? Console.message("Youre-a-VIP") : Console.message("Become-full-VIP")) : Console.message("Become-VIP")); + } + + if (this.numVisItem != null) { + this.numVisItem.setEnabled(this.getVIP()); + } + } + + public void addBroadcastMenu() { + if (this.bootSomeone == null) { + if (IniFile.gamma().getIniInt("Broadcast", 0) != 0) { + Menu menu = new Menu(Console.message("Broadcast")); + menu.add(this.broadcastToRoom = new MenuItem(Console.message("Users"))); + menu.add(this.broadcastToAll = new MenuItem(Console.message("All-users"))); + this.addMenuItem(menu, "Options"); + } + + this.bootSomeone = new MenuItem(Console.message("Boot-user")); + this.addMenuItem(this.bootSomeone, "Options"); + } + } + + private Menu updateChatLogMenu() { + if (this.chatLogMenu == null) { + this.chatLogMenu = new Menu(Console.message("View-Chat")); + } else { + this.chatLogMenu.removeAll(); + } + + ActionListener logAction = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + new SendURLAction("file:" + e.getActionCommand()).startBrowser(); + } + }; + String[] list = this.logList(); + MenuItem item = null; + + for (int i = 0; i < list.length; i++) { + int si = list[i].indexOf(".glog.html"); + if (si > 6) { + Object[] arguments = new Object[]{new String(list[i].substring(5, si))}; + item = new MenuItem(MessageFormat.format(Console.message("Chat-with"), arguments)); + } else { + if (si <= 0) { + continue; + } + + item = new MenuItem(Console.message("General-chat")); + } + + item.setActionCommand(list[i]); + item.addActionListener(logAction); + this.chatLogMenu.add(item); + } + + return this.chatLogMenu; + } + + private String[] logList() { + File dir = new File("."); + FilenameFilter f = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.startsWith("chat.") && name.endsWith(".glog.html"); + } + }; + return dir.list(f); + } + + private static String[] lpList() { + File dir = new File("."); + FilenameFilter f = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.startsWith("MessagesBundle") && name.endsWith(".properties"); + } + }; + String[] list = dir.list(f); + Collator sortCollator = Collator.getInstance(); + sortStrings(sortCollator, list); + return list; + } + + private int dpList(Vector<String> lList, Vector<String> sList, int[] lSizes) { + String err = NetUpdate.getLanguages(URL.make(NetUpdate.getUpgradeServerURL() + "I18N/" + "languages.lst"), lList, sList, lSizes); + if (err != null) { + System.out.println(err); + return 0; + } else { + return lList.size(); + } + } + + private int fpList(Vector<String> lList, Vector<String> sList, int[] lSizes) { + String err = NetUpdate.getLanguages(URL.make(NetUpdate.getUpgradeServerURL() + "I18N/" + "fonts.lst"), lList, sList, lSizes); + if (err != null) { + System.out.println(err); + return 0; + } else { + return lList.size(); + } + } + + public static void sortStrings(Collator collator, String[] words, Locale[] Locales, String[][] Codes) { + for (int i = 0; i < words.length; i++) { + for (int j = i + 1; j < words.length; j++) { + if (collator.compare(words[i], words[j]) > 0) { + String tmp = words[i]; + Locale ltmp = Locales[i]; + String c0 = Codes[i][0]; + String c1 = Codes[i][1]; + words[i] = words[j]; + Locales[i] = Locales[j]; + Codes[i][0] = Codes[j][0]; + Codes[i][1] = Codes[j][1]; + words[j] = tmp; + Locales[j] = ltmp; + Codes[j][0] = c0; + Codes[j][1] = c1; + } + } + } + } + + public static void sortStrings(Collator collator, String[] words, Locale[] Locales, Vector<String> CodeL, Vector<String> CodeS) { + for (int i = 0; i < words.length; i++) { + for (int j = i + 1; j < words.length; j++) { + if (collator.compare(words[i], words[j]) > 0) { + String tmp = words[i]; + Locale ltmp = Locales[i]; + String c0 = CodeL.elementAt(i); + String c1 = CodeS.elementAt(i); + words[i] = words[j]; + Locales[i] = Locales[j]; + CodeL.setElementAt(CodeL.elementAt(j), i); + CodeS.setElementAt(CodeS.elementAt(j), i); + words[j] = tmp; + Locales[j] = ltmp; + CodeL.setElementAt(c0, j); + CodeS.setElementAt(c1, j); + } + } + } + } + + public static void sortStrings(Collator collator, String[] words) { + for (int i = 0; i < words.length; i++) { + for (int j = i + 1; j < words.length; j++) { + if (collator.compare(words[i], words[j]) > 0) { + String tmp = words[i]; + words[i] = words[j]; + words[j] = tmp; + } + } + } + } + + @Override + public void activate(Container c) { + super.activate(c); + c.setBackground(Color.black); + c.setForeground(Color.white); + c.setLayout(new BorderLayout()); + c.add("Center", this.top); + c.add("South", this.bottom); + this.chat.line.setBackground(Color.white); + this.chat.line.setForeground(Color.black); + boolean useShaper = Gamma.getShaper() != null; + if (useShaper) { + this.shaperHelpItem = this.addMenuItem(Console.message("using-shaper"), "Help"); + } + + if (NetUpdate.getInfoURL() != null) { + this.helpItem = this.addMenuItem(Console.message("Help-Contents"), "Help"); + this.infoItem = this.addMenuItem(Console.message("Latest-info"), "Help"); + } + + Object[] arguments = new Object[]{new String(Std.getProductName())}; + this.aboutItem = this.addMenuItem(MessageFormat.format(Console.message("About-product"), arguments), "Help"); + int cameraMode = IniFile.gamma().getIniInt("CAM_MODE", 7); + int cameraSpeed = IniFile.gamma().getIniInt("CAM_SPEED", 3); + if (!useShaper && cameraMode == 9) { + cameraMode = 7; + } + + this.pilot.setOutsideCameraMode(cameraMode, cameraSpeed); + Menu viewMenu = new Menu(Console.message("Change-View")); + this.addMenuItem(viewMenu, "Options"); + MenuItem cameraVMenu = new MenuItem(Console.message("CAMERA-VIEW")); + cameraVMenu.setFont(mfont); + viewMenu.add(cameraVMenu); + this.viewItems = new Vector<CheckboxMenuItem>(); + + for (int i = 0; i < this.viewNames.size(); i++) { + DefaultConsole.CameraView currView = this.viewNames.elementAt(i); + CheckboxMenuItem item = new CheckboxMenuItem(" " + Console.message(currView.viewName), cameraMode == currView.viewID); + if (cameraMode == currView.viewID) { + this.currentViewItem = item; + } + + item.setFont(mfont); + viewMenu.add(item); + this.viewItems.addElement(item); + if (currView.viewName == "Orthographic") { + this.orthographicViewItem = item; + } + } + + viewMenu.addSeparator(); + MenuItem cameraSMenu = new MenuItem(Console.message("CAMERA-SPEED")); + cameraSMenu.setFont(mfont); + viewMenu.add(cameraSMenu); + this.camSpeedItems = new Vector<CheckboxMenuItem>(); + + for (int i = 0; i < this.speedNames.size(); i++) { + DefaultConsole.CameraSpeed currSpeed = this.speedNames.elementAt(i); + CheckboxMenuItem itemx = new CheckboxMenuItem(" " + Console.message(currSpeed.speedName), currSpeed.speedID == cameraSpeed); + if (currSpeed.speedID == cameraSpeed) { + this.currentCamSpeedItem = itemx; + } + + itemx.setFont(mfont); + viewMenu.add(itemx); + this.camSpeedItems.addElement(itemx); + } + + this.becomeVIPItem = this.addMenuItem(vip == 1 ? Console.message("Become-full-VIP") : Console.message("Become-VIP"), "VIP"); + this.addMenuItem(this.avatarMenu = new AvMenu(this, this.lastPilotRequested), "VIP"); + this.addMenuItem(this.savedAvs, "VIP"); + this.addMenuItem(this.avatarMenu.customize, "VIP"); + this.toggleVoiceChatItem = this.addMenuItem(Console.message("Enable-Voice"), "VIP"); + this.toggleVoiceChatItem.setEnabled(false); + this.numVisItem = this.addMenuItem(Console.message("Num-Visible"), "VIP"); + if (NetUpdate.isInternalVersion() || IniFile.gamma().getIniInt("EnableTrading", 0) == 1) { + this.inventoryItem = this.addMenuItem("My Stuff", "VIP"); + this.checkInventoryItem = this.addMenuItem("Check Inventory", "VIP"); + } + + if (NetUpdate.isInternalVersion() || IniFile.gamma().getIniInt("EnableBank", 0) == 1) { + this.bankItem = this.addMenuItem("Access Bank Account", "VIP"); + } + + if (IniFile.gamma().getIniInt("EnableUBU", 0) == 1) { + this.ubuItem = this.addMenuItem("U-B-U Vanatar", "VIP"); + } + + this.setMenusWRTVIP(); + this.proxyServerItem = this.addMenuItem(Console.message("Proxy-Server"), "Options"); + this.checkAccountItem = this.addMenuItem(Console.message("Account-Info"), "Options"); + if (useShaper) { + this.statisticsItem = this.addMenuItem(Console.message("Display-Stat"), "Options"); + } + + this.upgradeItem = this.addMenuItem(Console.message("Upgrade-Now"), "Options"); + if (useShaper) { + this.channelItem = this.addMenuItem(Console.message("Dimension-Sel"), "Options"); + } + + this.serverItem = this.addMenuItem(signIn, "Options"); + this.setOnlineState(this.galaxy.getOnlineEnabled(), this.galaxy.getOnline()); + if (IniFile.gamma().getIniInt("recorderEnabled", 1) == 1) { + Menu recorderMenu = new Menu(Console.message("Recorder")); + this.addMenuItem(recorderMenu, "Options"); + this.recorderRecItem = new MenuItem(Console.message("Record")); + recorderMenu.add(this.recorderRecItem); + this.recorderStopItem = new MenuItem(Console.message("Stop")); + recorderMenu.add(this.recorderStopItem); + this.recorderPlayItem = new MenuItem(Console.message("Play")); + recorderMenu.add(this.recorderPlayItem); + } + + if (NetUpdate.isInternalVersion()) { + Menu languageMenu = new Menu(Console.message("Languages")); + this.addMenuItem(languageMenu, "Options"); + Menu downloadFont = new Menu(Console.message("Download-Font")); + languageMenu.add(downloadFont); + downloadFont.setFont(mfont); + this.fontItems = new Vector<MenuItem>(); + + for (int i = 0; i < this.fLength; i++) { + if (this.flList.elementAt(i) != null) { + if (this.fsList.elementAt(i) != null) { + this.newfLocale[i] = new Locale(this.flList.elementAt(i), this.fsList.elementAt(i)); + String code = this.flList.elementAt(i) + "_" + this.fsList.elementAt(i); + if (code.equals(Console.message(code))) { + this.dFonts[i] = new MenuItem(this.newfLocale[i].getDisplayName()); + } else { + this.dFonts[i] = new MenuItem(Console.message(code)); + } + } else { + String code = this.flList.elementAt(i); + if (code.equals(Console.message(code))) { + this.dFonts[i] = new MenuItem(this.flList.elementAt(i)); + } else { + this.dFonts[i] = new MenuItem(Console.message(code)); + } + } + + this.dFonts[i].setFont(mfont); + downloadFont.add(this.dFonts[i]); + this.fontItems.addElement(this.dFonts[i]); + } + } + + Menu downloadLanguage = new Menu(Console.message("Download-Language")); + languageMenu.add(downloadLanguage); + downloadLanguage.setFont(mfont); + this.downItems = new Vector<MenuItem>(); + String[] sLangs = new String[this.dLength]; + + for (int ix = 0; ix < this.dLength; ix++) { + if (this.lList.elementAt(ix) != null) { + this.newdLocale[ix] = new Locale(this.lList.elementAt(ix), this.sList.elementAt(ix)); + String lName0; + if (ix > 0) { + Locale locale0 = new Locale(this.lList.elementAt(ix - 1), this.sList.elementAt(ix - 1)); + lName0 = locale0.getDisplayName(); + } else { + lName0 = this.newdLocale[ix].getDisplayName(); + } + + String lName1 = this.newdLocale[ix].getDisplayName(); + lName1 = lName1.substring(0, lName1.indexOf(40) - 1); + String lName; + if (ix < this.dLength - 1) { + Locale locale2 = new Locale(this.lList.elementAt(ix + 1), this.sList.elementAt(ix + 1)); + String lName2 = locale2.getDisplayName(); + lName2 = lName2.substring(0, lName2.indexOf(40) - 1); + if (lName2.equals(lName1)) { + lName = this.newdLocale[ix].getDisplayName(); + } else { + lName = lName1; + } + } else if (ix == this.dLength - 1) { + lName0 = lName0.substring(0, lName0.indexOf(40) - 1); + if (lName1.equals(lName0)) { + lName = this.newdLocale[ix].getDisplayName(); + } else { + lName = lName1; + } + } else if (sLangs[ix - 1].equals(lName1)) { + lName = this.newdLocale[ix].getDisplayName(); + } else { + lName = lName1; + } + + String code = this.lList.elementAt(ix) + "_" + this.sList.elementAt(ix); + if (code.equals(Console.message(code))) { + sLangs[ix] = lName; + } else { + sLangs[ix] = Console.message(code); + } + } + } + + Collator sortCollator = Collator.getInstance(); + sortStrings(sortCollator, sLangs, this.newdLocale, this.lList, this.sList); + + for (int ixx = 0; ixx < this.dLength; ixx++) { + this.dLangs[ixx] = new MenuItem(sLangs[ixx]); + this.dLangs[ixx].setFont(mfont); + downloadLanguage.add(this.dLangs[ixx]); + this.downItems.addElement(this.dLangs[ixx]); + } + + Menu switchLang = new Menu(Console.message("Switch-Language")); + languageMenu.add(switchLang); + switchLang.setFont(mfont); + this.langItems = new Vector<MenuItem>(); + + for (int ixx = 0; ixx < lLength; ixx++) { + int imb = lNames[ixx].indexOf(95); + if (imb < 0) { + lCodes[ixx][0] = "en"; + lCodes[ixx][1] = "US"; + } else { + int ipr = lNames[ixx].lastIndexOf(46); + if (ipr < 0) { + ipr = 0; + } + + lCodes[ixx][0] = lNames[ixx].substring(imb + 1, imb + 3); + if (ipr > imb + 4) { + lCodes[ixx][1] = lNames[ixx].substring(imb + 4, ipr); + } else { + lCodes[ixx][1] = lCodes[ixx][0].toUpperCase(); + } + } + } + + String[] slLangs = new String[lLength]; + + for (int ixxx = 0; ixxx < lLength; ixxx++) { + newLocale[ixxx] = new Locale(lCodes[ixxx][0], lCodes[ixxx][1]); + String lName0x; + if (ixxx > 0) { + Locale locale0 = new Locale(lCodes[ixxx - 1][0], lCodes[ixxx - 1][1]); + lName0x = locale0.getDisplayName(); + } else { + lName0x = newLocale[ixxx].getDisplayName(); + } + + String lName1x = newLocale[ixxx].getDisplayName(); + lName1x = lName1x.substring(0, lName1x.indexOf(40) - 1); + String lNamex; + if (ixxx < lLength - 1) { + Locale locale2 = new Locale(lCodes[ixxx + 1][0], lCodes[ixxx + 1][1]); + String lName2 = locale2.getDisplayName(); + lName2 = lName2.substring(0, lName2.indexOf(40) - 1); + if (lName2.equals(lName1x)) { + lNamex = newLocale[ixxx].getDisplayName(); + } else { + lNamex = lName1x; + } + } else if (ixxx == lLength - 1) { + lName0x = lName0x.substring(0, lName0x.indexOf(40) - 1); + if (lName1x.equals(lName0x)) { + lNamex = newLocale[ixxx].getDisplayName(); + } else { + lNamex = lName1x; + } + } else if (slLangs[ixxx - 1].equals(lName1x)) { + lNamex = newLocale[ixxx].getDisplayName(); + } else { + lNamex = lName1x; + } + + String code = lCodes[ixxx][0] + "_" + lCodes[ixxx][1]; + if (code.equals(Console.message(code))) { + slLangs[ixxx] = lNamex; + } else { + slLangs[ixxx] = Console.message(code); + } + } + + sortStrings(sortCollator, slLangs, newLocale, lCodes); + + for (int ixxx = 0; ixxx < lLength; ixxx++) { + lLangs[ixxx] = new MenuItem(slLangs[ixxx]); + lLangs[ixxx].setFont(mfont); + switchLang.add(lLangs[ixxx]); + this.langItems.addElement(lLangs[ixxx]); + } + + this.currentLang = new MenuItem(Console.message("Current-Language")); + languageMenu.add(this.currentLang); + this.currentLang.setFont(mfont); + } + + if (useShaper) { + this.condenseItem = this.addMenuItem(Console.message("Condense-Files"), "Options"); + this.expandItem = this.addMenuItem(Console.message("Expand-Files"), "Options"); + this.musicManItem = this.addMenuItem(Console.message("Music-Manager"), "Options"); + this.i18nTest = this.addMenuItem(Console.message("I18N-Test"), "Options"); + } + + this.cdPlayerItem = this.addMenuItem(Console.message("MusicM"), "Options"); + this.volumeItem = this.addMenuItem(Console.message("Volume-control"), "Options"); + if (RenderWare.get3DHardwareAvailable()) { + if (RenderWare.get3DHardwareInUse()) { + this.graphicsItem = this.addMenuItem(disable3D, "Options"); + } else { + this.graphicsItem = this.addMenuItem(enable3D, "Options"); + } + } + + if (IniFile.gamma().getIniInt("SHOWNAMETAGS", 1) == 1) { + this.nametagItem = this.addMenuItem(hideTags, "Options"); + } else { + this.nametagItem = this.addMenuItem(showTags, "Options"); + } + + if (IniFile.gamma().getIniInt("classicChatBox", 1) == 1) { + this.chatBoxItem = this.addMenuItem(disableClassicChat, "Options"); + } else { + this.chatBoxItem = this.addMenuItem(enableClassicChat, "Options"); + this.chatItem = this.addMenuItem(configureChat, "Options"); + } + + if (Gamma.loadProgress != null) { + Gamma.loadProgress.setMessage("Preloading avatars..."); + Gamma.loadProgress.advance(); + } + + this.menuDone(); + getFrame().activate(); + LogFile.mailLogIfPresent(this.getSmtpServer()); + this.render.requestFocus(); + this.setMenusWRTVIP(); + this.bootSomeone = null; + if (this.broadcastEnabled()) { + this.addBroadcastMenu(); + } + + this.universeMode = false; + } + + @Override + public void setVIP(boolean f) { + super.setVIP(f); + this.setMenusWRTVIP(); + this.setNameStr(); + } + + @Override + public void checkCourtesyVIP() { + super.checkCourtesyVIP(); + this.setMenusWRTVIP(); + this.setNameStr(); + } + + public void setNameStr() { + String nameStr = this.galaxy.getUsernameU(); + boolean isOnline = this.galaxy.getOnline(); + if (!isOnline) { + this.yourName.setText(Console.message("Off-line")); + } else { + if (nameStr.length() > 0) { + if (nameStr.regionMatches(true, 0, "VIP ", 0, 4)) { + nameStr = nameStr.substring(4); + } + + if (vip > 0) { + if (vip > 1) { + nameStr = Console.message("VIP") + " " + nameStr; + } else { + nameStr = Console.message("vip") + " " + nameStr; + } + } + + IniFile.gamma().setIniString("LASTCHATNAME", parseExtended(nameStr)); + this.yourName.setText(Console.parseUnicode(nameStr)); + } + } + } + + @Override + public void enableBroadcast(boolean enabled) { + super.enableBroadcast(enabled); + if (enabled) { + this.addBroadcastMenu(); + } + } + + @Override + public void deactivate() { + super.deactivate(); + this.universeMode = false; + } + + @Override + protected void setSleepMode(String mode) { + super.setSleepMode(mode); + if (mode != null && mode.equals(Console.message("asleep"))) { + this.statusMessage = sleepStatus; + } else if (this.statusMessage == sleepStatus) { + this.statusMessage = ""; + } + } + + private void relogin() { + if (this.serverItem.getLabel().equals(signOut)) { + this.reloginDialog = new OkCancelDialog( + getFrame(), this, Console.message("Re-login"), Console.message("Cancel"), Console.message("OK"), Console.message("auto-sign-out"), true + ); + } + } + + @Override + public boolean action(Event event, Object what) { + if (event.target == this.aboutItem) { + new AboutDialog(Std.getProductName(), getFrame()); + } else if (event.target == this.statisticsItem && this.statisticsItem != null) { + new StatisticsWindow(getFrame()); + } else if (this.viewItems.contains(event.target)) { + this.changeView((CheckboxMenuItem)event.target); + } else if (this.camSpeedItems.contains(event.target)) { + this.changeCamSpeed((CheckboxMenuItem)event.target); + } else if (event.target == this.gettingStartedItem) { + new SendURLAction(this.getHelpGettingStarted()).startBrowser(); + } else if (event.target == this.shaperHelpItem) { + String helpURL = IniFile.override().getIniString("ShaperHelp", this.getScriptServer() + "shaperhelp.pl") + "?u="; + String lastName = IniFile.gamma().getIniString("lastchatname", ""); + if (!lastName.equals("")) { + if (lastName.startsWith("VIP ")) { + lastName = lastName.substring(4); + } + + helpURL = helpURL + lastName; + } + + new SendURLAction(WebControlImp.processURL(helpURL)).startBrowser(); + } else if (event.target == this.helpItem) { + String serv = NetUpdate.getUpgradeServerURL(); + String directory = IniFile.override().getIniString("HelpDirectory", "help"); + String helpPage = IniFile.override().getIniString("HelpPage", Std.getVersion() + Console.message(".html")); + if (wasHttpNoSuchFile(serv + directory + "/" + helpPage)) { + helpPage = IniFile.override().getIniString("HelpPage", Std.getVersion() + ".html"); + } + + new SendURLAction(serv + directory + "/" + helpPage).startBrowser(); + } else if (event.target == this.infoItem) { + String infoOverride = IniFile.override().getIniString("infoOverride", ""); + if (infoOverride.equals("")) { + NetUpdate.showInfo(); + } else { + new SendURLAction(infoOverride).startBrowser(); + } + } else if (event.target == this.i18nTest) { + Locale df = Locale.getDefault(); + Console.println("Default = " + df.getDisplayName()); + DateFormat fulldate = DateFormat.getDateTimeInstance(1, 1); + Date today = new Date(); + Console.println("Today = " + fulldate.format(today)); + Locale[] list = DateFormat.getAvailableLocales(); + Console.println("Avaliable Locales are:"); + + for (int i = 0; i < list.length; i++) { + Locale.setDefault(list[i]); + Console.println(list[i].getDisplayName() + " " + list[i]); + } + + new Locale("en", "US"); + Locale fr = new Locale("fr", "FR"); + Locale de = new Locale("de", "DE"); + Locale ja = new Locale("ja", "JP"); + Locale zh = new Locale("zh", "CN"); + Locale th = new Locale("th", "TH"); + Locale ru = new Locale("ru", "RU"); + Locale iw = new Locale("iw", "IL"); + Console.println("file.encoding = " + System.getProperty("file.encoding")); + Console.println(this.message("test-language", fr)); + Console.println(this.message("test-language", de)); + Console.println(this.message("test-language", ja)); + Console.println(this.message("test-language", zh)); + Console.println(this.message("test-language", th)); + Console.println(this.message("test-language", ru)); + Console.println(this.message("test-language", iw)); + Console.println(this.message("test-language", df)); + } else if (event.target == this.checkAccountItem) { + String accountOverride = IniFile.override().getIniString("accountOverride", ""); + if (accountOverride.equals("")) { + String accountScript = IniFile.override().getIniString("accountInfoPage", "account" + Console.message(".pl")); + if (wasHttpNoSuchFile(this.getScriptServer() + accountScript)) { + accountScript = IniFile.override().getIniString("accountInfoPage", "account.pl"); + } + + new SendURLAction(this.getScriptServer() + accountScript, true).startBrowser(); + } else { + new SendURLAction(accountOverride).startBrowser(); + } + + this.relogin(); + } else if (event.target == this.upgradeItem) { + NetUpdate.doUpdate(true); + } else if (event.target == this.channelItem && this.channelItem != null) { + Galaxy g = this.getGalaxy(); + String channel = ""; + + assert g != null; + + if (g != null) { + channel = g.getChannel(); + } + + new ChannelDialog(getFrame(), this, Console.message("Dimension-Sel"), channel); + } else if (event.target == this.becomeVIPItem) { + String completeOverride = IniFile.override().getIniString("vipOverride", ""); + if (completeOverride.equals("")) { + String vipScript = IniFile.override().getIniString("vipPage", "vip" + Console.message(".pl")); + if (wasHttpNoSuchFile(this.getScriptServer() + vipScript)) { + vipScript = IniFile.override().getIniString("vipPage", "vip.pl"); + } + + new SendURLAction(this.getScriptServer() + vipScript, true).startBrowser(); + } else { + new SendURLAction(completeOverride, false).startBrowser(); + } + + this.relogin(); + } else if (event.target == this.numVisItem) { + new SetNumVisibleAvs(); + } else if (event.target == this.inventoryItem) { + EquipAction eAction = new EquipAction(); + eAction.trigger(null, null); + } else if (event.target == this.checkInventoryItem) { + new SendURLAction(this.getScriptServer() + "inventory.pl", true).startBrowser(); + } else if (event.target == this.bankItem) { + new SendURLAction(this.getScriptServer() + "bank.pl", true).startBrowser(); + } else if (event.target == this.ubuItem) { + String ubuDest = IniFile.gamma().getIniString("UbuDestURL", this.getScriptServer() + "ubu.pl"); + new SendURLAction(ubuDest, true).startBrowser(); + } else if (event.target == this.proxyServerItem) { + System.out.println("Triggering the Proxy Server dialog."); + ProxyServerDialog psd = new ProxyServerDialog(); + psd.show(); + } else if (event.target == this.toggleVoiceChatItem) { + VoiceChat.setVoiceChatEnabled(!VoiceChat.voiceChatEnabled); + this.setMenusWRTVIP(); + } else if (event.target == this.serverItem) { + this.handleServerItem(); + } else if (event.target == this.condenseItem) { + new ArchiveMaker(true); + } else if (event.target == this.expandItem) { + new ArchiveMaker(false); + } else if (event.target == this.musicManItem) { + MusicManager.showDialog(); + } else if (event.target == this.cdPlayerItem) { + if (this.cdcontrol == null) { + this.playedCD = true; + this.cdcontrol = new CDControl(getFrame(), this); + } + } else if (event.target == this.volumeItem) { + if (!CDPlayerAction.launchVolumeControlApp()) { + new OkCancelDialog(getFrame(), null, Console.message("No-Volume"), null, Console.message("OK"), Console.message("Cannot-locate"), true); + } + } else if (event.target == this.graphicsItem) { + this.handleGraphicsItem(); + } else if (event.target == this.nametagItem) { + this.handleNametagsItem(); + } else if (event.target == this.chatBoxItem) { + this.handleChatBoxItem(); + } else if (event.target == this.chatItem && this.chatItem != null) { + new ChatDialog( + getFrame(), + this, + Console.message("Chat-Configuration"), + IniFile.gamma().getIniInt("ChatFontSize", 12), + chatLines, + IniFile.gamma().getIniInt("ChatLengthLimit", 20000) + ); + } else if (event.target == this.bootSomeone) { + new BootDialog(getFrame(), this, Console.message("Boot-user")); + } else if (event.target == this.broadcastToRoom) { + startWhispering("room"); + } else if (event.target == this.broadcastToAll) { + startWhispering("world"); + } else if (event.target == this.currentLang) { + String code = Locale.getDefault().toString(); + if (code == Console.message(code)) { + Console.println(Console.message("Current-Language") + " = " + Locale.getDefault().getDisplayName()); + } else { + Console.println(Console.message("Current-Language") + " = " + Console.message(code)); + } + } else if (event.target == this.recorderPlayItem) { + println(Console.message("BlackBoxPlay")); + BlackBox.getInstance().play(); + } else if (event.target == this.recorderRecItem) { + println(Console.message("BlackBoxRec")); + BlackBox.getInstance().record(); + } else if (event.target == this.recorderStopItem) { + println(Console.message("BlackBoxStop")); + BlackBox.getInstance().stop(); + } else if (this.fontItems != null && this.fontItems.contains(event.target)) { + String languageURL = IniFile.gamma().getIniString("upgradeServer", "") + "/I18N/font_"; + + for (int i = 0; i < this.fLength; i++) { + if (event.target == this.fontItems.elementAt(i)) { + if (this.fsList.elementAt(i) != null) { + languageURL = languageURL + this.flList.elementAt(i) + "_" + this.fsList.elementAt(i) + ".EXE"; + } else { + languageURL = languageURL + this.flList.elementAt(i) + ".EXE"; + } + + int sz = this.fSizes[i]; + String fName = languageURL.substring(languageURL.lastIndexOf(47) + 1, languageURL.length()); + LanguageManager.handle(languageURL, sz, fName); + break; + } + } + } else if (this.downItems != null && this.downItems.contains(event.target)) { + String languageURL = IniFile.gamma().getIniString("upgradeServer", "") + "/I18N/language_"; + + for (int ix = 0; ix < this.dLength; ix++) { + if (event.target == this.downItems.elementAt(ix)) { + if (this.sList.elementAt(ix) != null) { + languageURL = languageURL + this.lList.elementAt(ix) + "_" + this.sList.elementAt(ix) + ".zip"; + IniFile.gamma().setIniString("DEFAULTLANGUAGE", this.lList.elementAt(ix) + "_" + this.sList.elementAt(ix)); + } else { + languageURL = languageURL + this.lList.elementAt(ix) + ".zip"; + IniFile.gamma().setIniString("DEFAULTLANGUAGE", this.lList.elementAt(ix)); + } + + int sz = this.lSizes[ix]; + String fName = languageURL.substring(languageURL.lastIndexOf(47) + 1, languageURL.length()); + LanguageManager.handle(languageURL, sz, fName); + break; + } + } + } else if (this.langItems != null && this.langItems.contains(event.target)) { + for (int ixx = 0; ixx < lLength; ixx++) { + if (event.target == this.langItems.elementAt(ixx)) { + Locale.setDefault(newLocale[ixx]); + String code = newLocale[ixx].toString(); + if (code == Console.message(code)) { + Console.println(message("Setting-to") + " " + newLocale[ixx].getDisplayName()); + } else { + Console.println(message("Setting-to") + " " + Console.message(code)); + } + + IniFile.gamma().setIniString("DEFAULTLANGUAGE", lCodes[ixx][0] + "_" + lCodes[ixx][1]); + new OkCancelDialog(getFrame(), null, Console.message("Alert"), null, Console.message("OK"), Console.message("Change-exit"), true); + break; + } + } + } else if (this.avatarMenu == null || !this.avatarMenu.action(event, what)) { + return super.action(event, what); + } + + return true; + } + + public void setCurrentAvatarItem(CheckboxMenuItem item) { + if (this.curAvatarItem != null) { + this.curAvatarItem.setState(false); + } + + this.curAvatarItem = item; + if (this.curAvatarItem != null) { + this.curAvatarItem.setState(true); + } + } + + public CheckboxMenuItem getCurrentAvatarItem() { + return this.curAvatarItem; + } + + public void deletedSavedAvatar(CheckboxMenuItem item) { + if (this.curAvatarItem == item) { + this.findAvatarMenuItem(this.getDefaultAvatarURL()); + } + } + + public void setNextAvatar(URL url, CheckboxMenuItem item) { + synchronized (this.nextAvatarMutex) { + this.nextAvatar = url; + this.nextAvatarItem = item; + } + } + + private void findAvatarMenuItem(URL url) { + synchronized (this.nextAvatarMutex) { + if (this.nextAvatarItem == null) { + CheckboxMenuItem item; + if ((this.savedAvs == null || (item = this.savedAvs.findMenuItem(url)) == null) + && (this.avatarMenu == null || (item = this.avatarMenu.findMenuItem(url)) == null)) { + this.setCurrentAvatarItem(null); + } else { + this.setCurrentAvatarItem(item); + } + } + } + } + + private URL getHelpGettingStarted() { + IniFile ini = new IniFile("InstalledWorlds"); + String helpName = Console.message("Getting-started"); + String w = ini.getIniString("InstalledWorld0", ""); + if (!w.equals("")) { + URL name = URL.make("home:" + w + "/" + helpName); + File f = new File(name.unalias()); + if (f.exists()) { + return name; + } + } + + return URL.make("home:" + helpName); + } + + private void changeView(CheckboxMenuItem item) { + this.chooseView = this.viewItems.indexOf(item); + if (item != this.currentViewItem) { + this.currentViewItem.setState(false); + this.currentViewItem = item; + this.currentViewItem.setState(true); + } + } + + private int getView() { + return this.viewItems.indexOf(this.currentViewItem); + } + + private void setView(int view) { + this.changeView(this.viewItems.elementAt(view)); + } + + private void changeCamSpeed(CheckboxMenuItem item) { + this.chooseCamSpeed = this.camSpeedItems.indexOf(item); + if (item != this.currentCamSpeedItem) { + this.currentCamSpeedItem.setState(false); + this.currentCamSpeedItem = item; + this.currentCamSpeedItem.setState(true); + } + } + + public void resetCamera() { + if (this.viewItems != null && this.camSpeedItems != null) { + this.chooseView = this.viewItems.indexOf(this.currentViewItem); + this.chooseCamSpeed = this.camSpeedItems.indexOf(this.currentCamSpeedItem); + } + } + + private void handleServerItem() { + if (!this.serverItem.getLabel().equals(signIn)) { + Galaxy.forceOffline(false); + } else { + this.getGalaxy().localForceOnline(); + this.getGalaxy().waitForConnection(this); + } + } + + public UniversePanel getUniverse() { + return this.universeMode ? this.universe : null; + } + + public synchronized void setUniverseMode(boolean f) { + if (f != this.universeMode) { + this.universeMode = f; + if (this.universeMode) { + if (this.universe == null) { + this.universe = new UniversePanel(this); + this.renderAndUniverse.add("universe", this.universe); + } + + this.renderCard.show(this.renderAndUniverse, "universe"); + this.universe.startWatch(); + this.render.requestFocus(); + } else { + this.renderCard.show(this.renderAndUniverse, "render"); + if (physMem < 64000000) { + this.renderAndUniverse.remove(this.universe); + this.universe.stopWatch(); + this.universe.flushImage(); + this.universe = null; + } + + this.renderAndUniverse.repaint(); + } + } + } + + public void toggleUniverseMode() { + this.setUniverseMode(!this.universeMode); + } + + public boolean isUniverseMode() { + return this.universeMode; + } + + @Override + public Object imageButtonsCallback(Component who, int which) { + if (who != this.driveButton) { + if (who == this.quitButton) { + maybeQuit(); + } else if (who == this.adCubeButton) { + String adURL = IniFile.gamma().getIniString("AdCubeURL", "http://www.worlds.com/"); + new SendURLAction(adURL, true).startBrowser(); + } else if (who == this.exploreButton) { + this.toggleUniverseMode(); + } else if (who == this.menuButtons) { + switch (which) { + case 0: + return this.getMenu("Help"); + case 1: + return this.getMenu("Options"); + case 2: + String prodName = IniFile.override().getIniString("ProductName", ""); + if (!prodName.equalsIgnoreCase("RedLightWorld") && !prodName.equalsIgnoreCase("RedLightCenter")) { + EMailPart.showMessage(this); + } + break; + case 3: + return (PopupMenu)this.marks.getMenu(); + case 4: + return (PopupMenu)this.marks.getLetsMenu(); + case 5: + this.actions.present(); + break; + case 6: + return this.getMenu("VIP"); + } + } + } + + return null; + } + + public RenderCanvas getRender() { + return this.render; + } + + public FriendsListPart getFriends() { + return this.friends; + } + + public MuteListPart getMutes() { + return this.mutes; + } + + @Override + public void generateFrameEvents(FrameEvent f) { + if (Window.getWindowState(Window.getFrameHandle()) == 1) { + this.goToSleep(); + } + + if (doDrive) { + doDrive = false; + this.render.drive(); + wasDelta = true; + } + + super.generateFrameEvents(f); + Pilot pilot = Pilot.getActive(); + GammaFrame frame = getFrame(); + String worldName = ""; + if (pilot != null) { + World world = pilot.getWorld(); + if (world != null) { + String name = world.getName(); + if (name != null) { + worldName = name; + } + } + } + + if (!lastWorldName.equals(worldName)) { + lastWorldName = worldName; + String newTitle = GammaFrame.getDefaultTitle(); + if (worldName.length() != 0) { + newTitle = newTitle + " - " + worldName; + if (!this.playedCD) { + CDAudio.startupPlay(); + this.playedCD = true; + } + } + + frame.setTitle(newTitle); + } + + if (pilot != null) { + if (this.chooseView != -1 || this.chooseCamSpeed != -1) { + int oldCameraMode = pilot.getOutsideCameraMode(); + int oldCameraSpeed = pilot.getOutsideCameraSpeed(); + int cameraMode = oldCameraMode; + int cameraSpeed = oldCameraSpeed; + if (this.chooseView != -1) { + cameraMode = this.viewNames.elementAt(this.chooseView).viewID; + } + + if (this.chooseCamSpeed != -1) { + cameraSpeed = this.speedNames.elementAt(this.chooseCamSpeed).speedID; + } + + pilot.setOutsideCameraMode(cameraMode, cameraSpeed); + if (cameraMode != 99) { + IniFile.gamma().setIniInt("CAM_MODE", cameraMode); + IniFile.gamma().setIniInt("CAM_SPEED", cameraSpeed); + } + + this.chooseView = -1; + this.chooseCamSpeed = -1; + } + + if (this.wasTeleporting != this.marks.isTeleporting()) { + this.wasTeleporting = this.marks.isTeleporting(); + if (this.wasTeleporting) { + this.statusMessage = loadingString; + } else if (this.statusMessage == loadingString) { + this.statusMessage = ""; + } + } + + this.checkVMWarning(); + if (wasDelta && !this.render.getDeltaMode()) { + this.statusMessage = arrowKeyMsg; + wasDelta = false; + this.driveButton.drawCursed(); + } + + synchronized (this.status) { + if (this.statusMessage != this.lastStatus && this.overrideMessage == null) { + this.lastStatus = this.statusMessage; + this.status.setText(this.statusMessage); + } + } + + synchronized (this.nextAvatarMutex) { + if (this.nextAvatar != null) { + this.setAvatar(this.nextAvatar); + this.nextAvatar = null; + if (this.avatarMenu != null) { + this.avatarMenu.notifyOfChange(); + } + + if (this.nextAvatarItem != null) { + this.setCurrentAvatarItem(this.nextAvatarItem); + this.nextAvatarItem = null; + } + } + } + } + } + + private void checkVMWarning() { + int now = Std.getFastTime(); + if (now > this.lastVMCheck + 10000) { + StatMemNode m = StatMemNode.getNode(); + m.updateMemoryStatus(); + if (m._availPageMem < 0) { + m._availPageMem = 2000000000; + } + + if (m._totPhysMem < 0) { + m._totPhysMem = 2000000000; + } + + physMem = m._totPhysMem; + if (m._availPageMem >= 4194304) { + if (m._availPageMem > 5242880 && this.lastVMBigWarning != 0) { + if (m._availPageMem > 10485760) { + Console.println(Console.message("plenty-virt")); + this.lastVMBigWarning = 0; + } else if (!this.showedMidWarn) { + Console.println(Console.message("plenty-virt-mem")); + this.showedMidWarn = true; + } + + if (this.statusMessage == lowVMMsg) { + this.statusMessage = ""; + } + } + } else { + if (this.lastVMBigWarning == 0 || this.showedMidWarn || now > this.lastVMBigWarning + 300000) { + Console.println(Console.message("Low-virt-mem")); + this.lastVMBigWarning = now; + this.showedMidWarn = false; + } + + this.statusMessage = lowVMMsg; + } + + Object[] arguments = new Object[]{new String(Std.getProductName()), new Integer(24)}; + if (startupMemCheck) { + if (m._totPhysMem < 24000000) { + String result = MessageFormat.format(Console.message("Mem-detected"), arguments); + new OkCancelDialog(getFrame(), null, Console.message("Too-Little-RAM"), null, Console.message("OK"), result, true); + } + + startupMemCheck = false; + System.out.println("System has " + m._totPhysMem + " bytes of physical RAM"); + } + + this.lastVMCheck = now; + } + } + + @Override + public URL getAvatarName() { + return this.avatarURL; + } + + @Override + public void setServerURL(URL serverURL) { + super.setServerURL(serverURL); + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + if (who instanceof QuitDialog) { + if (confirmed) { + Console.quit(); + } + } else if (who instanceof BootDialog) { + if (confirmed) { + BootDialog bd = (BootDialog)who; + String bname = bd.getBoot(); + if (!bname.equals("")) { + Pilot.sendText("world", "!boot " + bname); + } + } + } else if (who instanceof ChannelDialog) { + if (confirmed) { + ChannelDialog cd = (ChannelDialog)who; + String newChannel = cd.getChannel(); + Pilot pilot = Pilot.getActive(); + String oldPos = pilot != null ? pilot.getURL() : null; + if (oldPos != null) { + int channelIndex = oldPos.indexOf("<"); + int channelEndIndex = oldPos.indexOf(">"); + if (channelIndex >= 0 && channelEndIndex > channelIndex) { + TeleportAction.teleport(oldPos.substring(0, channelIndex + 1) + newChannel + oldPos.substring(channelEndIndex), null); + } + } else { + Console.println(Console.message("cant-determine")); + } + } + } else if (who instanceof ChatDialog) { + if (confirmed) { + ChatDialog cd = (ChatDialog)who; + int newFontsize = cd.getFontsize(); + int newLines = cd.getLines(); + int newLength = cd.getLength(); + if (newLines < 6) { + newLines = 6; + } + + int oldFontSize = IniFile.gamma().getIniInt("ChatFontSize", 12); + int oldLength = IniFile.gamma().getIniInt("ChatLengthLimit", 20000); + if (newFontsize != oldFontSize || newLines != chatLines || newLength != oldLength) { + if (newFontsize != oldFontSize) { + IniFile.gamma().setIniInt("ChatFontSize", newFontsize); + } + + if (newLines != chatLines) { + chatLines = newLines; + IniFile.gamma().setIniInt("ChatLines", newLines); + } + + if (newLength != oldLength) { + NewSharedTextArea.chatLengthLimit = newLength; + ClassicSharedTextArea.chatLengthLimit = newLength; + IniFile.gamma().setIniInt("ChatLengthLimit", newLength); + } + + if (this.chat.listen.getComponent().getClass() == NewSharedTextArea.class) { + try { + NewSharedTextArea gta = (NewSharedTextArea)this.chat.listen.getComponent(); + gta.setFontSize(newFontsize); + gta.setRows(newLines); + gta.scrollToBottom(); + gta.setScrollBounds(); + } catch (Exception var10) { + } + } + + int h = chatLines * this.chat.listen.getComponent().getFontMetrics(this.chat.listen.getFont()).getHeight(); + h -= 96; + if (h > 0 && this.adFiller != null) { + this.adFiller.setHeight(h); + } + + Console.frame.validate(); + Console.frame.repaint(); + } + } + } else if (who instanceof LoginWizard) { + assert false; + } else if (who instanceof CDControl) { + if (this.cdcontrol == who) { + this.cdcontrol = null; + } + } else if (who instanceof InternetConnectionDialog) { + assert false; + } else if (who == this.reloginDialog) { + if (confirmed) { + Galaxy.forceOffline(true); + } + + this.reloginDialog = null; + } + } + + @Override + public void setAvatar(URL url) { + this.avatarURL = url; + boolean isVIPAv = url.getInternal().toLowerCase().endsWith(".rwg"); + boolean hasAmnesty = url.equals(getDefaultURL()) && !this.getGalaxy().getOnline(); + if (!this.getVIP() && isVIPAv && !hasAmnesty) { + Console.println(Console.message("Only-VIPs") + " '" + SelectAvatarAction.getPrettyAvatarName(url.getBase()) + "'."); + } else if (VehicleShape.isVehicle(url)) { + this.tempCarAvatar = url.getAbsolute(); + super.setAvatar(url); + } else { + this.tempCarAvatar = ""; + if (this.avatarMenu != null) { + this.avatarMenu.customize.setEnabled(!url.getAbsolute().endsWith("mov")); + } + + if (!url.equals(this.getDefaultAvatarURL())) { + if (this.getVIPAvatars()) { + if (!isVIPAv) { + IniFile.gamma().setIniString("VIPAVATAR", ""); + } else { + IniFile.gamma().setIniString("VIPAVATAR", url.getAbsolute()); + } + } + + if (!isVIPAv) { + IniFile.gamma().setIniString("AVATAR", url.getAbsolute()); + } + } + + super.setAvatar(url); + } + } + + private CheckboxMenuItem findAvatar(Vector<CheckboxMenuItem> items, String name) { + if (items != null) { + int count = items.size(); + + for (int i = 0; i < count; i++) { + CheckboxMenuItem item = items.elementAt(i); + if (item.getLabel().equals(name)) { + return item; + } + } + } + + return null; + } + + @Override + protected void loadPilot(URL url) { + super.loadPilot(url); + this.findAvatarMenuItem(url); + } + + @Override + public void setChatname(String chatname) { + assert chatname != null; + + if (chatname.length() != 0) { + String nameStr = (this.getVIP() ? (vip > 1 ? Console.message("VIP") + " " : Console.message("vip")) + " " : "") + + "\"" + + Console.parseUnicode(chatname) + + "\""; + this.yourName.setText(nameStr); + IniFile.gamma().setIniString("LASTCHATNAME", parseExtended(nameStr)); + } else { + this.yourName.setText(Console.message("Off-line")); + } + } + + @Override + public void connectionCallback(Object caller, boolean connected) { + super.connectionCallback(caller, connected); + if (caller instanceof Galaxy) { + if (caller != this.galaxy) { + return; + } + + if (connected) { + WorldServer serv = this.getServerNew(); + this.friends.setServer(serv, this.getGalaxy().getIniSection()); + this.mutes.setServer(serv, this.getGalaxy().getIniSection()); + if (vip < 2) { + Console.println(vip == 1 ? Console.message("Press-full-VIP") : Console.message("Press-VIP")); + } + + PosableShape.downloadPermittedNames(); + } + } + } + + @Override + public void galaxyDisconnected() { + super.galaxyDisconnected(); + this.getFriends().maybeServerDisconnect(); + } + + @Override + public boolean okToQuit() { + int quitDlg = IniFile.override().getIniInt("QuitDialog", 1); + + try { + if (quitDlg == 1) { + new QuitDialog(getFrame(), this); + return false; + } + } catch (Exception var3) { + } + + return true; + } + + public Rectangle getBrowserPlacement() { + String coords = IniFile.gamma().getIniString("BROWSERWINDOW", ""); + if (coords.length() != 0) { + StringTokenizer tok = new StringTokenizer(coords, " ,"); + + try { + return new Rectangle( + Integer.parseInt(tok.nextToken()), Integer.parseInt(tok.nextToken()), Integer.parseInt(tok.nextToken()), Integer.parseInt(tok.nextToken()) + ); + } catch (NumberFormatException var9) { + } catch (NoSuchElementException var10) { + } + } + + int w = this.menuButtons.getLocationOnScreen().x - (int)(this.menuButtons.getSize().width * 0.7); + int frameWidth = Window.getSystemMetrics(32); + int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width; + int minWidth = Math.min(screenWidth, 640) + 2 * frameWidth; + int x = 0; + if (w != minWidth) { + if (w > minWidth) { + x += w - minWidth; + } + + w = minWidth; + } + + if (w > screenWidth) { + x += -frameWidth; + } + + int h = this.chat.listen.getLocationOnScreen().y + this.chat.listen.getSize().height - this.chat.line.getSize().height; + int y = 0; + if (h > maxWebSize) { + y += h - maxWebSize; + h = maxWebSize; + } + + return new Rectangle(x, y, w, h); + } + + @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 = URLPropertyEditor.make(new Property(this, index, "Avatar"), "rwg;mov"); + } else if (mode == 1) { + ret = this.lastPilotRequested; + } else if (mode == 2) { + this.setNextAvatar((URL)value, null); + } + break; + case 1: + if (mode == 0) { + ret = BooleanPropertyEditor.make(new Property(this, index, "Collect garbage"), "No", "Yes"); + } else if (mode == 1) { + ret = new Boolean(false); + } else if (mode == 2 && (Boolean)value) { + System.gc(); + System.runFinalization(); + } + break; + default: + ret = super.properties(index, offset + 2, mode, value); + } + + return ret; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(0, classCookie); + super.saveState(s); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + int vers = r.restoreVersion(classCookie); + switch (vers) { + case 0: + super.restoreState(r); + return; + default: + throw new TooNewException(); + } + } + + public class CameraSpeed { + public String speedName; + public int speedID; + + public CameraSpeed(String sn, int sid) { + this.speedName = sn; + this.speedID = sid; + } + } + + public class CameraView { + public String viewName; + public int viewID; + + public CameraView(String vn, int vid) { + this.viewName = vn; + this.viewID = vid; + } + } +} diff --git a/NET/worlds/console/DialogDisabled.java b/NET/worlds/console/DialogDisabled.java new file mode 100644 index 0000000..830043a --- /dev/null +++ b/NET/worlds/console/DialogDisabled.java @@ -0,0 +1,5 @@ +package NET.worlds.console; + +public interface DialogDisabled { + void dialogDisable(boolean var1); +} diff --git a/NET/worlds/console/DialogReceiver.java b/NET/worlds/console/DialogReceiver.java new file mode 100644 index 0000000..1412344 --- /dev/null +++ b/NET/worlds/console/DialogReceiver.java @@ -0,0 +1,5 @@ +package NET.worlds.console; + +public interface DialogReceiver { + void dialogDone(Object var1, boolean var2); +} diff --git a/NET/worlds/console/DuplexPart.java b/NET/worlds/console/DuplexPart.java new file mode 100644 index 0000000..abeb4be --- /dev/null +++ b/NET/worlds/console/DuplexPart.java @@ -0,0 +1,160 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.scape.FrameEvent; +import java.awt.Color; +import java.awt.Container; +import java.awt.Event; +import java.awt.TextField; +import java.util.Observer; +import java.util.Vector; + +public abstract class DuplexPart implements FramePart { + private boolean classicTextArea; + public TextField line = new FocusPreservingTextField(); + public SharedTextArea listen; + private Vector<String> talkVec = new Vector<String>(); + + public DuplexPart() { + this(true); + } + + public DuplexPart(boolean isShared) { + this(isShared, 3); + } + + public DuplexPart(boolean isShared, int height) { + this.classicTextArea = IniFile.gamma().getIniInt("classicChatBox", 1) == 1; + if (this.classicTextArea) { + this.listen = new ClassicSharedTextArea(height, 30, isShared); + this.listen.setBackground(Color.white); + } else { + this.listen = new NewSharedTextArea(height, 30, isShared); + this.listen.setBackground(GammaTextArea.getBackgroundColor()); + } + + this.listen.setForeground(Color.black); + } + + public void forceTakeFocus() { + ((FocusPreservingTextField)this.line).takeNextFocus(); + } + + @Override + public synchronized void activate(Console c, Container f, Console prev) { + if (this instanceof ChatPart) { + ((FocusPreservingTextField)this.line).isChatLine(); + } + + if (!this.classicTextArea) { + Color bg = GammaTextArea.getBackgroundColor(); + this.line.setBackground(bg); + this.listen.setBackground(bg); + this.line.setForeground(Color.black); + this.listen.setForeground(Color.black); + this.line.repaint(); + this.listen.repaint(); + } else { + this.listen.setBackground(Color.white); + this.listen.setForeground(Color.black); + } + } + + @Override + public void deactivate() { + } + + public void println(String msg) { + this.listen.println(msg); + } + + public synchronized void trigger() { + this.talkVec.addElement(this.line.getText()); + this.line.setText(""); + } + + public synchronized void say(String s) { + this.talkVec.addElement(s); + } + + public void scrollToBottom() { + this.listen.scrollToBottom(); + } + + @Override + public boolean action(Event event, Object what) { + if (event.target == this.line) { + this.trigger(); + return true; + } else { + return false; + } + } + + public void enableLogging(String fileName, String title, boolean append) { + this.listen.enableLogging(fileName, title, append); + } + + public void disableLogging() { + this.listen.disableLogging(); + } + + public static void addLogObserver(Observer o) { + NewSharedTextArea.addLogObserver(o); + ClassicSharedTextArea.addLogObserver(o); + } + + public static void deleteLogObserver(Observer o) { + NewSharedTextArea.deleteLogObserver(o); + ClassicSharedTextArea.addLogObserver(o); + } + + @Override + public synchronized boolean handle(FrameEvent f) { + this.listen.poll(); + + while (this.talkVec.size() > 0) { + String text = null; + synchronized (this) { + text = this.talkVec.firstElement(); + this.talkVec.removeElementAt(0); + } + + if (text != null) { + this.sendText(text); + } + } + + return true; + } + + public static String toHtml(String s) { + assert s != null; + + String h = ""; + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + switch (c) { + case '"': + h = h + """; + break; + case '&': + h = h + "&"; + break; + case '<': + h = h + "<"; + break; + case '>': + h = h + ">"; + break; + default: + h = h + c; + } + } + + return h; + } + + protected abstract void sendText(String var1); +} diff --git a/NET/worlds/console/EMailPart.java b/NET/worlds/console/EMailPart.java new file mode 100644 index 0000000..3df639a --- /dev/null +++ b/NET/worlds/console/EMailPart.java @@ -0,0 +1,11 @@ +package NET.worlds.console; + +public class EMailPart { + public static void showMessage(Console console) { + new MailDialog(console); + } + + public static void showMessage(Console console, String recipient) { + new MailDialog(console, recipient); + } +} diff --git a/NET/worlds/console/EditNamesDialog.java b/NET/worlds/console/EditNamesDialog.java new file mode 100644 index 0000000..6134ae5 --- /dev/null +++ b/NET/worlds/console/EditNamesDialog.java @@ -0,0 +1,143 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.List; + +class EditNamesDialog extends PolledDialog implements DialogReceiver { + private static final long serialVersionUID = -3309806087387084117L; + private List listbox = new List(10); + private Button addButton = new Button(Console.message("Add")); + private Button delButton = new Button(Console.message("Delete")); + private Button cancelButton = new Button(Console.message("Done")); + private NameListOwner owner; + private String addTitle; + private static Font font = new Font(Console.message("ButtonFont"), 0, 12); + + EditNamesDialog(NameListOwner owner, String title, String addTitle) { + super(Console.getFrame(), null, title, true); + this.owner = owner; + this.addTitle = addTitle; + this.ready(); + } + + @Override + protected void build() { + int count = this.owner.getNameListCount(); + + for (int i = 0; i < count; i++) { + this.listbox.add(this.owner.getNameListName(i)); + } + + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.fill = 1; + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 2; + c.gridheight = 3; + this.add(gbag, this.listbox, c); + c.weightx = 0.0; + c.weighty = 0.0; + c.gridwidth = 0; + c.gridheight = 1; + c.fill = 2; + this.addButton.setFont(font); + this.delButton.setFont(font); + this.cancelButton.setFont(font); + this.add(gbag, this.addButton, c); + this.add(gbag, this.delButton, c); + c.weighty = 1.0; + c.anchor = 15; + this.add(gbag, this.cancelButton, c); + } + + private void select(boolean state) { + this.delButton.setEnabled(state); + } + + @Override + public void show() { + super.show(); + if (this.listbox.getItemCount() != 0) { + this.listbox.select(0); + this.select(true); + } else { + this.select(false); + } + + this.listbox.requestFocus(); + } + + @Override + public boolean handleEvent(Event event) { + if (event.id == 701) { + this.select(true); + } else if (event.id == 702) { + this.select(false); + } + + return super.handleEvent(event); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.cancelButton) { + return this.done(false); + } else if (target == this.delButton) { + int index = this.listbox.getSelectedIndex(); + if (index != -1) { + this.listbox.remove(index); + this.owner.removeNameListName(index); + int count = this.listbox.getItemCount(); + if (index < count - 1) { + this.listbox.select(index); + } else if (count > 0) { + this.listbox.select(count - 1); + } else { + this.select(false); + this.listbox.requestFocus(); + } + } + + return true; + } else if (target == this.addButton) { + if (this.owner.mayAddNameListName(this)) { + new AddNameDialog(this, this.addTitle); + } + + return true; + } else { + return false; + } + } + + @Override + public boolean keyDown(Event event, int key) { + return key != 27 && key != 10 ? super.keyDown(event, key) : this.done(false); + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + if (confirmed) { + String name = Console.parseUnicode(((AddNameDialog)who).getName()); + int pos = this.owner.addNameListName(name); + if (pos == -1) { + return; + } + + if (pos == this.listbox.getItemCount()) { + this.listbox.add(name); + } + + this.listbox.makeVisible(pos); + this.listbox.select(pos); + this.select(true); + } + } +} diff --git a/NET/worlds/console/EmoteHandler.java b/NET/worlds/console/EmoteHandler.java new file mode 100644 index 0000000..96d3ec5 --- /dev/null +++ b/NET/worlds/console/EmoteHandler.java @@ -0,0 +1,78 @@ +package NET.worlds.console; + +import NET.worlds.network.Cache; +import NET.worlds.network.CacheFile; +import NET.worlds.network.NetUpdate; +import NET.worlds.network.URL; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.Hashtable; + +public class EmoteHandler { + private Hashtable<String, String> emoteHash = new Hashtable<String, String>(); + + public EmoteHandler() { + this.Load("EmoteList.txt"); + } + + public EmoteHandler(String filename) { + this.Load(filename); + } + + public void Load(String filename) { + File file = null; + + try { + CacheFile cf = Cache.getFile(URL.make(NetUpdate.getUpgradeServerURL() + filename)); + if (cf != null) { + file = new File(cf.getLocalName()); + cf.waitUntilLoaded(); + } + + if (file != null) { + this.LoadFile(file); + } + } catch (Exception var4) { + } + + file = new File(filename); + if (file != null) { + this.LoadFile(file); + } + } + + private void LoadFile(File file) { + if (file != null && file.exists()) { + try { + BufferedReader reader = new BufferedReader(new FileReader(file)); + String line = ""; + + while ((line = reader.readLine()) != null) { + String[] words = line.split("[ \t]"); + + for (int i = 1; i < words.length; i++) { + this.put(words[i].toLowerCase(), words[0]); + } + } + + reader.close(); + } catch (Exception var6) { + var6.printStackTrace(); + } + } + } + + public void put(String emote, String imagename) { + this.emoteHash.put(emote, imagename); + } + + public String get(String emote) { + return this.emoteHash.get(emote); + } + + public ImageCanvas getImage(String emote) { + String imagename = this.get(emote); + return imagename != null && imagename.length() > 0 ? new ImageCanvas(imagename) : null; + } +} diff --git a/NET/worlds/console/Escalator.java b/NET/worlds/console/Escalator.java new file mode 100644 index 0000000..880ca65 --- /dev/null +++ b/NET/worlds/console/Escalator.java @@ -0,0 +1,67 @@ +package NET.worlds.console; + +import NET.worlds.scape.Material; +import NET.worlds.scape.Point3; +import NET.worlds.scape.Point3Temp; +import NET.worlds.scape.Portal; +import NET.worlds.scape.Rect; +import NET.worlds.scape.Room; +import NET.worlds.scape.RoomEnvironment; +import NET.worlds.scape.World; + +public class Escalator { + public Portal bottom; + public Portal top; + private Room antelower; + private Stair stairs; + private Room anteupper; + + public Escalator( + World world, + String name, + float width, + float length, + float ascent, + float height, + float antelen, + int numsteps, + Material riser, + Material tread, + Material floor, + Material left, + Material right, + Material head, + Material ceiling, + float traveltime + ) { + this.stairs = new Stair(world, name, width, length, ascent, ascent + height, numsteps, riser, tread, left, right, head, ceiling); + this.antelower = new Room(world, "antelower." + name); + RoomEnvironment lenv = this.antelower.getEnvironment(); + lenv.add(new Rect(0.0F, 0.0F, 0.0F, 0.0F, antelen, height, left)); + lenv.add(new Rect(width, antelen, 0.0F, width, 0.0F, height, right)); + Portal bp = new Portal(0.0F, antelen, 0.0F, width, antelen, height).biconnect(this.stairs.bottom); + lenv.add(bp); + this.bottom = new Portal(width, 0.0F, 0.0F, 0.0F, 0.0F, height); + lenv.add(this.bottom); + lenv.add(Rect.floor(0.0F, 0.0F, 0.0F, width, antelen, floor)); + lenv.add(Rect.ceiling(0.0F, 0.0F, height, width, antelen, ceiling)); + this.anteupper = new Room(world, "anteupper." + name); + RoomEnvironment uenv = this.anteupper.getEnvironment(); + uenv.add(new Rect(0.0F, 0.0F, 0.0F, 0.0F, antelen, height, left)); + uenv.add(new Rect(width, antelen, 0.0F, width, 0.0F, height, right)); + Portal tp = new Portal(0.0F, antelen, 0.0F, width, antelen, height).biconnect(this.stairs.top); + uenv.add(tp); + this.top = new Portal(width, 0.0F, 0.0F, 0.0F, 0.0F, height); + uenv.add(this.top); + uenv.add(Rect.floor(0.0F, 0.0F, 0.0F, width, antelen, floor)); + uenv.add(Rect.ceiling(0.0F, 0.0F, height, width, antelen, ceiling)); + CameraConveyor convup = new CameraConveyor(Point3Temp.make(0.0F, length / traveltime, 0.0F)); + CameraConveyor convdn = new CameraConveyor(new Point3(0.0F, -length / traveltime, 0.0F)); + bp.addHandler(new AddHandler(convup)); + tp.addHandler(new AddHandler(convdn)); + this.stairs.bottom.addHandler(new RemoveHandler(convup)); + this.stairs.bottom.addHandler(new RemoveHandler(convdn)); + this.stairs.top.addHandler(new RemoveHandler(convup)); + this.stairs.top.addHandler(new RemoveHandler(convdn)); + } +} diff --git a/NET/worlds/console/ExpireDialog.java b/NET/worlds/console/ExpireDialog.java new file mode 100644 index 0000000..7b1f80f --- /dev/null +++ b/NET/worlds/console/ExpireDialog.java @@ -0,0 +1,48 @@ +package NET.worlds.console; + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.Event; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Panel; +import java.text.DateFormat; +import java.util.Date; + +class ExpireDialog extends Dialog { + private static final long serialVersionUID = -1622362025617429254L; + protected Button button; + private static Font font = new Font(Console.message("ButtonFont"), 0, 12); + + public ExpireDialog(Date expireDate) { + super(null, GammaFrame.getDefaultTitle(), false); + this.setLayout(new BorderLayout(15, 15)); + this.add("Center", new MultiLineLabel(Console.message("beta-expired") + DateFormat.getDateTimeInstance().format(expireDate), 20, 20)); + this.button = new Button(Console.message("OK")); + this.button.setFont(font); + Panel p = new Panel(); + p.setLayout(new FlowLayout(1, 15, 15)); + p.add(this.button); + this.add("South", p); + this.pack(); + } + + @Override + public boolean action(Event e, Object arg) { + if (e.target == this.button) { + this.hide(); + this.dispose(); + Main.end(); + return true; + } else { + return false; + } + } + + @Override + public boolean gotFocus(Event e, Object arg) { + this.button.requestFocus(); + return true; + } +} diff --git a/NET/worlds/console/ExposedPanel.java b/NET/worlds/console/ExposedPanel.java new file mode 100644 index 0000000..15f1f99 --- /dev/null +++ b/NET/worlds/console/ExposedPanel.java @@ -0,0 +1,19 @@ +package NET.worlds.console; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Panel; + +public class ExposedPanel extends Panel { + private static final long serialVersionUID = 6772016496031107748L; + + public ExposedPanel() { + this.setBackground(Color.white); + } + + @Override + public void paint(Graphics g) { + g.setColor(this.getBackground()); + g.fillRect(0, 0, this.getSize().width, this.getSize().height); + } +} diff --git a/NET/worlds/console/FileSaver.java b/NET/worlds/console/FileSaver.java new file mode 100644 index 0000000..dce997d --- /dev/null +++ b/NET/worlds/console/FileSaver.java @@ -0,0 +1,77 @@ +package NET.worlds.console; + +import NET.worlds.scape.World; +import java.text.MessageFormat; +import java.util.Enumeration; +import java.util.Vector; + +class FileSaver implements DialogReceiver { + private Vector<World> saveList = new Vector<World>(); + private int state; + public static final int QUIT = 0; + public static final int SAVING = 1; + public static final int CANCEL = 2; + + FileSaver() { + Enumeration<World> e = World.getWorlds(); + + while (e.hasMoreElements()) { + World w = e.nextElement(); + if (w.getEdited()) { + this.saveList.addElement(w); + } + } + + this.saveNext(false); + } + + public int getState() { + return this.state; + } + + private World getWorld() { + return this.saveList.elementAt(0); + } + + private void saveNext(boolean removeFirst) { + if (removeFirst) { + this.saveList.removeElementAt(0); + } + + if (this.saveList.size() != 0) { + this.state = 1; + Object[] arguments = new Object[]{new String(this.getWorld().getName())}; + new YesNoCancelDialog(Console.getFrame(), this, Console.message("Save-Changes2"), MessageFormat.format(Console.message("has-changed"), arguments)); + } else { + this.state = 0; + } + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + if (who instanceof YesNoCancelDialog) { + switch (((YesNoCancelDialog)who).getChoice()) { + case -1: + this.state = 2; + break; + case 0: + this.saveNext(true); + break; + case 1: + new FileSysDialog( + Console.getFrame(), this, Console.message("Save-World"), 1, "World Save Files|*.world", Shaper.getSaveName(this.getWorld()), true + ); + } + } else { + if (confirmed) { + FileSysDialog fileDialog = (FileSysDialog)who; + if (Shaper.doSave(fileDialog.fileName(), this.getWorld(), false)) { + this.saveNext(true); + return; + } + } + + this.state = 2; + } + } +} diff --git a/NET/worlds/console/FileSysDialog.java b/NET/worlds/console/FileSysDialog.java new file mode 100644 index 0000000..699f1ec --- /dev/null +++ b/NET/worlds/console/FileSysDialog.java @@ -0,0 +1,179 @@ +package NET.worlds.console; + +import java.awt.Frame; +import java.io.File; +import javax.swing.JFileChooser; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.filechooser.FileNameExtensionFilter; + +public class FileSysDialog implements Runnable { + public static final int OPEN = 0; + public static final int SAVE = 1; + private String title; + private String typesAndExts; + private String fileName; + private static File lastFile; + private int mode; + private DialogReceiver receiver; + private boolean parentDisabled = false; + private Frame parent; + JFileChooser fc = null; + private static String OpenFileText = "Open File"; + private static String SaveFileText = "Save File"; + private boolean disableParent; + + public FileSysDialog(Frame parent, DialogReceiver receiver, String title, int mode, String typesAndExts, String fileName, boolean disableParent) { + this.receiver = receiver; + this.title = title; + this.typesAndExts = typesAndExts; + this.mode = mode; + this.fileName = fileName; + this.parent = parent; + this.disableParent = disableParent; + SwingUtilities.invokeLater(this); + } + + @Override + public void run() { + if (this.disableParent && this.parent.isEnabled()) { + this.parent.setEnabled(false); + this.parentDisabled = true; + } + + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (ClassNotFoundException var3) { + var3.printStackTrace(); + return; + } catch (InstantiationException var4) { + var4.printStackTrace(); + return; + } catch (IllegalAccessException var5) { + var5.printStackTrace(); + return; + } catch (UnsupportedLookAndFeelException var6) { + var6.printStackTrace(); + return; + } + + File file = null; + + try { + if (this.fileName != null && this.fileName != "") { + file = new File(this.fileName); + if (file != null && file.getParent() != null) { + this.fc = new JFileChooser(file.getParent()); + } + } + + if (this.fc == null && lastFile != null && lastFile.getParent() != null) { + this.fc = new JFileChooser(lastFile.getParent()); + } + + if (this.fc == null) { + this.fc = new JFileChooser("."); + } + } catch (Exception var7) { + var7.printStackTrace(); + return; + } + + this.fc.setFileSelectionMode(0); + this.fc.setDialogType(this.mode == 0 ? 0 : 1); + if (this.title != null) { + this.fc.setDialogTitle(this.title); + } + + if (this.typesAndExts != null) { + buildFileChooser(this.fc, this.typesAndExts); + } + + if (file != null) { + this.fc.setSelectedFile(file); + } + + int retval = this.fc.showDialog(null, this.mode == 0 ? OpenFileText : SaveFileText); + if (retval == 0) { + this.approveSelection(); + } else { + this.cancelSelection(); + } + + if (this.disableParent && this.parentDisabled) { + this.parent.setEnabled(true); + this.parentDisabled = false; + } + } + + private static void buildFileChooser(JFileChooser fc2, String specString) { + String[] entries = specString.split("\\|"); + boolean even = false; + String desc = ""; + FileNameExtensionFilter first = null; + + for (String entry : entries) { + if (!even) { + desc = entry; + even = true; + } else { + String[] fields = entry.split(";"); + + for (int i = 0; i < fields.length; i++) { + String[] ext = fields[i].split("\\."); + if (ext.length > 0) { + fields[i] = ext[ext.length - 1]; + } + } + + FileNameExtensionFilter ff = null; + switch (fields.length) { + case 1: + ff = new FileNameExtensionFilter(desc, fields[0]); + break; + case 2: + ff = new FileNameExtensionFilter(desc, fields[0], fields[1]); + break; + case 3: + ff = new FileNameExtensionFilter(desc, fields[0], fields[1], fields[2]); + break; + case 4: + ff = new FileNameExtensionFilter(desc, fields[0], fields[1], fields[2], fields[3]); + } + + if (ff != null) { + fc2.addChoosableFileFilter(ff); + if (first == null) { + first = ff; + } + } + + even = false; + } + } + + if (first != null) { + fc2.setFileFilter(first); + } + } + + public int getMode() { + return this.mode; + } + + public void approveSelection() { + File file = this.fc.getSelectedFile(); + lastFile = file; + this.fileName = file.getAbsolutePath(); + this.receiver.dialogDone(this, this.fileName != null); + } + + public void cancelSelection() { + this.receiver.dialogDone(this, false); + } + + public String fileName() { + return this.fileName; + } +} diff --git a/NET/worlds/console/Filler.java b/NET/worlds/console/Filler.java new file mode 100644 index 0000000..6aa4d89 --- /dev/null +++ b/NET/worlds/console/Filler.java @@ -0,0 +1,25 @@ +package NET.worlds.console; + +import java.awt.Dimension; +import java.awt.Panel; + +public class Filler extends Panel { + private static final long serialVersionUID = 2578188264762528538L; + int wForced; + int hForced; + + public Filler(int w, int h) { + this.wForced = w; + this.hForced = h; + } + + @Override + public Dimension preferredSize() { + return this.minimumSize(); + } + + @Override + public Dimension minimumSize() { + return new Dimension(this.wForced, this.hForced); + } +} diff --git a/NET/worlds/console/FixedSizePanel.java b/NET/worlds/console/FixedSizePanel.java new file mode 100644 index 0000000..145d82a --- /dev/null +++ b/NET/worlds/console/FixedSizePanel.java @@ -0,0 +1,43 @@ +package NET.worlds.console; + +import java.awt.Dimension; +import java.awt.Panel; + +class FixedSizePanel extends Panel { + private static final long serialVersionUID = 3707537728341782609L; + int w; + int h; + + public FixedSizePanel(int w, int h) { + this.w = w; + this.h = h; + } + + @Override + public Dimension preferredSize() { + Dimension d = super.preferredSize(); + if (this.w >= 0) { + d.width = this.w; + } + + if (this.h >= 0) { + d.height = this.h; + } + + return d; + } + + @Override + public Dimension minimumSize() { + Dimension d = super.minimumSize(); + if (this.w >= 0) { + d.width = this.w; + } + + if (this.h >= 0) { + d.height = this.h; + } + + return d; + } +} diff --git a/NET/worlds/console/FixedWidthPanel.java b/NET/worlds/console/FixedWidthPanel.java new file mode 100644 index 0000000..d97e122 --- /dev/null +++ b/NET/worlds/console/FixedWidthPanel.java @@ -0,0 +1,22 @@ +package NET.worlds.console; + +import java.awt.Dimension; +import java.awt.LayoutManager; +import java.awt.Panel; + +class FixedWidthPanel extends Panel { + private static final long serialVersionUID = 1256222162739133960L; + private int width; + + public FixedWidthPanel(LayoutManager layout, int width) { + super(layout); + this.width = width; + } + + @Override + public Dimension preferredSize() { + Dimension d = super.preferredSize(); + d.width = this.width; + return d; + } +} diff --git a/NET/worlds/console/FocusPreservingTextField.java b/NET/worlds/console/FocusPreservingTextField.java new file mode 100644 index 0000000..57b656b --- /dev/null +++ b/NET/worlds/console/FocusPreservingTextField.java @@ -0,0 +1,89 @@ +package NET.worlds.console; + +import NET.worlds.scape.EventQueue; +import NET.worlds.scape.Pilot; +import java.awt.Event; +import java.awt.Font; +import java.awt.TextField; + +class FocusPreservingTextField extends TextField { + private static final long serialVersionUID = 7475622191515920214L; + private static FocusPreservingTextField lostFocus; + private static FocusPreservingTextField hasFocus; + private static FocusPreservingTextField chatLine; + private static Object hasFocusMutex = new Object(); + private static Font font = new Font(Console.message("GammaTextFont"), 0, 12); + boolean preserveFocus; + boolean takeNextFocus; + + public FocusPreservingTextField() { + super(30); + this.setFocusable(true); + this.setFont(font); + } + + public void isChatLine() { + chatLine = this; + } + + @Override + public void requestFocus() { + if (!this.takeNextFocus) { + synchronized (hasFocusMutex) { + this.preserveFocus = hasFocus != null && hasFocus.getText().length() != 0 || chatLine != null && chatLine.getText().length() != 0; + } + } else { + this.takeNextFocus = false; + } + + if (!this.preserveFocus) { + super.requestFocus(); + } + } + + public void takeNextFocus() { + this.preserveFocus = false; + this.takeNextFocus = true; + } + + @Override + public boolean handleEvent(Event e) { + synchronized (hasFocusMutex) { + if (e.id == 1005) { + if (hasFocus == this) { + lostFocus = this; + hasFocus = null; + this.preserveFocus = false; + } + } else if (e.id == 1004) { + hasFocus = this; + if (this.preserveFocus && lostFocus != null) { + lostFocus.takeNextFocus(); + lostFocus.requestFocus(); + } + + lostFocus = null; + this.preserveFocus = false; + } + } + + if (e.id == 401) { + Console.wake(); + if (e.key == 27) { + this.setText(""); + return true; + } + + if ((e.modifiers & 2) != 0 && e.key >= 1 && e.key <= 26 && e.key != 22) { + Pilot pilot = Pilot.getActive(); + if (pilot != null) { + pilot.animate("abcdefghijklmnopqrstuvwxyz".substring(e.key - 1, e.key)); + } + + return true; + } + } + + return EventQueue.redirectDrivingKeys(e) ? true : super.handleEvent(e); + } +} diff --git a/NET/worlds/console/ForwardButton.java b/NET/worlds/console/ForwardButton.java new file mode 100644 index 0000000..9e1b1f0 --- /dev/null +++ b/NET/worlds/console/ForwardButton.java @@ -0,0 +1,11 @@ +package NET.worlds.console; + +import java.awt.Button; + +class ForwardButton extends Button { + private static final long serialVersionUID = -1872202502789241725L; + + public ForwardButton(String name) { + super(name); + } +} diff --git a/NET/worlds/console/FourTilePanel.java b/NET/worlds/console/FourTilePanel.java new file mode 100644 index 0000000..f010994 --- /dev/null +++ b/NET/worlds/console/FourTilePanel.java @@ -0,0 +1,229 @@ +package NET.worlds.console; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Rectangle; + +public class FourTilePanel extends Panel { + private static final long serialVersionUID = -7002173409842219262L; + private static final int tw = 5; + private static final int th = 5; + private static final int aw = 7; + private static final int ah = 4; + private static final int bw = 3; + private static Color widgetColor = new Color(255, 238, 177); + private static Color lineColor = new Color(162, 162, 162); + private Component[] comps = new Component[4]; + private int[] order = new int[]{0, 1, 2, 3}; + private float[] divider = new float[]{0.22F, 0.63F}; + private int tx; + private int ty; + private int prevWidth; + private int prevHeight; + private Rectangle moveWidget = new Rectangle(); + private FourTileSwapper swap01 = new FourTileSwapper(this, 0, 1); + private FourTileSwapper swap02 = new FourTileSwapper(this, 0, 2); + private FourTileSwapper swap23 = new FourTileSwapper(this, 2, 3); + private FourTileSwapper swap13 = new FourTileSwapper(this, 1, 3); + private FourTileSwapper[] swaps = new FourTileSwapper[]{this.swap01, this.swap02, this.swap23, this.swap13}; + private boolean dragging; + private int offsetx; + private int offsety; + private int minx; + private int miny; + private int maxx; + private int maxy; + private int specialTileIndex; + private Component oneTile; + + public FourTilePanel(Component ul, Component ur, Component ll, Component lr, int special) { + this.setLayout(null); + this.specialTileIndex = special; + this.add(this.comps[0] = ul); + this.add(this.comps[1] = ur); + this.add(this.comps[2] = ll); + this.add(this.comps[3] = lr); + this.setBackground(Color.black); + if (GammaFrameState.restoreLayout(this.order, this.divider)) { + this.useOneTileMode(); + } else { + this.useFourTileMode(); + } + } + + public boolean isOneTileMode() { + return this.oneTile != null; + } + + public void useOneTileMode() { + if (this.oneTile == null) { + this.oneTile = this.comps[this.specialTileIndex]; + + for (int i = 0; i < 4; i++) { + if (i != this.specialTileIndex) { + this.remove(this.comps[i]); + } + } + + this.moveComponents(); + this.saveLayout(); + this.validate(); + } + } + + public void useFourTileMode() { + if (this.oneTile != null) { + this.oneTile = null; + + for (int i = 0; i < 4; i++) { + if (i != this.specialTileIndex) { + this.add(this.comps[i]); + } + } + + this.moveComponents(); + this.saveLayout(); + this.validate(); + } + } + + @Override + public void reshape(int x, int y, int width, int height) { + super.reshape(x, y, width, height); + if (!GammaFrameState.isIconic()) { + if (this.prevWidth != width) { + this.tx = Math.max((int)(this.divider[0] * width), 12); + this.prevWidth = width; + } + + if (this.prevHeight != height) { + this.ty = Math.max((int)(this.divider[1] * height), 9); + this.prevHeight = height; + } + + this.moveComponents(width, height); + } + } + + private void saveLayout() { + GammaFrameState.saveLayout(this.order, this.divider, this.oneTile != null); + } + + private void moveComponents() { + Dimension size = this.getSize(); + this.moveComponents(size.width, size.height); + } + + private void moveComponents(int width, int height) { + if (this.oneTile == null) { + this.comps[this.order[0]].reshape(3, 3, this.tx - 3, this.ty - 3); + this.comps[this.order[1]].reshape(this.tx + 5, 3, width - this.tx - 5 - 3, this.ty - 3); + this.comps[this.order[2]].reshape(3, this.ty + 5, this.tx - 3, height - this.ty - 5 - 3); + this.comps[this.order[3]].reshape(this.tx + 5, this.ty + 5, width - this.tx - 5 - 3, height - this.ty - 5 - 3); + } else { + this.oneTile.reshape(0, 0, width, height); + } + + this.repaint(); + } + + @Override + public void paint(Graphics g) { + Dimension size = this.getSize(); + g.setColor(this.getBackground()); + if (this.oneTile == null) { + g.fillRect(0, 0, 3, size.height); + g.fillRect(0, 0, size.width, 3); + g.fillRect(0, size.height - 3, size.width, 3); + g.fillRect(size.width - 3, 0, 3, size.height); + g.fillRect(0, this.ty, size.width, 5); + g.fillRect(this.tx, 0, 5, size.height); + g.setColor(lineColor); + g.drawLine(0, this.ty + 2, size.width, this.ty + 2); + g.drawLine(this.tx + 2, 0, this.tx + 2, size.height); + g.setColor(widgetColor); + g.fillRect(this.tx, this.ty, 5, 5); + this.moveWidget.reshape(this.tx, this.ty, 5, 5); + int tmp = (this.tx + 2 - 7) / 2; + g.fillArc(tmp, this.ty - 2, 7, 4, 0, -180); + g.fillArc(tmp, this.ty + 5 - 2, 7, 4, 0, 180); + this.swap02.reshape(tmp, this.ty, 7, 5); + tmp = (this.tx + 2 + size.width - 7) / 2; + g.fillArc(tmp, this.ty - 2, 7, 4, 0, -180); + g.fillArc(tmp, this.ty + 5 - 2, 7, 4, 0, 180); + this.swap13.reshape(tmp, this.ty, 7, 5); + tmp = (this.ty + 2 - 7) / 2; + g.fillArc(this.tx - 2, tmp, 4, 7, 90, -180); + g.fillArc(this.tx + 5 - 2, tmp, 4, 7, 90, 180); + this.swap01.reshape(this.tx, tmp, 5, 7); + tmp = (this.ty + 2 + size.height - 7) / 2; + g.fillArc(this.tx - 2, tmp, 4, 7, 90, -180); + g.fillArc(this.tx + 5 - 2, tmp, 4, 7, 90, 180); + this.swap23.reshape(this.tx, tmp, 5, 7); + } + } + + @Override + public boolean mouseDrag(Event evt, int x, int y) { + if (this.dragging) { + this.tx = x + this.offsetx; + this.ty = y + this.offsety; + this.divider[0] = (float)this.tx / this.getSize().width; + this.divider[1] = (float)this.ty / this.getSize().height; + this.tx = Math.max(this.tx, this.minx); + this.ty = Math.max(this.ty, this.miny); + this.tx = Math.min(this.tx, this.maxx); + this.ty = Math.min(this.ty, this.maxy); + this.moveComponents(); + } + + return true; + } + + @Override + public boolean mouseUp(Event evt, int x, int y) { + if (this.dragging) { + this.validate(); + this.saveLayout(); + } + + this.dragging = false; + return true; + } + + @Override + public boolean mouseDown(Event evt, int x, int y) { + for (int i = 0; i < this.swaps.length; i++) { + if (this.swaps[i].maybeSwap(x, y)) { + return true; + } + } + + if (this.moveWidget.inside(x, y)) { + this.offsetx = this.tx - x; + this.offsety = this.ty - y; + this.minx = 12; + this.maxx = this.getSize().width - this.minx; + this.miny = 12; + this.maxy = this.getSize().height - this.miny; + if (this.minx < this.maxx && this.miny < this.maxy) { + this.dragging = true; + } + } + + return true; + } + + void swap(int c1, int c2) { + int tmp = this.order[c1]; + this.order[c1] = this.order[c2]; + this.order[c2] = tmp; + this.moveComponents(); + this.validate(); + this.saveLayout(); + } +} diff --git a/NET/worlds/console/FourTileSwapper.java b/NET/worlds/console/FourTileSwapper.java new file mode 100644 index 0000000..c174fdf --- /dev/null +++ b/NET/worlds/console/FourTileSwapper.java @@ -0,0 +1,25 @@ +package NET.worlds.console; + +import java.awt.Rectangle; + +class FourTileSwapper extends Rectangle { + private static final long serialVersionUID = 6045056218784091538L; + private FourTilePanel parent; + private int c1; + private int c2; + + FourTileSwapper(FourTilePanel parent, int c1, int c2) { + this.parent = parent; + this.c1 = c1; + this.c2 = c2; + } + + boolean maybeSwap(int x, int y) { + if (this.inside(x, y)) { + this.parent.swap(this.c1, this.c2); + return true; + } else { + return false; + } + } +} diff --git a/NET/worlds/console/FramePart.java b/NET/worlds/console/FramePart.java new file mode 100644 index 0000000..d2cfe65 --- /dev/null +++ b/NET/worlds/console/FramePart.java @@ -0,0 +1,15 @@ +package NET.worlds.console; + +import NET.worlds.scape.FrameEvent; +import java.awt.Container; +import java.awt.Event; + +public interface FramePart { + void activate(Console var1, Container var2, Console var3); + + void deactivate(); + + boolean action(Event var1, Object var2); + + boolean handle(FrameEvent var1); +} diff --git a/NET/worlds/console/FriendsListPart.java b/NET/worlds/console/FriendsListPart.java new file mode 100644 index 0000000..583ee9a --- /dev/null +++ b/NET/worlds/console/FriendsListPart.java @@ -0,0 +1,988 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.core.Std; +import NET.worlds.network.BuddyListUpdateCmd; +import NET.worlds.network.Galaxy; +import NET.worlds.network.InfiniteWaitException; +import NET.worlds.network.NetUpdate; +import NET.worlds.network.NetworkObject; +import NET.worlds.network.PacketTooLargeException; +import NET.worlds.network.WorldServer; +import NET.worlds.network.netPacket; +import NET.worlds.network.whisperCmd; +import NET.worlds.scape.AnimatedActionManager; +import NET.worlds.scape.Drone; +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.MouseDownEvent; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.PosableDrone; +import NET.worlds.scape.PosableShape; +import NET.worlds.scape.TeleportAction; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.StringTokenizer; +import java.util.Vector; + +public class FriendsListPart extends QuantizedCanvas implements FramePart, DialogReceiver, DialogDisabled, NameListOwner, Comparator<String> { + private static final long serialVersionUID = 2875678557235430189L; + private static final String oldIniItemName = "Friends"; + private static final String iniItemName = "Friend"; + private static int maxFriends = Gamma.shaperEnabled() ? 500 : 250; + private static int absMaxFriends = 600; + private static final String separator = ";"; + private static final String whereQuery = "&|+where?"; + private static final String whereResponse = "&|+where>"; + VoiceChat chatter = new VoiceChat(); + private static final int MOUSEMOVE = 0; + private static final int MOUSEDRAG = 1; + private static final int MOUSEDOWN = 2; + private static final int MOUSEUP = 3; + private static final int MOUSEENTER = 4; + private static final int MOUSEEXIT = 5; + private static final int BLANK = 0; + private static final int NORMAL = 1; + private static final int CURSED = 2; + private static final int DOWN = 3; + private static final int TELEPORT_IDLE = 0; + private static final int TELEPORT_REQUEST_LOCATION = 1; + private static final int TELEPORT_WAIT_FOR_LOCATION = 2; + private static final int buttonWidth = 97; + private static final int buttonHeight = 11; + private static final int xText = 20; + private static final int yText = 9; + private static final int xTextClip = 94; + private static Image friendsImage; + private static Image moreFriendsImage; + private static Font font; + private static FriendsListPart active; + private Vector<String> friends = new Vector<String>(); + private Vector<String> onlineFriends = new Vector<String>(); + private Vector<String> mutedOnlineFriends = new Vector<String>(); + private Vector<BuddyListUpdateCmd> serverUpdates = new Vector<BuddyListUpdateCmd>(); + private Object friendsMutex = new Object(); + private int cursedButton = -1; + private int clickedButton = -1; + private boolean clickedButtonDown; + private PopupMenu menu; + private MenuItem teleportItem = new MenuItem(Console.message("Go-There")); + private MenuItem emailItem = new MenuItem(Console.message("E-Mail")); + private MenuItem muteItem = new MenuItem(Console.message("Mute")); + private MenuItem whisperItem = new MenuItem(Console.message("Whisper")); + private MenuItem voiceChatItem = new MenuItem(Console.message("Voice-Chat")); + private MenuItem infoItem = new MenuItem(Console.message("Personal-I")); + private MenuItem tradeItem = new MenuItem(Console.message("Talk-Trade")); + private PopupMenu droneMenu; + private MenuItem droneAddItem = new MenuItem(Console.message("Add-2-friends")); + private MenuItem droneEmailItem = new MenuItem(Console.message("E-Mail")); + private MenuItem droneMuteItem = new MenuItem(Console.message("Mute")); + private MenuItem droneWhisperItem = new MenuItem(Console.message("Whisper")); + private MenuItem droneVoiceChatItem = new MenuItem(Console.message("Voice-Chat")); + private MenuItem droneInfoItem = new MenuItem(Console.message("Personal-I")); + private MenuItem droneTradeItem = new MenuItem(Console.message("Talk-Trade")); + private String activeFriendName = ""; + private String teleportTarget; + private int teleportState = 0; + private int teleportWaitStartTime; + private boolean teleportWaitSentMsg; + private int friendsButtons; + private int moreFriendsButton; + private boolean moreFriendsActive; + private MenuItem editItem; + private Menu actionMenu; + private MoreFriendsDialog moreFriendsDialog; + private DefaultConsole console; + private Galaxy galaxy; + private IniFile serverSection; + private boolean isDialogDisabled; + private int showMenuY = -1; + private static final String voiceChatWhisper = "&|+voicechat"; + + public FriendsListPart() { + AnimatedActionManager.get(); + if (font == null) { + String friendsGif = IniFile.override().getIniString("friendsGif", "friends.gif"); + friendsImage = ImageCanvas.getSystemImage(friendsGif, this); + String moreFriendsGif = IniFile.override().getIniString("moreFriendsGif", Console.message("mfriends.gif")); + moreFriendsImage = ImageCanvas.getSystemImage(moreFriendsGif, this); + int fontSize = new Integer(Console.message("FriendsPointSize")); + font = new Font(Console.message("FriendsFont"), 0, fontSize); + } + + this.teleportItem.setFont(font); + this.emailItem.setFont(font); + this.muteItem.setFont(font); + this.whisperItem.setFont(font); + this.tradeItem.setFont(font); + this.voiceChatItem.setFont(font); + this.infoItem.setFont(font); + this.menu = new PopupMenu(); + this.menu.add(this.teleportItem); + String prodName = IniFile.override().getIniString("ProductName", ""); + if (!prodName.equalsIgnoreCase("RedLightWorld") && !prodName.equalsIgnoreCase("RedLightCenter")) { + this.menu.add(this.emailItem); + } + + this.menu.add(this.muteItem); + this.menu.add(this.whisperItem); + boolean allowTrading = IniFile.gamma().getIniInt("EnableTrading", 0) == 1 || NetUpdate.isInternalVersion(); + if (allowTrading) { + this.menu.add(this.tradeItem); + } + + this.menu.add(this.voiceChatItem); + if (!VoiceChat.voiceChatAvailable()) { + this.voiceChatItem.setEnabled(false); + } + + this.menu.add(this.infoItem); + this.add(this.menu); + this.droneAddItem.setFont(font); + this.droneEmailItem.setFont(font); + this.droneMuteItem.setFont(font); + this.droneWhisperItem.setFont(font); + this.droneTradeItem.setFont(font); + this.droneVoiceChatItem.setFont(font); + this.droneInfoItem.setFont(font); + this.droneMenu = new PopupMenu(); + this.droneMenu.setFont(font); + this.droneMenu.add(this.droneAddItem); + this.droneMenu.add(this.droneEmailItem); + this.droneMenu.add(this.droneMuteItem); + this.droneMenu.add(this.droneWhisperItem); + if (allowTrading) { + this.droneMenu.add(this.droneTradeItem); + } + + this.droneMenu.add(this.droneVoiceChatItem); + if (!VoiceChat.voiceChatAvailable()) { + this.droneVoiceChatItem.setEnabled(false); + } + + this.droneMenu.add(this.droneInfoItem); + } + + @Override + public void update(Graphics g) { + this.paint(g); + } + + @Override + public void paint(Graphics g) { + int height = this.getSize().height; + int buttons = height / 11; + synchronized (this.friendsMutex) { + int count = this.onlineFriends.size(); + this.moreFriendsButton = buttons - 1; + if (count >= buttons) { + this.friendsButtons = buttons - 1; + this.moreFriendsActive = true; + } else { + this.friendsButtons = count; + this.moreFriendsActive = false; + } + + int y = buttons * 11; + int extra = height - y; + if (extra > 0) { + g.setColor(Color.black); + g.fillRect(0, 0, 97, extra); + } + + for (int i = 0; i < buttons; i++) { + int state = 1; + if (i >= this.friendsButtons && !this.isMoreFriendsButton(i)) { + state = 0; + } else if (i == this.clickedButton) { + state = this.clickedButtonDown ? 3 : 1; + } else if (i == this.cursedButton) { + state = 2; + } + + this.drawButton(g, i, state); + } + } + } + + @Override + public int getRemainder(int proposedHeight) { + int buttons = proposedHeight / 11; + int y = buttons * 11; + return proposedHeight - y; + } + + @Override + public Dimension preferredSize() { + return new Dimension(97, 1); + } + + @Override + public Dimension minimumSize() { + return this.preferredSize(); + } + + @Override + public boolean mouseMove(Event e, int x, int y) { + return this.buttonAction(x, y, 0); + } + + @Override + public boolean mouseDown(Event e, int x, int y) { + return this.buttonAction(x, y, 2); + } + + @Override + public boolean mouseUp(Event e, int x, int y) { + if (this.buttonAction(x, y, 3)) { + if (this.showMenuY != -1) { + this.menu.show(this, 0, this.showMenuY); + this.showMenuY = -1; + } + + return true; + } else { + return false; + } + } + + @Override + public boolean mouseDrag(Event e, int x, int y) { + return this.buttonAction(x, y, 1); + } + + @Override + public boolean mouseEnter(Event e, int x, int y) { + return this.buttonAction(x, y, 4); + } + + @Override + public boolean mouseExit(Event e, int x, int y) { + return this.buttonAction(x, y, 5); + } + + @Override + public boolean handleEvent(Event event) { + return this.isDialogDisabled ? false : super.handleEvent(event); + } + + private void loadFriends() { + if (this.friends.size() != 0) { + this.friends.removeAllElements(); + } + + if (Console.getActive().broadcastEnabled()) { + maxFriends = 600; + } + + for (int i = 0; i < absMaxFriends; i++) { + String name = this.serverSection.getIniString("Friend" + i, ""); + if (name.length() == 0) { + break; + } + + if (isValidUserName(name) && !icontains(this.friends, name)) { + this.friends.addElement(name); + } + } + + if (this.friends.size() == 0) { + String friendsStr = this.serverSection.getIniString("Friends", ""); + StringTokenizer tokens = new StringTokenizer(friendsStr, ";"); + + while (tokens.hasMoreTokens() && this.friends.size() < absMaxFriends) { + String namex = tokens.nextToken(); + if (isValidUserName(namex) && !icontains(this.friends, namex)) { + this.friends.addElement(namex); + } + } + + if (this.friends.size() != 0) { + this.saveFriends(); + this.serverSection.setIniString("Friends", ""); + } + } + + Collections.sort(this.friends, this); + } + + void saveFriends() { + if (this.serverSection != null) { + int count = this.friends.size(); + + for (int i = 0; i < count; i++) { + this.serverSection.setIniString("Friend" + i, this.friends.elementAt(i)); + } + + this.serverSection.setIniString("Friend" + count, ""); + } + } + + private boolean isMoreFriendsButton(int button) { + return button == this.moreFriendsButton && this.moreFriendsActive; + } + + private Graphics drawButton(Graphics g, int button, int state) { + Image image = button == this.moreFriendsButton ? moreFriendsImage : friendsImage; + if (g != null || (g = this.getGraphics()) != null) { + int y = button * 11; + Graphics g1 = g.create(0, y, 97, 11); + g1.drawImage(image, -state * 97, 0, null); + if (button >= 0 && button < this.friendsButtons && button < this.onlineFriends.size()) { + g1.clipRect(0, 0, 94, 11); + g1.setFont(font); + g1.setColor(Color.white); + g1.drawString(this.onlineFriends.elementAt(button), 20, 9); + } + + g1.dispose(); + } + + return g; + } + + private boolean buttonAction(int x, int y, int action) { + synchronized (this.friendsMutex) { + Graphics g = null; + int button = y / 11; + if ((button < 0 || button >= this.friendsButtons) && !this.isMoreFriendsButton(button)) { + button = -1; + } + + if (action != 0 && action != 4) { + if (action == 5) { + if (this.cursedButton != -1) { + g = this.drawButton(g, this.cursedButton, 1); + this.cursedButton = -1; + } + + if (this.clickedButton != -1 && this.clickedButtonDown) { + g = this.drawButton(g, this.clickedButton, 1); + this.clickedButtonDown = false; + } + } else if (action == 2) { + if (this.clickedButton != -1) { + g = this.drawButton(g, this.clickedButton, 1); + this.clickedButtonDown = false; + } + + if ((this.clickedButton = button) != -1) { + g = this.drawButton(g, this.clickedButton, 3); + this.clickedButtonDown = true; + } + } else if (action == 1) { + if (this.clickedButton != -1) { + if (this.clickedButtonDown) { + if (button != this.clickedButton) { + g = this.drawButton(g, this.clickedButton, 1); + this.clickedButtonDown = false; + } + } else if (button == this.clickedButton) { + g = this.drawButton(g, this.clickedButton, 3); + this.clickedButtonDown = true; + } + } + } else if (action == 3) { + this.cursedButton = button; + if (this.clickedButtonDown) { + if (this.cursedButton == this.clickedButton) { + g = this.drawButton(g, this.clickedButton, 2); + } else { + g = this.drawButton(g, this.clickedButton, 1); + } + + if (this.clickedButton == this.moreFriendsButton) { + if (this.moreFriendsDialog == null) { + this.moreFriendsDialog = new MoreFriendsDialog(this, this.menu, this.onlineFriends); + } + } else if (this.clickedButton >= 0 && this.clickedButton < this.onlineFriends.size()) { + this.activeFriendName = this.onlineFriends.elementAt(this.clickedButton); + + assert this.activeFriendName != null; + + this.showMenuY = (this.clickedButton + 1) * 11; + } + } + + if (this.cursedButton != this.clickedButton) { + g = this.drawButton(g, this.cursedButton, 2); + } + + this.clickedButtonDown = false; + this.clickedButton = -1; + } + } else if (button != this.cursedButton) { + g = this.drawButton(g, this.cursedButton, 1); + g = this.drawButton(g, this.cursedButton = button, 2); + } + + if (g != null) { + g.dispose(); + } + + return true; + } + } + + private static boolean sendMsg(WorldServer server, netPacket packet) { + try { + server.sendNetworkMsg(packet); + return true; + } catch (InfiniteWaitException var3) { + } catch (PacketTooLargeException var4) { + } + + return false; + } + + @Override + public void activate(Console c, Container f, Console prev) { + active = this; + this.console = (DefaultConsole)c; + this.console.getRender().add(this.droneMenu); + this.editItem = c.addMenuItem(Console.message("Edit-Friends"), "Options"); + this.editItem.setEnabled(this.friends != null); + } + + @Override + public void deactivate() { + active = null; + this.editItem = null; + } + + @Override + public boolean action(Event event, Object what) { + if (event.target == this.editItem) { + new EditNamesDialog(this, Console.message("Edit-Friends2"), Console.message("Add-Friend")); + return true; + } else { + return this.maybeFriendAction(event.target); + } + } + + @Override + public boolean handle(FrameEvent f) { + synchronized (this.friendsMutex) { + int count = this.serverUpdates.size(); + if (count != 0) { + WorldServer server = this.console.getServerNew(); + if (server != null) { + while (count-- != 0 && sendMsg(server, this.serverUpdates.elementAt(0))) { + this.serverUpdates.removeElementAt(0); + } + } + } + } + + synchronized (this) { + if (this.teleportState == 1) { + WorldServer server = this.console.getServerNew(); + if (server != null) { + sendMsg(server, new whisperCmd(this.teleportTarget, "&|+where?")); + this.teleportState = 2; + this.teleportWaitStartTime = Std.getRealTime(); + this.teleportWaitSentMsg = false; + } else { + Console.println(Console.message("Cant-go-there")); + this.teleportState = 0; + } + } + + if (this.teleportState == 2) { + int now = Std.getRealTime(); + if (now > this.teleportWaitStartTime + 5000) { + if (now > this.teleportWaitStartTime + 30000) { + this.teleportState = 0; + if (this.teleportWaitSentMsg) { + Object[] arguments = new Object[]{new String(this.teleportTarget)}; + Console.println(MessageFormat.format(Console.message("Cancel-teleport"), arguments)); + } + } else if (!this.teleportWaitSentMsg) { + Object[] arguments = new Object[]{new String(this.teleportTarget)}; + Console.println(MessageFormat.format(Console.message("Delay-locating"), arguments)); + this.teleportWaitSentMsg = true; + } + } + } + + return true; + } + } + + @Override + public void dialogDisable(boolean disable) { + if (this.isDialogDisabled = disable) { + this.cursedButton = -1; + this.clickedButton = -1; + this.clickedButtonDown = false; + this.repaint(); + } + } + + public void setServer(WorldServer server, IniFile serverSection) { + this.serverSection = serverSection; + this.galaxy = server.getGalaxy(); + + assert serverSection != null; + + assert this.galaxy != null; + + this.loadFriends(); + if (this.editItem != null) { + this.editItem.setEnabled(true); + } + + this.sendAll(server); + } + + public void maybeServerDisconnect() { + if (this.galaxy != null) { + if (this.editItem != null) { + this.editItem.setEnabled(false); + } + + this.clearAll(); + } + } + + public static boolean tryToRun(String s) { + try { + Runtime.getRuntime().exec(s); + return true; + } catch (IOException var2) { + return false; + } + } + + private boolean maybeFriendAction(Object target) { + if (target == this.emailItem || target == this.droneEmailItem) { + EMailPart.showMessage(this.console, this.activeFriendName); + } else if (target == this.whisperItem || target == this.droneWhisperItem) { + Console.startWhispering(this.activeFriendName); + } else if (target == this.voiceChatItem || target == this.droneVoiceChatItem) { + this.chatter.beginChat(this.activeFriendName, this.console); + } else if (target == this.droneAddItem) { + if (this.mayAddNameListName(Console.getFrame())) { + this.addNameListName(this.activeFriendName); + } + } else if (target == this.teleportItem) { + synchronized (this) { + this.teleportTarget = this.activeFriendName; + if (this.teleportState == 2 && this.teleportWaitSentMsg) { + Console.println(Console.message("Cancel-new-tele")); + } + + this.teleportState = 1; + } + } else if (target == this.muteItem || target == this.droneMuteItem) { + if (this.console.getMutes().mayAddNameListName(Console.getFrame())) { + this.console.getMutes().addNameListName(this.activeFriendName); + } + } else if (target != this.infoItem && target != this.droneInfoItem) { + if (target != this.tradeItem && target != this.droneTradeItem) { + return false; + } + + WhisperManager.whisperManager().startToTrade(this.activeFriendName); + } else { + new PersonalInfoDownload(this.activeFriendName, this.console); + } + + return true; + } + + private void clearAll() { + if (this.galaxy != null) { + synchronized (this.friendsMutex) { + this.onlineFriends.removeAllElements(); + this.mutedOnlineFriends.removeAllElements(); + } + + if (active == this) { + this.repaint(); + } + + this.galaxy.sentFriendsList(false); + } + } + + private void sendAll(WorldServer server) { + if (!this.galaxy.sentFriendsList()) { + synchronized (this.friendsMutex) { + int count = this.friends.size(); + + for (int i = 0; i < count; i++) { + sendMsg(server, new BuddyListUpdateCmd(this.friends.elementAt(i), 1)); + } + } + + this.galaxy.sentFriendsList(true); + } + } + + private static String getWorldName(String url) { + int rindex = url.indexOf(".world#"); + int windex; + return rindex == -1 || (windex = url.lastIndexOf(47, rindex)) == -1 && (windex = url.lastIndexOf(58, rindex)) == -1 + ? null + : url.substring(windex + 1, rindex); + } + + public static void processWhisper(WorldServer server, String user, String text) { + if (active != null && active.galaxy == server.getGalaxy()) { + active.instanceProcessWhisper(server, user, text); + } + } + + private synchronized void instanceProcessWhisper(WorldServer server, String user, String text) { + if (text.startsWith("&|+where?")) { + Pilot pilot; + String url; + if ((pilot = Pilot.getActive()) != null && (url = pilot.getTeleportURL()) != null) { + if (this.console.getSpecialGuest()) { + int i = url.indexOf(60); + int j = url.indexOf(62); + url = url.substring(0, i) + url.substring(j + 1); + } + + if (Pilot.getActive().getRoom().getAllowTeleport()) { + sendMsg(server, new whisperCmd(user, "&|+where>" + url)); + } + } + } else if (text.startsWith("&|+where>")) { + if (this.teleportState == 2 && this.teleportTarget.equals(user)) { + String pos = text.substring("&|+where>".length()); + boolean valid = false; + String targetWorld = getWorldName(pos); + if (!pos.startsWith("home:") && !pos.startsWith("http://")) { + if (targetWorld != null && targetWorld.length() > 0) { + Pilot pilot = Pilot.getActive(); + if (pilot != null) { + String url = pilot.getTeleportURL(); + if (url != null && targetWorld.equals(getWorldName(url))) { + valid = true; + pos = url.substring(0, url.lastIndexOf(35)) + pos.substring(pos.lastIndexOf(35)); + } + } + } + + if (!valid) { + String s = WorldsMarkPart.findPackage(targetWorld); + if (s != null) { + valid = true; + pos = "home:" + s + "/" + s + ".world" + pos.substring(pos.lastIndexOf(35)); + } + } + } else { + valid = true; + } + + if (valid) { + TeleportAction.teleport(pos, null); + if (this.teleportWaitSentMsg) { + Object[] arguments = new Object[]{new String(this.teleportTarget)}; + Console.println(MessageFormat.format(Console.message("Found-tele"), arguments)); + } + } else { + Object[] arguments = new Object[]{new String(this.teleportTarget), new String(targetWorld)}; + String msg = MessageFormat.format(Console.message("Cant-go-world"), arguments); + Console.println(msg); + } + + this.teleportState = 0; + this.teleportTarget = null; + } + } else if (text.startsWith("&|+voicechat")) { + this.chatter.handleChatWhisper(user, text, this.console); + } else if (text.startsWith(VoiceChat.VCdebugCommand)) { + VoiceChat.setExtra(text); + } else if (text.startsWith(VoiceChat.VCdebugCommandReset)) { + VoiceChat.resetExtra(); + } + } + + @Override + public int getNameListCount() { + return this.friends.size(); + } + + @Override + public String getNameListName(int index) { + return this.friends.elementAt(index); + } + + @Override + public void removeNameListName(int index) { + synchronized (this.friendsMutex) { + String name = this.friends.elementAt(index); + this.friends.removeElementAt(index); + this.saveFriends(); + if ((index = iindexOf(this.onlineFriends, name)) != -1) { + this.onlineFriends.removeElementAt(index); + if (active == this) { + this.repaint(); + } + } + + if ((index = iindexOf(this.mutedOnlineFriends, name)) != -1) { + this.mutedOnlineFriends.removeElementAt(index); + } + + this.serverUpdates.addElement(new BuddyListUpdateCmd(name, 0)); + } + } + + @Override + public boolean mayAddNameListName(java.awt.Window currentWindow) { + if (this.friends.size() < maxFriends) { + return true; + } else { + Object[] arguments = new Object[]{new String("" + maxFriends)}; + new OkCancelDialog( + currentWindow, + null, + Console.message("Too-many-names"), + null, + Console.message("OK"), + MessageFormat.format(Console.message("You-are-limitedF"), arguments), + true + ); + return false; + } + } + + @Override + public int addNameListName(String name) { + synchronized (this.friendsMutex) { + int index = iindexOf(this.friends, name); + if (index != -1) { + return index; + } else { + this.friends.addElement(name); + Collections.sort(this.friends, this); + this.saveFriends(); + this.serverUpdates.addElement(new BuddyListUpdateCmd(name, 1)); + return this.friends.size() - 1; + } + } + } + + public int compare(String arg0, String arg1) { + return arg0.compareToIgnoreCase(arg1); + } + + public static void droneClick(Drone who, MouseDownEvent event) { + if (active != null) { + active.instanceDroneClick(who, event); + } + } + + private void instanceDroneClick(Drone who, MouseDownEvent event) { + String tmp = who.getLongID(); + if (tmp != null) { + this.activeFriendName = tmp; + Object[] arguments = new Object[]{new String(this.activeFriendName)}; + this.droneAddItem = new MenuItem(MessageFormat.format(Console.message("Add-to-friends"), arguments)); + this.droneMenu.remove(0); + this.droneAddItem.setFont(font); + this.droneMenu.insert(this.droneAddItem, 0); + this.droneAddItem.setEnabled(!icontains(this.friends, this.activeFriendName)); + if (this.actionMenu != null) { + this.droneMenu.remove(this.actionMenu); + } + + if (who instanceof PosableDrone) { + PosableDrone pd = (PosableDrone)who; + PosableShape ps = pd.getInternalPosableShape(); + if (ps != null) { + this.actionMenu = new Menu(Console.message("Actions")); + if (AnimatedActionManager.get().buildActionMenu(this.actionMenu, ps)) { + this.droneMenu.add(this.actionMenu); + this.actionMenu.addActionListener(AnimatedActionManager.get()); + } + } + } + + this.droneMenu.show(this.console.getRender(), event.x, event.y); + } + } + + public static void processBuddyListNotify(WorldServer server, String name, int state) { + Galaxy g = server.getGalaxy(); + Enumeration<NetworkObject> consoleList = g.getConsoles(); + + while (consoleList.hasMoreElements()) { + Object c = consoleList.nextElement(); + if (c instanceof DefaultConsole) { + FriendsListPart target = ((DefaultConsole)c).getFriends(); + if (state < 2) { + boolean muted = MuteListPart.isMuted(server, name); + if (state == 1) { + target.addOnlineFriend(name, muted); + } else { + target.removeOnlineFriend(name, muted); + } + } else { + assert name.length() == 0; + + target.clearAll(); + } + } + } + + if (state == 2) { + consoleList = g.getConsoles(); + + while (consoleList.hasMoreElements()) { + Object c = consoleList.nextElement(); + if (c instanceof DefaultConsole) { + FriendsListPart target = ((DefaultConsole)c).getFriends(); + target.sendAll(server); + break; + } + } + } + } + + public static String ilookup(Vector<String> v, String name) { + int count = v.size(); + + for (int i = 0; i < count; i++) { + String ele = v.elementAt(i); + if (ele.equalsIgnoreCase(name)) { + return ele; + } + } + + return null; + } + + public static int iindexOf(Vector<String> v, String name) { + int count = v.size(); + + for (int i = 0; i < count; i++) { + String ele = v.elementAt(i); + if (ele.equalsIgnoreCase(name)) { + return i; + } + } + + return -1; + } + + public static boolean icontains(Vector<String> v, String name) { + return iindexOf(v, name) != -1; + } + + public void changeMuteState(String name, boolean muted) { + synchronized (this.friendsMutex) { + if (icontains(this.friends, name)) { + if (muted) { + name = ilookup(this.onlineFriends, name); + if (name != null) { + this.removeOnlineFriend(name, false); + this.addOnlineFriend(name, true); + } + } else { + name = ilookup(this.mutedOnlineFriends, name); + if (name != null) { + this.removeOnlineFriend(name, true); + this.addOnlineFriend(name, false); + } + } + } + } + } + + private void listChanged() { + this.cursedButton = -1; + this.clickedButton = -1; + this.clickedButtonDown = false; + this.repaint(); + } + + private void addOnlineFriend(String name, boolean muted) { + synchronized (this.friendsMutex) { + if (this.friends != null && icontains(this.friends, name)) { + if (!muted && !icontains(this.onlineFriends, name)) { + this.onlineFriends.addElement(name); + if (active == this) { + this.listChanged(); + if (this.moreFriendsDialog != null) { + this.moreFriendsDialog.addName(name); + } + } + } else if (muted && !icontains(this.mutedOnlineFriends, name)) { + this.mutedOnlineFriends.addElement(name); + } + } + } + } + + private void removeOnlineFriend(String name, boolean muted) { + synchronized (this.friendsMutex) { + if (!muted) { + int index = this.onlineFriends.indexOf(name); + if (index != -1) { + this.onlineFriends.removeElementAt(index); + if (active == this) { + this.listChanged(); + if (this.moreFriendsDialog != null) { + this.moreFriendsDialog.removeName(index); + } + } + } + } else { + this.mutedOnlineFriends.removeElement(name); + } + } + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + synchronized (this.friendsMutex) { + if (who == this.moreFriendsDialog) { + this.moreFriendsDialog = null; + } + } + } + + public static boolean isValidUserName(String name) { + String validChars = "_-"; + name = Console.parseUnicode(name); + int length = name.length(); + if (length >= 2 && length <= 16) { + char[] nameChars = name.toCharArray(); + + for (int i = 0; i < length; i++) { + if (!Character.isLetterOrDigit(nameChars[i]) && validChars.indexOf(nameChars[i]) == -1) { + return false; + } + } + + return true; + } else { + return false; + } + } + + void moreFriendsAction(String name, MenuItem function) { + this.activeFriendName = name; + + assert this.activeFriendName != null; + + this.maybeFriendAction(function); + } +} diff --git a/NET/worlds/console/Gamma.java b/NET/worlds/console/Gamma.java new file mode 100644 index 0000000..422a88b --- /dev/null +++ b/NET/worlds/console/Gamma.java @@ -0,0 +1,555 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.core.Std; +import NET.worlds.network.NetUpdate; +import NET.worlds.scape.MusicManager; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.TeleportAction; +import NET.worlds.scape.TeleportStatus; +import NET.worlds.scape.World; +import java.awt.Button; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.text.MessageFormat; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.NoSuchElementException; +import java.util.Properties; +import java.util.StringTokenizer; + +public class Gamma implements Runnable, MainCallback, TeleportStatus { + private static SplashScreen splash = null; + public static ProgressBar loadProgress; + static final int LOAD_PROGRESS_STEPS = 12; + static final float failVersion = 1.13F; + private static String _home = "file:"; + private static String _dllPath = "home:"; + private static Hashtable<String, String> _params = new Hashtable<String, String>(); + private static boolean _autoplay = false; + static Shaper shaper; + private String startingURL; + private String loadErr; + + static boolean checkVersion(String ver) { + StringTokenizer tok = new StringTokenizer(ver, "._"); + float version = 0.0F; + + try { + Integer i = new Integer(tok.nextToken()); + version = i.intValue(); + i = new Integer(tok.nextToken()); + float min = i.floatValue() / 10.0F; + if (!(min < 1.0F)) { + return true; + } + + version += min; + i = new Integer(tok.nextToken()); + min = i.floatValue() / 100.0F; + version += min; + } catch (NoSuchElementException var9) { + } + + if (version <= 1.13F) { + BlockingDialog d = new BlockingDialog(new Frame(), "Worlds.com: Error", true); + GridBagLayout gbl = new GridBagLayout(); + d.setLayout(gbl); + d.setSize(200, 150); + MultiLineLabel mll = new MultiLineLabel("Your system's Java Virtual Machine\nis out of date. Please download our\nfull installer and try again."); + GridBagConstraints c = new GridBagConstraints(); + c.gridx = 0; + c.gridy = 0; + gbl.setConstraints(mll, c); + d.add(mll); + Button b = new Button("OK"); + b.addActionListener(d); + GridBagConstraints c2 = new GridBagConstraints(); + c2.gridx = 0; + c2.gridy = 1; + gbl.setConstraints(b, c2); + d.add(b); + d.validate(); + d.show(); + d.waitForResponse(); + return false; + } else { + return true; + } + } + + public static void main(String[] args) { + String worldURL = parseCommandLine(args); + String s = System.getProperty("java.version"); + if (!checkVersion(s)) { + System.exit(0); + } + + String vendor = System.getProperty("java.vendor"); + System.out.println("User running java version " + s + " from vendor " + System.getProperty("java.vendor")); + String awtDll = "winawt"; + String netDll = "net"; + boolean msvm = false; + if (vendor.indexOf("Microsoft") != -1) { + awtDll = "MSAWT"; + netDll = "MSNET32"; + msvm = true; + } + + System.out.println("Loading: " + earlyURLUnalias(_dllPath + "gamma.dll")); + System.load(earlyURLUnalias(_dllPath + "gamma.dll")); + if (msvm) { + Window.doMicrosoftVMHacks(); + } + + if (IniFile.gamma().getIniInt("MULTIRUN", 0) == 0 && !Startup.synchronizeStartup(worldURL, _autoplay)) { + System.exit(0); + } + + if (s.charAt(2) <= '1' && !msvm) { + try { + System.loadLibrary(awtDll); + } catch (UnsatisfiedLinkError var35) { + } + + try { + System.loadLibrary(netDll); + } catch (UnsatisfiedLinkError var34) { + } + } else { + if (!msvm) { + awtDll = "awt"; + } + + new Color(0, 0, 0); + + try { + URL stupid = new URL("http://127.0.0.1/"); + URLConnection uc = stupid.openConnection(); + uc.connect(); + } catch (MalformedURLException var36) { + } catch (IOException var37) { + } + } + + if (!msvm) { + Window.hookWinAPIs(awtDll); + } + + String inihome = earlyURLUnalias("home:worlds.ini"); + Std.initProductName(); + IniFile install = IniFile.override(); + String splashgif = install.getIniString("splashgif", Console.message("Opnscrnc.gif")); + splash = new SplashScreen(GammaFrame.getDefaultTitle(), splashgif); + splash.show(); + splash.toFront(); + String proxyIP = IniFile.gamma().getIniString("Proxy Server IP", ""); + String proxyPort = IniFile.gamma().getIniString("Proxy Server Port", ""); + if (proxyIP.length() > 7) { + Properties p = System.getProperties(); + System.out.println("Using Proxy Server: " + proxyIP + ":" + proxyPort); + p.remove("socksProxyHost"); + p.remove("socksProxyPort"); + p.put("socksProxyHost", proxyIP); + p.put("socksProxyPort", proxyPort); + System.setProperties(p); + } + + loadProgress = new ProgressBar("Loading Worldsplayer...", 12); + Dimension sd = splash.getSize(); + Dimension d = loadProgress.getSize(); + int px = splash.getLocationOnScreen().x + (sd.width >> 1) - (d.width >> 1); + int py = splash.getLocationOnScreen().y + sd.height; + loadProgress.setLocation(px, py); + loadProgress.show(); + java.awt.Cursor c = java.awt.Cursor.getPredefinedCursor(3); + loadProgress.setCursor(c); + splash.setCursor(c); + if (inihome.length() > 1 && inihome.charAt(1) == ':') { + Startup.computeVolumeInfo(inihome.charAt(0) + ":\\"); + } else { + Startup.computeVolumeInfo(null); + } + + try { + LogFile.open(); + Gamma g = new Gamma(worldURL); + Main.register(g); + if (loadProgress != null) { + loadProgress.setMessage("Starting main thread..."); + loadProgress.advance(); + } + + Thread mainThread = new Thread(g, "Gamma Main"); + mainThread.setDaemon(true); + mainThread.start(); + new Gamma.PriorityAdjuster(mainThread); + if (loadProgress != null) { + loadProgress.setMessage("Initializing ActiveX..."); + loadProgress.advance(); + } + + new Netscape(); + + try { + mainThread.join(); + } catch (InterruptedException var30) { + throw new Error(var30.toString()); + } + + GammaFrame frame = Console.getFrame(); + if (frame != null) { + frame.setVisible(false); + } + } catch (OutOfMemoryError var31) { + System.out.println("ERROR: Ran out of memory!!"); + System.out.println("Details: " + var31); + } catch (Throwable var32) { + System.out.println("Uncaught throwable: " + var32); + } finally { + LogFile.close(); + } + + System.exit(0); + } + + public static void hideSplash() { + if (splash != null) { + splash.hide(); + splash.dispose(); + splash = null; + if (loadProgress != null) { + loadProgress.hide(); + loadProgress.dispose(); + loadProgress = null; + } + } + } + + public static String earlyURLUnalias(String url) { + if (url.startsWith("home:")) { + url = _home + url.substring(5); + } + + if (url.startsWith("file:")) { + url = url.substring(5); + } + + url = url.replace('\\', '/'); + if (url.length() < 2 || url.charAt(1) != ':' && !url.startsWith("//")) { + String curDir = System.getProperty("user.dir").replace('\\', '/'); + if (!curDir.endsWith("/")) { + curDir = curDir + "/"; + } + + url = curDir + url; + } + + return url; + } + + public static String getParam(String name) { + return _params.get(name); + } + + private static String parseCommandLine(String[] args) { + String world = null; + + for (int i = 0; i < args.length; i++) { + if (args[i].length() > 0 && args[i].charAt(0) == '-') { + if (args[i].equalsIgnoreCase("-help")) { + usage("Help message"); + } else if (args[i].equalsIgnoreCase("-home")) { + if (++i == args.length) { + usage("-home must be followed by a path:"); + } + + _home = "file:" + args[i]; + System.out.println("Home: " + args[i]); + } else if (args[i].equalsIgnoreCase("-dllpath")) { + if (++i == args.length) { + usage("-dllpath must be followed by a path:"); + } + + _dllPath = args[i]; + } else if (args[i].equalsIgnoreCase("-set")) { + label51: { + if (++i != args.length) { + if (++i != args.length) { + break label51; + } + } + + usage("-set must be followed by a name of a parameter to set and its value"); + } + + _params.put(args[i - 1], args[i]); + } else if (args[i].equalsIgnoreCase("-autoplay")) { + _autoplay = true; + } else if (!args[i].equalsIgnoreCase("-embedding") + && !args[i].equalsIgnoreCase("/embedding") + && !args[i].equalsIgnoreCase("-automation") + && !args[i].equalsIgnoreCase("/automation")) { + usage("Unrecognized command line option: " + args[i]); + } + } else { + if (world != null) { + usage("There may be only one command-line world URL"); + } + + world = args[i]; + } + } + + _home = makeEndWithSlash(_home); + _dllPath = makeEndWithSlash(_dllPath); + return world; + } + + private static String makeEndWithSlash(String url) { + if (!url.endsWith("\\") && !url.endsWith("/") && !url.endsWith(":")) { + url = url + "\\"; + } + + return url; + } + + public static void usage(String msg) { + System.out + .println( + "Usage: javaw {-java_options} NET.worlds.console.Gamma {-options} WorldURL\nWorldURL is optional, the default world is the first WorldsMark.\nYes, it's gross, but the 'NET.worlds.console.Gamma' is required\nSome useful -java_options:\n -classpath Path Class search path [default is CLASSPATH env var]\n-options:\n -help Print this message (still runs Gamma)\n -home HomeDir Gamma home directory [defaults to current dir]\n -dllpath DLLPath Path to the native code DLL [current directory]\n -set Name Value Set the named parameter to the specified value" + ); + throw new Error(msg); + } + + public static String getHome() { + return _home; + } + + public static String getExePath() { + return getHome() + "bin\\"; + } + + public static void dllLoad(String dll) { + System.load(NET.worlds.network.URL.make(_dllPath + dll).unalias()); + } + + public static Shaper getShaper() { + return shaper; + } + + public static boolean shaperEnabled() { + return IniFile.gamma().getIniInt("DISABLESHAPER", 1) == 0 || IniFile.override().getIniInt("DISABLESHAPER", 1) == 0; + } + + private Gamma(String url) { + this.startingURL = url; + } + + private void die(Throwable e) { + e.printStackTrace(System.out); + if (getShaper() != null) { + Console.println(Console.message("Saving-modified")); + Enumeration<World> worlds = World.getWorlds(); + + while (worlds.hasMoreElements()) { + World w = worlds.nextElement(); + if (w.getEdited()) { + String base = w.getSourceURL().unalias(); + if (base.toLowerCase().endsWith(".wor")) { + base = base.substring(0, base.length() - 4); + } + + if (base.toLowerCase().endsWith(".world")) { + base = base.substring(0, base.length() - 6); + } + + int dash = base.lastIndexOf("-"); + if (dash != -1) { + for (int i = dash + 1; i < base.length(); i++) { + if (!Character.isDigit(base.charAt(i))) { + dash = -1; + break; + } + } + } + + if (dash != -1) { + base = base.substring(0, dash); + } + + String name = base + ".world"; + + for (int number = 1; new File(name).exists(); number++) { + name = base + "-" + number + ".world"; + } + + Object[] arguments = new Object[]{new String(w.getName()), new String("" + w.getSourceURL()), new String(name)}; + Console.println(MessageFormat.format(Console.message("Saving-name"), arguments)); + + try { + Shaper.doSave(name, w, false); + } catch (Exception var10) { + Console.println(Console.message("Ignoring") + var10); + } catch (Error var11) { + Console.println(Console.message("Ignoring") + var11); + } + } + } + } + } + + @Override + public void run() { + Main.register(new Gamma.RecordPosition()); + + try { + Main.mainLoop(); + } catch (Throwable var2) { + this.die(var2); + } + } + + @Override + public void mainCallback() { + Main.unregister(this); + if (NetUpdate.doUpdate(false)) { + Main.end(); + } else { + File bin = new File(earlyURLUnalias("home:bin")); + File prg = new File(bin, "gdkup.prg"); + File exe = new File(bin, "gdkup.exe"); + if (prg.exists() && (!exe.exists() || prg.lastModified() > exe.lastModified())) { + if (exe.exists()) { + exe.delete(); + } + + try { + FileInputStream i = new FileInputStream(prg); + FileOutputStream o = new FileOutputStream(exe); + byte[] buf = new byte[8192]; + + int len; + while ((len = i.read(buf)) > 0) { + o.write(buf, 0, len); + } + + i.close(); + o.close(); + } catch (Exception var10) { + var10.printStackTrace(System.out); + throw new Error("Can't copy gdkup.prg"); + } + } + + if (shaperEnabled()) { + shaper = new Shaper(); + } + + IniFile install = IniFile.override(); + String splashOver = install.getIniString("splashover", Console.message("Pwc.gif")); + int splashXOver = install.getIniInt("splashxover", 141); + int splashYOver = install.getIniInt("splashyover", 140); + if (splashXOver >= 0) { + splash.addOverlay(splashOver, splashXOver, splashYOver); + } + + if (loadProgress != null) { + loadProgress.setMessage("Teleporting to start location..."); + loadProgress.advance(); + } + + try { + TeleportAction.teleport(this.startingURL, this, false); + } catch (Exception var9) { + this.loadErr = "Couldn't teleport to " + this.startingURL + ": " + var9; + } + + if (this.loadErr != null) { + System.out.println(this.loadErr); + this.loadErr = null; + TeleportAction.teleport("world:", this, false); + if (this.loadErr != null) { + this.loadErr = null; + TeleportAction.teleport("home:NewWorld.world", this, false); + if (this.loadErr != null) { + Main.end(); + return; + } + } + + Main.register(new Gamma.StartupTeleport()); + } + + new MusicManager(); + } + } + + @Override + public void teleportStatus(String err, String url) { + if (err == null) { + this.loadErr = null; + } else { + this.loadErr = err; + } + } + + static class PriorityAdjuster implements MainCallback { + private Thread mainThread; + boolean wasActivated = true; + + PriorityAdjuster(Thread t) { + this.mainThread = t; + this.mainThread.setPriority(5); + Main.register(this); + } + + @Override + public void mainCallback() { + if (Window.isActivated() != this.wasActivated) { + this.wasActivated = !this.wasActivated; + this.mainThread.setPriority(this.wasActivated ? 5 : 1); + } + } + } + + public class RecordPosition implements MainCallback, MainTerminalCallback { + @Override + public void mainCallback() { + } + + @Override + public void terminalCallback() { + Pilot pilot = Pilot.getActive(); + if (pilot != null) { + IniFile.gamma().setIniString("RestartAt", pilot.getURL()); + } + + Main.unregister(this); + } + } + + class StartupTeleport implements MainCallback { + @Override + public void mainCallback() { + if (Console.getFrame() != null && Console.getFrame().isShowing()) { + Main.unregister(this); + + try { + TeleportAction.teleport(Gamma.this.startingURL, Gamma.this, true); + } catch (Exception var2) { + } + } + } + } +} diff --git a/NET/worlds/console/GammaFrame.java b/NET/worlds/console/GammaFrame.java new file mode 100644 index 0000000..4aec0db --- /dev/null +++ b/NET/worlds/console/GammaFrame.java @@ -0,0 +1,144 @@ +package NET.worlds.console; + +import NET.worlds.core.Std; +import NET.worlds.scape.EditTile; +import NET.worlds.scape.LibrariesTile; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Container; +import java.awt.Event; +import java.awt.Frame; + +public class GammaFrame extends Frame implements DialogDisabled { + private static final long serialVersionUID = 2725752068161032112L; + private Container consoleTile; + private Tree treeTile; + private EditTile editTile; + private LibrariesTile librariesTile; + private FourTilePanel fourTile; + private boolean isDialogDisabled; + + @Override + public boolean handleEvent(Event e) { + if (this.isDialogDisabled) { + return false; + } else { + Console c = Console.getActive(); + if (c != null && c.handleEvent(e)) { + return true; + } else { + return e.id == 201 ? Console.maybeQuit() : super.handleEvent(e); + } + } + } + + public static String getDefaultTitle() { + return Std.getProductName(); + } + + public GammaFrame() { + super(getDefaultTitle()); + } + + @Override + public void show() { + Gamma.hideSplash(); + Window.allowFGJavaPalette(false); + Console cons = Console.getActive(); + if (cons instanceof DefaultConsole) { + ((DefaultConsole)cons).setOrthoEnabled(this.isShaperVisible()); + } + + super.show(); + } + + public Container getConsoleTile() { + this.makeTiles(); + return this.consoleTile; + } + + public Tree getTreeTile() { + this.makeTiles(); + return this.treeTile; + } + + public EditTile getEditTile() { + this.makeTiles(); + return this.editTile; + } + + public LibrariesTile getLibrariesTile() { + this.makeTiles(); + return this.librariesTile; + } + + private void makeTiles() { + if (this.consoleTile == null) { + if (Gamma.getShaper() == null) { + this.consoleTile = this; + } else { + this.consoleTile = new ExposedPanel(); + this.treeTile = new Tree(); + this.editTile = new EditTile(this.treeTile); + this.librariesTile = new LibrariesTile(); + this.setLayout(new BorderLayout()); + this.fourTile = new FourTilePanel(this.librariesTile, this.consoleTile, this.treeTile, this.editTile, 1); + this.add("Center", this.fourTile); + } + + this.consoleTile.setLayout(new CardLayout()); + } + } + + public void setShaperVisible(boolean f) { + if (Gamma.getShaper() != null) { + if (this.fourTile.isOneTileMode() == f) { + if (f) { + this.fourTile.useFourTileMode(); + } else { + this.fourTile.useOneTileMode(); + } + } + + Console cons = Console.getActive(); + if (cons instanceof DefaultConsole) { + ((DefaultConsole)cons).setOrthoEnabled(f); + } + } + } + + public boolean isShaperVisible() { + return Gamma.getShaper() != null && this.fourTile != null && !this.fourTile.isOneTileMode(); + } + + public void deactivate() { + } + + public void activate() { + if (!this.isShowing()) { + new GammaFrameState(this); + this.show(); + } + } + + @Override + public boolean action(Event event, Object what) { + Console c = Console.getActive(); + return c != null && c.action(event, what) ? true : super.action(event, what); + } + + @Override + public void dialogDisable(boolean disable) { + this.isDialogDisabled = disable; + Console c = Console.getActive(); + if (c != null) { + c.dialogDisable(disable); + } + + if (this.isShaperVisible()) { + this.getTreeTile().dialogDisable(disable); + this.getLibrariesTile().dialogDisable(disable); + this.getEditTile().dialogDisable(disable); + } + } +} diff --git a/NET/worlds/console/GammaFrameState.java b/NET/worlds/console/GammaFrameState.java new file mode 100644 index 0000000..16497a6 --- /dev/null +++ b/NET/worlds/console/GammaFrameState.java @@ -0,0 +1,232 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Toolkit; +import java.util.StringTokenizer; + +public class GammaFrameState implements MainCallback { + private static final int defaultWidth = 568; + private static final int defaultHeight = 424; + private static final int minimumWidth = 142; + private static final int minimumHeight = 106; + private static int[] frameState = new int[5]; + private static GammaFrame frame; + private static int handle; + private static String borderKey; + private static final String layoutKey = "ShaperLayout"; + private static final String modeKey = "ChangeVideoMode"; + private static final float scale = 100.0F; + private boolean initMaximized; + private int[] videoMode; + + GammaFrameState(GammaFrame f) { + frame = f; + if (borderKey == null) { + borderKey = Gamma.shaperEnabled() ? "ShaperWindow" : "Window"; + } + + this.restoreBorder(); + int[] mode = new int[2]; + if (strToInts(IniFile.gamma().getIniString("ChangeVideoMode", ""), mode) == 2) { + this.videoMode = mode; + } + + Main.register(this); + } + + public static void saveBorder() { + int state; + if (handle != 0 && !isIconic(state = getFrameState())) { + Point loc = frame.getLocation(); + Dimension size = new Dimension(Window.getWindowWidth(handle), Window.getWindowHeight(handle)); + int[] newState = new int[frameState.length]; + if (!isMaximized(newState[4] = state)) { + newState[0] = loc.x; + newState[1] = loc.y; + newState[2] = size.width; + newState[3] = size.height; + } else { + for (int i = 0; i < 4; i++) { + newState[i] = frameState[i]; + } + } + + for (int i = 0; i < frameState.length; i++) { + if (newState[i] != frameState[i]) { + IniFile var10000 = IniFile.gamma(); + String var10001 = makeKey(borderKey); + frameState = newState; + var10000.setIniString(var10001, intsToStr(newState)); + break; + } + } + } + } + + private void restoreBorder() { + if (strToInts(IniFile.gamma().getIniString(makeKey(borderKey), ""), frameState) == 5) { + if (frameState[0] >= 0 && frameState[2] >= 142 && frameState[1] >= 0 && frameState[3] >= 106) { + if (isMaximized(frameState[4])) { + this.initMaximized = true; + } else { + frameState[4] = 0; + this.initMaximized = false; + } + + frame.reshape(frameState[0], frameState[1], frameState[2], frameState[3]); + } else { + this.makeDefaultBorder(); + } + } else { + this.makeDefaultBorder(); + } + } + + private void makeDefaultBorder() { + Dimension size = getScreenSize(); + int dx = size.width - 568; + int dy = size.height - 424; + if (dx <= 0) { + dx = 0; + } else { + dx /= 2; + } + + if (dy <= 0) { + dy = 0; + } else { + dy /= 2; + } + + frameState[0] = dx; + frameState[1] = dy; + frameState[2] = 568; + frameState[3] = 424; + frameState[4] = 0; + this.initMaximized = false; + frame.reshape(dx, dy, 568, 424); + } + + public static void saveLayout(int[] layout, float[] divider, boolean oneTile) { + IniFile.gamma().setIniString(makeKey("ShaperLayout"), intsToStr(layout) + " " + floatsToStr(divider) + " " + (oneTile ? "0" : "1")); + } + + public static boolean restoreLayout(int[] argLayout, float[] argDivider) { + int[] layout = new int[argLayout.length]; + float[] divider = new float[argDivider.length]; + int[] tmp = new int[layout.length + divider.length + 1]; + tmp[layout.length + divider.length] = 0; + if (strToInts(IniFile.gamma().getIniString(makeKey("ShaperLayout"), ""), tmp) < layout.length + divider.length) { + return true; + } else { + int[] used = new int[layout.length]; + + for (int i = 0; i < layout.length; i++) { + try { + used[layout[i] = tmp[i]]++; + } catch (ArrayIndexOutOfBoundsException var8) { + return true; + } + } + + for (int i = 0; i < layout.length; i++) { + if (used[i] != 1) { + return true; + } + } + + for (int ix = 0; ix < divider.length; ix++) { + float f = tmp[ix + layout.length] / 100.0F; + if (f < 0.0F || f > 1.0F) { + return true; + } + + divider[ix] = f; + } + + System.arraycopy(layout, 0, argLayout, 0, argLayout.length); + System.arraycopy(divider, 0, argDivider, 0, argDivider.length); + return tmp[layout.length + divider.length] == 0; + } + } + + private static int getFrameState() { + return Window.getWindowState(handle); + } + + public static boolean isIconic() { + return handle != 0 ? isIconic(getFrameState()) : false; + } + + private static boolean isIconic(int state) { + return state == 1; + } + + private static boolean isMaximized(int state) { + return state == 2; + } + + private static Dimension getScreenSize() { + return Toolkit.getDefaultToolkit().getScreenSize(); + } + + private static String makeKey(String prefix) { + Dimension screenSize = getScreenSize(); + return prefix + screenSize.width + "X" + screenSize.height; + } + + private static String intsToStr(int[] arr) { + String s = "" + arr[0]; + + for (int i = 1; i < arr.length; i++) { + s = s + " " + arr[i]; + } + + return s; + } + + private static String floatsToStr(float[] arr) { + int[] iarr = new int[arr.length]; + + for (int i = 0; i < arr.length; i++) { + iarr[i] = (int)(arr[i] * 100.0F); + } + + return intsToStr(iarr); + } + + private static int strToInts(String s, int[] arr) { + if (s == null) { + return 0; + } else { + StringTokenizer tok = new StringTokenizer(s, " "); + + int i; + for (i = 0; i < arr.length && tok.hasMoreTokens(); i++) { + try { + arr[i] = Integer.parseInt(tok.nextToken()); + } catch (NumberFormatException var5) { + break; + } + } + + return i; + } + } + + @Override + public void mainCallback() { + handle = Window.findWindow(frame.getTitle()); + if (handle != 0) { + if (this.videoMode != null) { + Window.setVideoMode(handle, this.videoMode[0], this.videoMode[1]); + } else if (this.initMaximized) { + Window.setWindowState(handle, 2); + } + + Main.unregister(this); + } + } +} diff --git a/NET/worlds/console/GammaPhoneMonitor.java b/NET/worlds/console/GammaPhoneMonitor.java new file mode 100644 index 0000000..b943d38 --- /dev/null +++ b/NET/worlds/console/GammaPhoneMonitor.java @@ -0,0 +1,149 @@ +package NET.worlds.console; + +import NET.worlds.scape.WavSoundPlayer; + +public class GammaPhoneMonitor extends Thread { + public static final int GA_FAILEDCONNECT = 100; + public static final int GPE_WHATEVER = 0; + public static final int GPE_OUT_OF_MEM = 1; + public static final int GPE_WEIRD = 2; + public static final int GPE_SOCKET = 3; + public static final int GPE_COMM = 4; + public static final int GPE_HOST = 5; + public static final int GPE_FILE = 6; + public static final int GPE_CRYPTO = 7; + public static final int GPE_MULTICAST = 8; + public static final int GPE_RECORD = 9; + public static final int GPE_WAVE_INPUT = 10; + public static final int GPE_PLAY = 11; + public static final int GPE_WAVE_OUTPUT = 12; + public static final int GPE_PORT = 13; + public static final int GPE_SOCKETS_VERSION = 14; + public static final int GPE_HALF_DUPLEX = 15; + public static final int GPE_USAGE = 16; + public static final int GPE_IS_HALF_DUPLEX = 17; + public static final int GPE_IS_FULL_DUPLEX = 18; + public static final int GPE_LWL = 19; + public static final int GPE_TIMEOUT = 20; + public static final int GPE_WAVE_IN_USE = 21; + public static final int GPE_CONNECTION_LOST = 22; + public static final int GPE_SUCCESS = 900; + public static final int GPE_STARTUP = 901; + public static final int GPE_SHUTDOWN = 902; + private VoiceChat _vc = null; + + public GammaPhoneMonitor(VoiceChat v) { + this._vc = v; + } + + private void release() { + this._vc.release(); + } + + @Override + public void run() { + int m = 0; + Window w = Window.getMainWindow(); + + try { + while (true) { + if (Window.getVoiceChatWParam() != 0) { + this.processMessage(Window.getVoiceChatWParam(), Window.getVoiceChatLParam()); + Window.resetVoiceChatMsg(); + } + + Thread.sleep(1000L); + } + } catch (InterruptedException var4) { + this.stop(); + } + } + + private void processMessage(int wParam, int lParam) { + switch (wParam) { + case 0: + this._vc.inform(wParam, "whatever "); + break; + case 1: + this._vc.inform(wParam, "out of memory "); + break; + case 2: + this._vc.inform(wParam, "! "); + break; + case 3: + this._vc.inform(wParam, "An error occurred while setting up the socket for Voice Chat."); + break; + case 4: + this._vc.inform(wParam, "communications "); + break; + case 5: + this._vc.inform(wParam, "can't find host "); + break; + case 6: + this._vc.inform(wParam, "can't open/read/write file "); + break; + case 7: + this._vc.inform(wParam, "we don't even use this! "); + break; + case 8: + this._vc.inform(wParam, "we don't even use this! "); + break; + case 9: + this._vc.inform(wParam, "can't record at 8000 or 11200 samp/sec"); + break; + case 10: + this._vc.inform(wParam, "error opening wave input device "); + break; + case 11: + this._vc.inform(wParam, "sound card can't play at 8000 or 11200"); + break; + case 12: + this._vc.inform(wParam, "error opening wave output device "); + break; + case 13: + this._vc.inform(wParam, "invalid port number specified "); + break; + case 14: + this._vc.inform(wParam, "incompatible (old) sockets library "); + break; + case 15: + this._vc.inform(wParam, "sound drivers can't support full duplex"); + break; + case 16: + this._vc.inform(wParam, "command line syntax error "); + break; + case 17: + this._vc.inform(wParam, "response to isFullDuplex command "); + break; + case 18: + this._vc.inform(wParam, "response to isFullDuplex command "); + break; + case 19: + this._vc.inform(wParam, " -Look Who's Listening- error, weird! "); + break; + case 20: + this._vc.inform(wParam, "Never heard back. "); + break; + case 21: + this._vc.inform(wParam, "VoiceChat failed because a wav device is in use."); + break; + case 22: + this._vc.inform(wParam, "VoiceChat has lost its connection."); + break; + case 100: + Console.println(Console.message("Voice-failed")); + break; + case 900: + this._vc.inform(wParam, "It worked o.k. "); + break; + case 901: + this._vc.registerProcess(lParam); + break; + case 902: + WavSoundPlayer.resumeSystem(); + break; + default: + Console.println(Console.message("Unrec-message") + wParam); + } + } +} diff --git a/NET/worlds/console/GammaTextArea.java b/NET/worlds/console/GammaTextArea.java new file mode 100644 index 0000000..d470e42 --- /dev/null +++ b/NET/worlds/console/GammaTextArea.java @@ -0,0 +1,923 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.scape.SendURLAction; +import NET.worlds.scape.TeleportAction; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.MenuItem; +import java.awt.Panel; +import java.awt.PopupMenu; +import java.awt.Scrollbar; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.FocusEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; +import java.util.StringTokenizer; +import java.util.Vector; + +public class GammaTextArea extends Panel implements AdjustmentListener, ActionListener { + private static final long serialVersionUID = 4042890054976563288L; + public static final int SCROLLBARS_BOTH = 1; + public static final int SCROLLBARS_VERTICAL_ONLY = 2; + public static final int SCROLLBARS_HORIZONTAL_ONLY = 3; + public static final int SCROLLBARS_NONE = 4; + protected static final int _margin = 2; + private int _width; + private int _height; + private StyledTextCanvas _canvas; + private String _string; + private Font _font; + private int _currentStyle; + private String _currentFontName; + private int _currentPointSize; + private Color _currentColor; + private GammaTextScrollbar _vertBar; + private GammaTextScrollbar _horzBar; + private int _numLines; + private int _canvasLines; + private int _scrollLine; + private Vector<String> _lines; + private Vector<Integer> _pos; + private int _lastpos = 0; + protected int _curpos = 0; + protected boolean _hasFocus; + protected int selectionStart = -1; + protected int selectionEnd = -1; + private static final Color skyblue = new Color(135, 206, 255); + private PopupMenu rightMenu; + private MenuItem textCopyItem = new MenuItem(Console.message("Copy")); + private MenuItem textCopyTextItem = new MenuItem(Console.message("Copy Text")); + private MenuItem textCopyAllItem = new MenuItem(Console.message("Copy All")); + private MenuItem textCopyAllTextItem = new MenuItem(Console.message("Copy All Text")); + private MenuItem textOpenURLItem = new MenuItem(Console.message("Open URL")); + static Color bgColor = null; + private int _numColumns; + private int _numRows; + private static int scrollWheelStep = IniFile.gamma().getIniInt("ScrollWheelStep", 3); + public static String boldStartTag = "<b>"; + public static String boldEndTag = "</b>"; + public static String italicStartTag = "<i>"; + public static String italicEndTag = "</i>"; + public static String colorStartMagentaTag = "<color=\"#FF00FF\">"; + public static String colorStartBlueTag = "<color=\"#0000FF\">"; + public static String colorStartRedTag = "<color=\"#FF0000\">"; + public static String colorStartGreenTag = "<color=\"#00FF00\">"; + public static String colorEndTag = "</color>"; + public static String colorMagenta2Tag = "<color=magenta>"; + public static String colorBlue2Tag = "<color=blue>"; + public static String colorRed2Tag = "<color=red>"; + public static String colorGreen2Tag = "<color=green>"; + public static String colorCyanTag = "<color=cyan>"; + public static String colorDarkGrayTag = "<color=darkgray>"; + public static String colorGrayTag = "<color=gray>"; + public static String colorOrangeTag = "<color=orange>"; + public static String colorPinkTag = "<color=pink>"; + public static String colorYellowTag = "<color=yellow>"; + public static String colorWhiteTag = "<color=white>"; + public static String colorLightGrayTag = "<color=lightgray>"; + public static EmoteHandler emotes = new EmoteHandler(); + protected static String[] tagList = new String[]{ + boldStartTag, + boldEndTag, + italicStartTag, + italicEndTag, + colorStartMagentaTag, + colorStartRedTag, + colorStartGreenTag, + colorStartBlueTag, + colorEndTag, + colorMagenta2Tag, + colorBlue2Tag, + colorRed2Tag, + colorGreen2Tag, + colorCyanTag, + colorDarkGrayTag, + colorGrayTag, + colorOrangeTag, + colorPinkTag, + colorYellowTag, + colorWhiteTag, + colorLightGrayTag + }; + private int lastWidth = 0; + protected boolean selectionConversion = false; + protected int _initialSelection = -1; + + @Override + public Font getFont() { + return this._font; + } + + @Override + public int getWidth() { + return this._width; + } + + @Override + public int getHeight() { + return this._height; + } + + public synchronized void setWidth(int w) { + this._width = w - 4; + } + + public synchronized void setHeight(int h) { + this._height = h - 4; + } + + public Vector<String> getLines() { + return this._lines; + } + + public int getScrollLine() { + return this._scrollLine; + } + + public int getCanvasLines() { + return this._canvasLines; + } + + public int getNumLines() { + return this._numLines; + } + + public boolean getHasFocus() { + return this._hasFocus; + } + + public Scrollbar getVertScrollbar() { + return this._vertBar; + } + + static Color getBackgroundColor() { + if (bgColor == null) { + int bgR = IniFile.override().getIniInt("chatBgR", 255); + int bgG = IniFile.override().getIniInt("chatBgG", 255); + int bgB = IniFile.override().getIniInt("chatBgB", 203); + bgColor = new Color(bgR, bgG, bgB); + } + + return bgColor; + } + + GammaTextArea(String text, int rows, int columns, int scrollbars) { + this._string = text; + this._numColumns = columns; + this._numRows = rows; + this._currentFontName = Console.message("GammaTextFont"); + this._currentStyle = 0; + this._currentPointSize = IniFile.gamma().getIniInt("ChatFontSize", 12); + this._currentColor = Color.black; + this._canvas = new StyledTextCanvas(); + this.setFontSize(this._currentPointSize); + this._lines = new Vector<String>(); + this._pos = new Vector<Integer>(); + this._lastpos = 0; + this._hasFocus = false; + this._numLines = this._scrollLine = this._canvasLines = 0; + switch (scrollbars) { + case 1: + this._vertBar = new GammaTextScrollbar(1); + this._horzBar = new GammaTextScrollbar(0); + break; + case 2: + this._vertBar = new GammaTextScrollbar(1); + this._horzBar = null; + break; + case 3: + this._vertBar = null; + this._horzBar = new GammaTextScrollbar(0); + break; + case 4: + this._vertBar = this._horzBar = null; + } + + GridBagLayout gridbag = new GridBagLayout(); + this.setLayout(gridbag); + GridBagConstraints c = new GridBagConstraints(); + c.fill = 1; + c.weightx = 1.0; + c.weighty = 1.0; + gridbag.setConstraints(this._canvas, c); + this.add(this._canvas); + if (this._vertBar != null) { + c = new GridBagConstraints(); + c.fill = 3; + c.gridwidth = 0; + gridbag.setConstraints(this._vertBar, c); + this.add(this._vertBar); + this._vertBar.addAdjustmentListener(this); + } + + if (this._horzBar != null) { + c = new GridBagConstraints(); + c.fill = 2; + c.gridwidth = 1; + this.add(this._horzBar); + this._horzBar.addAdjustmentListener(this); + } + + this.enableEvents(131231L); + this._canvas.repaint(); + } + + public synchronized void setFontSize(int fontsize) { + this._currentPointSize = fontsize; + this._font = new Font(this._currentFontName, this._currentStyle, this._currentPointSize); + this.recalcSize(); + } + + public synchronized void setRows(int rows) { + this._numRows = rows; + this.recalcSize(); + } + + public synchronized void recalcSize() { + FontMetrics fm = this._canvas.getFontMetrics(this._font); + + assert fm != null; + + int w = fm.charWidth('M') * this._numColumns; + int h = fm.getHeight() * this._numRows; + this.setWidth(w); + this.setHeight(h); + this._canvas.setSize(w, h); + this.setWidth(w); + this.setHeight(h); + } + + @Override + public void update(Graphics g) { + this.paint(g); + } + + @Override + protected synchronized void processMouseEvent(MouseEvent e) { + if (e.isPopupTrigger()) { + if (this.rightMenu != null && this.rightMenu.isEnabled()) { + this.hideRightMenu(); + } else { + this.showRightMenu(e.getX(), e.getY()); + } + } + + super.processMouseEvent(e); + } + + @Override + protected synchronized void processFocusEvent(FocusEvent e) { + if (e.getID() == 1004) { + this._hasFocus = true; + } else if (e.getID() == 1005) { + this._hasFocus = false; + } + + this._canvas.repaint(); + super.processFocusEvent(e); + } + + @Override + protected synchronized void processKeyEvent(KeyEvent e) { + this._canvas.dispatchEvent(e); + super.processKeyEvent(e); + } + + @Override + protected synchronized void processMouseWheelEvent(MouseWheelEvent e) { + if (e.getID() == 507) { + int move = 0; + if (e.getScrollType() == 0) { + move = e.getScrollAmount() * e.getWheelRotation(); + } else { + move = scrollWheelStep * e.getWheelRotation(); + } + + if (move != 0) { + this._vertBar.setValue(this._vertBar.getValue() + move); + this.requestFocus(); + this._canvas.sendDelayedMouseEvent(e); + this.adjustmentValueChanged(null); + } + } + + super.processMouseWheelEvent(e); + } + + @Override + public synchronized void adjustmentValueChanged(AdjustmentEvent e) { + this._scrollLine = this._vertBar.getValue(); + this._canvas.repaint(); + } + + public void setEditable(boolean b) { + if (b) { + System.out.println("Can't set GammaTextArea to be editable."); + } + } + + public synchronized String getText() { + return this._string; + } + + public synchronized void setText(String s) { + this._string = s; + this.wordWrapAll(); + this._scrollLine = this._numLines - this._canvasLines; + if (this._scrollLine < 0) { + this._scrollLine = 0; + } + + this.setScrollBounds(); + } + + @Override + public synchronized void repaint() { + this._canvas.repaint(); + super.repaint(); + } + + @Override + public synchronized void paint(Graphics g) { + this._canvas.paint(g); + super.paint(g); + } + + protected synchronized void wordWrapAll() { + this._lines.removeAllElements(); + this._pos.removeAllElements(); + this._numLines = 0; + this._lastpos = 0; + this.wordWrap(this._string); + } + + protected synchronized boolean isLastLineVisible() { + return !this._canvas.mouseActive && (this.selectionStart < 0 || this.selectionEnd <= this.selectionStart) + ? this._scrollLine >= this._numLines - this._canvasLines || this._numLines <= this._canvasLines + : false; + } + + protected synchronized boolean handleTag(Graphics g, String word, int x, int y) { + String lower = word.toLowerCase(); + if (word.charAt(0) == '<') { + for (int i = 0; i < tagList.length; i++) { + if (lower.equals(tagList[i].toLowerCase())) { + switch (i) { + case 0: + this._currentStyle |= 1; + break; + case 1: + this._currentStyle &= -2; + break; + case 2: + this._currentStyle |= 2; + break; + case 3: + this._currentStyle &= -3; + break; + case 4: + this._currentColor = Color.magenta; + break; + case 5: + this._currentColor = Color.red; + break; + case 6: + this._currentColor = Color.green; + break; + case 7: + this._currentColor = Color.blue; + break; + case 8: + this._currentColor = Color.black; + break; + case 9: + this._currentColor = Color.magenta; + break; + case 10: + this._currentColor = Color.blue; + break; + case 11: + this._currentColor = Color.red; + break; + case 12: + this._currentColor = Color.green; + break; + case 13: + this._currentColor = Color.cyan; + break; + case 14: + this._currentColor = Color.darkGray; + break; + case 15: + this._currentColor = Color.gray; + break; + case 16: + this._currentColor = Color.orange; + break; + case 17: + this._currentColor = Color.pink; + break; + case 18: + this._currentColor = Color.yellow; + break; + case 19: + this._currentColor = Color.white; + break; + case 20: + this._currentColor = Color.lightGray; + } + + try { + this._font = new Font(this._currentFontName, this._currentStyle, this._currentPointSize); + } catch (IllegalArgumentException var8) { + } + + return true; + } + } + } + + if (lower.startsWith("<color=\"#") && word.length() > 15) { + int color = 0; + + try { + int end = word.lastIndexOf(34); + if (end < 10 || end > 15) { + end = 15; + } + + color = Integer.parseInt(word.substring(9, end).trim(), 16); + } catch (Exception var10) { + } + + this._currentColor = new Color(color); + + try { + this._font = new Font(this._currentFontName, this._currentStyle, this._currentPointSize); + } catch (IllegalArgumentException var9) { + } + + return true; + } else { + return this.handleSmiley(g, lower, x, y); + } + } + + private synchronized boolean handleSmiley(Graphics g, String lower, int x, int y) { + ImageCanvas image = emotes.getImage(lower); + if (image != null) { + this.drawImage(g, image, x, y); + return true; + } else { + return false; + } + } + + private synchronized void drawImage(Graphics g, ImageCanvas image, int x, int y) { + if (image != null && image.loaded_) { + Dimension size = image.imageSize(); + if (g != null) { + image.paint(g, x, (int)(y - size.getHeight())); + } + + this.lastWidth = (int)(this.lastWidth - (size.getWidth() + 8.0)); + } + } + + protected void ClearTags(Graphics g) { + if (this._currentStyle != 0) { + this._currentStyle = 0; + this._font = new Font(this._currentFontName, this._currentStyle, this._currentPointSize); + } + + if (this._currentColor != Color.black) { + this._currentColor = Color.black; + } + + g.setFont(this._font); + g.setColor(this._currentColor); + } + + protected synchronized void wordWrap(String newText) { + int canvasWidth = this._width; + if (canvasWidth > 0) { + StringTokenizer rawLines = new StringTokenizer(newText, "\n\r"); + + while (rawLines.hasMoreTokens()) { + String rawLine = rawLines.nextToken(); + StringTokenizer words = new StringTokenizer(rawLine, "\n\r\t -", true); + int lineWidth = 0; + String thisLine = ""; + this.lastWidth = 0; + FontMetrics fm = this._canvas.getFontMetrics(this._font); + + assert fm != null; + + while (words.hasMoreTokens()) { + String word = words.nextToken(); + if (!word.equals("\n") && !word.equals("\r")) { + if (this.handleTag(null, word, 0, 0)) { + lineWidth -= this.lastWidth; + thisLine = thisLine + word; + if (words.hasMoreTokens()) { + thisLine = thisLine + words.nextToken(); + } + + this.lastWidth = 0; + fm = this._canvas.getFontMetrics(this._font); + + assert fm != null; + } else { + this.lastWidth = fm.stringWidth(word); + if (this.lastWidth >= canvasWidth) { + if (!thisLine.equals("")) { + this._pos.addElement(this._lastpos); + this._lastpos = this._lastpos + thisLine.length(); + this._lines.addElement(thisLine.trim()); + this._numLines++; + lineWidth = 0; + } + + while (this.lastWidth >= canvasWidth) { + word = this.breakWord(word, fm); + lineWidth = this.lastWidth = 0; + thisLine = ""; + if (word != null && word.length() > 0) { + this.lastWidth = fm.stringWidth(word); + } + } + } + + lineWidth += this.lastWidth; + if (lineWidth > 0 && word != null && word.length() > 0) { + if (lineWidth >= canvasWidth) { + this._pos.addElement(this._lastpos); + this._lastpos = this._lastpos + thisLine.length(); + this._lines.addElement(thisLine.trim()); + this._numLines++; + lineWidth = this.lastWidth; + thisLine = ""; + } + + thisLine = thisLine + word; + } + } + } + } + + if (!thisLine.equals("")) { + this._pos.addElement(this._lastpos); + this._lastpos = this._lastpos + thisLine.length() + 1; + this._numLines++; + this._lines.addElement(thisLine.trim()); + } + } + } + } + + protected String breakWord(String longWord, FontMetrics fm) { + int lineWidth = 0; + String thisLine = ""; + + for (int c = 0; c < longWord.length(); c++) { + char ch = longWord.charAt(c); + lineWidth += fm.charWidth(ch); + if (lineWidth >= this._width) { + this._pos.addElement(this._lastpos); + this._lastpos = this._lastpos + thisLine.length(); + this._lines.addElement(thisLine); + this._numLines++; + lineWidth = fm.charWidth(ch); + thisLine = ""; + } + + thisLine = thisLine + ch; + } + + if (thisLine.length() > 0) { + this._pos.addElement(this._lastpos); + this._lastpos = this._lastpos + thisLine.length(); + this._lines.addElement(thisLine); + this._numLines++; + } + + return ""; + } + + public synchronized void rewrap() { + if (this._width > 0 && this._height > 0) { + this.wordWrapAll(); + this._scrollLine = this._numLines - this._canvasLines; + if (this._scrollLine < 0) { + this._scrollLine = 0; + } + + this.setScrollBounds(); + this._canvas.repaint(); + } + } + + public synchronized void setScrollBounds() { + FontMetrics fm = this._canvas.getFontMetrics(this._font); + + assert fm != null; + + int lineHeight = fm.getHeight(); + this._canvasLines = (this._height + fm.getDescent()) / lineHeight; + if (this._vertBar != null) { + if (this._numLines <= this._canvasLines) { + this._vertBar.setEnabled(false); + } else { + this._vertBar.setEnabled(true); + this._vertBar.setValues(this._scrollLine, this._canvasLines, 0, this._numLines); + this._vertBar.setBlockIncrement(this._canvasLines); + } + } + } + + public synchronized void append(String s) { + this._string = this._string + s; + this.wordWrap(s); + this._scrollLine = this._numLines - this._canvasLines; + if (this._scrollLine < 0) { + this._scrollLine = 0; + } + + this.setScrollBounds(); + } + + public synchronized void replaceRange(String s, int start, int end) { + String newString = this._string.substring(0, start) + s + this._string.substring(end); + this._string = newString; + } + + public synchronized void drawLine(Graphics g, int lineNum, int y) { + if (lineNum < this._pos.size()) { + String thisLine = this._lines.elementAt(lineNum); + + assert thisLine != null; + + this._curpos = this._pos.elementAt(lineNum); + StringTokenizer st = new StringTokenizer(thisLine, " \n\r", true); + int x = 0; + this.lastWidth = 0; + + while (st.hasMoreTokens()) { + String word = st.nextToken(); + if (!this.handleTag(g, word, 2 + x, y + 2)) { + this.drawString(g, word, 2 + x, y + 2); + this.lastWidth = g.getFontMetrics().stringWidth(word); + x += this.lastWidth; + } else { + x -= this.lastWidth; + if (st.hasMoreTokens()) { + this._curpos = this._curpos + st.nextToken().length(); + } + + this.lastWidth = 0; + g.setFont(this._font); + g.setColor(this._currentColor); + this._curpos = this._curpos + word.length(); + } + } + + this.ClearTags(g); + } + } + + private void drawString(Graphics g, String text, int x, int y) { + FontMetrics fm = g.getFontMetrics(); + if (this.selectionConversion) { + int height = fm.getHeight(); + int pos = -1; + if (y - height < this._canvas.mouseY) { + if (y < this._canvas.mouseY) { + if (y < this._canvas.mouseY) { + if (this.selectionStart >= 0) { + pos = this._curpos + text.length(); + } + } else { + this.selectionConversion = false; + } + } else if (x <= this._canvas.mouseX) { + if (this._canvas.mouseX > x + g.getFontMetrics().stringWidth(text)) { + if (this.selectionStart >= 0 && this._curpos >= this.selectionStart) { + pos = this._curpos + text.length(); + } + } else { + if (this._canvas.mouseDoubleClick) { + this._canvas.mouseDoubleClick = false; + this.selectionStart = this._initialSelection = this._curpos; + this.selectionEnd = this._curpos + text.length(); + pos = -1; + } else { + int i = 0; + + while (i < text.length() - 1 && x + fm.stringWidth(text.substring(0, i + 1)) < this._canvas.mouseX) { + i++; + } + + pos = this._curpos + i; + } + + this.selectionConversion = false; + } + } else { + this.selectionConversion = false; + } + } else if (this.selectionStart >= 0 && this._curpos >= this.selectionStart) { + this.selectionConversion = false; + } + + if (pos >= 0) { + if (this.selectionStart < 0) { + this.selectionStart = this._initialSelection = pos; + this.selectionEnd = this.selectionStart + 1; + } else if (pos < this._initialSelection) { + this.selectionStart = pos; + this.selectionEnd = this._initialSelection + 1; + } else { + this.selectionStart = this._initialSelection; + this.selectionEnd = pos + 1; + } + } + } + + if (this.selectionStart >= 0 && this.selectionEnd > this.selectionStart) { + int startdist = this.selectionStart - this._curpos; + if (startdist > 0) { + if (startdist < text.length()) { + int end = text.length(); + if (this._curpos + end >= this.selectionEnd) { + end = this.selectionEnd - this._curpos; + } + + this.drawHighlight(g, text.substring(startdist, end), x + fm.stringWidth(text.substring(0, startdist)), y); + } + } else if (this.selectionEnd > this._curpos) { + if (this.selectionEnd - this._curpos < text.length()) { + this.drawHighlight(g, text.substring(0, this.selectionEnd - this._curpos), x, y); + } else { + this.drawHighlight(g, text, x, y); + } + } + } + + g.drawString(text, x, y); + this._curpos = this._curpos + text.length(); + } + + private void drawHighlight(Graphics g, String text, int x, int y) { + if (text != null && text.length() > 0) { + Color c = g.getColor(); + g.setColor(skyblue); + int height = g.getFontMetrics().getHeight(); + g.fillRect(x, y - (height - 2), g.getFontMetrics().stringWidth(text), height); + g.setColor(c); + } + } + + public int getSelectionStart() { + return this.selectionStart; + } + + public int getSelectionEnd() { + return this.selectionEnd; + } + + public void setSelectionStart(int position) { + this.selectionStart = position; + } + + public void setSelectionEnd(int position) { + this.selectionEnd = position; + } + + public synchronized String getSelectionText() { + if (this.selectionStart >= 0 && this.selectionEnd > this.selectionStart) { + return this.selectionEnd >= this.getText().length() + ? this.getText().substring(this.selectionStart) + : this.getText().substring(this.selectionStart, this.selectionEnd); + } else { + return ""; + } + } + + private void initRightMenu() { + this.rightMenu = new PopupMenu(); + this.rightMenu.add(this.textCopyItem); + this.rightMenu.add(this.textCopyTextItem); + if (this.selectionStart >= 0 && this.selectionEnd > this.selectionStart) { + this.textCopyItem.setEnabled(true); + this.textCopyTextItem.setEnabled(true); + } else { + this.textCopyItem.setEnabled(false); + this.textCopyTextItem.setEnabled(false); + } + + this.rightMenu.add(this.textCopyAllItem); + this.rightMenu.add(this.textCopyAllTextItem); + this.rightMenu.add(this.textOpenURLItem); + this.rightMenu.addActionListener(this); + this.add(this.rightMenu); + } + + private void showRightMenu(int x, int y) { + if (this.rightMenu == null) { + this.initRightMenu(); + } + + this.rightMenu.show(this, x, y); + } + + private void hideRightMenu() { + this.remove(this.rightMenu); + this.rightMenu = null; + } + + @Override + public synchronized void actionPerformed(ActionEvent e) { + String text = null; + boolean doClean = false; + if (e.getActionCommand() == this.textCopyItem.getActionCommand()) { + text = this.getSelectionText(); + this.selectionStart = this.selectionEnd = -1; + this.repaint(); + } else if (e.getActionCommand() == this.textCopyTextItem.getActionCommand()) { + text = this.getSelectionText(); + doClean = true; + this.selectionStart = this.selectionEnd = -1; + this.repaint(); + } else if (e.getActionCommand() == this.textCopyAllItem.getActionCommand()) { + text = this.getText(); + } else if (e.getActionCommand() == this.textCopyAllTextItem.getActionCommand()) { + text = this.getText(); + doClean = true; + } else if (e.getActionCommand() == this.textOpenURLItem.getActionCommand()) { + text = this.getSelectionText().trim(); + if (text != null && text.length() > 5) { + if (!text.startsWith("http://") && !text.startsWith("https://") && !text.startsWith("world:")) { + text = "http://" + text; + } + + if (text.startsWith("world:") || text.contains(".world#") || (text.startsWith("http") || text.startsWith("file:")) && text.endsWith(".world")) { + if (text.startsWith("world:")) { + text = text.substring(6); + } + + TeleportAction.teleport(text, null); + } else { + new SendURLAction(text).startBrowser(); + } + + this.selectionStart = this.selectionEnd = -1; + this.repaint(); + } + + this.hideRightMenu(); + return; + } + + if (doClean) { + StringTokenizer st = new StringTokenizer(text, " \n\r", true); + String newText = ""; + + while (st.hasMoreTokens()) { + String word = st.nextToken(); + if (!this.handleTag(null, word, 0, 0)) { + newText = newText + word; + } else { + if (newText.length() > 0 && newText.substring(newText.length() - 1).toCharArray()[0] == ' ') { + newText = newText.substring(0, newText.length() - 1); + } + + if (st.hasMoreTokens()) { + st.nextToken(); + } + } + } + + text = newText; + } + + if (text != null && text.length() > 0) { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(new StringSelection(text), null); + } + + this.hideRightMenu(); + } +} diff --git a/NET/worlds/console/GammaTextScrollbar.java b/NET/worlds/console/GammaTextScrollbar.java new file mode 100644 index 0000000..c3eed33 --- /dev/null +++ b/NET/worlds/console/GammaTextScrollbar.java @@ -0,0 +1,22 @@ +package NET.worlds.console; + +import java.awt.Scrollbar; +import java.awt.event.MouseEvent; + +class GammaTextScrollbar extends Scrollbar { + private static final long serialVersionUID = -3376693721088718777L; + + GammaTextScrollbar(int orientation) { + super(orientation); + this.enableEvents(20L); + } + + @Override + protected void processMouseEvent(MouseEvent e) { + if (e.getID() == 501) { + this.getParent().requestFocus(); + } + + super.processMouseEvent(e); + } +} diff --git a/NET/worlds/console/GiftDialog.java b/NET/worlds/console/GiftDialog.java new file mode 100644 index 0000000..73cfc10 --- /dev/null +++ b/NET/worlds/console/GiftDialog.java @@ -0,0 +1,45 @@ +package NET.worlds.console; + +import NET.worlds.core.Std; +import NET.worlds.scape.InventoryItem; +import NET.worlds.scape.InventoryManager; +import java.text.MessageFormat; +import java.util.Hashtable; + +class GiftDialog extends OkCancelDialog { + private static final long serialVersionUID = -5698666260017940591L; + private String inv; + private int autoCloseTime; + + public static String calcMsg(String inv, int duration) { + InventoryManager im = InventoryManager.getInventoryManager(); + Hashtable<String, InventoryItem> inventory = im.parseInventoryString(inv); + String hr = TradeDialog.buildInvDesc(inventory); + Object[] arguments = new Object[]{new String(hr), new String("" + duration / 1000)}; + return MessageFormat.format(Console.message("To-claim-hr"), arguments); + } + + public GiftDialog(String _inv, int duration) { + super(Console.getFrame(), null, Console.message("A-Gift"), null, "Accept", calcMsg(_inv, duration), false); + this.autoCloseTime = Std.getFastTime() + duration; + this.inv = _inv; + } + + @Override + protected void activeCallback() { + super.activeCallback(); + if (Std.getFastTime() > this.autoCloseTime && this.autoCloseTime != 0) { + this.done(false); + } + } + + @Override + protected synchronized boolean done(boolean confirmed) { + WhisperManager.whisperManager().giftDialogDone(); + if (confirmed) { + TradeDialog.sendTradeMessage("&|+deal>TRADE ," + this.inv); + } + + return super.done(confirmed); + } +} diff --git a/NET/worlds/console/IClassFactory.java b/NET/worlds/console/IClassFactory.java new file mode 100644 index 0000000..566a130 --- /dev/null +++ b/NET/worlds/console/IClassFactory.java @@ -0,0 +1,123 @@ +package NET.worlds.console; + +import NET.worlds.core.RegKey; +import NET.worlds.core.RegKeyNotFoundException; +import java.io.IOException; + +public class IClassFactory extends IUnknown { + private static final String IID_IClassFactory = "{00000001-0000-0000-C000-000000000046}"; + private long _registerID; + + public IClassFactory() throws IOException { + } + + public IClassFactory(String svrID) throws IOException { + super(svrID, "{00000001-0000-0000-C000-000000000046}"); + } + + public IClassFactory(IUnknown pIUnknown) throws IOException, OLEInvalidObjectException { + super(pIUnknown, "{00000001-0000-0000-C000-000000000046}"); + } + + public synchronized void activate(String CLSID) throws IOException { + assert this._registerID == 0L; + + assert Main.isMainThread(); + + if ((ActiveX.getDebugLevel() & 8) > 0) { + System.out.println(this + ": activating server as " + CLSID); + } + + this._registerID = this.nActivate(CLSID); + if ((ActiveX.getDebugLevel() & 8) > 0) { + System.out.println(this + ": successful"); + } + } + + public synchronized void deactivate() throws IOException { + assert this._registerID != 0L; + + assert Main.isMainThread(); + + if ((ActiveX.getDebugLevel() & 8) > 0) { + System.out.println(this + ": deactivating server"); + } + + this.nDeactivate(this._registerID); + } + + @Override + public synchronized void Release() throws OLEInvalidObjectException { + if (this._refs == 1 && this._registerID != 0L) { + if ((ActiveX.getDebugLevel() & 4) > 0) { + System.out.println(this + ": deactivating before Release"); + } + + try { + this.deactivate(); + } catch (IOException var2) { + System.out.println("DEBUG: " + this); + var2.printStackTrace(System.out); + + assert false; + } + + this._registerID = 0L; + } + + super.Release(); + } + + @Override + public String internalData() { + return "_registerID = " + this._registerID + ", " + super.internalData(); + } + + @Override + public String toString() { + return "IClassFactory(" + this.internalData() + ")"; + } + + public void register(String friendlyName, String CLSID, String VerIndProgID, String ProgID) { + try { + RegKey root = RegKey.getRootKey(0); + RegKey gammaKey = new RegKey(root, "world\\shell\\open\\command", 0); + String gammaPath = gammaKey.getStringValue(""); + int argIndx = gammaPath.indexOf(" \"%1\""); + gammaPath = gammaPath.substring(0, argIndx); + RegKey classKey = new RegKey(root, "CLSID\\" + CLSID, 2); + classKey.setStringValue("", friendlyName, false); + RegKey subKey = new RegKey(classKey, "LocalServer32", 2); + subKey.setStringValue("", gammaPath, false); + subKey.close(); + subKey = new RegKey(classKey, "ProgID", 2); + subKey.setStringValue("", ProgID, false); + subKey.close(); + subKey = new RegKey(classKey, "VersionIndependentProgID", 2); + subKey.setStringValue("", VerIndProgID, false); + subKey.close(); + classKey.close(); + RegKey verIndKey = new RegKey(root, VerIndProgID, 2); + verIndKey.setStringValue("", friendlyName, false); + subKey = new RegKey(verIndKey, "CLSID", 2); + subKey.setStringValue("", CLSID, false); + subKey.close(); + subKey = new RegKey(verIndKey, "CurVer", 2); + subKey.setStringValue("", ProgID, false); + subKey.close(); + verIndKey.close(); + RegKey progKey = new RegKey(root, ProgID, 2); + progKey.setStringValue("", friendlyName, false); + subKey = new RegKey(progKey, "CLSID", 2); + subKey.setStringValue("", CLSID, false); + subKey.close(); + progKey.close(); + } catch (RegKeyNotFoundException var13) { + System.out.println("Warning: System Registry not configured properly by Worlds."); + } + } + + private native long nActivate(String var1) throws IOException; + + private native void nDeactivate(long var1) throws IOException; +} diff --git a/NET/worlds/console/IDispatch.java b/NET/worlds/console/IDispatch.java new file mode 100644 index 0000000..858576b --- /dev/null +++ b/NET/worlds/console/IDispatch.java @@ -0,0 +1,42 @@ +package NET.worlds.console; + +import java.io.IOException; + +public class IDispatch extends IUnknown { + private static final String IID_IDispatch = "{00020400-0000-0000-C000-000000000046}"; + + public IDispatch(String svrID) throws IOException { + try { + this.init(svrID, "{00020400-0000-0000-C000-000000000046}"); + } catch (IOException var16) { + IUnknown tmpUnk = new IUnknown(svrID); + + try { + this.init(tmpUnk, "{00020400-0000-0000-C000-000000000046}"); + } catch (OLEInvalidObjectException var14) { + System.out.println("DEBUG: " + this); + + assert false; + } finally { + try { + tmpUnk.Release(); + } catch (OLEInvalidObjectException var13) { + System.out.println("DEBUG: " + this); + + assert false; + } + } + } + } + + public IDispatch(IUnknown pIUnknown) throws IOException, OLEInvalidObjectException { + super(pIUnknown, "{00020400-0000-0000-C000-000000000046}"); + } + + public native void Invoke(String var1); + + @Override + public String toString() { + return "IDispatch(" + this.internalData() + ")"; + } +} diff --git a/NET/worlds/console/IEWebControlImp.java b/NET/worlds/console/IEWebControlImp.java new file mode 100644 index 0000000..e06310a --- /dev/null +++ b/NET/worlds/console/IEWebControlImp.java @@ -0,0 +1,130 @@ +package NET.worlds.console; + +class IEWebControlImp extends WebControlImp { + private int nativeIEInstance; + private int m_hwnd; + private boolean detached; + + private native boolean nativeInit(int var1, boolean var2); + + private native void nativeDestroy(); + + private native void nativeSetURL(String var1, String var2); + + private native void nativeGoBack(); + + private native void nativeGoForward(); + + private native void nativeStop(); + + private native void nativeRefresh(); + + private native void nativeHome(); + + private native void nativePrint(int var1, int var2); + + private native void nativeResize(int var1, int var2, int var3, int var4); + + private native void nativeAddToolbar(); + + private native int nativeGetHWND(); + + public IEWebControlImp(int hwnd, boolean toolbar, boolean isBanner) throws NoWebControlException { + super(hwnd); + this.m_hwnd = hwnd; + this.nativeIEInstance = 0; + this.detached = false; + if (!this.nativeInit(hwnd, isBanner)) { + this.detached = true; + throw new NoWebControlException("Could not initialize IE control"); + } else { + if (toolbar) { + this.nativeAddToolbar(); + } + } + } + + @Override + public void finalize() { + this.detach(); + } + + @Override + public void renderTo(int dc) { + this.nativePrint(dc, this.m_hwnd); + } + + @Override + public boolean setURL(String pURL) { + pURL = processURL(pURL); + if (pURL == null) { + return false; + } else { + this.nativeSetURL(pURL, null); + return true; + } + } + + @Override + public boolean setURL(String pURL, String pPostData) { + pURL = processURL(pURL); + if (pURL == null) { + return false; + } else { + if (pPostData != null) { + pPostData = processURL(pPostData); + if (pPostData == null) { + return false; + } + } + + this.nativeSetURL(pURL, pPostData); + return true; + } + } + + @Override + public void detach() { + if (!this.detached) { + this.nativeDestroy(); + super.detach(); + this.nativeIEInstance = 0; + this.detached = true; + } + } + + @Override + public void resize(int w, int h, int xPer, int yPer) { + this.nativeResize(w, h, xPer, yPer); + } + + @Override + public void goBack() { + this.nativeGoBack(); + } + + @Override + public void goForward() { + this.nativeGoForward(); + } + + @Override + public void stop() { + this.nativeStop(); + } + + @Override + public void refresh() { + this.nativeRefresh(); + } + + @Override + public void home() { + this.nativeHome(); + } + + @Override + public int getHWND() { + return this.nativeGetHWND(); + } +} diff --git a/NET/worlds/console/INetscapeRegistry.java b/NET/worlds/console/INetscapeRegistry.java new file mode 100644 index 0000000..f7f78ee --- /dev/null +++ b/NET/worlds/console/INetscapeRegistry.java @@ -0,0 +1,18 @@ +package NET.worlds.console; + +import java.io.IOException; + +public class INetscapeRegistry extends IDispatch { + public INetscapeRegistry() throws IOException { + super("Netscape.Registry.1"); + } + + public native boolean RegisterViewer(String var1, String var2) throws IOException; + + public native boolean RegisterProtocol(String var1, String var2) throws IOException; + + @Override + public String toString() { + return "INetscapeRegistry(" + this.internalData() + ")"; + } +} diff --git a/NET/worlds/console/IUnknown.java b/NET/worlds/console/IUnknown.java new file mode 100644 index 0000000..3a80b20 --- /dev/null +++ b/NET/worlds/console/IUnknown.java @@ -0,0 +1,166 @@ +package NET.worlds.console; + +import java.io.IOException; + +public class IUnknown { + protected int _pInterface = 0; + protected int _refs = 0; + private static final String IID_IUnknown = "{00000000-0000-0000-c000-000000000046}"; + + public IUnknown() throws IOException { + } + + protected synchronized void init(int pInterface) throws IOException { + assert pInterface != 0; + + ActiveX.init(this); + this._pInterface = pInterface; + this._refs = 1; + } + + public IUnknown(String svrID) throws IOException { + if ((ActiveX.getDebugLevel() & 2) > 0) { + System.out.println(this + ": constructor: svrID = " + svrID); + } + + ActiveX.init(this); + + try { + try { + this._pInterface = ActiveX.getClassFClsID(svrID, "{00000000-0000-0000-c000-000000000046}"); + this._refs++; + } catch (IOException var3) { + this._pInterface = ActiveX.getClassFProgID(svrID, "{00000000-0000-0000-c000-000000000046}"); + this._refs++; + } + } catch (IOException var4) { + ActiveX.uninit(this); + throw var4; + } + + if ((ActiveX.getDebugLevel() & 2) > 0) { + System.out.println("IUnknown: constructed " + this); + } + } + + public IUnknown(String svrID, String intfID) throws IOException { + if ((ActiveX.getDebugLevel() & 2) > 0) { + System.out.println(this + ": constructor: svrID = " + svrID + ", intfID = " + intfID); + } + + this.init(svrID, intfID); + if ((ActiveX.getDebugLevel() & 2) > 0) { + System.out.println("IUnknown: constructed " + this); + } + } + + protected synchronized void init(String svrID, String intfID) throws IOException { + ActiveX.init(this); + + try { + try { + this._pInterface = ActiveX.getClassFClsID(svrID, intfID); + this._refs++; + } catch (IOException var4) { + this._pInterface = ActiveX.getClassFProgID(svrID, intfID); + this._refs++; + } + } catch (IOException var5) { + ActiveX.uninit(this); + throw var5; + } + } + + public IUnknown(IUnknown parent, String intfID) throws IOException, OLEInvalidObjectException { + if ((ActiveX.getDebugLevel() & 2) > 0) { + System.out.println(this + ": constructor: parent = " + parent + ", intfID = " + intfID); + } + + this.init(parent, intfID); + if ((ActiveX.getDebugLevel() & 2) > 0) { + System.out.println("IUnknown: constructed " + this); + } + } + + protected synchronized void init(IUnknown parent, String intfID) throws IOException, OLEInvalidObjectException { + assert parent != null; + + ActiveX.init(this); + + try { + this._pInterface = parent.QueryInterface(intfID); + this._refs = 1; + } catch (IOException var4) { + ActiveX.uninit(this); + throw var4; + } catch (OLEInvalidObjectException var5) { + ActiveX.uninit(this); + throw var5; + } + } + + public synchronized void Release() throws OLEInvalidObjectException { + if ((ActiveX.getDebugLevel() & 4) > 0) { + System.out.println(this + ": Releasing"); + } + + if (this._pInterface == 0) { + throw new OLEInvalidObjectException(); + } else { + if (this._pInterface != 0 && this._refs > 0) { + this.true_Release(); + } + + this._refs--; + if (this._refs == 0) { + this._pInterface = 0; + ActiveX.uninit(this); + } + } + } + + @Override + public void finalize() { + if (this._pInterface != 0) { + while (this._refs > 0) { + try { + this.Release(); + } catch (OLEInvalidObjectException var2) { + System.out.println("DEBUG: " + this); + + assert false; + } + } + } + } + + public synchronized void AddRef() throws OLEInvalidObjectException { + if ((ActiveX.getDebugLevel() & 4) > 0) { + System.out.println(this + ": AddingRef"); + } + + if (this._pInterface == 0) { + throw new OLEInvalidObjectException(); + } else { + this._refs++; + this.true_AddRef(); + } + } + + public native void true_AddRef(); + + public native int QueryInterface(String var1) throws IOException, OLEInvalidObjectException; + + public native void true_Release() throws OLEInvalidObjectException; + + protected native int getPtr() throws OLEInvalidObjectException; + + public String internalData() { + return "_pInterface=" + this._pInterface + ", _refs=" + this._refs; + } + + @Override + public String toString() { + return "IUnknown(" + this.internalData() + ")"; + } +} diff --git a/NET/worlds/console/IWebBrowserApp.java b/NET/worlds/console/IWebBrowserApp.java new file mode 100644 index 0000000..88451da --- /dev/null +++ b/NET/worlds/console/IWebBrowserApp.java @@ -0,0 +1,26 @@ +package NET.worlds.console; + +import java.io.IOException; + +public class IWebBrowserApp extends IUnknown { + public static final String CLSID_InternetExplorer = "{0002DF01-0000-0000-C000-000000000046}"; + public static final String IID_IWebBrowserApp = "{0002DF05-0000-0000-C000-000000000046}"; + + public IWebBrowserApp() throws IOException { + super("{0002DF01-0000-0000-C000-000000000046}", "{0002DF05-0000-0000-C000-000000000046}"); + } + + public IWebBrowserApp(IUnknown parent) throws IOException, OLEInvalidObjectException { + super(parent, "{0002DF05-0000-0000-C000-000000000046}"); + } + + public native void put_Visible(boolean var1); + + public native void put_StatusBar(boolean var1); + + public native void put_MenuBar(boolean var1); + + public native void Navigate(String var1); + + public native void Quit(); +} diff --git a/NET/worlds/console/IllegalPilotException.java b/NET/worlds/console/IllegalPilotException.java new file mode 100644 index 0000000..c4d8c8b --- /dev/null +++ b/NET/worlds/console/IllegalPilotException.java @@ -0,0 +1,12 @@ +package NET.worlds.console; + +public class IllegalPilotException extends Exception { + private static final long serialVersionUID = 421670050791293454L; + + IllegalPilotException(String s) { + super(s); + } + + IllegalPilotException() { + } +} diff --git a/NET/worlds/console/ImageButtons.java b/NET/worlds/console/ImageButtons.java new file mode 100644 index 0000000..b27f9e5 --- /dev/null +++ b/NET/worlds/console/ImageButtons.java @@ -0,0 +1,392 @@ +package NET.worlds.console; + +import NET.worlds.scape.FrameEvent; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Graphics; +import java.awt.PopupMenu; +import java.awt.Rectangle; +import java.awt.event.MouseEvent; + +public class ImageButtons extends ImageCanvas implements FramePart, DialogDisabled { + private static final long serialVersionUID = -1495360044843592740L; + protected static final int BLANK = 0; + protected static final int NORMAL = 1; + protected static final int CURSED = 2; + protected static final int DOWN = 3; + private static final int TITLE = 0; + private static final int BUTTON = 1; + private int width; + private int height; + private Dimension ghostImageDimension; + protected Rectangle[] buttons; + private int[] types; + private boolean background = false; + private int cursedButton = -1; + private int clickedButton = -1; + private boolean clickedButtonDown; + private ImageButtonsCallback handler; + private ImageButtonsCallback downUpHandler; + private PopupMenu menu; + private boolean isDialogDisabled; + + private void initEvents() { + this.enableEvents(16L); + this.enableEvents(32L); + } + + protected ImageButtons() { + this.buttons = new Rectangle[0]; + this.initEvents(); + } + + public ImageButtons(String imageName, int buttonWidth, int buttonHeight, ImageButtonsCallback handler) { + this(imageName, buttonWidth, intToInts(buttonHeight), handler); + } + + public ImageButtons(String imageName, Rectangle[] buttonRects, ImageButtonsCallback handler) { + super(imageName); + this.handler = handler; + this.background = true; + this.setHotspots(buttonRects); + this.initEvents(); + } + + public ImageButtons(String imageName, int buttonWidth, int[] buttonHeights, ImageButtonsCallback handler) { + super(imageName); + this.handler = handler; + this.buttons = new Rectangle[buttonHeights.length]; + this.types = new int[buttonHeights.length]; + int y = 0; + + for (int i = 0; i < buttonHeights.length; i++) { + int h = buttonHeights[i]; + int rh; + if (h > 0) { + rh = h; + this.types[i] = 1; + } else { + rh = -h; + this.types[i] = 0; + } + + this.buttons[i] = new Rectangle(0, y, buttonWidth, rh); + y += rh; + } + + this.ghostImageDimension = new Dimension(buttonWidth * 4, buttonHeights[0]); + this.initEvents(); + } + + public void setHandler(ImageButtonsCallback handler) { + this.handler = handler; + } + + public void setDownUpHandler(ImageButtonsCallback handler) { + this.downUpHandler = handler; + } + + protected void setBackground(boolean background) { + this.background = background; + } + + protected void setWidth(int width) { + this.width = width; + } + + protected void setHeight(int height) { + this.height = height; + } + + protected synchronized void setHotspots(Rectangle[] buttonRects) { + this.buttons = new Rectangle[buttonRects.length]; + this.types = new int[buttonRects.length]; + + for (int i = 0; i < buttonRects.length; i++) { + this.types[i] = 1; + this.buttons[i] = new Rectangle(buttonRects[i]); + } + + this.cursedButton = -1; + this.clickedButton = -1; + this.clickedButtonDown = false; + } + + @Override + public synchronized void paint(Graphics g) { + g.clipRect(0, 0, this.width, this.height); + if (this.background && this.image_ != null) { + g.drawImage(this.image_, -1 * this.width, 0, null); + } + + for (int i = 0; i < this.buttons.length; i++) { + int state = 1; + if (i == this.cursedButton) { + state = 2; + } + + if (i == this.clickedButton) { + state = this.clickedButtonDown ? 3 : 1; + } + + this.drawButton(g, i, state); + } + } + + @Override + public Dimension preferredSize() { + Dimension d = super.preferredSize(); + if (d.width == 0 && d.height == 0 && this.ghostImageDimension != null) { + d = this.ghostImageDimension; + } + + return new Dimension(this.width = d.width / 4, this.height = d.height); + } + + @Override + public Dimension minimumSize() { + return this.preferredSize(); + } + + @Override + public void processMouseMotionEvent(MouseEvent e) { + if (!this.isDialogDisabled) { + switch (e.getID()) { + case 503: + case 506: + this.buttonAction(e.getX(), e.getY(), e.getID()); + case 504: + case 505: + } + } + + super.processMouseEvent(e); + } + + @Override + public void processMouseEvent(MouseEvent e) { + if (!this.isDialogDisabled) { + switch (e.getID()) { + case 501: + case 502: + case 504: + case 505: + this.buttonAction(e.getX(), e.getY(), e.getID()); + case 503: + } + } + + super.processMouseEvent(e); + } + + @Override + public boolean mouseMove(Event e, int x, int y) { + return this.buttonAction(x, y, 503); + } + + @Override + public boolean mouseDown(Event e, int x, int y) { + return (e.modifiers & 12) != 0 ? false : this.buttonAction(x, y, 501); + } + + @Override + public boolean mouseUp(Event e, int x, int y) { + return (e.modifiers & 12) != 0 ? false : this.buttonAction(x, y, 502); + } + + @Override + public boolean mouseDrag(Event e, int x, int y) { + return this.buttonAction(x, y, 506); + } + + @Override + public boolean mouseEnter(Event e, int x, int y) { + return this.buttonAction(x, y, 504); + } + + @Override + public boolean mouseExit(Event e, int x, int y) { + return this.buttonAction(x, y, 505); + } + + @Override + public boolean handleEvent(Event event) { + return this.isDialogDisabled ? false : super.handleEvent(event); + } + + protected Graphics drawButton(Graphics g, int button, int state) { + if (button != -1) { + Rectangle r = this.buttons[button]; + if (this.image_ != null && (g != null || (g = this.getGraphics()) != null)) { + Graphics g1 = g.create(r.x, r.y, r.width, r.height); + g1.drawImage(this.image_, -state * this.width - r.x, -r.y, null); + g1.dispose(); + } + } + + return g; + } + + private synchronized boolean buttonAction(int x, int y, int action) { + return this.buttonAction(this.locateButton(x, y), action); + } + + private int locateButton(int x, int y) { + for (int i = 0; i < this.buttons.length; i++) { + if (this.types[i] == 1 && this.buttons[i].inside(x, y)) { + return i; + } + } + + return -1; + } + + public void drawFirstButton(int state) { + if (this.buttons.length > 0) { + Graphics g = this.drawButton(null, 0, state); + if (g != null) { + g.dispose(); + } + } + } + + public void drawNormal() { + this.drawFirstButton(1); + } + + public void drawCursed() { + this.drawFirstButton(2); + } + + public void drawDown() { + this.drawFirstButton(3); + } + + boolean buttonAction(int button, int action) { + Graphics g = null; + if (action != 503 && action != 504) { + if (action == 505) { + if (this.cursedButton != -1) { + g = this.drawButton(g, this.cursedButton, 1); + this.cursedButton = -1; + } + + if (this.downUpHandler == null && this.clickedButton != -1 && this.clickedButtonDown) { + g = this.drawButton(g, this.clickedButton, 1); + this.clickedButtonDown = false; + } + } else if (action == 501) { + if (this.clickedButton != -1) { + g = this.drawButton(g, this.clickedButton, 1); + if (this.downUpHandler != null) { + this.downUpHandler.imageButtonsCallback(this, -1); + } + + this.clickedButtonDown = false; + } + + if (this.cursedButton != -1) { + g = this.drawButton(g, this.cursedButton, 1); + this.cursedButton = -1; + } + + if ((this.clickedButton = button) != -1) { + g = this.drawButton(g, this.clickedButton, 3); + this.clickedButtonDown = true; + if (this.downUpHandler != null) { + this.downUpHandler.imageButtonsCallback(this, button); + } + } + } else if (action == 506) { + if (this.downUpHandler == null && this.clickedButton != -1) { + if (this.clickedButtonDown) { + if (button != this.clickedButton) { + g = this.drawButton(g, this.clickedButton, 1); + this.clickedButtonDown = false; + } + } else if (button == this.clickedButton) { + g = this.drawButton(g, this.clickedButton, 3); + this.clickedButtonDown = true; + } + } + } else if (action == 502) { + this.cursedButton = button; + if (this.cursedButton != -1) { + g = this.drawButton(g, this.cursedButton, 2); + } + + if (this.clickedButtonDown) { + if (this.cursedButton != this.clickedButton) { + g = this.drawButton(g, this.clickedButton, 1); + } + + Object ret = this.handler.imageButtonsCallback(this, this.clickedButton); + if (ret instanceof PopupMenu && this.clickedButton != -1) { + if (this.menu != null) { + this.remove(this.menu); + } + + this.add(this.menu = (PopupMenu)ret); + this.menu.show(this, this.buttons[this.clickedButton].x, this.buttons[this.clickedButton].y + this.buttons[this.clickedButton].height); + } + + if (this.downUpHandler != null && this.downUpHandler.imageButtonsCallback(this, -1) != null) { + this.cursedButton = -1; + } + + this.clickedButtonDown = false; + this.clickedButton = -1; + } + } + } else { + if (button != this.cursedButton) { + g = this.drawButton(g, this.cursedButton, 1); + g = this.drawButton(g, this.cursedButton = button, 2); + } + + if (this.clickedButton != -1 && this.clickedButton != button && this.downUpHandler == null) { + g = this.drawButton(g, this.clickedButton, 1); + this.clickedButtonDown = false; + } + } + + if (g != null) { + g.dispose(); + } + + return true; + } + + public static int[] intToInts(int value) { + return new int[]{value}; + } + + @Override + public void activate(Console c, Container f, Console prev) { + } + + @Override + public void deactivate() { + } + + @Override + public boolean action(Event event, Object what) { + return false; + } + + @Override + public boolean handle(FrameEvent f) { + return false; + } + + @Override + public void dialogDisable(boolean disable) { + if (this.isDialogDisabled = disable) { + this.cursedButton = -1; + this.clickedButton = -1; + this.clickedButtonDown = false; + this.repaint(); + } + } +} diff --git a/NET/worlds/console/ImageButtonsCallback.java b/NET/worlds/console/ImageButtonsCallback.java new file mode 100644 index 0000000..4458803 --- /dev/null +++ b/NET/worlds/console/ImageButtonsCallback.java @@ -0,0 +1,7 @@ +package NET.worlds.console; + +import java.awt.Component; + +public interface ImageButtonsCallback { + Object imageButtonsCallback(Component var1, int var2); +} diff --git a/NET/worlds/console/ImageCanvas.java b/NET/worlds/console/ImageCanvas.java new file mode 100644 index 0000000..9610438 --- /dev/null +++ b/NET/worlds/console/ImageCanvas.java @@ -0,0 +1,193 @@ +package NET.worlds.console; + +import NET.worlds.network.URL; +import NET.worlds.scape.BGLoaded; +import NET.worlds.scape.BackgroundLoader; +import NET.worlds.scape.Room; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.Toolkit; + +public class ImageCanvas extends Component implements BGLoaded { + private static final long serialVersionUID = 1687513733496926512L; + protected URL imageURL_; + protected Image image_; + protected boolean loaded_; + protected Dimension dim_; + protected static final URL defaultImageURL = URL.make("home:..\\default.gif"); + + public ImageCanvas(URL inURL) { + this.setNewImage(inURL); + } + + protected ImageCanvas() { + } + + public ImageCanvas(String nm) { + this.loadImage(nm); + } + + private Image loadImage(String nm) { + this.imageURL_ = URL.make("home:" + nm); + this.image_ = this.loadLocalImage(this.imageURL_.unalias()); + if (this.image_ == null) { + this.imageURL_ = URL.make("home:..\\" + nm); + this.image_ = this.loadLocalImage(this.imageURL_.unalias()); + } + + if (this.image_ == null) { + this.setNewImage(URL.make(nm)); + } + + return this.image_; + } + + public void setNewImage(URL newImageURL, Graphics g) { + this.setNewImage(newImageURL); + } + + public void setNewImage(URL newImageURL) { + this.imageURL_ = newImageURL; + this.flushImage(); + this.loaded_ = false; + this.loadRemoteImage(); + } + + protected void flushImage() { + if (this.image_ != null) { + this.image_.flush(); + this.image_ = null; + } + } + + @Override + public void update(Graphics g) { + if (g != null) { + Dimension d = this.getSize(); + if (this.image_ == null || d.width > this.dim_.width || d.height > this.dim_.height) { + super.update(g); + } + + this.paint(g); + } + } + + @Override + public void paint(Graphics g) { + if (this.image_ != null && g != null) { + g.drawImage(this.image_, 0, 0, this); + } + } + + public void paint(Graphics g, int x, int y) { + if (this.image_ != null && g != null) { + g.drawImage(this.image_, x, y, this); + } + } + + public Dimension imageSize() { + if (this.image_ == null) { + this.dim_ = new Dimension(0, 0); + } else { + int width = this.image_.getWidth(this); + int height = this.image_.getHeight(this); + if (width != -1 && height != -1) { + this.dim_ = new Dimension(width, height); + } + } + + return this.dim_; + } + + @Override + public Object asyncBackgroundLoad(String localName, URL remoteURL) { + this.image_ = this.loadLocalImage(localName); + if (this.getGraphics() != null) { + this.update(this.getGraphics()); + } + + return localName; + } + + @Override + public boolean syncBackgroundLoad(Object obj, URL remoteURL) { + String localName = (String)obj; + this.image_ = this.loadLocalImage(localName); + if (this.getGraphics() != null) { + this.update(this.getGraphics()); + } + + return false; + } + + @Override + public Room getBackgroundLoadRoom() { + return null; + } + + private void loadRemoteImage() { + this.image_ = this.loadLocalImage(defaultImageURL.unalias()); + if (this.imageURL_ != defaultImageURL) { + BackgroundLoader.get(this, this.imageURL_); + } + } + + private Image loadLocalImage(String fName) { + Image image = Toolkit.getDefaultToolkit().getImage(fName); + MediaTracker tracker = new MediaTracker(this); + tracker.addImage(image, 0); + + try { + tracker.waitForAll(); + } catch (InterruptedException var5) { + } + + if (!tracker.isErrorAny()) { + this.loaded_ = true; + return image; + } else { + return null; + } + } + + public static Image loadImage(URL url, Component comp) { + Image image = Toolkit.getDefaultToolkit().getImage(url.unalias()); + MediaTracker tracker = new MediaTracker(comp); + tracker.addImage(image, 0); + + try { + tracker.waitForAll(); + } catch (InterruptedException var5) { + } + + return !tracker.isErrorAny() ? image : null; + } + + public static Image getSystemImage(String name, Component comp) { + for (int pass = 0; pass < 2; pass++) { + Image image = loadImage(URL.make("home:" + name), comp); + if (image != null) { + return image; + } + + if (pass == 0) { + name = "..\\" + name; + } + } + + return null; + } + + @Override + public Dimension preferredSize() { + return this.imageSize(); + } + + @Override + public Dimension minimumSize() { + return this.imageSize(); + } +} diff --git a/NET/worlds/console/InsetPanel.java b/NET/worlds/console/InsetPanel.java new file mode 100644 index 0000000..b22d0f6 --- /dev/null +++ b/NET/worlds/console/InsetPanel.java @@ -0,0 +1,30 @@ +package NET.worlds.console; + +import java.awt.Color; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Panel; + +class InsetPanel extends Panel { + private static final long serialVersionUID = -8045587676805647253L; + private Insets insets; + + InsetPanel(LayoutManager layout, int top, int left, int bottom, int right) { + super(layout); + this.init(top, left, bottom, right); + } + + InsetPanel(int top, int left, int bottom, int right) { + this.init(top, left, bottom, right); + } + + private void init(int top, int left, int bottom, int right) { + this.insets = new Insets(top, left, bottom, right); + this.setBackground(Color.black); + } + + @Override + public Insets getInsets() { + return this.insets; + } +} diff --git a/NET/worlds/console/InternetConnectionDialog.java b/NET/worlds/console/InternetConnectionDialog.java new file mode 100644 index 0000000..66a3c7c --- /dev/null +++ b/NET/worlds/console/InternetConnectionDialog.java @@ -0,0 +1,79 @@ +package NET.worlds.console; + +import NET.worlds.network.Galaxy; +import NET.worlds.network.VarErrorException; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.Panel; + +public class InternetConnectionDialog extends PolledDialog { + private static final long serialVersionUID = 612016940893432560L; + private String msg; + private Button okButton = new Button(Console.message("Retry")); + private Button cancelButton = new Button(Console.message("Single-user")); + private static boolean firstTimeDone; + private static boolean choseSingleUserMode; + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + + public static boolean isFirstTimeDone() { + return firstTimeDone; + } + + public static boolean choseSingleUserMode() { + return choseSingleUserMode; + } + + public InternetConnectionDialog(Galaxy galaxy, VarErrorException ve) { + super(Console.getFrame(), galaxy, Console.message("Internet-Connection"), true); + this.setAlignment(1); + this.msg = ve.getMsg().replace('\n', ' '); + this.ready(); + } + + @Override + protected boolean done(boolean confirmed) { + boolean ret = super.done(confirmed); + choseSingleUserMode = !confirmed; + firstTimeDone = true; + return ret; + } + + @Override + protected void build() { + this.setLayout(new BorderLayout()); + Panel txtPanel = new Panel(new BorderLayout()); + txtPanel.add("Center", new TextCanvas(this.msg, 400)); + txtPanel.add("North", new Filler(10, 10)); + txtPanel.add("South", new Filler(10, 10)); + txtPanel.add("East", new Filler(10, 10)); + txtPanel.add("West", new Filler(10, 10)); + this.add("Center", txtPanel); + Panel buttons = new Panel(); + this.okButton.setFont(bfont); + this.cancelButton.setFont(bfont); + buttons.add(this.okButton); + buttons.add(this.cancelButton); + this.add("South", buttons); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.okButton) { + return this.done(true); + } else { + return target == this.cancelButton ? this.done(false) : false; + } + } + + @Override + public boolean keyDown(Event event, int key) { + if (key == 27) { + return this.done(false); + } else { + return key == 10 ? this.done(true) : super.keyDown(event, key); + } + } +} diff --git a/NET/worlds/console/InternetExplorer.java b/NET/worlds/console/InternetExplorer.java new file mode 100644 index 0000000..5a72487 --- /dev/null +++ b/NET/worlds/console/InternetExplorer.java @@ -0,0 +1,82 @@ +package NET.worlds.console; + +import NET.worlds.scape.CDAudio; +import NET.worlds.scape.WavSoundPlayer; +import java.io.IOException; + +public class InternetExplorer extends IUnknown implements MainCallback, MainTerminalCallback { + WebBrowser _parent; + + public InternetExplorer(WebBrowser parent) throws IOException { + ActiveX.init(this); + this._parent = parent; + this._refs = 1; + Main.register(this); + } + + @Override + public synchronized void Release() throws OLEInvalidObjectException { + if (this._refs > 0) { + this._refs--; + if (this._parent != null) { + this._parent.close(); + } + + ActiveX.uninit(this); + } + } + + @Override + public String toString() { + return "InternetExplorer(" + this.internalData() + ")"; + } + + @Override + public void mainCallback() { + boolean justActivated = Window.getActivated(); + if (justActivated) { + WebBrowser killMe = WebBrowser.findTag("sound:"); + if (killMe != null) { + killMe.close(); + } + + killMe = WebBrowser.findTag("videoMap:"); + if (killMe != null) { + killMe.close(); + } + + killMe = WebBrowser.findTag("videoAd:"); + if (killMe != null) { + killMe.close(); + } + + killMe = WebBrowser.findTag("zoom:"); + if (killMe != null) { + killMe.close(); + } + + killMe = WebBrowser.findTag("zoomLeft:"); + if (killMe != null) { + killMe.close(); + } + + killMe = WebBrowser.findTag("outside:"); + if (killMe != null) { + killMe.close(); + } + + try { + Thread.sleep(1L); + } catch (InterruptedException var4) { + } + + WavSoundPlayer.resumeSystem(); + CDAudio.get().setEnabled(true); + } + } + + @Override + public void terminalCallback() { + Main.unregister(this); + } +} diff --git a/NET/worlds/console/InventoryPart.java b/NET/worlds/console/InventoryPart.java new file mode 100644 index 0000000..a5e2997 --- /dev/null +++ b/NET/worlds/console/InventoryPart.java @@ -0,0 +1,30 @@ +package NET.worlds.console; + +import NET.worlds.scape.FrameEvent; +import java.awt.Container; +import java.awt.Event; +import java.awt.MenuItem; + +public class InventoryPart implements FramePart { + MenuItem inventoryItem; + + @Override + public void activate(Console c, Container f, Console prev) { + this.inventoryItem = c.addMenuItem(Console.message("Inventory") + "...", "File"); + } + + @Override + public void deactivate() { + this.inventoryItem = null; + } + + @Override + public boolean handle(FrameEvent f) { + return true; + } + + @Override + public boolean action(Event event, Object what) { + return false; + } +} diff --git a/NET/worlds/console/LanguageManager.java b/NET/worlds/console/LanguageManager.java new file mode 100644 index 0000000..c8fe072 --- /dev/null +++ b/NET/worlds/console/LanguageManager.java @@ -0,0 +1,163 @@ +package NET.worlds.console; + +import NET.worlds.core.Std; +import NET.worlds.network.ProgressDialog; +import NET.worlds.network.URL; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.Vector; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +public class LanguageManager implements Runnable { + private String m_Name; + private String m_FinishName; + private int m_fSize; + + public static void handle(String name, int fSize, String finishName) { + LanguageManager lm = new LanguageManager(name, fSize, finishName); + Thread t = new Thread(lm); + t.setDaemon(true); + t.start(); + } + + public LanguageManager(String name, int fSize, String finishName) { + this.m_Name = name; + this.m_fSize = fSize; + this.m_FinishName = finishName; + } + + @Override + public void run() { + String fName = this.m_Name.substring(this.m_Name.lastIndexOf(47) + 1, this.m_Name.length()); + Console.println(Console.message("Downloading-update") + fName); + Vector<String> names = new Vector<String>(); + names.addElement(fName); + Vector<URL> urls = new Vector<URL>(); + urls.addElement(URL.make(this.m_Name)); + int now = Std.getFastTime(); + ProgressDialog progD = new ProgressDialog(this.m_fSize); + + try { + System.out.println("ProgressDialog start, now = " + now); + System.out.println("fName = " + fName + ", name = " + this.m_Name); + if (!progD.loadFiles(names, urls)) { + System.out.println("Can't load " + fName); + return; + } + + now = Std.getFastTime(); + System.out.println("ProgressDialog end, now = " + now); + } catch (IOException var7) { + System.out.println("Exception " + var7.toString() + " loading file " + fName); + } + + this.finishDownload(this.m_FinishName); + } + + public synchronized boolean finishDownload(String localName) { + String fType = localName.substring(localName.lastIndexOf(46), localName.length()); + System.out.println("Finished Downloading " + localName); + if (fType.equals(".EXE")) { + if (tryToRun(localName)) { + System.out.println(Console.message("Loading2") + localName); + } else { + Console.println(Console.message("Loading2") + localName + " " + Console.message("failed")); + } + } else if (fType.equals(".zip")) { + ZipFile langZip; + try { + langZip = new ZipFile(localName); + } catch (IOException var12) { + System.out.println("Error opening language file " + localName); + this.notify(); + return false; + } + + System.out.println("Expanding language file."); + Enumeration<? extends ZipEntry> enums = langZip.entries(); + + while (enums.hasMoreElements()) { + ZipEntry ze = enums.nextElement(); + String filename = ze.getName(); + String langFile = filename; + String[] validExtensions = new String[]{".properties", ".jpg", ".bmp", ".gif"}; + boolean validFile = false; + + for (int idx = 0; idx < validExtensions.length; idx++) { + if (langFile.toString().endsWith(validExtensions[idx])) { + validFile = true; + break; + } + } + + if (validFile) { + this.CopyLangFile(langZip, ze, langFile); + System.out.println(langFile); + } + } + + try { + langZip.close(); + } catch (IOException var11) { + } + } + + this.notify(); + new OkCancelDialog(Console.getFrame(), null, Console.message("Alert"), null, Console.message("OK"), Console.message("Change-exit"), true); + return false; + } + + private void CopyLangFile(ZipFile langZip, ZipEntry ze, String langFile) { + InputStream is; + try { + is = langZip.getInputStream(ze); + } catch (IOException var11) { + return; + } + + FileOutputStream os; + try { + os = new FileOutputStream(langFile); + } catch (IOException var10) { + try { + is.close(); + } catch (IOException var8) { + } + + return; + } + + byte[] buffer = new byte[1024]; + + while (true) { + try { + int bytesRead = is.read(buffer); + if (bytesRead == -1) { + break; + } + + os.write(buffer, 0, bytesRead); + } catch (IOException var12) { + break; + } + } + + try { + is.close(); + os.close(); + } catch (IOException var9) { + } + } + + public static boolean tryToRun(String s) { + try { + Runtime.getRuntime().exec(s); + return true; + } catch (IOException var2) { + return false; + } + } +} diff --git a/NET/worlds/console/LocationDialog.java b/NET/worlds/console/LocationDialog.java new file mode 100644 index 0000000..468e544 --- /dev/null +++ b/NET/worlds/console/LocationDialog.java @@ -0,0 +1,94 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Color; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; + +public class LocationDialog extends PolledDialog { + private static final long serialVersionUID = -6550771504344935484L; + private Button okButton = new Button(Console.message("OK")); + private Button cancelButton = new Button(Console.message("Cancel")); + private Label label = new Label(Console.message("New-URL")); + private static Font font = new Font(Console.message("ButtonFont"), 0, 12); + private static Font gfont = new Font(Console.message("GammaTextFont"), 0, 12); + private TextField locationField; + + public LocationDialog(java.awt.Window parent, DialogReceiver receiver, String title, String location) { + super(parent, receiver, title, true); + this.locationField = new TextField(location, 40); + this.locationField.setFont(gfont); + this.ready(); + } + + public String getLocationURL() { + return this.locationField.getText(); + } + + @Override + protected void build() { + this.setBackground(Color.white); + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.weightx = 0.0; + c.weighty = 0.0; + c.gridheight = 1; + c.fill = 0; + c.anchor = 13; + c.gridwidth = 1; + this.label.setFont(font); + this.add(gbag, this.label, c); + c.weightx = 1.0; + c.weighty = 0.0; + c.gridwidth = 0; + c.fill = 2; + c.anchor = 17; + this.locationField.setFont(gfont); + this.add(gbag, this.locationField, c); + Panel buttons = new Panel(); + this.okButton.setFont(font); + this.cancelButton.setFont(font); + buttons.add(this.okButton); + buttons.add(this.cancelButton); + c.gridwidth = 0; + c.anchor = 10; + c.fill = 0; + this.add(gbag, buttons, c); + } + + @Override + public void show() { + super.show(); + this.locationField.requestFocus(); + } + + @Override + public boolean handleEvent(Event event) { + return event.id == 201 ? this.done(false) : super.handleEvent(event); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.cancelButton) { + return this.done(false); + } else { + return target == this.okButton ? this.done(true) : false; + } + } + + @Override + public boolean keyDown(Event event, int key) { + if (key == 27) { + return this.done(false); + } else { + return key == 10 ? this.done(true) : super.keyDown(event, key); + } + } +} diff --git a/NET/worlds/console/LogFile.java b/NET/worlds/console/LogFile.java new file mode 100644 index 0000000..54fa2d4 --- /dev/null +++ b/NET/worlds/console/LogFile.java @@ -0,0 +1,218 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.core.Std; +import NET.worlds.core.SystemInfo; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.text.DateFormat; +import java.util.Date; + +public class LogFile { + private static PrintStream out = null; + private static String baseName = null; + private static final String tempSuffix = ".open"; + private static final String mailSuffix = ".mail"; + private static final String noCloseTag = ", it terminated unexpectedly.\nPlease fill in the box below with an explanation of which\nfeatures you were exercising at the time, then click the\nReport button to automatically email the report to Worlds.\n"; + private static final String errorFoundTag = ", it generated a debugging log.\nPlease fill in the box below with an explanation of anything\nunusual that occurred (if anything), then click the Report\nbutton to automatically email the report to Worlds.\n"; + private static final String includeEmail = "Also, please include your email address.\n"; + private static String mailReason = "error encountered"; + private static String mailTag = ", it generated a debugging log.\nPlease fill in the box below with an explanation of anything\nunusual that occurred (if anything), then click the Report\nbutton to automatically email the report to Worlds.\n"; + private static final String iniFile = "worlds.ini"; + + public static void open() { + baseName = IniFile.gamma().getIniString("logfile", ""); + if (baseName.length() != 0) { + baseName = Gamma.earlyURLUnalias("home:" + baseName); + File f = new File(baseName + ".open"); + if (f.isFile()) { + if (scanFileForException(f)) { + mailReason = "logfile not closed--probable crash"; + mailTag = ", it terminated unexpectedly.\nPlease fill in the box below with an explanation of which\nfeatures you were exercising at the time, then click the\nReport button to automatically email the report to Worlds.\n"; + File mf = new File(baseName + ".mail"); + f.renameTo(mf); + mf = null; + } else { + f.delete(); + } + } + + f = new File(baseName); + if (f.isFile()) { + f.delete(); + } + + File var9 = null; + FileOutputStream FOout = null; + + try { + FOout = new FileOutputStream(baseName + ".open"); + } catch (IOException var6) { + System.out.println("Error opening logfile \"" + baseName + "\""); + return; + } + + out = new PrintStream(new BufferedOutputStream(FOout), true); + System.setOut(out); + System.setErr(out); + out.println("Logfile of " + DateFormat.getDateTimeInstance().format(new Date())); + out.println( + "Gamma " + + Std.getVersion() + + ":" + + "1890a40" + + ", build " + + Std.getBuildInfo() + + " of " + + DateFormat.getDateTimeInstance().format(new Date(Std.getBuildDate())) + ); + out.println("system info---------------------------------"); + SystemInfo.Record(out); + out.println("worlds.ini----------------------------------"); + + try { + String from = System.getProperty("file.encoding"); + InputStream in = new FileInputStream("worlds.ini"); + BufferedReader ini = new BufferedReader(new InputStreamReader(in, from)); + + for (String s = ini.readLine(); s != null; s = ini.readLine()) { + out.println(s); + } + + ini.close(); + } catch (IOException var7) { + } + + out.println("--------------------------------------------"); + } + } + + public static void close() { + if (out != null) { + out.println("Logfile closed."); + out.close(); + } + + File f = new File(baseName + ".open"); + if (scanFileForException(f)) { + File mf = new File(baseName + ".mail"); + f.renameTo(mf); + mf = null; + } else { + File nf = new File(baseName); + if (f.isFile()) { + f.renameTo(nf); + } + + nf = null; + } + + File var2 = null; + } + + public static void mailLogIfPresent(final String server) { + DialogReceiver rcvr = new DialogReceiver() { + @Override + public void dialogDone(Object who, boolean confirmed) { + LogMailDialog dlg = (LogMailDialog)who; + File f = new File(LogFile.baseName + ".mail"); + if (f.isFile()) { + if (confirmed) { + LogFile.sendCrashMail(server, f, LogFile.mailReason, dlg.getComment()); + } else { + f.delete(); + } + } + } + }; + File f = new File(baseName + ".mail"); + if (f.isFile()) { + String tag = "The last time you ran " + Std.getProductName() + mailTag; + if (IniFile.gamma().getIniString("LASTCHATNAME", "").length() == 0) { + new LogMailDialog(rcvr, tag + "Also, please include your email address.\n"); + } else { + new LogMailDialog(rcvr, tag); + } + } + } + + private static void sendCrashMail(String server, File logFile, String tagLine, String comment) { + MailMessage msg = new LogFileMailMessage(server, logFile); + + try { + if (tagLine != null) { + msg.appendBody(" (" + tagLine + ")"); + } + + msg.appendBody(".\n\n"); + if (comment != null) { + msg.appendBody("The user reports:\n"); + msg.appendParagraphs(comment); + msg.appendBody("\n\n"); + } + + msg.appendBody("The log file reads:\n\n"); + String from = System.getProperty("file.encoding"); + InputStream in = new FileInputStream(logFile); + BufferedReader log = new BufferedReader(new InputStreamReader(in, from)); + long fl = logFile.length(); + if (fl <= 64000L) { + for (String s = log.readLine(); s != null; s = log.readLine()) { + msg.appendBody(s + "\n"); + } + } else { + int lc = 0; + long cc = 0L; + + for (String s = log.readLine(); s != null && lc < 2048; s = log.readLine()) { + msg.appendBody(s + "\n"); + lc++; + cc += s.length(); + } + + msg.appendBody("-------------------------------------...\n"); + msg.appendBody(" Log file too long; skipping center\n"); + msg.appendBody("...-------------------------------------\n"); + log.skip(fl - (cc + 16030L)); + log.readLine(); + + for (String s = log.readLine(); s != null; s = log.readLine()) { + msg.appendBody(s + "\n"); + } + } + + log.close(); + } catch (IOException var14) { + System.out.println("Error writing logfile to mail note: " + var14); + } + + msg.send(); + } + + private static boolean scanFileForException(File logFile) { + try { + String from = System.getProperty("file.encoding"); + InputStream in = new FileInputStream(logFile); + BufferedReader log = new BufferedReader(new InputStreamReader(in, from)); + + for (String s = log.readLine(); s != null; s = log.readLine()) { + if (s.indexOf("\tat NET.worlds") != -1 || s.indexOf("\tat java.lang") != -1 || s.indexOf("\tat sun.awt") != -1) { + log.close(); + return true; + } + } + + log.close(); + } catch (IOException var5) { + } + + return false; + } +} diff --git a/NET/worlds/console/LogFileMailMessage.java b/NET/worlds/console/LogFileMailMessage.java new file mode 100644 index 0000000..af068bd --- /dev/null +++ b/NET/worlds/console/LogFileMailMessage.java @@ -0,0 +1,22 @@ +package NET.worlds.console; + +import java.io.File; + +class LogFileMailMessage extends MailMessage { + private static final String mailTo = "[email protected]"; + private File logFile; + + LogFileMailMessage(String server, File logFile) { + super(server, "[email protected]", "[email protected]", "Gamma Log: Abnormal Termination", "A Gamma log with potential errors has been detected"); + this.logFile = logFile; + } + + @Override + protected void finished(boolean wasError) { + if (!wasError) { + this.logFile.delete(); + } else { + Console.println(Console.message("Error-mailing")); + } + } +} diff --git a/NET/worlds/console/LogMailDialog.java b/NET/worlds/console/LogMailDialog.java new file mode 100644 index 0000000..add5948 --- /dev/null +++ b/NET/worlds/console/LogMailDialog.java @@ -0,0 +1,57 @@ +package NET.worlds.console; + +import java.awt.GridBagConstraints; +import java.awt.TextArea; + +class LogMailDialog extends OkCancelDialog { + private static final long serialVersionUID = -6276776216084519247L; + private TextArea commentArea; + private String tagString; + + public LogMailDialog(DialogReceiver rcvr, String tag) { + super(Console.getFrame(), rcvr, Console.message("Log-Mailer"), Console.message("Dont-Report"), Console.message("Report"), null, false); + this.tagString = tag; + this.commentArea = new TextArea("", 5, 60, 1); + this.commentArea.setEditable(true); + this.setConfirmKey(-1); + } + + @Override + protected void build() { + GridBagConstraints c = new GridBagConstraints(); + if (this.tagString != null) { + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 0; + this.add(this.gbag, new MultiLineLabel(this.tagString, 5, 5), c); + } + + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 0; + this.add(this.gbag, this.commentArea, c); + int count = 0; + if (this.okButton != null) { + count++; + } + + if (this.cancelButton != null) { + count++; + } + + c.gridwidth = count; + c.weightx = 1.0; + c.weighty = 0.0; + if (this.okButton != null) { + this.add(this.gbag, this.okButton, c); + } + + if (this.cancelButton != null) { + this.add(this.gbag, this.cancelButton, c); + } + } + + public String getComment() { + return this.commentArea.getText(); + } +} diff --git a/NET/worlds/console/LoginWizard.java b/NET/worlds/console/LoginWizard.java new file mode 100644 index 0000000..60d6f69 --- /dev/null +++ b/NET/worlds/console/LoginWizard.java @@ -0,0 +1,941 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.core.Std; +import NET.worlds.network.Cache; +import NET.worlds.network.CacheFile; +import NET.worlds.network.Galaxy; +import NET.worlds.network.NetworkObject; +import NET.worlds.network.RemoteFileConst; +import NET.worlds.network.URL; +import NET.worlds.scape.SendURLAction; +import java.awt.Button; +import java.awt.CardLayout; +import java.awt.Checkbox; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Enumeration; +import java.util.Random; +import java.util.Vector; + +public class LoginWizard extends PolledDialog implements DialogReceiver, DialogDisabled, RemoteFileConst { + private static final long serialVersionUID = -1951115972999605117L; + private static final int HAVE_USERS = 0; + private static final int ACCOUNT_TYPE = 1; + private static final int REGWAIT = 2; + private static final int WELCOME = 3; + private static final int CODEWORD_WAIT = 4; + private static final int NEW_USER_INFO = 5; + private static final int LOGGING_IN = 7; + private static final int NOT_LOGGED_IN = 8; + private static final int ERROR = 9; + private static final int CONNECTION_DIED = 10; + private static final int AUTO_LOGIN_FAILED = 11; + private static final int REGWAIT2 = 12; + private static final int BAD_PASSWORD = 13; + private static final int SCREEN_COUNT = 14; + private static final int STATE_GET_INFO = 0; + private static final int STATE_SEND_INFO = 1; + private static final int STATE_WAIT = 2; + private static final int STATE_AUTO_LOGIN = 3; + private static final int STATE_LOGGED_IN = 4; + private static final String defaultRegisterScriptL = "register" + Console.message(".pl"); + private static final String defaultRegisterScript = "register.pl"; + private static final String nameConstraints = Console.message("n-contain-letters"); + private static final String passwordConstraints1 = Console.message("p-contain-letters"); + private static final int oldMinPasswordLen = 4; + private static final int newMinPasswordLen = 6; + private static final String savePasswordText = Console.message("Remember-password"); + private static final String passwordMismatchText = Console.message("do-not-match"); + private static final String userNameIniKey = "User"; + private static final String passwordIniKey = "Password"; + private static final String serialNumIniKey = "SNum"; + private static final String handshakeIDIniKey = "handshakeID"; + private static final String defaultUserIniKey = "DefaultUser"; + static final int width = 480; + static final int height = 280; + static final int textWidth = 400; + private Galaxy galaxy; + private IniFile iniFile; + private CardLayout cardLayout = new CardLayout(); + private int currentScreen = -1; + private int lastScreen = -1; + private int loginFrom = -1; + private int errorFrom; + private Panel[] screens = new Panel[14]; + private boolean queryingServer; + private Button createNewUsernameButton; + private Button alternateBrowserButton; + private Button signInButton; + private Button noEmailButton; + private Button showRegButton; + private Button pwMailbackButtonKnown; + private Button typeUsername; + private TextField codewordField = null; + private TextField newUserName = null; + private TextField newPassword1 = null; + private TextField newPassword2 = null; + private TextField typedUsername = null; + private static Font font = new Font(Console.message("GammaTextFont"), 0, 12); + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + private TextField knownPassword = null; + private Checkbox savePassword = new Checkbox(savePasswordText, true); + private Vector<String> users = new Vector<String>(); + private Vector<String> passwords = new Vector<String>(); + private int defaultUser; + private String loginUserName; + private String loginPassword; + private String loginSerialNumber; + private String newSerialNumber; + private String newHandshakeID; + private int loginMode; + private int loginIndex = 0; + private int loginState; + private String errMsg; + private boolean isDialogDisabled; + private Component defComponent; + private int id; + private static boolean startUp = true; + private static boolean firstTimeDone; + private static int seq; + private CacheFile cf; + + public static boolean isFirstTimeDone() { + return firstTimeDone; + } + + public boolean safeToQueryServer() { + return this.queryingServer; + } + + public LoginWizard(Galaxy galaxy, IniFile iniFile) { + this(galaxy, iniFile, null); + } + + boolean isAnonServer() { + return this.galaxy.getGalaxyType() == 4 || this.galaxy.getGalaxyType() == 2; + } + + public LoginWizard(Galaxy galaxy, IniFile iniFile, String errMsg) { + super(Console.getFrame(), galaxy, "", false); + this.galaxy = galaxy; + this.iniFile = iniFile; + this.errMsg = errMsg; + this.id = seq++; + this.queryingServer = false; + int userNum = 0; + + while (true) { + String user = iniFile.getIniString("User" + userNum, ""); + if (user.length() == 0) { + this.defaultUser = iniFile.getIniInt("DefaultUser", 0); + this.newSerialNumber = iniFile.getIniString("SNum", ""); + if (this.newSerialNumber.length() == 0) { + this.newSerialNumber = null; + } + + this.newHandshakeID = iniFile.getIniString("handshakeID", ""); + if (this.newHandshakeID.length() == 0) { + this.newHandshakeID = null; + } + + this.setTitle(Console.message("Logging-in")); + this.setLayout(this.cardLayout); + this.loginState = 0; + if (errMsg != null) { + this.currentScreen = 10; + } else if (this.users.size() <= 0 && !this.isAnonServer() && IniFile.override().getIniInt("nocreateaccount", 0) != 1) { + this.setTitle(Console.message("Setting-Up-Acct")); + if (this.newSerialNumber == null) { + if (this.newHandshakeID == null) { + this.currentScreen = 1; + } else { + this.currentScreen = 12; + } + } else { + this.currentScreen = 5; + } + } else { + this.currentScreen = 0; + } + + startUp = false; + if (this.loginState != 3) { + this.disableParent(); + this.ready(); + } + + return; + } + + this.users.addElement(user); + this.passwords.addElement(Console.decode(iniFile.getIniString("Password" + userNum, ""))); + userNum++; + } + } + + public boolean waitingForConnection() { + return this.loginState == 3 || this.loginState == 2; + } + + public void setConnected() { + int oldState = this.loginState; + this.loginState = 4; + if (this.loginFrom != 0 || this.users.size() <= this.loginIndex) { + this.users.addElement(this.loginUserName); + this.passwords.addElement(null); + this.iniFile.setIniString("User" + this.loginIndex, this.loginUserName); + if (this.loginFrom == 5) { + this.iniFile.setIniString("SNum" + this.loginIndex, this.loginSerialNumber); + } + } + + boolean save = this.savePassword.getState(); + String pass = this.galaxy.getPassword(); + if (this.loginPassword != null + && pass != null + && (save != this.isPasswordSaved(this.loginIndex) || !pass.equals(this.passwords.elementAt(this.loginIndex)))) { + String val = save ? pass : null; + this.passwords.setElementAt(val, this.loginIndex); + this.iniFile.setIniString("Password" + this.loginIndex, Console.encode(val)); + } + + String name = this.galaxy.getChatname(); + String nameU = this.galaxy.getUsernameU(); + if (this.loginFrom != 5 && !name.equals(this.users.elementAt(this.loginIndex))) { + this.users.setElementAt(name, this.loginIndex); + this.iniFile.setIniString("User" + this.loginIndex, nameU); + } + + this.iniFile.setIniInt("DefaultUser", this.loginIndex); + this.defaultUser = this.loginIndex; + if (this.newSerialNumber != null) { + this.newHandshakeID = null; + this.newSerialNumber = null; + this.iniFile.setIniString("handshakeID", ""); + this.iniFile.setIniString("SNum", ""); + } + + if (this.loginFrom != 0) { + this.selectScreen(3); + } else if (oldState != 3) { + this.done(true); + } else { + assert Main.isMainThread(); + + this.galaxy.dialogDone(this, true); + firstTimeDone = true; + } + } + + public void loginError(String errMsg) { + this.removeScreen(8); + if (errMsg == null) { + errMsg = Console.message("Unknown-error"); + } + + this.errMsg = errMsg; + if (this.loginState == 3) { + this.currentScreen = 11; + this.disableParent(); + this.ready(); + } else { + if (this.loginFrom == -1) { + this.loginFrom = 0; + } + + this.selectScreen(8); + } + + this.loginState = 0; + } + + @Override + public void show() { + super.show(); + if (this.defComponent != null) { + this.defComponent.requestFocus(); + } + } + + @Override + public void dispose() { + super.dispose(); + } + + @Override + protected void activeCallback() { + if (this.loginState == 1) { + this.loginState = 2; + this.galaxy.setAuthInfo(this.loginUserName, null, this.loginPassword, null, this.loginSerialNumber, this.loginMode); + } + } + + @Override + protected void build() { + this.selectScreen(this.currentScreen); + } + + @Override + public Dimension size() { + return new Dimension(480, 280); + } + + private void selectScreen(int which) { + String name = "" + which; + if (this.screens[which] == null) { + this.add(name, this.screens[which] = this.buildScreen(which)); + } + + this.cardLayout.show(this, name); + if (this.lastScreen != which && this.lastScreen >= 0 && this.screens[this.lastScreen] != null) { + this.removeScreen(this.lastScreen); + } + + this.currentScreen = which; + this.lastScreen = which; + if (which == 2) { + new SendURLAction(this.getRegisterScriptName()).startBrowser(); + } else if (which == 4) { + new LoginWizard.AwaitCodeword(this.codewordField.getText()); + } + } + + private Panel buildScreen(int which) { + GridBagLayout gbag = new GridBagLayout(); + GridBagConstraints c = new GridBagConstraints(); + Panel p = new Panel(gbag); + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 0; + switch (which) { + case 0: + return this.buildKnownUsersScreen(p, gbag, c); + case 1: + return this.buildAccountTypeScreen(p, gbag, c); + case 2: + return this.buildRegWait(p, gbag, c); + case 3: + return this.buildWelcome(p, gbag, c); + case 4: + return this.buildCodewordWaitScreen(p, gbag, c); + case 5: + return this.buildNewUserInfoScreen(p, gbag, c); + case 6: + default: + return null; + case 7: + return this.buildLoggingInScreen(p, gbag, c); + case 8: + case 9: + case 10: + case 11: + return this.buildErrorScreen(p, gbag, c, which); + case 12: + return this.buildRegWait2(p, gbag, c); + } + } + + private void removeScreen(int screen) { + if (this.screens[screen] != null) { + this.remove(this.screens[screen]); + this.screens[screen] = null; + } + } + + private void selectErrorScreen(String msg) { + this.errMsg = msg; + this.errorFrom = this.currentScreen; + this.selectScreen(9); + } + + private Panel buildKnownUsersScreen(Panel p, GridBagLayout gbag, GridBagConstraints c) { + this.typedUsername = new TextField(16); + this.knownPassword = new TextField(12); + this.knownPassword.setEchoChar('*'); + Panel tmp = new Panel(); + String enterText = Console.message("one-username"); + if (this.isAnonServer()) { + enterText = Console.message("a-username"); + } + + TextCanvas text = new TextCanvas(enterText, 400); + tmp.add(text); + add(p, tmp, gbag, c); + if (this.createNewUsernameButton == null) { + this.createNewUsernameButton = new Button(Console.message("Create-Username")); + } + + if (this.pwMailbackButtonKnown == null) { + this.pwMailbackButtonKnown = new Button(Console.message("Remind-Me")); + } + + if (this.defaultUser < this.users.size()) { + String pass = this.passwords.elementAt(this.defaultUser); + boolean knowPassword = pass != null; + this.knownPassword.setText(knowPassword ? pass : ""); + this.savePassword.setState(knowPassword); + this.typedUsername.setText(this.users.elementAt(this.defaultUser)); + } + + tmp = new Panel(new GridLayout(2, 2)); + Label uName = new Label(Console.message("Username"), 1); + uName.setFont(font); + this.typedUsername.setFont(font); + this.knownPassword.setFont(font); + tmp.add(uName); + tmp.add(this.typedUsername); + if (this.isAnonServer()) { + this.knownPassword.setText(Console.message("anonymous")); + add(p, tmp, gbag, c); + } else { + Label pWord = new Label(Console.message("Password"), 1); + pWord.setFont(font); + tmp.add(pWord); + tmp.add(this.knownPassword); + add(p, tmp, gbag, c); + this.savePassword.setFont(font); + add(p, this.savePassword, gbag, c); + } + + tmp = new Panel(); + String help = Console.message("youve-upgraded"); + if (this.iniFile.getIniString("AutoLogin", "").equals("") && this.iniFile.getIniString("User1", "").equals("")) { + help = ""; + } + + String instr = Console.message("first-time-user" + help); + if (this.isAnonServer()) { + instr = help; + } + + text = new TextCanvas(instr, 400); + tmp.add(text); + add(p, tmp, gbag, c); + if (!this.isAnonServer() && IniFile.override().getIniInt("nocreateaccount", 0) != 1) { + this.addButtons( + p, + gbag, + this.users.size() > 0 ? Console.message("Cancel") : "<< " + Console.message("Back"), + this.createNewUsernameButton, + this.pwMailbackButtonKnown, + Console.message("Sign-In") + ); + } else { + this.addButtons(p, gbag, Console.message("Cancel"), null, null, Console.message("Sign-In")); + } + + if (this.knownPassword.getText().length() == 0) { + if (this.typedUsername.getText().length() == 0) { + this.defComponent = this.typedUsername; + } else { + this.defComponent = this.knownPassword; + } + } + + return p; + } + + private void validateKnownUserInfo() { + if (this.acceptLoginUserName(this.typedUsername.getText()) && this.acceptLoginPassword(this.knownPassword.getText(), this.loginUserName, 4)) { + this.loginSerialNumber = null; + this.loginMode = 2; + this.loginIndex = 0; + this.doLogin(); + } + } + + private Panel buildAccountTypeScreen(Panel p, GridBagLayout gbag, GridBagConstraints c) { + TextCanvas text = new TextCanvas(Console.message("first-time-user2"), 400); + add(p, text, gbag, c); + if (this.alternateBrowserButton == null) { + this.alternateBrowserButton = new Button(Console.message("Alt-Browser")); + } + + if (this.signInButton == null) { + this.signInButton = new Button(Console.message("Sign-In")); + } + + return this.addButtons(p, gbag, Console.message("Cancel"), this.signInButton, this.alternateBrowserButton, Console.message("Next")); + } + + private Panel buildRegWaitCommon(Panel p, GridBagLayout gbag, GridBagConstraints c, int which) { + String start = ""; + if (which == 0) { + start = Console.message("registration"); + } + + TextCanvas text = new TextCanvas(start + Console.message("completed"), 400); + add(p, text, gbag, c); + Panel tmp = new Panel(new GridLayout()); + Label code = new Label(Console.message("Codeword"), 1); + code.setFont(font); + tmp.add(code); + this.codewordField = new TextField(10); + if (this.newSerialNumber != null) { + this.codewordField.setText(this.newSerialNumber); + } + + this.codewordField.setFont(font); + tmp.add(this.codewordField); + add(p, tmp, gbag, c); + String browserSpecific = new String(); + if (WebBrowser.isDisabled()) { + if (which == 0) { + browserSpecific = browserSpecific + Console.message("manually-view"); + } else { + browserSpecific = browserSpecific + Console.message("just-view"); + } + + browserSpecific = browserSpecific + this.getRegisterScriptName(); + } else { + browserSpecific = browserSpecific + Console.message("click-Back"); + } + + if (this.users.size() == 0) { + String ifText = Console.message("within-20"); + if (which == 1) { + ifText = Console.message("Show-Reg-Form1"); + } + + text = new TextCanvas(new String(ifText + browserSpecific), 400); + add(p, text, gbag, c); + } else if (which == 1) { + text = new TextCanvas(Console.message("Show-Reg-Form1"), 400); + add(p, text, gbag, c); + } + + if (this.noEmailButton == null) { + this.noEmailButton = new Button(Console.message("Didnt-Get-Email")); + } + + if (this.showRegButton == null) { + this.showRegButton = new Button(Console.message("Show-Reg-Form3")); + } + + Button showReg = which == 0 ? null : this.showRegButton; + return this.addButtons(p, gbag, "<< " + Console.message("Back"), showReg, this.noEmailButton, Console.message("Next") + " >>"); + } + + private Panel buildRegWait(Panel p, GridBagLayout gbag, GridBagConstraints c) { + return this.buildRegWaitCommon(p, gbag, c, 0); + } + + private Panel buildRegWait2(Panel p, GridBagLayout gbag, GridBagConstraints c) { + return this.buildRegWaitCommon(p, gbag, c, 1); + } + + private Panel buildWelcome(Panel p, GridBagLayout gbag, GridBagConstraints c) { + add(p, new Label(""), gbag, c); + Object[] arguments = new Object[]{new String(Std.getProductName())}; + add(p, new Label(MessageFormat.format(Console.message("Youre-signed"), arguments), 1), gbag, c); + Panel tmp = new Panel(); + TextCanvas text = new TextCanvas(Console.message("Use-arrow-keys2"), 400); + tmp.add(text); + add(p, tmp, gbag, c); + add(p, new Label(""), gbag, c); + return this.addButtons(p, gbag, null, null, null, Console.message("Enter-Worlds")); + } + + private static boolean isMadeOf(String test, String set) { + char[] testChars = test.toCharArray(); + + for (int i = 0; i < testChars.length; i++) { + if (set.indexOf(testChars[i]) == -1) { + return false; + } + } + + return true; + } + + private Panel buildCodewordWaitScreen(Panel p, GridBagLayout gbag, GridBagConstraints c) { + TextCanvas text = new TextCanvas(Console.message("Checking-codeword"), 400); + add(p, text, gbag, c); + return this.addButtons(p, gbag, Console.message("Cancel"), null, null, null); + } + + private Panel buildNewUserInfoScreen(Panel p, GridBagLayout gbag, GridBagConstraints c) { + this.newUserName = new TextField(16); + this.newPassword1 = new TextField(12); + this.newPassword2 = new TextField(12); + Object[] arguments = new Object[]{new String(Std.getProductName())}; + TextCanvas text = new TextCanvas(MessageFormat.format(Console.message("Enter-username"), arguments), 400); + text.setFont(font); + add(p, text, gbag, c); + Panel tmp = new Panel(); + tmp.setFont(font); + tmp.add(new Label(Console.message("Type-username"))); + tmp.add(this.newUserName); + add(p, tmp, gbag, c); + text = new TextCanvas(Console.message("Enter-password"), 400); + add(p, text, gbag, c); + tmp = new Panel(new GridLayout(2, 2)); + tmp.setFont(font); + tmp.add(new Label(Console.message("Type-password"), 1)); + this.newPassword1.setEchoChar('*'); + tmp.add(this.newPassword1); + tmp.add(new Label(Console.message("Re-type-password"), 1)); + this.newPassword2.setEchoChar('*'); + tmp.add(this.newPassword2); + add(p, tmp, gbag, c); + add(p, this.savePassword, gbag, c); + return this.addButtons( + p, gbag, this.newHandshakeID == null ? Console.message("Finish-Later") : "<< " + Console.message("Back"), null, null, Console.message("Next") + " >>" + ); + } + + private void validateNewUserInfo() { + if (this.acceptLoginUserName(this.newUserName.getText()) && this.acceptLoginPassword(this.newPassword1.getText(), this.newUserName.getText(), 6)) { + if (!this.loginPassword.equals(this.newPassword2.getText())) { + this.selectErrorScreen(passwordMismatchText); + } else { + this.loginMode = 1; + this.loginSerialNumber = this.newSerialNumber; + this.loginIndex = 0; + this.doLogin(); + } + } + } + + private Panel buildLoggingInScreen(Panel p, GridBagLayout gbag, GridBagConstraints c) { + Label logging = new Label(Console.message("Logging-in-wait")); + logging.setFont(font); + add(p, logging, gbag, c); + return p; + } + + private Panel buildErrorScreen(Panel p, GridBagLayout gbag, GridBagConstraints c, int which) { + this.errMsg = this.errMsg.replace('\n', ' ').replace('\t', '\n'); + TextCanvas text = new TextCanvas(this.errMsg, 400); + this.errMsg = null; + add(p, text, gbag, c); + return this.addButtons(p, gbag, which != 9 && which != 8 ? Console.message("Continue") : "<< " + Console.message("Back"), null, null, null); + } + + private boolean acceptLoginPassword(String password, String username, int minLength) { + if (FriendsListPart.isValidUserName(password) && password.length() >= minLength) { + this.loginPassword = password; + return true; + } else { + Object[] arguments = new Object[]{new String("" + minLength)}; + String text = Console.message("password-not-valid") + MessageFormat.format(passwordConstraints1, arguments); + this.selectErrorScreen(text); + return false; + } + } + + private boolean acceptLoginUserName(String name) { + if (!FriendsListPart.isValidUserName(name)) { + this.selectErrorScreen(Console.message("username-not-valid") + nameConstraints + " - " + name); + return false; + } else { + this.loginUserName = name; + return true; + } + } + + private void doLogin() { + this.loginFrom = this.currentScreen; + this.selectScreen(7); + this.loginState = 1; + } + + private boolean isPasswordSaved(int user) { + return user < this.passwords.size() && this.passwords.elementAt(user) != null; + } + + private static void add(Container cont, Component comp, GridBagLayout gbag, GridBagConstraints c) { + gbag.setConstraints(comp, c); + cont.add(comp); + } + + private Panel addButtons(Panel p, GridBagLayout gbag, String prev, Button mid1, Button mid2, String next) { + Panel buttons = new Panel(); + buttons.setFont(bfont); + if (prev != null) { + buttons.add(new BackButton(prev)); + } + + if (mid1 != null) { + buttons.add(mid1); + } + + if (mid2 != null) { + buttons.add(mid2); + } + + if (next != null) { + buttons.add(this.defComponent = new ForwardButton(next)); + } + + GridBagConstraints c = new GridBagConstraints(); + c.anchor = 14; + add(p, buttons, gbag, c); + return p; + } + + private String getScriptServer() { + Enumeration<NetworkObject> e = this.galaxy.getConsoles(); + + assert e.hasMoreElements(); + + this.queryingServer = true; + String ret = ((Console)e.nextElement()).getScriptServer(); + this.queryingServer = false; + System.out.println("Scriptserver is " + ret); + return ret; + } + + private String getRegisterScriptName() { + if (this.newHandshakeID == null) { + int id = new Random(((long)Startup.getVolumeInfo() << 30) + (int)(Math.random() * 1.0737418E9F)).nextInt(); + if (id < 0) { + id = -id; + } + + this.newHandshakeID = "" + id; + this.iniFile.setIniString("handshakeID", this.newHandshakeID); + } + + IniFile ini = IniFile.override(); + String url = ini.getIniString("register", ""); + if (url.equals("")) { + url = defaultRegisterScriptL; + if (Console.wasHttpNoSuchFile(url)) { + url = "register.pl"; + } + + ini = new IniFile("InstalledWorlds"); + String w = ini.getIniString("InstalledWorld0", ""); + if (!w.equals("")) { + String fn = URL.make("home:" + w + "/register.txt").unalias(); + DataInputStream in = null; + + try { + in = new DataInputStream(new FileInputStream(fn)); + String line = in.readLine(); + if (line != null) { + url = line; + } + } catch (IOException var15) { + } finally { + try { + if (in != null) { + in.close(); + } + } catch (IOException var14) { + } + } + } + } + + return new String(this.getScriptServer() + url + "?id=" + this.newHandshakeID); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target instanceof ForwardButton) { + if (this.currentScreen == 0) { + this.validateKnownUserInfo(); + } else if (this.currentScreen == 1) { + WebBrowser.setDisabled(false); + this.selectScreen(2); + } else if (this.currentScreen == 2 || this.currentScreen == 12) { + this.selectScreen(4); + } else if (this.currentScreen == 5) { + this.validateNewUserInfo(); + } else if (this.currentScreen == 3) { + this.done(true); + } + } else if (target instanceof BackButton) { + if (this.currentScreen == 0) { + if (this.users.size() > 0) { + this.done(false); + } else { + this.selectScreen(1); + } + } else if (this.currentScreen == 1) { + if (this.users.size() == 0) { + this.done(false); + } else { + this.selectScreen(0); + } + } else if (this.currentScreen == 2 || this.currentScreen == 12) { + this.selectScreen(this.users.size() > 0 ? 0 : 1); + } else if (this.currentScreen == 5) { + if (this.newSerialNumber != null && this.newSerialNumber.length() > 6 && this.newHandshakeID != null) { + this.selectScreen(12); + } else if (this.users.size() > 0) { + this.selectScreen(0); + } else { + this.done(false); + } + } else if (this.currentScreen == 4) { + if (this.cf != null) { + this.cf.close(); + } + + this.selectScreen(12); + } else if (this.currentScreen == 8) { + this.selectScreen(this.loginFrom); + } else if (this.currentScreen == 9) { + this.selectScreen(this.errorFrom); + } else if (this.currentScreen == 11 || this.currentScreen == 10) { + this.selectScreen(0); + } + } else if (target == this.pwMailbackButtonKnown) { + new SendURLAction(this.getScriptServer() + "emailback.pl", true).startBrowser(); + } else if (target == this.typedUsername) { + this.knownPassword.requestFocus(); + } else if (target == this.knownPassword) { + this.validateKnownUserInfo(); + } else if (target == this.createNewUsernameButton) { + String redir = IniFile.override().getIniString("CreateUserRedirect", "Fred"); + if (redir.equals("Fred")) { + if (this.newHandshakeID != null) { + this.selectScreen(12); + } else if (this.newSerialNumber == null) { + this.selectScreen(2); + } else { + this.selectScreen(5); + } + } else { + new SendURLAction(URL.make(redir)).startBrowser(); + } + } else if (target == this.alternateBrowserButton) { + WebBrowser.setDisabled(true); + this.selectScreen(2); + } else if (target == this.signInButton) { + this.selectScreen(0); + } else { + if (target != this.noEmailButton && target != this.showRegButton) { + return false; + } + + this.selectScreen(2); + } + + return true; + } + + @Override + public boolean keyDown(Event event, int key) { + if (key == 10) { + this.action(event, null); + return true; + } else { + return super.keyDown(event, key); + } + } + + @Override + public boolean handleEvent(Event event) { + if (this.isDialogDisabled) { + return false; + } else { + return event.id == 201 && this.loginState == 2 ? true : super.handleEvent(event); + } + } + + @Override + protected boolean done(boolean confirmed) { + boolean ret = super.done(confirmed); + firstTimeDone = true; + return ret; + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + } + + @Override + public void dialogDisable(boolean disable) { + this.isDialogDisabled = disable; + super.dialogDisable(disable); + } + + @Override + public String toString() { + return "LoginWizard" + this.id; + } + + class AwaitCodeword extends Thread { + public AwaitCodeword(String cw) { + if (cw.length() > 6) { + LoginWizard.this.selectScreen(5); + LoginWizard.this.newSerialNumber = cw; + LoginWizard.this.iniFile.setIniString("SNum", LoginWizard.this.newSerialNumber); + } else { + LoginWizard.this.cf = Cache.getFile( + URL.make(LoginWizard.this.getScriptServer() + "codeword.pl?id=" + LoginWizard.this.newHandshakeID + "&codeword=" + cw) + ); + this.setDaemon(true); + this.start(); + } + } + + @Override + public void run() { + LoginWizard.this.cf.waitUntilLoaded(); + if (LoginWizard.this.cf.isActive()) { + if (LoginWizard.this.cf.error()) { + LoginWizard.this.currentScreen = 12; + LoginWizard.this.selectErrorScreen(Console.message("Error-accessing")); + } else { + DataInputStream in = null; + + label114: { + try { + in = new DataInputStream(new FileInputStream(LoginWizard.this.cf.getLocalName())); + String line = in.readLine(); + if (!line.startsWith("1,0,") && !line.startsWith("1,1,")) { + break label114; + } + + LoginWizard.this.newSerialNumber = line.substring(4); + LoginWizard.this.iniFile.setIniString("SNum", LoginWizard.this.newSerialNumber); + LoginWizard.this.newHandshakeID = null; + LoginWizard.this.iniFile.setIniString("handshakeID", ""); + LoginWizard.this.selectScreen(5); + LoginWizard.this.cf.close(); + } catch (FileNotFoundException var14) { + break label114; + } catch (IOException var15) { + break label114; + } finally { + try { + if (in != null) { + in.close(); + } + } catch (IOException var13) { + } + } + + return; + } + + LoginWizard.this.currentScreen = 12; + LoginWizard.this.selectErrorScreen(Console.message("codeword-no-match")); + } + + LoginWizard.this.cf.close(); + } + } + } +} diff --git a/NET/worlds/console/MailDialog.java b/NET/worlds/console/MailDialog.java new file mode 100644 index 0000000..95b976b --- /dev/null +++ b/NET/worlds/console/MailDialog.java @@ -0,0 +1,107 @@ +package NET.worlds.console; + +import java.awt.Component; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.TextArea; +import java.awt.TextField; +import java.util.StringTokenizer; + +class MailDialog extends OkCancelDialog { + private static final long serialVersionUID = -5118823076163262543L; + private TextField recipientField; + private TextField subjectField; + private TextArea bodyTextArea; + private static Font font = new Font(Console.message("ConsoleFont"), 0, 12); + + public MailDialog(Console console) { + super(Console.getFrame(), new MailDialogReceiver(console), Console.message("Mail"), Console.message("Dont-Send"), Console.message("Send"), null, false); + this.setConfirmKey(0); + this.recipientField = new TextField(); + this.recipientField.setFont(font); + this.subjectField = new TextField(); + this.subjectField.setFont(font); + this.bodyTextArea = new TextArea("", 5, 50, 1); + this.bodyTextArea.setEditable(true); + this.bodyTextArea.setFont(font); + this.setAlignment(1); + } + + public MailDialog(Console console, String recipient) { + this(console); + this.recipientField.setText(Console.parseExtended(recipient)); + this.recipientField.setFont(font); + } + + @Override + protected void build() { + GridBagConstraints c = new GridBagConstraints(); + int line = 0; + c.fill = 0; + c.anchor = 13; + this.add(this.gbag, new Label(Console.message("To")), c, 0, line, 1, 1, 0, 0); + c.fill = 2; + c.anchor = 17; + this.add(this.gbag, this.recipientField, c, 1, line, 3, 1, 100, 0); + line++; + c.fill = 0; + c.anchor = 13; + Label subjectLabel = new Label(Console.message("Subject")); + subjectLabel.setFont(font); + this.add(this.gbag, subjectLabel, c, 0, line, 1, 1, 0, 0); + c.fill = 2; + c.anchor = 17; + this.add(this.gbag, this.subjectField, c, 1, line, 3, 1, 100, 0); + line++; + c.anchor = 10; + c.fill = 1; + this.add(this.gbag, this.bodyTextArea, c, 0, line, 4, 1, 100, 100); + line++; + c.fill = 0; + if (this.okButton != null) { + this.okButton.setFont(font); + this.add(this.gbag, this.okButton, c, 1, line, 1, 1, 100, 0); + } + + if (this.cancelButton != null) { + this.cancelButton.setFont(font); + this.add(this.gbag, this.cancelButton, c, 2, line, 1, 1, 100, 0); + } + } + + private void add(GridBagLayout gbag, Component comp, GridBagConstraints cont, int x, int y, int w, int h, int wx, int wy) { + cont.gridx = x; + cont.gridy = y; + cont.gridwidth = w; + cont.gridheight = h; + cont.weightx = wx; + cont.weighty = wy; + this.add(gbag, comp, cont); + } + + public String[] getTo() { + Console console = Console.getActive(); + String toLine = this.recipientField.getText(); + StringTokenizer tokenizer = new StringTokenizer(toLine, ","); + String[] to = new String[tokenizer.countTokens()]; + + for (int i = 0; tokenizer.hasMoreTokens(); i++) { + to[i] = tokenizer.nextToken().trim(); + if (to[i].indexOf("@") == -1 && console != null) { + to[i] = to[i] + "@" + console.getMailDomain(); + } + } + + return to; + } + + public String getSubject() { + return this.subjectField.getText(); + } + + public String getBody() { + return this.bodyTextArea.getText(); + } +} diff --git a/NET/worlds/console/MailDialogReceiver.java b/NET/worlds/console/MailDialogReceiver.java new file mode 100644 index 0000000..4a403b1 --- /dev/null +++ b/NET/worlds/console/MailDialogReceiver.java @@ -0,0 +1,35 @@ +package NET.worlds.console; + +import java.awt.Font; + +class MailDialogReceiver implements DialogReceiver { + Console console; + private static Font font = new Font(Console.message("ConsoleFont"), 0, 12); + + public MailDialogReceiver(Console console) { + this.console = console; + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + MailDialog dlg = (MailDialog)who; + dlg.setFont(font); + if (confirmed) { + String[] to = dlg.getTo(); + if (to.length > 0) { + MailMessage msg = new MailMessage( + this.console.getSmtpServer(), this.console.getLongID() + "@" + this.console.getMailDomain(), to[0], dlg.getSubject(), null + ); + + for (int i = 1; i < to.length; i++) { + msg.addCC(to[i]); + } + + msg.appendParagraphs(dlg.getBody()); + msg.send(); + } else { + Console.println(Console.message("No-recipient")); + } + } + } +} diff --git a/NET/worlds/console/MailMessage.java b/NET/worlds/console/MailMessage.java new file mode 100644 index 0000000..fbc5828 --- /dev/null +++ b/NET/worlds/console/MailMessage.java @@ -0,0 +1,297 @@ +package NET.worlds.console; + +import NET.worlds.network.DNSLookup; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.net.Socket; +import java.util.Enumeration; +import java.util.Vector; + +public class MailMessage extends Thread { + private String server; + private String from; + private String to; + private Vector<String> cc; + private String subject; + private Vector<String> body; + private boolean lock = false; + + public MailMessage(String server) { + this(server, null, null, null, null); + } + + public MailMessage(String server, String from, String to) { + this(server, from, to, null, null); + } + + public MailMessage(String server, String from, String to, String subject, String body) { + this.server = server; + this.from = from; + this.to = to; + this.cc = new Vector<String>(); + this.subject = subject; + this.body = new Vector<String>(); + if (body != null) { + this.body.addElement(body); + } + } + + public void setFrom(String f) { + if (!this.locked()) { + this.from = f; + } + } + + public void setTo(String t) { + if (!this.locked()) { + this.to = t; + } + } + + public void addCC(String c) { + if (!this.locked()) { + this.cc.addElement(c); + } + } + + public void setSubject(String s) { + if (!this.locked()) { + this.subject = s; + } + } + + public void setBody(String b) { + if (!this.locked()) { + this.body = new Vector<String>(); + this.body.addElement(b); + } + } + + public void appendBody(String b) { + if (!this.locked()) { + this.body.addElement(b); + } + } + + public void appendParagraphs(String text, String sepStr, int lineLen) { + if (!this.locked()) { + String b = ""; + String white = ""; + String word = ""; + boolean startParagraph = false; + int len = 0; + + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + if (word.length() > 0 && Character.isWhitespace(c)) { + len += white.length() + word.length(); + if (len > lineLen) { + b = b + sepStr; + len = word.length(); + } else { + b = b + white; + } + + b = b + word; + word = ""; + white = ""; + } + + if (c != '\n' && c != '\r') { + startParagraph = false; + if (Character.isWhitespace(c)) { + white = white + c; + } else { + word = word + c; + } + } else if (!startParagraph) { + len = 0; + b = b + sepStr; + b = b + sepStr; + startParagraph = true; + } + } + + if (word.length() > 0) { + b = b + white; + b = b + word; + } + + this.body.addElement(b); + } + } + + public void appendParagraphs(String text) { + this.appendParagraphs(text, "\n", 70); + } + + private synchronized void lockMessage() { + this.lock = true; + } + + private synchronized void unlockMessage() { + this.lock = false; + } + + private synchronized boolean locked() { + return this.lock; + } + + protected void finished(boolean wasError) { + } + + public void send() { + this.start(); + } + + @Override + public void run() { + this.lockMessage(); + this.from = Console.parseUnicode(this.from); + this.to = Console.parseUnicode(this.to); + this.cc = Console.parseUnicode(this.cc); + this.subject = Console.parseUnicode(this.subject); + this.body = Console.parseUnicode(this.body); + boolean wasError = !sendNote(this.server, this.from, this.to, this.cc, this.subject, this.body); + this.unlockMessage(); + this.finished(wasError); + } + + public static synchronized boolean sendNote(String server, String from, String to, Vector<String> cc, String subject, Vector<String> body) { + int port = 25; + int cindex = server.indexOf(58); + if (cindex != -1) { + port = Integer.parseInt(server.substring(cindex + 1)); + server = server.substring(0, cindex); + } + + Socket smtpSocket = null; + + label123: { + try { + smtpSocket = new Socket(DNSLookup.lookup(server), port); + InputStream smtpIn = smtpSocket.getInputStream(); + PrintWriter smtpOut = new PrintWriter(smtpSocket.getOutputStream()); + if (getReply(smtpIn) + && print(smtpOut, "HELO worlds.net\r\n") + && getReply(smtpIn) + && print(smtpOut, "MAIL FROM:<" + from + ">\r\n") + && getReply(smtpIn) + && print(smtpOut, "RCPT TO:<" + to + ">\r\n") + && getReply(smtpIn) + && printCCcmd(smtpOut, smtpIn, cc) + && print(smtpOut, "DATA\r\n") + && getReply(smtpIn) + && print(smtpOut, "MIME-Version: 1.0\r\n") + && print(smtpOut, "MContent-Type: text/plain; charset=\"us-ascii\"\r\n") + && print(smtpOut, "From: " + from + "\r\n") + && print(smtpOut, "To: " + to + "\r\n") + && printCCline(smtpOut, cc) + && print(smtpOut, "Subject: " + subject + "\r\n\r\n") + && print(smtpOut, body) + && print(smtpOut, "\r\n.\r\n")) { + getReply(smtpIn); + } + break label123; + } catch (IOException var19) { + System.out.println("Error communicating with mail server: " + var19); + } finally { + try { + if (smtpSocket != null) { + smtpSocket.close(); + } + } catch (IOException var18) { + } + } + + return false; + } + + System.out.println("MailMessage.sendNote: complete."); + return true; + } + + private static boolean print(PrintWriter out, String text) { + out.print(text); + return !out.checkError(); + } + + private static boolean print(PrintWriter out, Vector<String> text) { + int size = text.size(); + + for (int i = 0; i < size; i++) { + out.print(text.elementAt(i)); + if (out.checkError()) { + return false; + } + } + + return true; + } + + private static boolean printCCcmd(PrintWriter out, InputStream in, Vector<String> cc) { + if (cc.size() > 0) { + Enumeration<String> en = cc.elements(); + + while (en.hasMoreElements()) { + String rcp = en.nextElement(); + if (!print(out, "RCPT TO:<" + rcp + ">\r\n")) { + return false; + } + + if (!getReply(in)) { + return false; + } + } + } + + return true; + } + + private static boolean printCCline(PrintWriter out, Vector<String> cc) { + int num = cc.size(); + if (num > 0) { + if (!print(out, "cc: ")) { + return false; + } + + Enumeration<String> en = cc.elements(); + + while (en.hasMoreElements()) { + String rcp = en.nextElement(); + if (num-- > 1) { + rcp = rcp + ", "; + } + + if (!print(out, rcp)) { + return false; + } + } + + if (!print(out, "\r\n")) { + return false; + } + } + + return true; + } + + private static boolean getReply(InputStream in) { + try { + int result; + while ((result = in.read()) >= 0 && result != 10) { + } + + return true; + } catch (IOException var2) { + return false; + } + } + + public static void main(String[] args) { + Vector<String> body = new Vector<String>(); + body.addElement("Looks like it worked...\n"); + sendNote("www.3dcd.com:25", "Gamma Mail Service", "[email protected]", new Vector<String>(), "this is a test", body); + } +} diff --git a/NET/worlds/console/Main.java b/NET/worlds/console/Main.java new file mode 100644 index 0000000..49f89bd --- /dev/null +++ b/NET/worlds/console/Main.java @@ -0,0 +1,93 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.core.Std; +import java.util.Vector; + +public class Main { + public static int profile = IniFile.gamma().getIniInt("Profile", 0); + private static Thread mainThread; + private static boolean stopFlag = false; + private static Vector<MainCallback> v = new Vector<MainCallback>(); + private static int lastAt = -1; + + private Main() { + } + + public static void mainLoop() { + for (mainThread = Thread.currentThread(); !stopFlag; Thread.yield()) { + MainCallback cb = getNextCallback(); + if (cb != null) { + if (profile != 0) { + int start = Std.getRealTime(); + long startBytes = Runtime.getRuntime().freeMemory(); + cb.mainCallback(); + int dur = Std.getRealTime() - start; + long used = startBytes - Runtime.getRuntime().freeMemory(); + if (dur > profile && !(cb instanceof Console)) { + System.out.println("Took " + dur + "ms and " + used + " bytes to call mainCallback " + cb); + } + } else { + cb.mainCallback(); + } + } + } + + MainCallback cb; + while ((cb = getNextCallback()) != null) { + if (cb instanceof MainTerminalCallback) { + ((MainTerminalCallback)cb).terminalCallback(); + Thread.yield(); + } else { + unregister(cb); + } + } + + mainThread = null; + } + + public static void end() { + stopFlag = true; + } + + public static boolean isMainThread() { + return Thread.currentThread() == mainThread; + } + + public static int queueLength() { + return v.size(); + } + + private static MainCallback getNextCallback() { + synchronized (v) { + int n = v.size(); + MainCallback cb; + if (n == 0) { + lastAt = -1; + cb = null; + } else { + if (++lastAt >= n) { + lastAt = 0; + } + + cb = v.elementAt(lastAt); + } + + return cb; + } + } + + public static void register(MainCallback x) { + v.addElement(x); + } + + public static void unregister(MainCallback x) { + synchronized (v) { + int i = v.indexOf(x); + v.removeElementAt(i); + if (lastAt >= i) { + lastAt--; + } + } + } +} diff --git a/NET/worlds/console/MainCallback.java b/NET/worlds/console/MainCallback.java new file mode 100644 index 0000000..37deb6d --- /dev/null +++ b/NET/worlds/console/MainCallback.java @@ -0,0 +1,5 @@ +package NET.worlds.console; + +public interface MainCallback { + void mainCallback(); +} diff --git a/NET/worlds/console/MainTerminalCallback.java b/NET/worlds/console/MainTerminalCallback.java new file mode 100644 index 0000000..fc07fa9 --- /dev/null +++ b/NET/worlds/console/MainTerminalCallback.java @@ -0,0 +1,5 @@ +package NET.worlds.console; + +public interface MainTerminalCallback { + void terminalCallback(); +} diff --git a/NET/worlds/console/MapFrame.java b/NET/worlds/console/MapFrame.java new file mode 100644 index 0000000..184afce --- /dev/null +++ b/NET/worlds/console/MapFrame.java @@ -0,0 +1,19 @@ +package NET.worlds.console; + +import java.awt.FlowLayout; +import java.awt.Frame; + +public class MapFrame extends Frame { + private static final long serialVersionUID = 1756423575260176209L; + MapTile mp; + + public MapFrame() { + super(Console.message("Map-Tile")); + this.setLayout(new FlowLayout()); + this.mp = new MapTile(); + this.add(this.mp); + this.resize(325, 300); + this.validate(); + this.show(); + } +} diff --git a/NET/worlds/console/MapPart.java b/NET/worlds/console/MapPart.java new file mode 100644 index 0000000..76188fe --- /dev/null +++ b/NET/worlds/console/MapPart.java @@ -0,0 +1,234 @@ +package NET.worlds.console; + +import NET.worlds.network.URL; +import NET.worlds.scape.BGLoaded; +import NET.worlds.scape.BackgroundLoader; +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Room; +import NET.worlds.scape.SendURLAction; +import NET.worlds.scape.TeleportAction; +import NET.worlds.scape.World; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.StringTokenizer; + +public class MapPart extends ImageButtons implements FramePart, ImageButtonsCallback, BGLoaded { + private static final long serialVersionUID = 1886153221201046188L; + private static final int width = 158; + private static final int height = 124; + private URL lastURL; + private URL mapURL; + private URL infURL; + private int filesLoaded; + private Rectangle[] hotspots; + private String[] names; + private String[] locations; + private int cursedButton; + private DefaultConsole console; + + public MapPart() { + this.setHandler(this); + this.setBackground(true); + this.setWidth(158); + this.setHeight(124); + } + + private synchronized void changeURL(URL url) { + this.lastURL = url; + String path = url.getAbsolute(); + path = path.substring(0, path.lastIndexOf(46)); + this.filesLoaded = 0; + this.setHotspots(new Rectangle[0]); + this.console.exploreButton.setVisible(true); + this.console.relayoutMap(); + this.locations = null; + this.repaint(); + BackgroundLoader.get(this, this.mapURL = URL.make(path + "-map.gif"), true); + BackgroundLoader.get(this, this.infURL = URL.make(path + "-map.inf"), true); + } + + private boolean readInfo(String localName) { + DataInputStream in = null; + + try { + in = new DataInputStream(new FileInputStream(localName)); + + String line; + for (int item = -1; (line = in.readLine()) != null; item++) { + line = line.trim(); + if (item == -1) { + int count = Integer.parseInt(line); + this.hotspots = new Rectangle[count]; + this.names = new String[count]; + this.locations = new String[count]; + } else { + StringTokenizer tok = new StringTokenizer(line); + this.hotspots[item] = new Rectangle( + Integer.parseInt(tok.nextToken()), Integer.parseInt(tok.nextToken()), Integer.parseInt(tok.nextToken()), Integer.parseInt(tok.nextToken()) + ); + this.names[item] = tok.nextToken().replace('_', ' '); + this.locations[item] = tok.nextToken(); + + while (tok.hasMoreTokens()) { + this.locations[item] = this.locations[item] + " " + tok.nextToken(); + } + } + } + + return true; + } catch (Exception var14) { + } finally { + try { + if (in != null) { + in.close(); + } + } catch (IOException var13) { + } + } + + return false; + } + + private int hasLink(String name) { + if (this.locations != null) { + for (int i = 0; i < this.locations.length; i++) { + if (name.equals(this.locations[i])) { + return i; + } + } + } + + return -1; + } + + @Override + public synchronized void paint(Graphics g) { + if (this.filesLoaded == 2) { + super.paint(g); + } + } + + @Override + public synchronized boolean handleEvent(Event event) { + return super.handleEvent(event); + } + + @Override + public Dimension preferredSize() { + return new Dimension(158, 124); + } + + @Override + protected Graphics drawButton(Graphics g, int button, int state) { + Graphics ret = super.drawButton(g, button, state); + if (state == 2 || state == 3) { + this.cursedButton = button; + if (button != -1 && this.console != null) { + this.console.overrideStatusMsg(this.names[button]); + } + } else if (state == 1 && button == this.cursedButton) { + this.cursedButton = -1; + if (this.console != null) { + this.console.overrideStatusMsg(null); + } + } + + return ret; + } + + @Override + public synchronized Object imageButtonsCallback(Component who, int which) { + String loc = this.locations[which]; + if (loc.startsWith("pnm:")) { + new SendURLAction(loc).startBrowser(); + return null; + } else if (loc.equals("system:universe")) { + this.console.toggleUniverseMode(); + return null; + } else { + if (loc.charAt(0) == '-') { + loc = loc.substring(1); + } else { + loc = this.lastURL.getAbsolute() + "#" + loc; + } + + TeleportAction.teleport(loc, null); + return null; + } + } + + @Override + public void activate(Console c, Container f, Console prev) { + this.console = (DefaultConsole)c; + } + + @Override + public void deactivate() { + } + + @Override + public synchronized boolean handle(FrameEvent f) { + Pilot pilot = Pilot.getActive(); + if (pilot != null) { + World world = pilot.getWorld(); + if (world != null) { + URL sourceURL = world.getSourceURL(); + if (sourceURL != this.lastURL && sourceURL != null) { + this.changeURL(sourceURL); + } + } + } + + return true; + } + + @Override + public Object asyncBackgroundLoad(String localName, URL remoteURL) { + boolean success = false; + if (localName != null) { + if (remoteURL == this.mapURL) { + this.image_ = loadImage(URL.make(localName), this); + success = this.image_ != null; + if (success) { + this.setWidth(this.image_.getWidth(null) / 4); + this.setHeight(this.image_.getHeight(null)); + } + } else { + success = this.readInfo(localName); + if (this.hasLink("system:universe") >= 0) { + this.console.exploreButton.hide(); + this.console.relayoutMap(); + } + } + } + + if (success) { + synchronized (this) { + if (++this.filesLoaded == 2) { + this.setHotspots(this.hotspots); + this.repaint(); + } + } + } + + return null; + } + + @Override + public boolean syncBackgroundLoad(Object obj, URL remoteURL) { + return false; + } + + @Override + public Room getBackgroundLoadRoom() { + return null; + } +} diff --git a/NET/worlds/console/MapTile.java b/NET/worlds/console/MapTile.java new file mode 100644 index 0000000..672f893 --- /dev/null +++ b/NET/worlds/console/MapTile.java @@ -0,0 +1,7 @@ +package NET.worlds.console; + +import java.awt.Canvas; + +public class MapTile extends Canvas { + private static final long serialVersionUID = -7698366766402434599L; +} diff --git a/NET/worlds/console/MoreFriendsDialog.java b/NET/worlds/console/MoreFriendsDialog.java new file mode 100644 index 0000000..29c7f01 --- /dev/null +++ b/NET/worlds/console/MoreFriendsDialog.java @@ -0,0 +1,159 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.List; +import java.awt.Menu; +import java.awt.MenuItem; +import java.util.Vector; + +class MoreFriendsDialog extends PolledDialog { + private static final long serialVersionUID = -2543183536371825585L; + private List listbox = new List(10); + private Button cancelButton = new Button(Console.message("Close")); + private FriendsListPart friends; + private Menu menu; + private Vector<Button> buttons = new Vector<Button>(); + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + private Object listMutex = new Object(); + + MoreFriendsDialog(FriendsListPart friends, Menu menu, Vector<String> online) { + super(Console.getFrame(), friends, Console.message("Friends-Online"), false); + this.setAlignment(1); + this.friends = friends; + this.menu = menu; + + for (int i = 0; i < online.size(); i++) { + this.listbox.add(online.elementAt(i)); + } + + this.ready(); + } + + @Override + protected void build() { + int buttonCount = this.menu.getItemCount(); + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.fill = 1; + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 2; + c.gridheight = buttonCount + 1; + this.listbox.setFont(font); + this.add(gbag, this.listbox, c); + c.weightx = 0.0; + c.weighty = 0.0; + c.gridwidth = 0; + c.gridheight = 1; + c.fill = 2; + + for (int i = 0; i < buttonCount; i++) { + String item = this.menu.getItem(i).getLabel(); + Button button = new Button(item); + button.setFont(bfont); + this.buttons.addElement(button); + this.add(gbag, button, c); + } + + c.weighty = 1.0; + c.anchor = 15; + this.cancelButton.setFont(bfont); + this.add(gbag, this.cancelButton, c); + } + + void addName(String name) { + synchronized (this.listMutex) { + this.listbox.add(name); + if (this.listbox.getItemCount() == 1) { + this.listbox.select(0); + this.select(true); + } + } + } + + void removeName(int index) { + synchronized (this.listMutex) { + int selIndex = this.listbox.getSelectedIndex(); + this.listbox.remove(index); + if (selIndex == index) { + int count = this.listbox.getItemCount(); + if (index < count - 1) { + this.listbox.select(index); + } else if (count > 0) { + this.listbox.select(count - 1); + } else { + this.select(false); + this.listbox.requestFocus(); + } + } + } + } + + private void select(boolean state) { + for (int i = 0; i < this.buttons.size(); i++) { + Button button = this.buttons.elementAt(i); + button.setEnabled(state); + } + } + + @Override + public void show() { + super.show(); + synchronized (this.listMutex) { + if (this.listbox.getItemCount() != 0) { + this.listbox.select(0); + this.select(true); + } else { + this.select(false); + } + } + + this.listbox.requestFocus(); + } + + @Override + public boolean handleEvent(Event event) { + if (event.id == 701) { + this.select(true); + } else if (event.id == 702) { + this.select(false); + } + + return super.handleEvent(event); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.cancelButton) { + return this.done(false); + } else { + int index = this.buttons.indexOf(target); + if (index != -1) { + MenuItem function = this.menu.getItem(index); + String selectedFriend; + synchronized (this.listMutex) { + selectedFriend = this.listbox.getSelectedItem(); + } + + if (selectedFriend != null) { + this.friends.moreFriendsAction(selectedFriend, function); + return true; + } + } + + return false; + } + } + + @Override + public boolean keyDown(Event event, int key) { + return key != 27 && key != 10 ? super.keyDown(event, key) : this.done(false); + } +} diff --git a/NET/worlds/console/MoveablePolygon.java b/NET/worlds/console/MoveablePolygon.java new file mode 100644 index 0000000..7607a4f --- /dev/null +++ b/NET/worlds/console/MoveablePolygon.java @@ -0,0 +1,58 @@ +package NET.worlds.console; + +import java.awt.Graphics; +import java.awt.Polygon; +import java.awt.Rectangle; + +class MoveablePolygon extends Polygon { + private static final long serialVersionUID = 8800634603983512717L; + private int xOffset; + private int yOffset; + private Rectangle boundingBox = new Rectangle(); + + public MoveablePolygon() { + } + + public MoveablePolygon(int[] xpoints, int[] ypoints) { + super(xpoints, ypoints, xpoints.length); + } + + public void moveTo(int x, int y) { + if (x != this.xOffset || y != this.yOffset) { + int xdelta = x - this.xOffset; + int ydelta = y - this.yOffset; + this.xOffset = x; + this.yOffset = y; + + for (int i = 0; i < this.npoints; i++) { + this.xpoints[i] = this.xpoints[i] + xdelta; + this.ypoints[i] = this.ypoints[i] + ydelta; + } + } + } + + public void drawFilled(Graphics g, int x, int y) { + this.moveTo(x, y); + g.fillPolygon(this); + } + + @Override + public Rectangle getBoundingBox() { + int boundsMinX = Integer.MAX_VALUE; + int boundsMinY = Integer.MAX_VALUE; + int boundsMaxX = Integer.MIN_VALUE; + int boundsMaxY = Integer.MIN_VALUE; + + for (int i = 0; i < this.npoints; i++) { + int x = this.xpoints[i]; + boundsMinX = Math.min(boundsMinX, x); + boundsMaxX = Math.max(boundsMaxX, x); + int y = this.ypoints[i]; + boundsMinY = Math.min(boundsMinY, y); + boundsMaxY = Math.max(boundsMaxY, y); + } + + this.boundingBox.reshape(boundsMinX, boundsMinY, boundsMaxX - boundsMinX, boundsMaxY - boundsMinY); + return this.boundingBox; + } +} diff --git a/NET/worlds/console/MultiLineLabel.java b/NET/worlds/console/MultiLineLabel.java new file mode 100644 index 0000000..b3443e8 --- /dev/null +++ b/NET/worlds/console/MultiLineLabel.java @@ -0,0 +1,179 @@ +package NET.worlds.console; + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.util.StringTokenizer; + +public class MultiLineLabel extends Canvas { + private static final long serialVersionUID = -3840151921412552795L; + public static final int LEFT = 0; + public static final int CENTER = 1; + public static final int RIGHT = 2; + protected String[] lines; + protected int num_lines; + protected int margin_width; + protected int margin_height; + protected int line_height; + protected int line_ascent; + protected int[] line_widths; + protected int max_width; + protected int alignment = 0; + + protected void newLabel(String label) { + StringTokenizer t = new StringTokenizer(label, "\n"); + this.num_lines = t.countTokens(); + this.lines = new String[this.num_lines]; + this.line_widths = new int[this.num_lines]; + + for (int i = 0; i < this.num_lines; i++) { + this.lines[i] = t.nextToken(); + } + } + + protected void measure() { + FontMetrics fm = this.getFontMetrics(this.getFont()); + if (fm != null) { + this.line_height = fm.getHeight(); + this.line_ascent = fm.getAscent(); + this.max_width = 0; + + for (int i = 0; i < this.num_lines; i++) { + this.line_widths[i] = fm.stringWidth(this.lines[i]); + if (this.line_widths[i] > this.max_width) { + this.max_width = this.line_widths[i]; + } + } + } + } + + public MultiLineLabel(String label, int margin_width, int margin_height, int alignment) { + this.newLabel(label); + this.margin_width = margin_width; + this.margin_height = margin_height; + this.alignment = alignment; + } + + public MultiLineLabel(String label, int margin_width, int margin_height) { + this(label, margin_width, margin_height, 0); + } + + public MultiLineLabel(String label, int alignment) { + this(label, 10, 10, alignment); + } + + public MultiLineLabel(String label) { + this(label, 10, 10, 0); + } + + public MultiLineLabel() { + this("", 10, 10, 0); + } + + public void setLabel(String label) { + this.newLabel(label); + this.measure(); + this.repaint(); + } + + public String getLabel() { + if (this.lines.length == 0) { + return ""; + } else { + String s = this.lines[0]; + + for (int i = 1; i < this.lines.length; i++) { + s = s + "\n" + this.lines[i]; + } + + return s; + } + } + + @Override + public void setFont(Font f) { + super.setFont(f); + this.measure(); + this.repaint(); + } + + @Override + public void setForeground(Color c) { + super.setForeground(c); + this.repaint(); + } + + public void setAlignment(int a) { + this.alignment = a; + this.repaint(); + } + + public void setMarginWidth(int mw) { + this.margin_width = mw; + this.repaint(); + } + + public void setMarginHeight(int mh) { + this.margin_height = mh; + this.repaint(); + } + + public int getAlignment() { + return this.alignment; + } + + public int getMarginWidth() { + return this.margin_width; + } + + public int getMarginHeight() { + return this.margin_height; + } + + public int getLines() { + return this.num_lines; + } + + @Override + public void addNotify() { + super.addNotify(); + this.measure(); + } + + @Override + public Dimension preferredSize() { + return new Dimension(this.max_width + 2 * this.margin_width, this.num_lines * this.line_height + 2 * this.margin_height); + } + + @Override + public Dimension minimumSize() { + return this.preferredSize(); + } + + @Override + public void paint(Graphics g) { + Dimension d = this.getSize(); + int y = this.line_ascent + (d.height - this.num_lines * this.line_height) / 2; + + for (int i = 0; i < this.num_lines; y += this.line_height) { + int x; + switch (this.alignment) { + case 0: + x = this.margin_width; + break; + case 1: + default: + x = (d.width - this.line_widths[i]) / 2; + break; + case 2: + x = d.width - this.margin_width - this.line_widths[i]; + } + + g.drawString(this.lines[i], x, y); + i++; + } + } +} diff --git a/NET/worlds/console/MuteListPart.java b/NET/worlds/console/MuteListPart.java new file mode 100644 index 0000000..9692966 --- /dev/null +++ b/NET/worlds/console/MuteListPart.java @@ -0,0 +1,254 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.network.Galaxy; +import NET.worlds.network.NetworkObject; +import NET.worlds.network.ObjID; +import NET.worlds.network.WorldServer; +import NET.worlds.scape.Drone; +import NET.worlds.scape.FrameEvent; +import java.awt.Container; +import java.awt.Event; +import java.awt.MenuItem; +import java.text.MessageFormat; +import java.util.Enumeration; +import java.util.StringTokenizer; +import java.util.Vector; + +public class MuteListPart implements FramePart, NameListOwner { + private static final String oldIniItemName = "Mutes"; + private static final String iniItemName = "Mute"; + private static final int maxMutes = 50; + private static final String separator = ";"; + private static MuteListPart active; + private Vector<String> mutes; + private Vector<String> syncMutes = new Vector<String>(); + private MenuItem editItem; + private MenuItem disableWhisperItem; + private boolean rejectWhispers; + private DefaultConsole console; + private Galaxy galaxy; + private IniFile serverSection; + private Object mutesMutex = new Object(); + private Vector<String> updates = new Vector<String>(); + + private void loadMutes() { + this.mutes = new Vector<String>(); + + for (int i = 0; i < 50; i++) { + String name = this.serverSection.getIniString("Mute" + i, ""); + if (name.length() == 0) { + break; + } + + if (FriendsListPart.isValidUserName(name) && !FriendsListPart.icontains(this.mutes, name)) { + this.mutes.addElement(name); + } + } + + if (this.mutes.size() == 0) { + String mutesStr = this.serverSection.getIniString("Mutes", ""); + StringTokenizer tokens = new StringTokenizer(mutesStr, ";"); + + while (tokens.hasMoreTokens() && this.mutes.size() < 50) { + String namex = tokens.nextToken(); + if (FriendsListPart.isValidUserName(namex) && !FriendsListPart.icontains(this.mutes, namex)) { + this.mutes.addElement(namex); + } + } + + if (this.mutes.size() != 0) { + this.saveMutes(); + this.serverSection.setIniString("Mutes", ""); + } + } + } + + void saveMutes() { + int count = this.mutes.size(); + + for (int i = 0; i < count; i++) { + this.serverSection.setIniString("Mute" + i, this.mutes.elementAt(i)); + } + + this.serverSection.setIniString("Mute" + count, ""); + } + + private void setDisableWhisper() { + this.rejectWhispers = IniFile.gamma().getIniInt("RejectWhispers", 0) == 1; + if (this.rejectWhispers) { + this.disableWhisperItem.setLabel(Console.message("Accept-Whispers")); + } else { + this.disableWhisperItem.setLabel(Console.message("Reject-Whispers")); + } + } + + @Override + public void activate(Console c, Container f, Console prev) { + active = this; + this.console = (DefaultConsole)c; + this.editItem = c.addMenuItem(Console.message("Edit-Mute-List"), "Options"); + this.editItem.setEnabled(this.mutes != null); + this.disableWhisperItem = c.addMenuItem(Console.message("Reject-Whispers"), "Options"); + this.setDisableWhisper(); + } + + @Override + public void deactivate() { + active = null; + this.editItem = null; + } + + @Override + public boolean action(Event event, Object what) { + if (event.target == this.editItem) { + new EditNamesDialog(this, Console.message("Edit-Mute-List"), Console.message("Add-Mute-List")); + return true; + } else { + if (event.target == this.disableWhisperItem) { + IniFile.gamma().setIniInt("RejectWhispers", this.rejectWhispers ? 0 : 1); + this.setDisableWhisper(); + } + + return false; + } + } + + @Override + public boolean handle(FrameEvent f) { + synchronized (this.mutesMutex) { + int count = this.updates.size(); + if (count != 0) { + WorldServer server = this.console.getServerNew(); + if (server != null) { + for (int i = 0; i < count; i++) { + String name = this.updates.elementAt(i); + boolean muted = this.mutes.contains(name); + NetworkObject obj = server.getObject(new ObjID(name)); + if (obj instanceof Drone) { + Drone d = (Drone)obj; + d.muteStateChanged(); + } + + this.console.getFriends().changeMuteState(name, muted); + } + + this.updates.removeAllElements(); + this.syncMutes = (Vector<String>)this.mutes.clone(); + } + } + + return true; + } + } + + public void setServer(WorldServer server, IniFile serverSection) { + this.serverSection = serverSection; + this.galaxy = server.getGalaxy(); + this.loadMutes(); + if (this.editItem != null) { + this.editItem.setEnabled(true); + } + } + + public static boolean isMuted(WorldServer server, String name) { + if (server != null && name != null) { + Galaxy g = server.getGalaxy(); + Enumeration<NetworkObject> consoleList = g.getConsoles(); + + while (consoleList.hasMoreElements()) { + Object c = consoleList.nextElement(); + if (c instanceof DefaultConsole) { + MuteListPart target = ((DefaultConsole)c).getMutes(); + if (target.mutes != null) { + return FriendsListPart.icontains(target.mutes, name); + } + } + } + } + + return false; + } + + public static boolean isRejecting(WorldServer server) { + if (server != null) { + Galaxy g = server.getGalaxy(); + Enumeration<NetworkObject> consoleList = g.getConsoles(); + + while (consoleList.hasMoreElements()) { + Object c = consoleList.nextElement(); + if (c instanceof DefaultConsole) { + MuteListPart target = ((DefaultConsole)c).getMutes(); + if (target.rejectWhispers) { + return true; + } + } + } + } + + return false; + } + + @Override + public int getNameListCount() { + return this.mutes.size(); + } + + @Override + public String getNameListName(int index) { + return this.mutes.elementAt(index); + } + + @Override + public void removeNameListName(int index) { + synchronized (this.mutesMutex) { + String name = this.mutes.elementAt(index); + this.mutes.removeElementAt(index); + this.saveMutes(); + if (!this.updates.contains(name)) { + this.updates.addElement(name); + } + } + } + + @Override + public boolean mayAddNameListName(java.awt.Window currentWindow) { + if (this.mutes.size() < 50) { + return true; + } else { + Object[] arguments = new Object[]{new String("50")}; + new OkCancelDialog( + currentWindow, + null, + Console.message("Too-many-names"), + null, + Console.message("OK"), + MessageFormat.format(Console.message("You-are-limitedM"), arguments), + true + ); + return false; + } + } + + @Override + public int addNameListName(String name) { + synchronized (this.mutesMutex) { + if (name.toLowerCase().startsWith("host")) { + return -1; + } else { + int index = FriendsListPart.iindexOf(this.mutes, name); + if (index != -1) { + return index; + } else { + this.mutes.addElement(name); + this.saveMutes(); + if (!this.updates.contains(name)) { + this.updates.addElement(name); + } + + return this.mutes.size() - 1; + } + } + } + } +} diff --git a/NET/worlds/console/NSProtocolHandler.java b/NET/worlds/console/NSProtocolHandler.java new file mode 100644 index 0000000..bb19216 --- /dev/null +++ b/NET/worlds/console/NSProtocolHandler.java @@ -0,0 +1,36 @@ +package NET.worlds.console; + +import NET.worlds.scape.TeleportAction; +import java.io.IOException; + +public class NSProtocolHandler extends IClassFactory { + public static final String CLSID_GammaProtocol1 = "{f8535c80-f5ee-11d2-a6ac-0050041a1735}"; + + public NSProtocolHandler() throws IOException { + this.init(createLocal()); + } + + public void activate() throws IOException { + super.activate("{f8535c80-f5ee-11d2-a6ac-0050041a1735}"); + } + + public void register() { + super.register("Gamma Protocol Handler", "{f8535c80-f5ee-11d2-a6ac-0050041a1735}", "Gamma.Protocol", "Gamma.Protocol.1"); + } + + public static void newURL(String url) { + if ((ActiveX.getDebugLevel() & 16) > 0) { + System.out.println("OLEDEBUG: Netscape URL: " + url); + } + + TeleportAction.teleport(url, null, true); + GammaFrame frame = Console.getFrame(); + int handle = Window.findWindow(frame.getTitle()); + if (handle != 0) { + Window.setWindowState(handle, 0); + Window.setForegroundWindow(handle); + } + } + + public static native int createLocal() throws IOException; +} diff --git a/NET/worlds/console/NameListOwner.java b/NET/worlds/console/NameListOwner.java new file mode 100644 index 0000000..cbf2cc2 --- /dev/null +++ b/NET/worlds/console/NameListOwner.java @@ -0,0 +1,13 @@ +package NET.worlds.console; + +public interface NameListOwner { + int getNameListCount(); + + String getNameListName(int var1); + + void removeNameListName(int var1); + + boolean mayAddNameListName(java.awt.Window var1); + + int addNameListName(String var1); +} diff --git a/NET/worlds/console/Netscape.java b/NET/worlds/console/Netscape.java new file mode 100644 index 0000000..3e7cbdd --- /dev/null +++ b/NET/worlds/console/Netscape.java @@ -0,0 +1,55 @@ +package NET.worlds.console; + +import java.io.IOException; + +public class Netscape implements MainCallback, MainTerminalCallback { + private INetscapeRegistry _registry = null; + private NSProtocolHandler _protocolHandler = null; + + public Netscape() { + Main.register(this); + } + + @Override + public void mainCallback() { + Main.unregister(this); + + try { + this._registry = new INetscapeRegistry(); + if ((ActiveX.getDebugLevel() & 16) > 0) { + System.out.println("OLEDEBUG: Netscape OLE found"); + } + + this._protocolHandler = new NSProtocolHandler(); + this._protocolHandler.activate(); + if ((ActiveX.getDebugLevel() & 16) > 0) { + System.out.println("OLEDEBUG: NSProtocolHandler started"); + } + + this._protocolHandler.register(); + boolean reg = this._registry.RegisterProtocol("world", "Gamma.Protocol.1"); + if ((ActiveX.getDebugLevel() & 16) > 0) { + System.out.println("OLEDEBUG: world: registered with Netscape"); + } + } catch (IOException var10) { + if ((ActiveX.getDebugLevel() & 16) > 0) { + System.out.println("OLEDEBUG: No Netscape: " + var10.getMessage()); + } + } finally { + if (this._registry != null) { + try { + this._registry.Release(); + } catch (OLEInvalidObjectException var9) { + var9.printStackTrace(System.out); + } + + this._registry = null; + } + } + } + + @Override + public void terminalCallback() { + Main.unregister(this); + } +} diff --git a/NET/worlds/console/NewSharedTextArea.java b/NET/worlds/console/NewSharedTextArea.java new file mode 100644 index 0000000..581ab3e --- /dev/null +++ b/NET/worlds/console/NewSharedTextArea.java @@ -0,0 +1,223 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import java.awt.AWTEvent; +import java.awt.Component; +import java.awt.event.FocusEvent; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.text.DateFormat; +import java.util.Date; +import java.util.Observer; + +class NewSharedTextArea extends GammaTextArea implements SharedTextArea { + private static final long serialVersionUID = 6732411958099438561L; + private static String sharedText; + private boolean isShared; + private String unsharedText; + private String unaddedText = null; + private PrintWriter logFile; + private String logFileName; + private static final long oneMeg = 1048576L; + private static final long logLengthLimit = 524288L; + private static PublicObservable obsLogFile = new PublicObservable(); + private static int autoScrollLimit = IniFile.gamma().getIniInt("AutoScrollLimit", 0); + public static int chatLengthLimit = IniFile.gamma().getIniInt("ChatLengthLimit", 20000); + + public NewSharedTextArea(int rows, int cols, boolean isShared) { + super("", rows, cols, 2); + this.isShared = isShared; + this.setEditable(false); + } + + @Override + public void finalize() { + this.disableLogging(); + } + + @Override + public Component getComponent() { + return this; + } + + @Override + public synchronized void validate() { + super.validate(); + String text = this.isShared ? sharedText : this.unsharedText; + if (text != null) { + this.setText(text); + } + } + + @Override + public synchronized void enableLogging(String fileName, String title, boolean append) { + if (this.logFile != null) { + if (this.logFileName.equals(fileName)) { + return; + } + + this.logFile.close(); + } + + try { + if (append && new File(fileName).exists()) { + this.truncateIfExceeds(fileName, title, 524288L); + this.logFile = new PrintWriter(new FileWriter(fileName, true)); + } else { + this.logFile = new PrintWriter(new FileWriter(fileName, false)); + obsLogFile.setChanged(true); + this.logFile.println("<html>"); + this.logFile.println("<head>"); + this.logFile.println("<title>" + title + "</title>"); + this.logFile.println("</head>"); + this.logFile.println("<body>"); + } + + this.logFileName = fileName; + this.logFile.println("<hr>"); + this.logFile.println("<h3>Conversation of " + DateFormat.getDateTimeInstance().format(new Date()) + "</h3>"); + this.logFile.flush(); + obsLogFile.notifyObservers(this); + } catch (IOException var5) { + System.out.println("Log file not opened: " + var5); + } + } + + public static void addLogObserver(Observer o) { + obsLogFile.addObserver(o); + } + + public static void deleteLogObserver(Observer o) { + obsLogFile.deleteObserver(o); + } + + private void truncateIfExceeds(String fileName, String title, long lengthLimit) { + File f = new File(fileName); + if (f.length() > lengthLimit) { + File tf = new File(fileName + ".temp"); + + try { + BufferedReader in = new BufferedReader(new FileReader(f)); + PrintWriter out = new PrintWriter(new FileWriter(tf)); + out.println("<html>"); + out.println("<head>"); + out.println("<title>" + title + "</title>"); + out.println("</head>"); + out.println("<body>"); + in.skip(f.length() - lengthLimit / 2L); + String line = in.readLine(); + + for (String var13 = in.readLine(); var13 != null; var13 = in.readLine()) { + out.println(var13); + } + + in.close(); + out.close(); + f.delete(); + f = new File(fileName); + tf.renameTo(f); + } catch (FileNotFoundException var10) { + System.out.println("DuplexPart fatal: " + var10); + } catch (IOException var11) { + System.out.println("DuplexPart: Unable to write, " + var11); + } + } + } + + @Override + public synchronized void disableLogging() { + if (this.logFile != null) { + this.logFile.close(); + this.logFile = null; + } + } + + @Override + public boolean canAddText() { + if (this.getText().length() < 3) { + return true; + } else { + return autoScrollLimit > 0 && autoScrollLimit < this.unaddedText.length() ? true : this.isLastLineVisible(); + } + } + + @Override + public synchronized void println(String msg) { + if (this.logFile != null && msg != null) { + this.logFile.println(DuplexPart.toHtml(msg) + "<br>"); + this.logFile.flush(); + } + + if (this.unaddedText == null) { + this.unaddedText = msg; + } else if (msg != null) { + this.unaddedText = this.unaddedText + "\n" + msg; + } + + if (this.unaddedText != null && this.canAddText()) { + if (this.getText().length() == 0) { + this.append(this.unaddedText); + } else { + this.append("\n" + this.unaddedText); + } + + this.unaddedText = null; + String text = this.getText(); + if (text.length() > chatLengthLimit) { + int linePos = text.indexOf(10, chatLengthLimit / 2 - 80); + if (linePos >= 0) { + text = text.substring(linePos + 1); + linePos = text.lastIndexOf(10); + if (linePos > 0) { + this.setText(text.substring(0, linePos)); + this.append(text.substring(linePos)); + } + } + } + + if (this.isShared) { + sharedText = text; + } else { + this.unsharedText = text; + } + + this.repaint(); + } + } + + @Override + public synchronized void scrollToBottom() { + String text = this.getText(); + this.setText(""); + this.append(text); + this.repaint(); + } + + @Override + protected void processFocusEvent(FocusEvent e) { + super.processFocusEvent(e); + } + + @Override + protected void processEvent(AWTEvent e) { + this.poll(); + super.processEvent(e); + } + + @Override + public synchronized void poll() { + if (this.unaddedText != null) { + this.println(null); + } + } + + @Override + public boolean isFocusTraversable() { + return false; + } +} diff --git a/NET/worlds/console/NoWebControlException.java b/NET/worlds/console/NoWebControlException.java new file mode 100644 index 0000000..ca4a7ef --- /dev/null +++ b/NET/worlds/console/NoWebControlException.java @@ -0,0 +1,12 @@ +package NET.worlds.console; + +public class NoWebControlException extends Exception { + private static final long serialVersionUID = 8391822026004106330L; + + NoWebControlException() { + } + + NoWebControlException(String s) { + super(s); + } +} diff --git a/NET/worlds/console/OLEInvalidObjectException.java b/NET/worlds/console/OLEInvalidObjectException.java new file mode 100644 index 0000000..62ec5a6 --- /dev/null +++ b/NET/worlds/console/OLEInvalidObjectException.java @@ -0,0 +1,12 @@ +package NET.worlds.console; + +public class OLEInvalidObjectException extends Exception { + private static final long serialVersionUID = -8603974556147263692L; + + public OLEInvalidObjectException() { + } + + public OLEInvalidObjectException(String msg) { + super(msg); + } +} diff --git a/NET/worlds/console/OkCancelDialog.java b/NET/worlds/console/OkCancelDialog.java new file mode 100644 index 0000000..2b2f6d2 --- /dev/null +++ b/NET/worlds/console/OkCancelDialog.java @@ -0,0 +1,150 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +public class OkCancelDialog extends PolledDialog { + private static final long serialVersionUID = -232374191442133438L; + protected Button okButton = new Button(Console.message("OK")); + protected Button cancelButton = new Button(Console.message("Cancel")); + protected GridBagLayout gbag = new GridBagLayout(); + private String prompt; + protected int cancelKey = 27; + protected int confirmKey = 10; + protected static Font font = new Font(Console.message("GammaTextFont"), 0, 12); + protected static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + + protected OkCancelDialog(java.awt.Window parent, String title) { + this(parent, (DialogReceiver)parent, title); + } + + protected OkCancelDialog(java.awt.Window parent, String title, String cancel, String ok) { + this(parent, (DialogReceiver)parent, title, cancel, ok); + } + + protected OkCancelDialog(java.awt.Window parent, DialogReceiver target, String title) { + this(parent, target, title, true); + } + + protected OkCancelDialog(java.awt.Window parent, DialogReceiver target, String title, boolean modal) { + super(parent, target, title, modal); + this.setLayout(this.gbag); + } + + protected OkCancelDialog(java.awt.Window parent, DialogReceiver target, String title, String cancel, String ok) { + this(parent, target, title, cancel, ok, true); + } + + protected OkCancelDialog(java.awt.Window parent, DialogReceiver target, String title, String cancel, String ok, boolean modal) { + this(parent, target, title, modal); + if (ok != null) { + this.okButton.setFont(bfont); + this.okButton.setLabel(ok); + } else { + this.okButton = null; + } + + if (cancel != null) { + this.cancelButton.setFont(bfont); + this.cancelButton.setLabel(cancel); + } else { + this.cancelButton = null; + } + } + + public OkCancelDialog(java.awt.Window parent, DialogReceiver target, String title, String cancel, String ok, String prompt) { + this(parent, target, title, cancel, ok, prompt, true); + } + + public OkCancelDialog(java.awt.Window parent, DialogReceiver target, String title, String cancel, String ok, String prompt, boolean modal) { + this(parent, target, title, cancel, ok, modal); + this.prompt = prompt; + this.ready(); + } + + public OkCancelDialog(java.awt.Window parent, DialogReceiver target, String title, String cancel, String ok, String prompt, boolean modal, int alignment) { + this(parent, target, title, cancel, ok, modal); + this.prompt = prompt; + this.setAlignment(alignment); + this.ready(); + } + + @Override + protected void build() { + GridBagConstraints c = new GridBagConstraints(); + if (this.prompt != null) { + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 0; + MultiLineLabel mll = new MultiLineLabel(this.prompt, 5, 5); + mll.setFont(font); + this.add(this.gbag, mll, c); + } + + int count = 0; + if (this.okButton != null) { + count++; + } + + if (this.cancelButton != null) { + count++; + } + + c.gridwidth = count; + c.weightx = 1.0; + c.weighty = 0.0; + if (this.okButton != null) { + this.okButton.setFont(bfont); + this.add(this.gbag, this.okButton, c); + } + + if (this.cancelButton != null) { + this.cancelButton.setFont(bfont); + this.add(this.gbag, this.cancelButton, c); + } + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.okButton && this.setValue()) { + return this.done(true); + } else { + return target == this.cancelButton ? this.done(false) : false; + } + } + + protected boolean setValue() { + return true; + } + + public void setCancelKey(int key) { + this.cancelKey = key; + } + + public void setConfirmKey(int key) { + this.confirmKey = key; + } + + @Override + public boolean keyDown(Event event, int key) { + if (key == this.cancelKey) { + return this.done(false); + } else { + if (key == this.confirmKey) { + if (this.okButton == null) { + return this.done(false); + } + + if (this.setValue()) { + return this.done(true); + } + } + + return super.keyDown(event, key); + } + } +} diff --git a/NET/worlds/console/Overlay.java b/NET/worlds/console/Overlay.java new file mode 100644 index 0000000..237c506 --- /dev/null +++ b/NET/worlds/console/Overlay.java @@ -0,0 +1,53 @@ +package NET.worlds.console; + +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; + +class Overlay { + private String name; + private int x; + private int y; + private Image image; + private Dimension dim; + + public Overlay(String name, int x, int y) { + this.name = name; + this.x = x; + this.y = y; + this.image = null; + } + + public void paint(Graphics g, Component c) { + if (this.image != null) { + g.drawImage(this.image, this.x, this.y, c); + } + } + + public Dimension imageSize(Component c) { + if (this.image == null) { + this.image = SplashCanvas.getEarlyImage(this.name, c); + if (this.image != null) { + int width = this.image.getWidth(c); + int height = this.image.getHeight(c); + if (width != -1 && height != -1) { + return this.dim = new Dimension(width, height); + } + } + + this.dim = new Dimension(0, 0); + } + + return this.dim; + } + + public boolean matches(String name, int x, int y) { + return x == this.x && y == this.y && name.equals(this.name); + } + + public void flush() { + this.image.flush(); + this.image = null; + } +} diff --git a/NET/worlds/console/PersonalInfoDialog.java b/NET/worlds/console/PersonalInfoDialog.java new file mode 100644 index 0000000..db5c6e2 --- /dev/null +++ b/NET/worlds/console/PersonalInfoDialog.java @@ -0,0 +1,113 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.TextArea; +import java.util.StringTokenizer; +import java.util.Vector; + +class PersonalInfoDialog extends PolledDialog { + private static final long serialVersionUID = 1200424099007473332L; + private Vector<String> info; + private Button okButton = new Button(Console.message("OK")); + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + + public PersonalInfoDialog(String name, Vector<String> info) { + super(Console.getFrame(), null, Console.message("Personal-Info") + name, false); + this.info = info; + this.ready(); + } + + @Override + protected void build() { + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + + try { + int count = this.info.size(); + int i = 0; + + while (i < count) { + StringTokenizer tok = new StringTokenizer(this.info.elementAt(i++), ":"); + String heading = tok.nextToken(); + c.gridwidth = -1; + c.gridheight = 1; + c.fill = 1; + Label lHead = new Label(heading, 1); + lHead.setFont(font); + this.add(gbag, lHead, c); + int totalLines = Integer.parseInt(tok.nextToken()); + int displayLines = Math.max(Math.min(3, totalLines), 1); + int maxLine = 0; + + for (int j = 0; j < totalLines; j++) { + maxLine = Math.max(maxLine, this.info.elementAt(i + j).length()); + } + + int scrollFlags = 3; + if (maxLine > 40) { + if (totalLines > ++displayLines) { + scrollFlags = 0; + } else { + scrollFlags = 2; + } + } else if (totalLines > displayLines) { + scrollFlags = 1; + } + + TextArea t = new TextArea("", displayLines, 40, scrollFlags); + t.setFont(font); + + for (int j = 0; j < totalLines; j++) { + if (j > 0) { + t.append("\n"); + } + + t.append(this.info.elementAt(i++)); + } + + c.fill = 0; + c.gridwidth = 0; + c.gridheight = displayLines; + t.setEditable(false); + this.add(gbag, t, c); + } + } catch (Exception var14) { + this.removeAll(); + c.fill = 0; + c.gridwidth = 0; + c.gridheight = 1; + Label lFormat = new Label(Console.message("Format-error")); + lFormat.setFont(font); + this.add(gbag, lFormat, c); + } + + c.fill = 0; + c.gridwidth = 0; + c.gridheight = 1; + this.okButton.setFont(bfont); + this.add(gbag, this.okButton, c); + } + + @Override + public boolean action(Event event, Object what) { + return event.target == this.okButton ? this.done(false) : false; + } + + @Override + public boolean keyDown(Event event, int key) { + return key != 27 && key != 10 ? super.keyDown(event, key) : this.done(false); + } + + @Override + public void show() { + super.show(); + this.okButton.requestFocus(); + } +} diff --git a/NET/worlds/console/PersonalInfoDownload.java b/NET/worlds/console/PersonalInfoDownload.java new file mode 100644 index 0000000..4e4e890 --- /dev/null +++ b/NET/worlds/console/PersonalInfoDownload.java @@ -0,0 +1,99 @@ +package NET.worlds.console; + +import NET.worlds.network.Cache; +import NET.worlds.network.CacheFile; +import NET.worlds.network.URL; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.Label; +import java.io.DataInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Vector; + +class PersonalInfoDownload extends OkCancelDialog implements Runnable { + private static final long serialVersionUID = -198244581766521022L; + private String name; + private CacheFile cf; + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + + public PersonalInfoDownload(String name, Console console) { + super(Console.getFrame(), null, Console.message("Downloading2"), Console.message("Cancel"), null, false); + this.name = name; + String cfS = console.getScriptServer() + "profile" + Console.message(".pl") + "?" + name; + this.cf = Cache.getFile(URL.make(cfS)); + if (Console.wasHttpNoSuchFile(cfS)) { + this.cf = Cache.getFile(URL.make(console.getScriptServer() + "profile.pl?" + name)); + } + + this.setFont(new Font(Console.message("FriendsFont"), 0, 12)); + Thread t = new Thread(this); + t.setDaemon(true); + t.start(); + } + + @Override + protected void build() { + GridBagConstraints c = new GridBagConstraints(); + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 0; + Object[] arguments = new Object[]{new String(this.name)}; + Label lDown = new Label(MessageFormat.format(Console.message("Downloading"), arguments)); + lDown.setFont(font); + this.add(this.gbag, lDown, c); + Label lWait = new Label(Console.message("Please-wait")); + lWait.setFont(font); + this.add(this.gbag, lWait, c); + super.build(); + } + + @Override + public void run() { + this.readySetGo(); + this.cf.waitUntilLoaded(); + if (this.cf.isActive()) { + this.done(true); + if (this.cf.error()) { + Object[] arguments = new Object[]{new String(this.name)}; + new OkCancelDialog( + Console.getFrame(), + null, + Console.message("Error"), + null, + Console.message("OK"), + MessageFormat.format(Console.message("Error-down"), arguments), + false + ); + System.out.println("Error downloading personal info for " + this.name); + } else { + Vector<String> data = new Vector<String>(); + DataInputStream in = null; + + try { + in = new DataInputStream(new FileInputStream(this.cf.getLocalName())); + + String line; + while ((line = in.readLine()) != null) { + data.addElement(line); + } + + new PersonalInfoDialog(this.name, data); + } catch (FileNotFoundException var14) { + } catch (IOException var15) { + } finally { + try { + if (in != null) { + in.close(); + } + } catch (IOException var13) { + } + } + } + + this.cf.close(); + } + } +} diff --git a/NET/worlds/console/PolledDialog.java b/NET/worlds/console/PolledDialog.java new file mode 100644 index 0000000..0f26bc0 --- /dev/null +++ b/NET/worlds/console/PolledDialog.java @@ -0,0 +1,286 @@ +package NET.worlds.console; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Point; +import java.awt.Toolkit; + +public abstract class PolledDialog extends Dialog implements MainCallback, DialogDisabled { + private static final long serialVersionUID = -2608298148446880055L; + public static final int CENTER = 0; + public static final int BOTTOM = 1; + public static final int RIGHT = 2; + public static final int LEFT = 3; + private boolean active; + private boolean built; + private boolean restarting; + private boolean confirmed; + private boolean killed; + private boolean disableParent; + private boolean toBeDisposed; + private java.awt.Window parent; + private DialogReceiver receiver; + private int alignment = 0; + private Point initialOffset = new Point(0, 0); + private Object startupWaiter; + private boolean started; + + protected PolledDialog(java.awt.Window parent, DialogReceiver receiver, String title, boolean disableParent) { + super(findFrame(parent), title, false); + this.parent = parent; + this.receiver = receiver; + if (disableParent) { + this.disableParent(); + } + } + + protected void disableParent() { + this.disableParent = this.parent instanceof DialogDisabled; + if (this.disableParent) { + ((DialogDisabled)this.parent).dialogDisable(true); + } + } + + protected void ready() { + this.killed = false; + if (this.built && !this.active) { + this.restarting = true; + } + + Main.register(this); + this.setResizable(true); + } + + protected void readySetGo() { + this.startupWaiter = new Object(); + this.started = false; + synchronized (this.startupWaiter) { + this.ready(); + + while (!this.started) { + try { + this.startupWaiter.wait(); + } catch (InterruptedException var3) { + } + } + } + + this.startupWaiter = null; + this.started = false; + } + + protected void setAlignment(int alignment) { + this.setAlignment(alignment, 0, 0); + } + + protected void setAlignment(int alignment, int offsetX, int offsetY) { + this.alignment = alignment; + this.initialOffset.x = offsetX; + this.initialOffset.y = offsetY; + } + + private static Frame findFrame(Container container) { + while (!(container instanceof Frame) && container != null) { + container = container.getParent(); + } + + return (Frame)container; + } + + protected abstract void build(); + + @Override + public final synchronized void mainCallback() { + if (!this.killed) { + if (!this.built) { + try { + this.build(); + this.pack(); + this.restoreFrame(); + this.position(); + this.show(); + this.built = true; + this.active = true; + } catch (Exception var2) { + System.out.println("Caught exception building dialog " + this.toString() + " " + var2.getMessage()); + } + } else if (this.restarting) { + this.restoreFrame(); + this.show(); + this.restarting = false; + this.active = true; + } + } + + if (!this.killed && this.active) { + this.activeCallback(); + } else { + if (this.toBeDisposed) { + this.setVisible(false); + this.parent.requestFocus(); + if (this.getPeer() != null) { + this.dispose(); + } + + this.toBeDisposed = false; + } + + Main.unregister(this); + if (this.receiver != null) { + this.receiver.dialogDone(this, this.confirmed); + } + } + } + + protected void activeCallback() { + } + + private void restoreFrame() { + int handle = Window.getFrameHandle(); + if (handle != 0 && Window.getWindowState(handle) == 1) { + Window.setWindowState(handle, 0); + } + } + + @Override + public void show() { + try { + super.show(); + } catch (Exception var3) { + System.out.println("Caught exception in PolledDialog::show: " + var3.getMessage()); + } + + if (this.startupWaiter != null) { + synchronized (this.startupWaiter) { + this.started = true; + this.startupWaiter.notify(); + } + } + } + + public void closeIt(boolean state) { + this.done(state); + } + + protected synchronized boolean done(boolean confirmed) { + if (!this.killed && this.disableParent) { + ((DialogDisabled)this.parent).dialogDisable(false); + } + + this.killed = true; + this.toBeDisposed = true; + if (this.active) { + this.savePosAndSize(new PolledDialogSaver(this)); + this.active = false; + } + + this.confirmed = confirmed; + return true; + } + + @Override + public boolean isActive() { + return this.active; + } + + protected void add(GridBagLayout gbag, Component comp, GridBagConstraints c) { + if (comp != null && c != null) { + gbag.setConstraints(comp, c); + this.add(comp); + } else { + System.out.println("Bad parameter passed to PolledDialog::add, how bizarre."); + } + } + + @Override + public boolean handleEvent(Event event) { + if (event.id == 201) { + return this.done(false); + } else { + if (event.id == 401 || event.id == 501) { + Console.wake(); + } + + return super.handleEvent(event); + } + } + + @Override + public void dialogDisable(boolean disable) { + this.setVisible(!disable); + } + + public boolean getConfirmed() { + return this.confirmed; + } + + protected void position() { + Dimension mySize = this.getSize(); + this.initialSize(mySize.width, mySize.height); + } + + protected void initialSize(int width, int height) { + if (!PolledDialogSaver.restorePosAndSize(this.restorePosAndSize(), this)) { + Point loc = this.parent.location(); + Dimension size = null; + if (this.parent instanceof Frame) { + int hwnd = Window.getFrameHandle(); + if (hwnd != 0) { + size = new Dimension(Window.getWindowWidth(hwnd), Window.getWindowHeight(hwnd)); + } + } + + if (size == null) { + size = this.parent.getSize(); + } + + int x; + if (this.alignment == 2) { + x = loc.x + this.initialOffset.x + size.width; + } else if (this.alignment == 3) { + x = loc.x + this.initialOffset.x - width; + } else { + x = loc.x + this.initialOffset.x + (size.width - width) / 2; + } + + int y; + if (this.alignment == 1) { + y = loc.y + this.initialOffset.y + size.height - height; + } else { + y = loc.y + this.initialOffset.y + (size.height - height) / 2; + } + + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + if (y + height > screenSize.height) { + y = screenSize.height - height; + } + + if (y < 0) { + y = 0; + } + + if (x + width > screenSize.width) { + x = screenSize.width - width; + } + + if (x < 0) { + x = 0; + } + + this.reshape(x, y, width, height); + } + } + + public void savePosAndSize(Object o) { + } + + public Object restorePosAndSize() { + return null; + } +} diff --git a/NET/worlds/console/PolledDialogSaver.java b/NET/worlds/console/PolledDialogSaver.java new file mode 100644 index 0000000..e597d02 --- /dev/null +++ b/NET/worlds/console/PolledDialogSaver.java @@ -0,0 +1,31 @@ +package NET.worlds.console; + +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Point; + +class PolledDialogSaver { + int x; + int y; + int w; + int h; + + PolledDialogSaver(Dialog dbox) { + Point loc = dbox.location(); + Dimension size = dbox.getSize(); + this.x = loc.x; + this.y = loc.y; + this.w = size.width; + this.h = size.height; + } + + static boolean restorePosAndSize(Object o, PolledDialog d) { + if (o != null) { + PolledDialogSaver t = (PolledDialogSaver)o; + d.reshape(t.x, t.y, t.w, t.h); + return true; + } else { + return false; + } + } +} diff --git a/NET/worlds/console/ProgressBar.java b/NET/worlds/console/ProgressBar.java new file mode 100644 index 0000000..c4159d7 --- /dev/null +++ b/NET/worlds/console/ProgressBar.java @@ -0,0 +1,142 @@ +package NET.worlds.console; + +import NET.worlds.network.CacheEntry; +import java.awt.Button; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Event; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GridLayout; +import java.awt.Image; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ProgressBar extends Frame implements ActionListener { + private static final long serialVersionUID = -5057984821909220829L; + private int _total; + private int _current = 0; + private boolean _offline = false; + private Canvas _barCanvas; + private Label _header; + private TextField _message; + private Button _offlineButton; + private static final int BAR_WIDTH = 250; + private static final int BAR_HEIGHT = 20; + private static final int BORDER = 10; + + public ProgressBar(String header, int total) { + this._header = new Label(header); + this._total = total; + if (this._total < 1) { + this._total = 1; + } + + this.build(); + this.setTitle("Loading Progress"); + } + + public void advance() { + this._current++; + if (this._current > this._total) { + this._current = this._total; + } + + this.paintBar(); + } + + public int current() { + return this._current; + } + + public int total() { + return this._total; + } + + public int percentComplete() { + return this._current * 100 / this._total; + } + + public boolean offline() { + return this._offline; + } + + public void setMessage(String m) { + this._message.setText(m); + this.update(this.getGraphics()); + } + + protected int pixelsComplete() { + return this._current * 250 / this._total; + } + + protected void build() { + this.setLayout(new GridLayout(3, 1, 10, 0)); + this._barCanvas = new Canvas(); + this._barCanvas.setSize(270, 40); + this.add(this._barCanvas); + this._message = new TextField("Working..."); + this._message.setEditable(false); + this.add(this._message); + Panel buttonPanel = new Panel(); + this._offlineButton = new Button("Go Offline"); + this._offlineButton.addActionListener(this); + buttonPanel.add(this._offlineButton); + this.add(buttonPanel); + this.pack(); + } + + @Override + public void paint(Graphics g) { + this.paintBar(); + } + + @Override + public void actionPerformed(ActionEvent ae) { + if (ae.getSource() == this._offlineButton) { + this._offline = true; + CacheEntry.setOffline(); + this._offlineButton.setEnabled(false); + } + } + + @Override + public boolean handleEvent(Event e) { + if (e.id == 201) { + this.setVisible(false); + this.dispose(); + Main.end(); + throw new Error("User cancelled startup."); + } else { + return super.handleEvent(e); + } + } + + protected void paintBar() { + Graphics g = this._barCanvas.getGraphics(); + Image off = this.createImage(270, 40); + Graphics offG = off.getGraphics(); + offG.setColor(this.getBackground()); + offG.fillRect(0, 0, 270, 40); + offG.setColor(Color.gray); + offG.fillRect(10, 10, this.pixelsComplete(), 20); + offG.setColor(Color.darkGray); + offG.draw3DRect(11, 11, this.pixelsComplete() - 1, 18, true); + offG.setColor(Color.black); + offG.drawRect(10, 10, 250, 20); + String perString = Integer.toString(this.percentComplete()) + "% Complete"; + g.setFont(new Font("Times Roman", 0, 12)); + FontMetrics fm = g.getFontMetrics(); + int halfHeight = fm.getHeight() / 2; + int halfWidth = fm.stringWidth(perString) / 2; + offG.drawString(perString, 135 - halfWidth, 20 + halfHeight); + g.drawImage(off, 0, 0, null); + offG.dispose(); + off.flush(); + } +} diff --git a/NET/worlds/console/ProxyServerDialog.java b/NET/worlds/console/ProxyServerDialog.java new file mode 100644 index 0000000..310a9a8 --- /dev/null +++ b/NET/worlds/console/ProxyServerDialog.java @@ -0,0 +1,63 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import java.awt.GridBagConstraints; +import java.awt.Label; +import java.awt.TextField; +import java.util.Properties; + +class ProxyServerDialog extends OkCancelDialog { + private static final long serialVersionUID = 8421990344972629940L; + private Label ipLabel = new Label("Proxy IP"); + private TextField ipText = new TextField("", 15); + private Label portLabel = new Label("Proxy Port"); + private TextField portText = new TextField("", 3); + + public ProxyServerDialog() { + super(Console.getFrame(), null, Console.message("Proxy-Server"), "Cancel", "Ok", "", false); + this.ipText.setText(IniFile.gamma().getIniString("Proxy Server IP", "")); + this.portText.setText(IniFile.gamma().getIniString("Proxy Server Port", "")); + } + + @Override + protected synchronized boolean done(boolean confirmed) { + if (confirmed) { + Properties p = System.getProperties(); + IniFile.gamma().setIniString("Proxy Server IP", this.ipText.getText()); + IniFile.gamma().setIniString("Proxy Server Port", this.portText.getText()); + p.remove("socksProxyHost"); + p.remove("socksProxyPort"); + p.put("socksProxyHost", this.ipText.getText()); + p.put("socksProxyPort", this.portText.getText()); + System.setProperties(p); + } + + return super.done(confirmed); + } + + @Override + public void build() { + GridBagConstraints c = new GridBagConstraints(); + c.gridx = 1; + c.gridy = 1; + c.weightx = 1.0; + c.weighty = 1.0; + this.add(this.gbag, this.ipLabel, c); + c.gridy = 2; + this.add(this.gbag, this.portLabel, c); + c.gridx = 2; + c.gridy = 1; + c.weightx = 3.0; + this.add(this.gbag, this.ipText, c); + c.gridy = 2; + this.add(this.gbag, this.portText, c); + this.okButton.setFont(bfont); + this.cancelButton.setFont(bfont); + c.gridx = 1; + c.gridy = 3; + c.weightx = 1.0; + this.add(this.gbag, this.okButton, c); + c.gridx = 4; + this.add(this.gbag, this.cancelButton, c); + } +} diff --git a/NET/worlds/console/PublicObservable.java b/NET/worlds/console/PublicObservable.java new file mode 100644 index 0000000..aa30602 --- /dev/null +++ b/NET/worlds/console/PublicObservable.java @@ -0,0 +1,13 @@ +package NET.worlds.console; + +import java.util.Observable; + +class PublicObservable extends Observable { + public void setChanged(boolean changed) { + if (changed) { + this.setChanged(); + } else { + this.clearChanged(); + } + } +} diff --git a/NET/worlds/console/QuantizedCanvas.java b/NET/worlds/console/QuantizedCanvas.java new file mode 100644 index 0000000..e79e8a0 --- /dev/null +++ b/NET/worlds/console/QuantizedCanvas.java @@ -0,0 +1,9 @@ +package NET.worlds.console; + +import java.awt.Canvas; + +public abstract class QuantizedCanvas extends Canvas { + private static final long serialVersionUID = 5574577104641386073L; + + abstract int getRemainder(int var1); +} diff --git a/NET/worlds/console/QuantizedStackedLayout.java b/NET/worlds/console/QuantizedStackedLayout.java new file mode 100644 index 0000000..98f12f0 --- /dev/null +++ b/NET/worlds/console/QuantizedStackedLayout.java @@ -0,0 +1,63 @@ +package NET.worlds.console; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Insets; + +class QuantizedStackedLayout extends StackedLayout { + ColorFiller m_filler; + + public QuantizedStackedLayout(ColorFiller filler) { + this.m_filler = filler; + } + + @Override + public void layoutContainer(Container target) { + int count = target.getComponentCount(); + Insets insets = target.getInsets(); + Dimension size = target.getSize(); + int width = size.width - insets.left - insets.right; + int height = size.height - insets.top - insets.bottom; + int fillerHeight = 0; + + for (int i = 0; i < count; i++) { + Component c = target.getComponent(i); + if (c != this.m_filler) { + int h = c.getPreferredSize().height; + if (i == count - 1) { + h = Math.max(h, height); + } else { + h = Math.min(h, height); + } + + h = Math.max(0, h); + height -= h; + if (c instanceof QuantizedCanvas) { + QuantizedCanvas qc = (QuantizedCanvas)c; + fillerHeight += qc.getRemainder(h); + } + } + } + + this.m_filler.setHeight(fillerHeight); + int x = insets.left; + int y = insets.top; + height = size.height - insets.top - insets.bottom; + + for (int ix = 0; ix < count; ix++) { + Component c = target.getComponent(ix); + int hx = c.getPreferredSize().height; + if (ix == count - 1) { + hx = Math.max(hx, height); + } else { + hx = Math.min(hx, height); + } + + hx = Math.max(0, hx); + c.setBounds(x, y, width, hx); + height -= hx; + y += hx; + } + } +} diff --git a/NET/worlds/console/QuitDialog.java b/NET/worlds/console/QuitDialog.java new file mode 100644 index 0000000..8c1eef1 --- /dev/null +++ b/NET/worlds/console/QuitDialog.java @@ -0,0 +1,49 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import java.awt.Component; +import java.awt.Event; +import java.awt.Rectangle; + +public class QuitDialog extends PolledDialog implements ImageButtonsCallback { + private static final long serialVersionUID = 2648594609846911429L; + private ImageButtons ib; + + public QuitDialog(java.awt.Window parent, DialogReceiver receiver) { + super(parent, receiver, Console.message("Quit"), true); + Rectangle[] rects = new Rectangle[2]; + int yesX = IniFile.override().getIniInt("quitYesX", 141); + int yesY = IniFile.override().getIniInt("quitYesY", 76); + int yesW = IniFile.override().getIniInt("quitYesW", 78); + int yesH = IniFile.override().getIniInt("quitYesH", 22); + rects[0] = new Rectangle(yesX, yesY, yesW, yesH); + int noX = IniFile.override().getIniInt("quitNoX", 141); + int noY = IniFile.override().getIniInt("quitNoY", 114); + int noW = IniFile.override().getIniInt("quitNoW", 78); + int noH = IniFile.override().getIniInt("quitNoH", 22); + rects[1] = new Rectangle(noX, noY, noW, noH); + String quitGif = IniFile.override().getIniString("quitDlg", Console.message("DYRWTQ.GIF")); + this.ib = new ImageButtons(quitGif, rects, this); + this.ready(); + } + + @Override + protected void build() { + this.add("Center", this.ib); + } + + @Override + public Object imageButtonsCallback(Component who, int which) { + this.done(which == 0); + return null; + } + + @Override + public boolean keyDown(Event event, int key) { + if (key == 27) { + return this.done(false); + } else { + return key == 10 ? this.done(true) : super.keyDown(event, key); + } + } +} diff --git a/NET/worlds/console/RealG2.java b/NET/worlds/console/RealG2.java new file mode 100644 index 0000000..188edc6 --- /dev/null +++ b/NET/worlds/console/RealG2.java @@ -0,0 +1,251 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.scape.CDAudio; +import java.awt.Dimension; +import java.awt.Rectangle; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; + +public class RealG2 implements Runnable, MainCallback, MainTerminalCallback { + private static RealG2 instance = new RealG2(); + private Thread realThread; + private Vector<RealG2.RG2Request> requestList = new Vector<RealG2.RG2Request>(2, 1); + private boolean cancel; + private boolean isPlaying = false; + + private RealG2() { + this.realThread = new Thread(this); + this.realThread.start(); + } + + public static RealG2 get() { + return instance; + } + + @Override + public void run() { + boolean initerror = false; + this.cancel = false; + Main.register(this); + + while (!this.cancel) { + if (!this.requestList.isEmpty()) { + CDAudio.get().setEnabled(false); + } + + while (!this.requestList.isEmpty()) { + this.startPlaying(); + + try { + initRealG2(); + } catch (IOException var5) { + this.cancel = true; + initerror = true; + } + + while (!this.requestList.isEmpty()) { + RealG2.RG2Request request = this.requestList.firstElement(); + this.requestList.removeElementAt(0); + + try { + this.browse(request.getURL(), request.getPosition()); + } catch (IOException var4) { + } + } + + if (!initerror) { + closeRealG2(); + } + + this.stopPlaying(); + if (this.requestList.isEmpty()) { + CDAudio.get().setEnabled(true); + } + } + + if (!this.cancel) { + this.timedWait(15); + } + } + + Main.unregister(this); + } + + private synchronized void timedWait(int secs) { + if (!this.cancel) { + try { + this.wait(secs * 1000); + } catch (InterruptedException var3) { + } + } + } + + private synchronized void startPlaying() { + this.isPlaying = true; + } + + private synchronized void stopPlaying() { + this.isPlaying = false; + } + + public synchronized boolean playing() { + return this.isPlaying; + } + + public void pleaseStopNow() { + if (this.playing()) { + this.setPlayInterrupt(); + + while (this.playing()) { + try { + this.wait(500L); + } catch (InterruptedException var2) { + } + } + } + } + + public void pleaseStop() { + this.setPlayInterrupt(); + } + + public static boolean isInstalled() { + IniFile ini = new IniFile("RealPlayer"); + return ini.getIniInt("HasReal", 0) != 0; + } + + public void play(String urlin) throws IOException { + this.play(urlin, null); + } + + public void play(String urlin, Rectangle placementin) throws IOException { + if (!isInstalled()) { + throw new IOException(); + } else { + RealG2.RG2Request r = new RealG2.RG2Request(urlin, placementin); + this.requestList.addElement(r); + this.setPlayInterrupt(); + this.realThread.interrupt(); + } + } + + private Rectangle getAdPartPlacement() { + Rectangle placement = null; + Console c = Console.getActive(); + if (c != null) { + AdPart ap = null; + Enumeration<FramePart> e = c.getParts(); + + while (e.hasMoreElements()) { + Object o = e.nextElement(); + if (o instanceof AdPart) { + ap = (AdPart)o; + break; + } + } + + if (ap != null) { + placement = new Rectangle(ap.getLocationOnScreen(), new Dimension(ap.getWindow().fullWidth(), ap.getWindow().fullHeight())); + } + } + + return placement; + } + + private Rectangle getMapPartPlacement() { + Rectangle placement = null; + Console c = Console.getActive(); + if (c != null) { + MapPart ap = null; + Enumeration<FramePart> e = c.getParts(); + + while (e.hasMoreElements()) { + Object o = e.nextElement(); + if (o instanceof MapPart) { + ap = (MapPart)o; + break; + } + } + + if (ap != null) { + placement = new Rectangle(ap.getLocationOnScreen(), ap.getSize()); + } + } + + return placement; + } + + public void browse(String url, Rectangle placement) throws IOException { + int x = -1; + int y = -1; + int w = -1; + int h = -1; + if (placement != null) { + x = placement.x; + y = placement.y; + w = placement.width; + h = placement.height; + } else if ((placement = this.getMapPartPlacement()) != null) { + x = placement.x - 18; + y = placement.y - 34; + w = placement.width; + h = placement.height; + } + + try { + browse(url, x, y, w, h); + } catch (IOException var8) { + this.close(); + throw var8; + } + } + + @Override + public void mainCallback() { + } + + @Override + public void terminalCallback() { + this.close(); + } + + public void close() { + this.cancel = true; + playInterrupt(); + this.realThread.interrupt(); + } + + private static native void browse(String var0, int var1, int var2, int var3, int var4) throws IOException; + + private static native void initRealG2() throws IOException; + + private static native void closeRealG2(); + + private static native void playInterrupt(); + + public synchronized void setPlayInterrupt() { + if (this.playing()) { + playInterrupt(); + } + } + + public class RG2Request { + private String url = null; + private Rectangle position = null; + + public RG2Request(String u, Rectangle r) { + this.url = u; + this.position = r; + } + + public Rectangle getPosition() { + return this.position; + } + + public String getURL() { + return this.url; + } + } +} diff --git a/NET/worlds/console/RemoveHandler.java b/NET/worlds/console/RemoveHandler.java new file mode 100644 index 0000000..11e964b --- /dev/null +++ b/NET/worlds/console/RemoveHandler.java @@ -0,0 +1,93 @@ +package NET.worlds.console; + +import NET.worlds.scape.BumpEventTemp; +import NET.worlds.scape.BumpHandler; +import NET.worlds.scape.NoSuchPropertyException; +import NET.worlds.scape.Portal; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Room; +import NET.worlds.scape.Saver; +import NET.worlds.scape.SuperRoot; +import NET.worlds.scape.TooNewException; +import NET.worlds.scape.VectorProperty; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; + +public class RemoveHandler extends SuperRoot implements BumpHandler { + private Vector<Object> handlers = new Vector<Object>(1); + private static Object classCookie = new Object(); + + public RemoveHandler() { + } + + public RemoveHandler(SuperRoot oldhandler) { + this.handlers.addElement(oldhandler); + } + + @Override + public boolean handle(BumpEventTemp e) { + Room sc = ((Portal)e.target).getRoom(); + + assert sc instanceof Staircase || sc instanceof Stair; + + Enumeration<Object> enh = this.handlers.elements(); + + while (enh.hasMoreElements()) { + SuperRoot handler = (SuperRoot)enh.nextElement(); + if (sc.hasHandler(handler)) { + sc.removeHandler(handler); + } + } + + return true; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(2, classCookie); + super.saveState(s); + s.saveVector(this.handlers); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + switch (r.restoreVersion(classCookie)) { + case 1: + super.restoreState(r); + case 0: + if (r.restoreBoolean()) { + this.handlers.addElement(r.restore()); + } + break; + case 2: + super.restoreState(r); + this.handlers = r.restoreVector(); + break; + default: + throw new TooNewException(); + } + } + + @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 VectorProperty(this, index, "Handlers to Remove"); + } else if (mode == 1) { + ret = this.handlers.clone(); + } else if (mode == 4) { + this.handlers.removeElement(value); + } else if (mode == 3) { + this.handlers.addElement(value); + } + break; + default: + ret = super.properties(index, offset + 1, mode, value); + } + + return ret; + } +} diff --git a/NET/worlds/console/RenderCanvas.java b/NET/worlds/console/RenderCanvas.java new file mode 100644 index 0000000..619accd --- /dev/null +++ b/NET/worlds/console/RenderCanvas.java @@ -0,0 +1,233 @@ +package NET.worlds.console; + +import NET.worlds.scape.Camera; +import NET.worlds.scape.EventQueue; +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.LibraryDropTarget; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.ToolTipManager; +import java.awt.Canvas; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.IllegalComponentStateException; +import java.awt.Point; +import java.util.Enumeration; +import java.util.Vector; + +public class RenderCanvas extends Canvas implements FramePart, LibraryDropTarget { + private static final long serialVersionUID = -811200590685352009L; + DefaultConsole universeConsole; + private Window w; + private Dimension dim; + private Camera camera; + private int xRenderExtent; + private int yRenderExtent; + private boolean fullScreenOverlay = false; + private boolean mayNeedToResize; + private Vector<RenderCanvasOverlay> overlays; + + public RenderCanvas(Dimension d) { + this(null, d); + } + + public RenderCanvas(DefaultConsole dc, Dimension d) { + this.universeConsole = dc; + this.dim = d; + this.overlays = new Vector<RenderCanvasOverlay>(); + } + + public void drive() { + if (this.w != null && Pilot.getActiveRoom() != null) { + this.w.setDeltaMode(true); + } + } + + public boolean getDeltaMode() { + return this.w == null ? false : this.w.getDeltaMode(); + } + + @Override + public void activate(Console c, Container f, Console prev) { + } + + @Override + public void deactivate() { + } + + public void setCamera(Camera cam) { + this.camera = cam; + if (cam != null) { + cam.setCanvas(this); + } + } + + public Camera getCamera() { + return this.camera; + } + + public Window getWindow() { + return this.w; + } + + @Override + public void update(Graphics g) { + } + + @Override + public void paint(Graphics g) { + } + + @Override + public void reshape(int x, int y, int width, int height) { + super.reshape(x, y, width, height); + this.mayNeedToResize = true; + } + + @Override + public Dimension minimumSize() { + return this.dim; + } + + @Override + public Dimension preferredSize() { + return this.dim; + } + + public void addOverlay(RenderCanvasOverlay overlay) { + assert this.overlays != null; + + this.overlays.addElement(overlay); + this.mayNeedToResize = true; + } + + public void removeOverlay(RenderCanvasOverlay overlay) { + assert this.overlays != null; + + this.overlays.removeElement(overlay); + this.mayNeedToResize = true; + } + + private void computeOverlayDimensions() { + int minYPer = 100; + int minXPer = 100; + this.fullScreenOverlay = false; + Dimension size = this.getSize(); + if (this.overlays != null) { + Enumeration<RenderCanvasOverlay> e = this.overlays.elements(); + + while (e.hasMoreElements()) { + RenderCanvasOverlay o = e.nextElement(); + o.canvasResized(size.width, size.height); + if (o.isFullscreen()) { + this.fullScreenOverlay = true; + minYPer = 0; + minXPer = 0; + } + + int ox = 100 - o.getXPercent(); + int oy = 100 - o.getYPercent(); + if (ox < minXPer) { + minXPer = ox; + } + + if (oy < minYPer) { + minYPer = oy; + } + } + } + + if (minXPer == 0 && minYPer == 0) { + this.xRenderExtent = this.yRenderExtent = 0; + } else if (minXPer == 0) { + this.xRenderExtent = size.width; + this.yRenderExtent = (int)((double)size.height * minYPer * 0.01); + } else if (minYPer == 0) { + this.xRenderExtent = (int)((double)size.width * minXPer * 0.01); + this.yRenderExtent = size.height; + } else { + this.xRenderExtent = size.width; + this.yRenderExtent = size.height; + } + } + + @Override + public boolean handle(FrameEvent f) { + if (this.camera == null) { + return true; + } else if (!this.checkForWindow(true)) { + return true; + } else { + EventQueue.pollForEvents(this.camera); + if (this.w == null) { + return true; + } else { + if (this.mayNeedToResize) { + this.computeOverlayDimensions(); + this.w.maybeResize(this.xRenderExtent, this.yRenderExtent); + if (Window.usingMicrosoftVMHacks()) { + Point pt = this.getLocationOnScreen(); + Dimension dim = this.getSize(); + this.w.reShape(pt.x, pt.y, dim.width, dim.height); + } + + this.mayNeedToResize = false; + } + + if (this.camera != null) { + this.doRender(); + } + + return true; + } + } + } + + public boolean checkForWindow(boolean interceptEvents) { + if (this.w == null) { + String title = Console.getFrame().getTitle(); + if (title == null) { + return false; + } + + try { + this.w = new Window(title, this.getLocationOnScreen(), this.getSize(), this.camera, interceptEvents); + } catch (IllegalComponentStateException var4) { + return false; + } catch (WindowNotFoundException var5) { + return false; + } + + this.mayNeedToResize = false; + } + + return true; + } + + private synchronized void doRender() { + if (this.universeConsole != null && this.universeConsole.isUniverseMode()) { + ToolTipManager.toolTipManager().killToolTip(); + if (this.w != null) { + this.w.hideNativeWindow(); + } + } else { + ToolTipManager.toolTipManager().heartbeat(); + this.w.showNativeWindow(); + if (this.fullScreenOverlay) { + ToolTipManager.toolTipManager().killToolTip(); + } else { + this.camera.renderToCanvas(); + } + } + } + + @Override + public void removeNotify() { + if (this.w != null) { + this.w.dispose(); + this.w = null; + } + + super.removeNotify(); + } +} diff --git a/NET/worlds/console/RenderCanvasOverlay.java b/NET/worlds/console/RenderCanvasOverlay.java new file mode 100644 index 0000000..dfc33e7 --- /dev/null +++ b/NET/worlds/console/RenderCanvasOverlay.java @@ -0,0 +1,129 @@ +package NET.worlds.console; + +public abstract class RenderCanvasOverlay { + private RenderCanvas canvas; + private int xPercent; + private int yPercent; + private int xFixed; + private int yFixed; + private boolean isFixed; + private boolean fullscreen; + private int hwnd; + private boolean allowFocus; + + public RenderCanvasOverlay(RenderCanvas pCanvas, int pX, int pY, boolean pIsFixed, boolean pAllowFocus) throws NoWebControlException { + assert pX > 0 || pY > 0; + + if (pCanvas != null && pCanvas.getWindow() != null) { + this.canvas = pCanvas; + this.isFixed = pIsFixed; + this.allowFocus = pAllowFocus; + if (this.isFixed) { + this.xFixed = pX; + this.yFixed = pY; + this.xPercent = this.yPercent = 1; + } else { + this.xPercent = pX; + this.yPercent = pY; + } + + this.fullscreen = false; + } else { + throw new NoWebControlException("RenderCanvas does not exist"); + } + } + + public RenderCanvasOverlay(RenderCanvas pCanvas) { + assert pCanvas != null; + + this.canvas = pCanvas; + this.xPercent = this.yPercent = 100; + this.isFixed = false; + this.allowFocus = true; + this.fullscreen = true; + this.hwnd = this.canvas.getWindow().getHwnd(); + } + + public void activate() { + this.canvas.addOverlay(this); + } + + int getNativeWindowHandle() { + assert this.canvas.getWindow() != null; + + if (this.hwnd == 0) { + if (this.fullscreen) { + this.hwnd = this.canvas.getWindow().getHwnd(); + } else { + this.hwnd = this.nativeMakeChild(this.canvas.getWindow().getHwnd(), this.xPercent, this.yPercent, this.allowFocus); + } + } + + return this.hwnd; + } + + int getXPercent() { + return this.xPercent; + } + + int getYPercent() { + return this.yPercent; + } + + int getFixedWidth() { + return this.xFixed; + } + + int getFixedHeight() { + return this.yFixed; + } + + boolean getIsFixedSize() { + return this.isFixed; + } + + void canvasResized(int parentX, int parentY) { + int w; + int h; + if (this.isFixed) { + w = this.xFixed; + h = this.yFixed; + if (w > parentX) { + w = parentX; + } + + if (h > parentY) { + h = parentY; + } + + this.xPercent = (int)Math.ceil((double)w / parentX * 100.0); + this.yPercent = (int)Math.ceil((double)h / parentY * 100.0); + } else { + w = (int)(parentX * this.xPercent * 0.01); + h = (int)(parentY * this.yPercent * 0.01); + } + + if (this.hwnd != 0) { + this.nativeResizeChild(this.hwnd, w, h); + } + } + + boolean isFullscreen() { + return this.fullscreen || !this.isFixed && this.xPercent == 100 && this.yPercent == 100; + } + + protected abstract void handleCommand(int var1); + + void detach() { + this.canvas.removeOverlay(this); + if (!this.fullscreen && this.hwnd != 0) { + this.nativeKillChild(this.hwnd); + } + } + + private native int nativeMakeChild(long var1, int var3, int var4, boolean var5); + + private native void nativeKillChild(long var1); + + private native void nativeResizeChild(int var1, int var2, int var3); +} diff --git a/NET/worlds/console/RightMenu.java b/NET/worlds/console/RightMenu.java new file mode 100644 index 0000000..832f0a4 --- /dev/null +++ b/NET/worlds/console/RightMenu.java @@ -0,0 +1,119 @@ +package NET.worlds.console; + +import NET.worlds.scape.Action; +import NET.worlds.scape.RunningActionHandler; +import NET.worlds.scape.WObject; +import java.util.Enumeration; +import java.util.Hashtable; + +public class RightMenu implements MainCallback { + private static RightMenu _current = null; + private WObject _obj; + private Enumeration<Action> _acts; + private Hashtable<Integer, Action> _inttobuttons = new Hashtable<Integer, Action>(); + private int _edit = 0; + private int _pm = 0; + private int _lastID = 0; + + public RightMenu(WObject obj, Enumeration<Action> acts) { + this._obj = obj; + this._acts = acts; + Main.register(this); + } + + private int add(String label) { + if (this._lastID == 0) { + this._lastID = 100; + } + + int id = this._lastID++; + + assert this._lastID < 200; + + nativeAdd(label, id, this._pm); + return id; + } + + private static native int create(); + + private static native void nativeAdd(String var0, int var1, int var2); + + private static native void addSeparator(int var0); + + private static native void show(int var0, int var1); + + private static native void discard(int var0); + + private static native int checkPressed(); + + private void build(Enumeration<Action> acts) { + if (_current != null) { + _current.close(); + } + + _current = this; + int rows = 0; + Hashtable<String, Action> buttons = new Hashtable<String, Action>(); + + while (acts.hasMoreElements()) { + Action act = acts.nextElement(); + String label = act.rightMenuLabel; + if (label != null && label != "") { + buttons.put(label, act); + rows++; + } + } + + if (rows <= 0 && Gamma.getShaper() == null) { + this.close(); + } else { + this._pm = create(); + if (Gamma.getShaper() != null) { + this._edit = this.add("Edit Properties..."); + if (rows > 0) { + addSeparator(this._pm); + } + } + + Enumeration<String> en = buttons.keys(); + + while (en.hasMoreElements()) { + String label = en.nextElement(); + this._inttobuttons.put(new Integer(this.add(label)), buttons.get(label)); + } + + show(Window.getHWnd(), this._pm); + } + } + + private void close() { + discard(this._pm); + this._pm = 0; + Main.unregister(this); + _current = null; + } + + private void checkButton() { + int pressed = checkPressed(); + if (pressed != 0) { + if (pressed == this._edit) { + Console.getFrame().getEditTile().viewProperties(this._obj); + } else { + Action action = this._inttobuttons.get(new Integer(pressed)); + RunningActionHandler.trigger(action, this._obj.getWorld(), null); + } + + this.close(); + } + } + + @Override + public void mainCallback() { + if (this._acts != null) { + this.build(this._acts); + this._acts = null; + } else { + this.checkButton(); + } + } +} diff --git a/NET/worlds/console/SavedAvAddDialog.java b/NET/worlds/console/SavedAvAddDialog.java new file mode 100644 index 0000000..ee7f128 --- /dev/null +++ b/NET/worlds/console/SavedAvAddDialog.java @@ -0,0 +1,79 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Panel; +import java.awt.TextField; + +class SavedAvAddDialog extends PolledDialog { + private static final long serialVersionUID = 6413925837010864629L; + private TextField nameField = new TextField(40); + private Button okButton = new Button(Console.message("OK")); + private Button cancelButton = new Button(Console.message("Cancel")); + private String newName; + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + + public SavedAvAddDialog(java.awt.Window parent, SavedAvPart avatars) { + super(parent, avatars, Console.message("Save-Avatar"), true); + this.ready(); + } + + @Override + protected void build() { + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.fill = 0; + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 2; + c.gridheight = 1; + this.add(gbag, new Label(Console.message("Name")), c); + c.gridwidth = 0; + c.fill = 2; + this.nameField.setFont(font); + this.add(gbag, this.nameField, c); + Panel buttons = new Panel(); + this.okButton.setFont(bfont); + this.cancelButton.setFont(bfont); + buttons.add(this.okButton); + buttons.add(this.cancelButton); + c.gridwidth = 0; + c.fill = 0; + this.add(gbag, buttons, c); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.okButton && this.mayConfirm()) { + return this.done(true); + } else { + return target == this.cancelButton ? this.done(false) : false; + } + } + + @Override + public String getName() { + return this.newName; + } + + private boolean mayConfirm() { + this.newName = this.nameField.getText().trim(); + return this.newName.length() != 0; + } + + @Override + public boolean keyDown(Event event, int key) { + if (key == 27) { + return this.done(false); + } else { + return key == 10 && this.mayConfirm() ? this.done(true) : super.keyDown(event, key); + } + } +} diff --git a/NET/worlds/console/SavedAvDeleteDialog.java b/NET/worlds/console/SavedAvDeleteDialog.java new file mode 100644 index 0000000..bd4ed83 --- /dev/null +++ b/NET/worlds/console/SavedAvDeleteDialog.java @@ -0,0 +1,119 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.List; + +class SavedAvDeleteDialog extends PolledDialog { + private static final long serialVersionUID = 1L; + private List listbox = new List(10); + private Button delButton = new Button(Console.message("Delete")); + private Button cancelButton = new Button(Console.message("Done")); + private SavedAvPart avatars; + + SavedAvDeleteDialog(SavedAvPart avatars) { + super(Console.getFrame(), null, Console.message("Delete-Avatar"), true); + this.avatars = avatars; + this.ready(); + } + + @Override + protected void build() { + int count = SavedAvPart.getAvatarCount(); + + for (int i = 0; i < count; i++) { + this.listbox.addItem(SavedAvPart.getAvatarName(i)); + } + + Label caption = new Label(Console.message("Choose-Avatar")); + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.fill = 2; + c.gridwidth = 0; + c.gridheight = 1; + c.weightx = 1.0; + c.weighty = 0.0; + this.add(gbag, caption, c); + c.fill = 1; + c.gridwidth = 0; + c.gridheight = 6; + c.weightx = 1.0; + c.weighty = 1.0; + this.add(gbag, this.listbox, c); + c.fill = 0; + c.gridwidth = -1; + c.gridheight = 0; + c.anchor = 14; + c.weightx = 0.45; + c.weighty = 0.0; + this.add(gbag, this.delButton, c); + c.gridwidth = 0; + c.anchor = 16; + c.weightx = 0.55; + this.add(gbag, this.cancelButton, c); + } + + private void select(boolean state) { + this.delButton.setEnabled(state); + } + + @Override + public void show() { + super.show(); + if (this.listbox.countItems() != 0) { + this.listbox.select(0); + this.select(true); + } else { + this.select(false); + } + + this.listbox.requestFocus(); + } + + @Override + public boolean handleEvent(Event event) { + if (event.id == 701) { + this.select(true); + } else if (event.id == 702) { + this.select(false); + } + + return super.handleEvent(event); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.cancelButton) { + return this.done(false); + } else if (target == this.delButton) { + int index = this.listbox.getSelectedIndex(); + if (index != -1) { + this.listbox.remove(index); + this.avatars.removeAvatar(index); + int count = this.listbox.getItemCount(); + if (index < count - 1) { + this.listbox.select(index); + } else if (count > 0) { + this.listbox.select(count - 1); + } else { + this.select(false); + this.listbox.requestFocus(); + } + } + + return true; + } else { + return false; + } + } + + @Override + public boolean keyDown(Event event, int key) { + return key != 27 && key != 10 ? super.keyDown(event, key) : this.done(false); + } +} diff --git a/NET/worlds/console/SavedAvMenuItem.java b/NET/worlds/console/SavedAvMenuItem.java new file mode 100644 index 0000000..b819a91 --- /dev/null +++ b/NET/worlds/console/SavedAvMenuItem.java @@ -0,0 +1,53 @@ +package NET.worlds.console; + +import NET.worlds.scape.Persister; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Saver; +import NET.worlds.scape.TooNewException; +import java.awt.CheckboxMenuItem; +import java.io.IOException; + +public class SavedAvMenuItem extends CheckboxMenuItem implements Persister { + private static final long serialVersionUID = 4876455058245955809L; + private String avatar; + private static Object classCookie = new Object(); + + public SavedAvMenuItem(String name, String avatar) { + super(name); + this.avatar = avatar; + } + + public SavedAvMenuItem() { + } + + public String getAvatar() { + return this.avatar; + } + + public void setAvatar(String av) { + this.avatar = av; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(1, classCookie); + s.saveString(this.getLabel()); + s.saveString(this.avatar); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + switch (r.restoreVersion(classCookie)) { + case 1: + this.setLabel(r.restoreString()); + this.avatar = r.restoreString(); + return; + default: + throw new TooNewException(); + } + } + + @Override + public void postRestore(int version) { + } +} diff --git a/NET/worlds/console/SavedAvPart.java b/NET/worlds/console/SavedAvPart.java new file mode 100644 index 0000000..73d2b6a --- /dev/null +++ b/NET/worlds/console/SavedAvPart.java @@ -0,0 +1,155 @@ +package NET.worlds.console; + +import NET.worlds.network.URL; +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Saver; +import java.awt.CheckboxMenuItem; +import java.awt.Container; +import java.awt.Event; +import java.awt.Font; +import java.awt.Menu; +import java.awt.MenuItem; +import java.util.Vector; + +public class SavedAvPart extends Menu implements FramePart, DialogReceiver { + private static final long serialVersionUID = -3931139364330871273L; + private static final int firstUserItem = 3; + private static final String avsFileName = "Gamma.avatars"; + private static URL savedAvsURL = URL.make("home:Gamma.avatars"); + private static Vector<Object> savedAvatars; + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private Menu menu; + private MenuItem saveItem = new MenuItem(Console.message("Save-Avatar")); + private MenuItem deleteItem = new MenuItem(Console.message("Delete-Avatar")); + private DefaultConsole console; + + public SavedAvPart() { + super(Console.message("Saved-Avatars")); + if (savedAvatars == null) { + loadAvatars(); + } + } + + private static void loadAvatars() { + try { + Restorer r = new Restorer(savedAvsURL); + savedAvatars = r.restoreVector(); + r.done(); + } catch (Exception var1) { + savedAvatars = new Vector<Object>(); + } + } + + private static void saveAvatars() { + try { + Saver s = new Saver(savedAvsURL); + s.saveVector(savedAvatars); + s.done(); + } catch (Exception var1) { + } + } + + static int getAvatarCount() { + return savedAvatars.size(); + } + + private static SavedAvMenuItem getAvatar(int index) { + return (SavedAvMenuItem)savedAvatars.elementAt(index); + } + + static String getAvatarName(int index) { + return getAvatar(index).getLabel(); + } + + static String getAvatarAvatar(int index) { + return getAvatar(index).getAvatar(); + } + + private SavedAvMenuItem addAvatar(String name, String avatar) { + SavedAvMenuItem item = new SavedAvMenuItem(name, avatar); + item.setFont(font); + this.add(item); + savedAvatars.addElement(item); + saveAvatars(); + return item; + } + + void removeAvatar(int index) { + Object item = savedAvatars.elementAt(index); + savedAvatars.removeElementAt(index); + this.remove(index + 3); + saveAvatars(); + this.console.deletedSavedAvatar((CheckboxMenuItem)item); + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + if (confirmed) { + SavedAvAddDialog adder = (SavedAvAddDialog)who; + URL avName = this.console.getDefaultAvatarURL(); + if (avName != null) { + this.console.setCurrentAvatarItem(this.addAvatar(adder.getName(), avName.getAbsolute())); + } + } + } + + @Override + public void activate(Console c, Container f, Console prev) { + this.console = (DefaultConsole)c; + this.saveItem.setFont(font); + this.deleteItem.setFont(font); + this.add(this.saveItem); + this.add(this.deleteItem); + this.addSeparator(); + + for (int i = 0; i < savedAvatars.size(); i++) { + MenuItem item = (MenuItem)savedAvatars.elementAt(i); + item.setFont(font); + this.add(item); + } + } + + @Override + public void deactivate() { + this.removeAll(); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.saveItem) { + new SavedAvAddDialog(Console.getFrame(), this); + } else if (target == this.deleteItem) { + new SavedAvDeleteDialog(this); + } else { + if (!(target instanceof SavedAvMenuItem)) { + return false; + } + + SavedAvMenuItem item = (SavedAvMenuItem)target; + this.console.setNextAvatar(URL.make(item.getAvatar()), item); + } + + return true; + } + + @Override + public boolean handle(FrameEvent f) { + return true; + } + + public CheckboxMenuItem findMenuItem(URL url) { + String name = url.getAbsolute(); + int count = getAvatarCount(); + + for (int i = 0; i < count; i++) { + SavedAvMenuItem item = getAvatar(i); + if (item.getAvatar().equals(name)) { + return item; + } + } + + return null; + } +} diff --git a/NET/worlds/console/ScapePicCanvas.java b/NET/worlds/console/ScapePicCanvas.java new file mode 100644 index 0000000..44c8d7a --- /dev/null +++ b/NET/worlds/console/ScapePicCanvas.java @@ -0,0 +1,55 @@ +package NET.worlds.console; + +import java.awt.Canvas; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Point; + +public class ScapePicCanvas extends Canvas { + private static final long serialVersionUID = 927951584800056826L; + private int hWnd; + + public void drawScapePicImage(ScapePicImage image, int xDst, int yDst, int xSrc, int ySrc, int width, int height) { + if (this.hWnd == 0) { + Point loc = this.locationInWindow(); + Dimension size = this.getSize(); + String title = this.getFrameTitle(); + + assert title != null; + + int hWndParent = Window.findWindow(title); + + assert hWndParent != 0; + + this.hWnd = Window.findChildWindow(hWndParent, loc.x, loc.y, size.width, size.height); + + assert this.hWnd != 0; + } + + bitBlt(this.hWnd, image.getDIB(), xDst, yDst, xSrc, ySrc, width, height); + } + + private String getFrameTitle() { + for (Container c = this.getParent(); c != null; c = c.getParent()) { + if (c instanceof Frame) { + return ((Frame)c).getTitle(); + } + } + + return null; + } + + private Point locationInWindow() { + Point offset = this.location(); + + for (Container c = this.getParent(); c != null; c = c.getParent()) { + Point move = c.location(); + offset.translate(move.x, move.y); + } + + return offset; + } + + public static native void bitBlt(int var0, int var1, int var2, int var3, int var4, int var5, int var6, int var7); +} diff --git a/NET/worlds/console/ScapePicImage.java b/NET/worlds/console/ScapePicImage.java new file mode 100644 index 0000000..ca315a4 --- /dev/null +++ b/NET/worlds/console/ScapePicImage.java @@ -0,0 +1,37 @@ +package NET.worlds.console; + +import NET.worlds.network.URL; + +public class ScapePicImage { + private int hDIB; + private int width; + private int height; + + public ScapePicImage(URL url) { + nativeInit(); + this.loadImage(url.unalias()); + } + + public int getWidth() { + return this.width; + } + + public int getHeight() { + return this.height; + } + + public native void flush(); + + @Override + public void finalize() { + this.flush(); + } + + int getDIB() { + return this.hDIB; + } + + private native void loadImage(String var1); + + public static native void nativeInit(); +} diff --git a/NET/worlds/console/ScapePicPanel.java b/NET/worlds/console/ScapePicPanel.java new file mode 100644 index 0000000..29f5f75 --- /dev/null +++ b/NET/worlds/console/ScapePicPanel.java @@ -0,0 +1,150 @@ +package NET.worlds.console; + +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Panel; +import java.awt.Point; + +public class ScapePicPanel extends Panel { + private static final long serialVersionUID = -1019314311757410999L; + private static final int QUARTERED = 0; + private static final int UPPERLEFT = 1; + private ScapePicImage image = null; + private int hWnd; + private int drawMode = 0; + + public ScapePicPanel() { + this(null); + } + + public ScapePicPanel(ScapePicImage image) { + this.setImage(image); + } + + public void setImage(ScapePicImage image) { + this.image = image; + } + + @Override + public void paint(Graphics g) { + this.drawBackground(); + super.paint(g); + } + + @Override + public void update(Graphics g) { + this.paint(g); + } + + public void setQuartered() { + this.drawMode = 0; + } + + public void setUpperLeft() { + this.drawMode = 1; + } + + private void drawBackground() { + assert this.drawMode == 1 || this.drawMode == 0; + + if (this.image != null) { + Dimension size = this.getSize(); + + assert size != null; + + assert size.height >= 0 && size.width >= 0; + + if (this.drawMode == 1) { + for (int j = 0; j < size.height; j += this.image.getHeight()) { + for (int i = 0; i < size.width; i += this.image.getWidth()) { + this.drawScapePicImage(this.image, i, j, 0, 0, this.image.getWidth(), this.image.getHeight()); + } + } + } + + if (this.drawMode == 0) { + int cx = size.width / 2; + int cy = size.height / 2; + + for (int j = 0; j < cy; j += this.image.getHeight()) { + for (int i = 0; i < cx; i += this.image.getWidth()) { + int endX = Math.min(cx - i, this.image.getWidth()); + int endY = Math.min(cy - j, this.image.getHeight()); + this.drawScapePicImage(this.image, i, j, 0, 0, endX, endY); + } + } + + for (int j = 0; j < cy; j += this.image.getHeight()) { + for (int i = size.width; i > cx; i -= this.image.getWidth()) { + int startX = Math.max(i - this.image.getWidth(), cx); + int imageStartX = this.image.getWidth() - (i - startX); + int endY = Math.min(cy - j, this.image.getHeight()); + this.drawScapePicImage(this.image, startX, j, imageStartX, 0, i - startX, endY); + } + } + + for (int j = size.height; j > cy; j -= this.image.getHeight()) { + for (int i = 0; i < cx; i += this.image.getWidth()) { + int endX = Math.min(cx - i, this.image.getWidth()); + int startY = Math.max(j - this.image.getHeight(), cy); + int imageStartY = this.image.getHeight() - (j - startY); + this.drawScapePicImage(this.image, i, startY, 0, imageStartY, endX, j - startY); + } + } + + for (int j = size.height; j > cy; j -= this.image.getHeight()) { + for (int i = size.width; i > cx; i -= this.image.getWidth()) { + int startX = Math.max(i - this.image.getWidth(), cx); + int imageStartX = this.image.getWidth() - (i - startX); + int startY = Math.max(j - this.image.getHeight(), cy); + int imageStartY = this.image.getHeight() - (j - startY); + this.drawScapePicImage(this.image, startX, startY, imageStartX, imageStartY, i - startX, j - startY); + } + } + } + } + } + + public void drawScapePicImage(ScapePicImage image, int xDst, int yDst, int xSrc, int ySrc, int width, int height) { + if (this.hWnd == 0) { + Point loc = this.locationInWindow(); + Dimension size = this.getSize(); + String title = this.getFrameTitle(); + + assert title != null; + + int hWndParent = Window.findWindow(title); + + assert hWndParent != 0; + + this.hWnd = Window.findChildWindow(hWndParent, loc.x, loc.y, size.width, size.height); + + assert this.hWnd != 0; + } + + ScapePicCanvas.bitBlt(this.hWnd, image.getDIB(), xDst, yDst, xSrc, ySrc, width, height); + } + + private String getFrameTitle() { + for (Container c = this.getParent(); c != null; c = c.getParent()) { + if (c instanceof Frame) { + return ((Frame)c).getTitle(); + } + } + + return null; + } + + private Point locationInWindow() { + Point offset = this.location(); + + for (Container c = this.getParent(); c != null; c = c.getParent()) { + Point move = c.location(); + offset.translate(move.x, move.y); + } + + return offset; + } +} diff --git a/NET/worlds/console/SetNumVisibleAvs.java b/NET/worlds/console/SetNumVisibleAvs.java new file mode 100644 index 0000000..b1fea7d --- /dev/null +++ b/NET/worlds/console/SetNumVisibleAvs.java @@ -0,0 +1,101 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.network.Galaxy; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.CheckboxGroup; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.Label; +import java.awt.Panel; + +public class SetNumVisibleAvs extends PolledDialog { + private static final long serialVersionUID = -1189914406658113132L; + private Button okButton = new Button(Console.message("Apply-Vis")); + CheckboxGroup numAvsChoice = new CheckboxGroup(); + CheckboxGroup fullAvsChoice = new CheckboxGroup(); + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + + public SetNumVisibleAvs() { + super(Console.getFrame(), null, Console.message("Num-Visible"), true); + this.ready(); + } + + @Override + protected void build() { + this.setLayout(new BorderLayout()); + this.add("North", new Filler(5, 5)); + this.add("South", new Filler(10, 10)); + this.add("East", new Filler(5, 5)); + this.add("West", new Filler(5, 5)); + Panel main = new Panel(new BorderLayout()); + main.setFont(font); + main.add("North", new MultiLineLabel(Console.message("sel-max-av"), 5, 5)); + Panel choices = new Panel(new GridLayout(10, 2)); + int numAvs = IniFile.gamma().getIniInt("avatars", 24); + choices.add(new Label("")); + choices.add(new Label(Console.message("Max-Avs"))); + choices.add(new Label(Console.message("Slower"), 1)); + choices.add(new Checkbox("100", this.numAvsChoice, numAvs == 100)); + choices.add(new Label("")); + choices.add(new Checkbox("80", this.numAvsChoice, numAvs == 80)); + choices.add(new Label("")); + choices.add(new Checkbox("60", this.numAvsChoice, numAvs == 60)); + choices.add(new Label("")); + choices.add(new Checkbox("40", this.numAvsChoice, numAvs == 40)); + choices.add(new Label("")); + choices.add(new Checkbox("32", this.numAvsChoice, numAvs == 32)); + choices.add(new Label("")); + choices.add(new Checkbox("24", this.numAvsChoice, numAvs == 24)); + choices.add(new Label("")); + choices.add(new Checkbox("16", this.numAvsChoice, numAvs == 16)); + choices.add(new Label("")); + choices.add(new Checkbox("8", this.numAvsChoice, numAvs == 8)); + choices.add(new Label(Console.message("Faster"), 1)); + choices.add(new Checkbox("4", this.numAvsChoice, numAvs == 4)); + main.add("Center", choices); + main.add("South", this.okButton); + this.add("Center", main); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.okButton) { + this.done(true); + return true; + } else { + return false; + } + } + + @Override + protected boolean done(boolean confirmed) { + if (confirmed) { + Checkbox c = this.numAvsChoice.getSelectedCheckbox(); + if (c != null) { + try { + IniFile.gamma().setIniInt("avatars", Integer.parseInt(c.getLabel())); + } catch (NumberFormatException var5) { + } + } + + c = this.fullAvsChoice.getSelectedCheckbox(); + if (c != null) { + try { + String s = c.getLabel(); + s = s.substring(0, s.length() - 1); + IniFile.gamma().setIniInt("fullavpercent", Integer.parseInt(s)); + } catch (NumberFormatException var4) { + } + } + + Galaxy.forceOffline(true); + } + + return super.done(confirmed); + } +} diff --git a/NET/worlds/console/Shaper.java b/NET/worlds/console/Shaper.java new file mode 100644 index 0000000..eb9644d --- /dev/null +++ b/NET/worlds/console/Shaper.java @@ -0,0 +1,277 @@ +package NET.worlds.console; + +import NET.worlds.network.URL; +import NET.worlds.scape.LoadedURLSelf; +import NET.worlds.scape.Manifest; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Saver; +import NET.worlds.scape.TeleportAction; +import NET.worlds.scape.URLSelf; +import NET.worlds.scape.World; +import java.awt.Container; +import java.awt.Event; +import java.awt.Menu; +import java.awt.MenuItem; +import java.io.IOException; +import java.util.Enumeration; + +public class Shaper implements MainCallback, DialogReceiver, LoadedURLSelf { + MenuItem newItem; + MenuItem openItem; + MenuItem saveItem; + MenuItem propItem; + MenuItem consolePropItem; + MenuItem pilotPropItem; + MenuItem undoItem; + MenuItem cutItem; + MenuItem copyItem; + MenuItem pasteItem; + MenuItem sortAttributesItem; + MenuItem snapToolItem; + MenuItem newLibraryItem; + MenuItem newLibraryEntryItem; + MenuItem iconsVisibleLibraryItem; + Menu worldsMenu; + MenuItem shaperVisibleItem; + private World newWorldTemplate; + private boolean makeNew = true; + private static URL newworld = URL.make("home:NewWorld.world"); + private boolean quitFlag; + private FileSaver fileSaver; + private boolean worldListHasChanged = false; + + public Shaper() { + Main.register(this); + } + + public void activate(Console c, Container f, Console prev) { + this.newItem = c.addMenuItem(Console.message("New"), "File", 78, false); + this.openItem = c.addMenuItem(Console.message("Open"), "File", 79, false); + this.saveItem = c.addMenuItem(Console.message("Save"), "File", 83, false); + this.propItem = c.addMenuItem(Console.message("World-Prop"), "File"); + this.consolePropItem = c.addMenuItem(Console.message("Console-Prop"), "File"); + this.pilotPropItem = c.addMenuItem(Console.message("Pilot-Prop"), "File"); + this.undoItem = c.addMenuItem(Console.message("Undo"), "Edit", 90, false); + c.getMenu("Edit").addSeparator(); + this.cutItem = c.addMenuItem(Console.message("Cut"), "Edit", 88, false); + this.copyItem = c.addMenuItem(Console.message("Copy"), "Edit", 67, false); + this.pasteItem = c.addMenuItem(Console.message("Paste"), "Edit", 86, false); + this.sortAttributesItem = c.addMenuItem(Console.message("Sort-Attributes"), "Edit"); + this.snapToolItem = c.addMenuItem(Console.message("Snap-Tool-Settings"), "Edit"); + this.newLibraryItem = c.addMenuItem(Console.message("New-Library"), "Libraries"); + this.newLibraryEntryItem = c.addMenuItem(Console.message("New-Library-Entry"), "Libraries"); + this.iconsVisibleLibraryItem = c.addMenuItem(Console.message("Icons-On-Off"), "Libraries", 73, false); + this.worldsMenu = c.getMenu("Worlds"); + this.worldListChange(); + this.shaperVisibleItem = c.addMenuItem(Console.message("Shaper-On-Off"), "Options"); + } + + public void deactivate() { + this.worldsMenu = null; + } + + public boolean action(Event event, Object what) { + GammaFrame f = Console.getFrame(); + if (event.target == this.newItem) { + this.makeNew = true; + } else if (event.target == this.openItem) { + new FileSysDialog( + f, this, Console.message("Open-World"), 0, "World Save Files|*.world|World Class Files|*.class|World Files|*.class;*.world", "", true + ); + } else if (event.target == this.saveItem) { + new FileSysDialog(f, this, Console.message("Save-World"), 1, "World Save Files|*.world|World Manifest (text) Files|*.mft", this.getSaveName(), true); + } else if (event.target == this.propItem) { + if (Pilot.getActiveRoom() != null) { + f.getEditTile().viewProperties(Pilot.getActiveWorld()); + } + } else if (event.target == this.consolePropItem) { + f.getEditTile().viewProperties(Console.getActive()); + } else if (event.target == this.pilotPropItem) { + f.getEditTile().viewProperties(Pilot.getActive()); + } else if (event.target == this.sortAttributesItem) { + new AttributeSortPanel(f); + } else if (event.target == this.snapToolItem) { + new SnapToolPanel(f); + } else if (event.target == this.undoItem) { + f.getEditTile().undo(); + } else if (event.target == this.cutItem) { + f.getEditTile().cut(); + } else if (event.target == this.copyItem) { + f.getEditTile().copy(); + } else if (event.target == this.pasteItem) { + f.getEditTile().paste(); + } else if (event.target == this.newLibraryItem) { + f.getLibrariesTile().addLibrary(); + } else if (event.target == this.newLibraryEntryItem) { + f.getLibrariesTile().addElement(); + } else if (event.target == this.iconsVisibleLibraryItem) { + f.getLibrariesTile().setIconsVisible(!f.getLibrariesTile().isIconsVisible()); + } else if (event.target == this.shaperVisibleItem) { + f.setShaperVisible(!f.isShaperVisible()); + } else { + int i = this.worldsMenu.getItemCount(); + + do { + i--; + } while (i >= 0 && this.worldsMenu.getItem(i) != event.target); + + if (i < 0) { + return false; + } + + String url = (String)what; + if (url.endsWith(" (changed)")) { + url = url.substring(0, url.length() - 10); + } + + TeleportAction.teleport(url, null); + } + + return true; + } + + public String getSaveName() { + return getSaveName(Pilot.getActive().getWorld()); + } + + public static String getSaveName(World w) { + URL url = w.getSourceURL(); + String name = url.unalias(); + int index = name.indexOf(58); + return index != -1 && index != 1 ? url.getBase() : name.replace('/', '\\'); + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + if (confirmed) { + FileSysDialog fileDialog = (FileSysDialog)who; + String name = fileDialog.fileName(); + if (fileDialog.getMode() == 0) { + TeleportAction.teleport(name, null, true); + } else { + this.doSave(name); + } + } + } + + @Override + public void loadedURLSelf(URLSelf o, URL url, String err) { + this.newWorldTemplate = (World)o; + } + + @Override + public void mainCallback() { + if (this.quitFlag) { + if (this.fileSaver == null) { + this.fileSaver = new FileSaver(); + } + + switch (this.fileSaver.getState()) { + case 0: + GammaFrameState.saveBorder(); + Main.end(); + case 1: + default: + break; + case 2: + this.quitFlag = false; + this.fileSaver = null; + } + } + + if (this.newWorldTemplate != null) { + this.newWorldTemplate.incRef(); + } + + if (this.makeNew) { + this.makeNew = false; + if (this.newWorldTemplate == null) { + World.load(newworld, this, true); + } else { + World w = (World)this.newWorldTemplate.clone(); + w.setEdited(true); + TeleportAction.teleport(w.getSourceURL().getAbsolute(), null); + } + } + + if (this.worldListHasChanged) { + this.worldListHasChanged = false; + this.rebuildWorldsMenu(); + } + } + + public void maybeQuit() { + this.quitFlag = true; + } + + public void worldListChange() { + this.worldListHasChanged = true; + } + + private void rebuildWorldsMenu() { + if (this.worldsMenu != null) { + while (this.worldsMenu.getItemCount() > 0) { + this.worldsMenu.remove(0); + } + + Enumeration<World> e = World.getWorlds(); + + while (e.hasMoreElements()) { + World w = e.nextElement(); + URL url = w.getSourceURL(); + String name; + if (url == null) { + name = w.getName(); + } else { + name = url.getAbsolute(); + if (url.equals(newworld)) { + continue; + } + } + + if (w.getEdited()) { + name = name + " (changed)"; + } + + this.worldsMenu.add(new MenuItem(name)); + } + } + } + + public void doSave(String name) { + doSave(name, Pilot.getActive().getWorld(), true); + } + + public static boolean doSave(String name, World world, boolean allowManifest) { + if (allowManifest && name.endsWith(".mft")) { + try { + Manifest mft = new Manifest(name); + mft.saveProps(world); + mft.done(); + return true; + } catch (IOException var4) { + Console.println(Console.message("Error-manifest") + var4.toString()); + } + } else { + if (name.toLowerCase().endsWith(".wor")) { + name = name.substring(0, name.length() - 4); + } + + if (!name.toLowerCase().endsWith(".world")) { + name = name + ".world"; + } + + try { + Saver saver = new Saver(new URL(URL.getCurDir(), name)); + saver.save(world); + saver.done(); + world.setEdited(false); + return true; + } catch (IOException var5) { + Console.println(Console.message("Error-saving") + var5.toString()); + } + } + + return false; + } +} diff --git a/NET/worlds/console/SharedTextArea.java b/NET/worlds/console/SharedTextArea.java new file mode 100644 index 0000000..0f9d70b --- /dev/null +++ b/NET/worlds/console/SharedTextArea.java @@ -0,0 +1,39 @@ +package NET.worlds.console; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Point; + +interface SharedTextArea { + void validate(); + + void enableLogging(String var1, String var2, boolean var3); + + void disableLogging(); + + boolean canAddText(); + + void println(String var1); + + void scrollToBottom(); + + void poll(); + + void setBackground(Color var1); + + void repaint(); + + Component getComponent(); + + void setForeground(Color var1); + + Font getFont(); + + void setFont(Font var1); + + Point getLocationOnScreen(); + + Dimension getSize(); +} diff --git a/NET/worlds/console/SnapTool.java b/NET/worlds/console/SnapTool.java new file mode 100644 index 0000000..0a6af6b --- /dev/null +++ b/NET/worlds/console/SnapTool.java @@ -0,0 +1,114 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.scape.Point2; +import NET.worlds.scape.Point3Temp; + +public class SnapTool { + private static SnapTool theSnapTool = null; + private int snapX = 1; + private int snapY = 1; + private int snapZ = 1; + private boolean useSnap = false; + + public static SnapTool snapTool() { + if (theSnapTool == null) { + theSnapTool = new SnapTool(); + } + + return theSnapTool; + } + + private SnapTool() { + this.snapX = IniFile.gamma().getIniInt("Shaper.snapX", 100); + this.snapY = IniFile.gamma().getIniInt("Shaper.snapY", 100); + this.snapZ = IniFile.gamma().getIniInt("Shaper.snapZ", 1); + this.useSnap = IniFile.gamma().getIniInt("Shaper.useSnapTool", 0) != 0; + } + + public Point3Temp snapTo(Point3Temp inVal) { + if (!this.useSnap) { + return inVal; + } else { + float newX = this.snapTo(inVal.x, this.snapX); + float newY = this.snapTo(inVal.y, this.snapY); + float newZ = this.snapTo(inVal.z, this.snapZ); + return Point3Temp.make(newX, newY, newZ); + } + } + + public Point2 snapTo(Point2 inVal) { + if (!this.useSnap) { + return inVal; + } else { + float newX = this.snapTo(inVal.x, this.snapX); + float newY = this.snapTo(inVal.y, this.snapY); + return new Point2(newX, newY); + } + } + + public float snapTo(float oldVal, int snapIncrement) { + if (!this.useSnap) { + return oldVal; + } else { + int multiple = Math.round(oldVal / snapIncrement); + return multiple * snapIncrement; + } + } + + public int getSnapX() { + return this.snapX; + } + + public void setSnapX(int newVal) { + if (newVal > 0) { + this.snapX = newVal; + IniFile.gamma().setIniInt("Shaper.snapX", newVal); + } + } + + public int getSnapY() { + return this.snapY; + } + + public void setSnapY(int newVal) { + if (newVal > 0) { + this.snapY = newVal; + IniFile.gamma().setIniInt("Shaper.snapY", newVal); + } + } + + public int getSnapZ() { + return this.snapZ; + } + + public void setSnapZ(int newVal) { + if (newVal > 0) { + this.snapZ = newVal; + IniFile.gamma().setIniInt("Shaper.snapZ", newVal); + } + } + + public boolean useSnap() { + return this.useSnap; + } + + public void setSnap(boolean use) { + this.useSnap = use; + IniFile.gamma().setIniInt("Shaper.useSnapTool", use ? 1 : 0); + } + + public void print() { + System.out.println("SnapTool " + (this.useSnap ? "ON" : "OFF")); + System.out.println("SnapTool Settings: X=" + this.snapX + " Y=" + this.snapY + " Z=" + this.snapZ); + } + + public void test() { + this.setSnapX(150); + this.setSnapY(200); + this.setSnapY(-100); + this.setSnapY(0); + this.setSnapZ(5); + this.print(); + } +} diff --git a/NET/worlds/console/SnapToolPanel.java b/NET/worlds/console/SnapToolPanel.java new file mode 100644 index 0000000..460c065 --- /dev/null +++ b/NET/worlds/console/SnapToolPanel.java @@ -0,0 +1,135 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Label; +import java.awt.Point; +import java.awt.TextField; + +public class SnapToolPanel extends Frame implements MainCallback, MainTerminalCallback { + private static final long serialVersionUID = 1673536928568480266L; + private Label xLabel; + private Label yLabel; + private Label zLabel; + private TextField xValue; + private TextField yValue; + private TextField zValue; + private Checkbox useSnapBox; + private Button okButton = new Button("Ok"); + private Button cancelButton = new Button("Cancel"); + private int snapX; + private int snapY; + private int snapZ; + private boolean useSnap; + + public SnapToolPanel(java.awt.Window parent) { + super("Snap Tool Settings"); + this.xLabel = new Label("X Snap Value"); + this.yLabel = new Label("Y Snap Value"); + this.zLabel = new Label("Z Snap Value"); + this.snapX = SnapTool.snapTool().getSnapX(); + this.snapY = SnapTool.snapTool().getSnapY(); + this.snapZ = SnapTool.snapTool().getSnapZ(); + this.useSnap = SnapTool.snapTool().useSnap(); + this.useSnapBox = new Checkbox("Use Snap Tool", this.useSnap); + this.xValue = new TextField("" + this.snapX); + this.yValue = new TextField("" + this.snapY); + this.zValue = new TextField("" + this.snapZ); + GridBagLayout gbag = new GridBagLayout(); + GridBagConstraints c = new GridBagConstraints(); + this.setLayout(gbag); + this.setBackground(Color.gray); + c.gridx = 1; + c.gridy = 1; + c.gridheight = 1; + c.gridwidth = 1; + c.anchor = 18; + gbag.setConstraints(this.xLabel, c); + this.add(this.xLabel); + c.gridx = 2; + c.gridy = 1; + gbag.setConstraints(this.xValue, c); + this.add(this.xValue); + c.gridx = 1; + c.gridy = 2; + gbag.setConstraints(this.yLabel, c); + this.add(this.yLabel); + c.gridx = 2; + c.gridy = 2; + gbag.setConstraints(this.yValue, c); + this.add(this.yValue); + c.gridx = 1; + c.gridy = 3; + gbag.setConstraints(this.zLabel, c); + this.add(this.zLabel); + c.gridx = 2; + c.gridy = 3; + gbag.setConstraints(this.zValue, c); + this.add(this.zValue); + c.gridx = 2; + c.gridy = 5; + gbag.setConstraints(this.useSnapBox, c); + this.add(this.useSnapBox); + c.gridx = 5; + c.gridy = 1; + gbag.setConstraints(this.okButton, c); + this.add(this.okButton); + c.gridx = 5; + c.gridy = 2; + gbag.setConstraints(this.cancelButton, c); + this.add(this.cancelButton); + this.pack(); + Point loc = parent.location(); + Dimension size = parent.getSize(); + this.reshape(loc.x + (size.width - 320) / 2, loc.y + (size.height - 240) / 2, 320, 240); + this.show(); + Main.register(this); + } + + @Override + public boolean handleEvent(Event ev) { + switch (ev.id) { + case 201: + this.dispose(); + return true; + default: + return super.handleEvent(ev); + } + } + + @Override + public boolean action(Event e, Object o) { + if (e.target == this.cancelButton) { + this.dispose(); + return true; + } else if (e.target == this.okButton) { + this.snapX = Integer.parseInt(this.xValue.getText()); + this.snapY = Integer.parseInt(this.yValue.getText()); + this.snapZ = Integer.parseInt(this.zValue.getText()); + this.useSnap = this.useSnapBox.getState(); + SnapTool.snapTool().setSnap(this.useSnap); + SnapTool.snapTool().setSnapX(this.snapX); + SnapTool.snapTool().setSnapY(this.snapY); + SnapTool.snapTool().setSnapZ(this.snapZ); + this.dispose(); + return true; + } else { + return false; + } + } + + @Override + public void mainCallback() { + } + + @Override + public void terminalCallback() { + Main.unregister(this); + } +} diff --git a/NET/worlds/console/SplashCanvas.java b/NET/worlds/console/SplashCanvas.java new file mode 100644 index 0000000..9d7d499 --- /dev/null +++ b/NET/worlds/console/SplashCanvas.java @@ -0,0 +1,126 @@ +package NET.worlds.console; + +import java.awt.Canvas; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.Toolkit; +import java.util.Vector; + +class SplashCanvas extends Canvas { + private static final long serialVersionUID = 341168247494647821L; + protected String name; + protected Image image; + protected Dimension dim; + protected Vector<Overlay> overlays = new Vector<Overlay>(); + + SplashCanvas(String name) { + this.name = name; + } + + public void flush() { + this.image.flush(); + this.image = null; + + for (int i = 0; i < this.overlays.size(); i++) { + Overlay over = this.overlays.elementAt(i); + over.flush(); + } + + this.overlays.removeAllElements(); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + g.drawImage(this.image, 0, 0, this); + + for (int i = 0; i < this.overlays.size(); i++) { + Overlay over = this.overlays.elementAt(i); + over.paint(g, this); + } + } + + public void setImage(String name) { + this.name = name; + this.image = null; + this.imageSize(); + } + + public void addOverlay(String name, int x, int y) { + Overlay over = new Overlay(name, x, y); + Dimension dim = over.imageSize(this); + this.overlays.addElement(over); + this.repaint(x, y, dim.width, dim.height); + } + + public void removeOverlay(String name, int x, int y) { + for (int i = 0; i < this.overlays.size(); i++) { + Overlay over = this.overlays.elementAt(i); + if (over.matches(name, x, y)) { + Dimension dim = over.imageSize(this); + this.overlays.removeElementAt(i); + this.repaint(x, y, dim.width, dim.height); + return; + } + } + } + + private Dimension imageSize() { + if (this.image == null) { + this.image = getEarlyImage(this.name, this); + if (this.image != null) { + int width = this.image.getWidth(this); + int height = this.image.getHeight(this); + if (width != -1 && height != -1) { + return this.dim = new Dimension(width, height); + } + } + + this.dim = new Dimension(0, 0); + } + + for (int i = 0; i < this.overlays.size(); i++) { + Overlay over = this.overlays.elementAt(i); + over.imageSize(this); + } + + return this.dim; + } + + public static Image getEarlyImage(String name, Component comp) { + for (int pass = 0; pass < 2; pass++) { + String imagename = Gamma.earlyURLUnalias(name); + Image image = Toolkit.getDefaultToolkit().getImage(imagename); + MediaTracker tracker = new MediaTracker(comp); + tracker.addImage(image, 0); + + try { + tracker.waitForAll(); + } catch (InterruptedException var7) { + } + + if (!tracker.isErrorAny()) { + return image; + } + + if (pass == 0) { + name = "..\\" + name; + } + } + + return null; + } + + @Override + public Dimension preferredSize() { + return this.imageSize(); + } + + @Override + public Dimension minimumSize() { + return this.imageSize(); + } +} diff --git a/NET/worlds/console/SplashScreen.java b/NET/worlds/console/SplashScreen.java new file mode 100644 index 0000000..4ebf637 --- /dev/null +++ b/NET/worlds/console/SplashScreen.java @@ -0,0 +1,53 @@ +package NET.worlds.console; + +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Toolkit; + +public class SplashScreen extends java.awt.Window { + private static final long serialVersionUID = 4848128412139723543L; + private SplashCanvas sc = null; + + public SplashScreen(String appname, String imagename) { + super(new Frame(appname)); + this.sc = new SplashCanvas(imagename); + this.add(this.sc); + this.pack(); + this.center(); + } + + public void setImageName(String imagename) { + this.sc.setImage(imagename); + this.pack(); + this.center(); + this.sc.repaint(); + } + + public void addOverlay(String name, int x, int y) { + this.sc.addOverlay(name, x, y); + this.center(); + } + + public void removeOverlay(String name, int x, int y) { + this.sc.removeOverlay(name, x, y); + } + + public void center() { + Dimension dim = this.getSize(); + Dimension scrdim = Toolkit.getDefaultToolkit().getScreenSize(); + int x = scrdim.width >= dim.width ? (scrdim.width - dim.width) / 2 : 0; + int y = scrdim.height >= dim.height ? (scrdim.height - dim.height) / 2 : 0; + this.setLocation(x, y); + } + + @Override + public void dispose() { + super.dispose(); + + try { + this.sc.flush(); + } catch (NullPointerException var2) { + System.out.println("Flushing went bad!"); + } + } +} diff --git a/NET/worlds/console/StackedLayout.java b/NET/worlds/console/StackedLayout.java new file mode 100644 index 0000000..2cbc840 --- /dev/null +++ b/NET/worlds/console/StackedLayout.java @@ -0,0 +1,69 @@ +package NET.worlds.console; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.LayoutManager; + +class StackedLayout implements LayoutManager { + public StackedLayout() { + } + + @Override + public void addLayoutComponent(String name, Component c) { + } + + @Override + public void removeLayoutComponent(Component c) { + } + + @Override + public Dimension preferredLayoutSize(Container target) { + Dimension size = new Dimension(0, 0); + int count = target.getComponentCount(); + + for (int i = 0; i < count; i++) { + Component m = target.getComponent(i); + Dimension d = m.getPreferredSize(); + size.width = Math.max(size.width, d.width); + size.height = size.height + d.height; + } + + Insets insets = target.getInsets(); + size.width = size.width + insets.left + insets.right; + size.height = size.height + insets.top + insets.bottom; + return size; + } + + @Override + public Dimension minimumLayoutSize(Container target) { + return this.preferredLayoutSize(target); + } + + @Override + public void layoutContainer(Container target) { + Insets insets = target.getInsets(); + Dimension size = target.getSize(); + int x = insets.left; + int y = insets.top; + int width = size.width - insets.left - insets.right; + int height = size.height - insets.top - insets.bottom; + int count = target.getComponentCount(); + + for (int i = 0; i < count; i++) { + Component c = target.getComponent(i); + int h = c.getPreferredSize().height; + if (i == count - 1) { + h = Math.max(h, height); + } else { + h = Math.min(h, height); + } + + h = Math.max(0, h); + c.setBounds(x, y, width, h); + height -= h; + y += h; + } + } +} diff --git a/NET/worlds/console/Stair.java b/NET/worlds/console/Stair.java new file mode 100644 index 0000000..c4380d9 --- /dev/null +++ b/NET/worlds/console/Stair.java @@ -0,0 +1,194 @@ +package NET.worlds.console; + +import NET.worlds.scape.Material; +import NET.worlds.scape.NoSuchPropertyException; +import NET.worlds.scape.Point3; +import NET.worlds.scape.Point3Temp; +import NET.worlds.scape.Portal; +import NET.worlds.scape.Property; +import NET.worlds.scape.Rect; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Room; +import NET.worlds.scape.RoomEnvironment; +import NET.worlds.scape.Saver; +import NET.worlds.scape.TooNewException; +import NET.worlds.scape.World; +import java.io.IOException; + +public class Stair extends Room { + public Portal bottom; + public Portal top; + private int _lengthwise; + static final int PLUSX = 0; + static final int PLUSY = 1; + static final int MINUSX = 2; + static final int MINUSY = 3; + private float _length; + private float _width; + private float _rise; + private static Object classCookie = new Object(); + + public Stair( + World world, + String name, + float width, + float length, + float rise, + float ceilingz, + int numsteps, + Material riser, + Material tread, + Material left, + Material right, + Material head, + Material ceiling + ) { + super(world, name); + this._lengthwise = 1; + this._length = length; + this._width = width; + this._rise = rise; + RoomEnvironment env = this.getEnvironment(); + env.add(Rect.ceiling(0.0F, 0.0F, ceilingz, width, length, ceiling)); + float lowerz = ceilingz - rise; + env.add(new Rect(-0.1F, 0.0F, 0.0F, -0.1F, length, ceilingz, left)); + env.add(new Rect(width + 0.1F, length, 0.0F, width + 0.1F, 0.0F, ceilingz, right)); + env.add(new Rect(width, 0.0F, lowerz, 0.0F, 0.0F, ceilingz, head)); + this.bottom = new Portal(width, 0.0F, 0.0F, 0.0F, 0.0F, lowerz); + this.top = new Portal(0.0F, length, rise, width, length, ceilingz); + float dy = length / numsteps; + float dz = rise / numsteps; + + for (int i = 0; i < numsteps; i++) { + Rect w = new Rect(0.0F, i * dy, i * dz, width, i * dy, (i + 1) * dz, riser); + w.setTileSize(dz, dz); + env.add(w); + } + + for (int i = 0; i < numsteps; i++) { + Rect w = Rect.floor(0.0F, i * dy, (i + 1) * dz, width, (i + 1) * dy, tread); + w.setTileSize(dy, dy); + env.add(w); + } + + env.add(this.bottom); + env.add(this.top); + } + + public Stair() { + } + + void setLength(float len) { + this._length = len; + } + + void setRise(float r) { + this._rise = r; + } + + void setLengthwise(int lw) { + this._lengthwise = lw; + } + + @Override + public float floorHeight(float x, float y, float z) { + float dist = 0.0F; + switch (this._lengthwise) { + case 0: + dist = x; + break; + case 1: + dist = y; + break; + case 2: + dist = this._length - x; + break; + case 3: + dist = this._length - y; + break; + default: + assert false; + } + + return dist / this._length * this._rise; + } + + public Point3 surfaceNormal(float x, float y) { + Point3 A = new Point3(this._width, 0.0F, 0.0F); + Point3Temp B = Point3Temp.make(0.0F, this._length, this._rise); + A.cross(B); + A.normalize(); + return A; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(1, classCookie); + super.saveState(s); + s.saveFloat(this._length); + s.saveFloat(this._rise); + s.saveInt(this._lengthwise); + s.save(this.bottom); + s.save(this.top); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + switch (r.restoreVersion(classCookie)) { + case 0: + super.restoreState(r); + this._length = r.restoreFloat(); + this._rise = r.restoreFloat(); + this.bottom = (Portal)r.restore(); + this.top = (Portal)r.restore(); + this.setLengthwise(1); + break; + case 1: + super.restoreState(r); + this._length = r.restoreFloat(); + this._rise = r.restoreFloat(); + this._lengthwise = r.restoreInt(); + this.bottom = (Portal)r.restore(); + this.top = (Portal)r.restore(); + break; + default: + throw new TooNewException(); + } + } + + void superRestoreState(Restorer r) throws IOException, TooNewException { + super.restoreState(r); + } + + @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, "Length"); + } else if (mode == 1) { + ret = new Float(this._length); + } + break; + case 1: + if (mode == 0) { + ret = new Property(this, index, "Rise"); + } else if (mode == 1) { + ret = new Float(this._rise); + } + break; + case 2: + if (mode == 0) { + ret = new Property(this, index, "Direction"); + } else if (mode == 1) { + ret = new Integer(this._lengthwise); + } + break; + default: + ret = super.properties(index, offset + 3, mode, value); + } + + return ret; + } +} diff --git a/NET/worlds/console/Staircase.java b/NET/worlds/console/Staircase.java new file mode 100644 index 0000000..1932e23 --- /dev/null +++ b/NET/worlds/console/Staircase.java @@ -0,0 +1,251 @@ +package NET.worlds.console; + +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.FrameHandler; +import NET.worlds.scape.Material; +import NET.worlds.scape.Point3; +import NET.worlds.scape.Point3Temp; +import NET.worlds.scape.Portal; +import NET.worlds.scape.Rect; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Room; +import NET.worlds.scape.RoomEnvironment; +import NET.worlds.scape.Saver; +import NET.worlds.scape.TooNewException; +import NET.worlds.scape.WObject; +import NET.worlds.scape.World; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; + +public class Staircase extends Room implements FrameHandler { + public Portal bottom; + public Portal top; + private float dzdx; + private float dzdy; + private Vector<WObject> seenThings = new Vector<WObject>(); + private Vector<Point3> seenStarts = new Vector<Point3>(); + private static Object classCookie = new Object(); + + public Staircase( + World world, + String name, + float x1, + float y1, + float z1, + float x2, + float y2, + float z2, + float ceilingz, + int numsteps, + Material riser, + Material tread, + Material left, + Material right, + Material head, + Material ceiling + ) { + super(world, name); + float dx = (x2 - x1) / numsteps; + float dy = (y2 - y1) / numsteps; + float dz = (z2 - z1) / numsteps; + this.dzdx = dz / dx; + this.dzdy = dz / dy; + + assert dz >= 0.0F; + + float bottomtopz = z1 + ceilingz - z2; + RoomEnvironment env = this.getEnvironment(); + env.add(Rect.ceiling(x1, y1, ceilingz, x2, y2, ceiling)); + if (dx > 0.0F) { + if (dy > 0.0F) { + env.add(new Rect(x1 - 0.1F, y1, z1, x1 - 0.1F, y2, ceilingz, left)); + env.add(new Rect(x2 + 0.1F, y2, z1, x2 + 0.1F, y1, ceilingz, right)); + env.add(new Rect(x2, y1, bottomtopz, x1, y1, ceilingz, head)); + this.bottom = new Portal(x2, y1, z1, x1, y1, bottomtopz); + this.top = new Portal(x1, y2, z2, x2, y2, ceilingz); + + for (int i = 0; i < numsteps; i++) { + Rect w = new Rect(x1, y1 + i * dy, z1 + i * dz, x2, y1 + i * dy, z1 + (i + 1) * dz, riser); + w.setTileSize(dz, dz); + env.add(w); + } + + for (int i = 0; i < numsteps; i++) { + Rect w = Rect.floor(x1, y1 + i * dy, z1 + (i + 1) * dz, x2, y1 + (i + 1) * dy, tread); + w.setTileSize(Math.abs(dy), Math.abs(dy)); + env.add(w); + } + + this.dzdx = 0.0F; + } else { + env.add(new Rect(x1, y1 - 0.1F, z1, x2, y1 - 0.1F, ceilingz, left)); + env.add(new Rect(x2, y2 + 0.1F, z1, x1, y2 + 0.1F, ceilingz, right)); + env.add(new Rect(x1, y2, bottomtopz, x1, y1, ceilingz, head)); + this.bottom = new Portal(x1, y2, z1, x1, y1, bottomtopz); + this.top = new Portal(x2, y1, z2, x2, y2, ceilingz); + + for (int i = 0; i < numsteps; i++) { + Rect w = new Rect(x1 + i * dx, y1, z1 + i * dz, x1 + i * dx, y2, z1 + (i + 1) * dz, riser); + w.setTileSize(dz, dz); + env.add(w); + } + + for (int i = 0; i < numsteps; i++) { + Rect w = Rect.floor(x1 + i * dx, y2, z1 + (i + 1) * dz, x1 + (i + 1) * dx, y1, tread); + w.setTileSize(Math.abs(dx), Math.abs(dx)); + env.add(w); + } + + this.dzdy = 0.0F; + } + } else if (dy > 0.0F) { + env.add(new Rect(x1, y1 - 0.1F, z1, x2, y1 - 0.1F, ceilingz, left)); + env.add(new Rect(x2, y2 + 0.1F, z1, x1, y2 + 0.1F, ceilingz, right)); + env.add(new Rect(x1, y2, bottomtopz, x1, y1, ceilingz, head)); + this.bottom = new Portal(x1, y2, z1, x1, y1, bottomtopz); + this.top = new Portal(x2, y1, z2, x2, y2, ceilingz); + + for (int i = 0; i < numsteps; i++) { + Rect w = new Rect(x1 + i * dx, y1, z1 + i * dz, x1 + i * dx, y2, z1 + (i + 1) * dz, riser); + w.setTileSize(dz, dz); + env.add(w); + } + + for (int i = 0; i < numsteps; i++) { + Rect w = Rect.floor(x1 + (i + 1) * dx, y1, z1 + (i + 1) * dz, x1 + i * dx, y2, tread); + w.setTileSize(Math.abs(dx), Math.abs(dx)); + env.add(w); + } + + this.dzdy = 0.0F; + } else { + env.add(new Rect(x1 + 0.1F, y1, z1, x1 + 0.1F, y2, ceilingz, left)); + env.add(new Rect(x2 - 0.1F, y2, z1, x2 - 0.1F, y1, ceilingz, right)); + env.add(new Rect(x2, y1, bottomtopz, x1, y1, ceilingz, head)); + this.bottom = new Portal(x2, y1, z1, x1, y1, bottomtopz); + this.top = new Portal(x1, y2, z2, x2, y2, ceilingz); + + for (int i = 0; i < numsteps; i++) { + Rect w = new Rect(x1, y1 + i * dy, z1 + i * dz, x2, y1 + i * dy, z1 + (i + 1) * dz, riser); + w.setTileSize(dz, dz); + env.add(w); + } + + for (int i = 0; i < numsteps; i++) { + Rect w = Rect.floor(x2, y1 + (i + 1) * dy, z1 + (i + 1) * dz, x1, y1 + i * dy, tread); + w.setTileSize(Math.abs(dy), Math.abs(dy)); + env.add(w); + } + + this.dzdx = 0.0F; + } + + env.add(this.bottom); + env.add(this.top); + } + + public Staircase() { + } + + @Override + public boolean handle(FrameEvent e) { + Enumeration<WObject> stuff = (Enumeration<WObject>)this.getContents(); + + while (stuff.hasMoreElements()) { + WObject thing = stuff.nextElement(); + int i = this.seenThings.indexOf(thing); + if (i == -1) { + this.seenThings.addElement(thing); + Point3Temp startpos = thing.getPosition(); + Point3Temp topctr = Point3Temp.make(this.top.getScaleX(), 0.0F, this.top.getScaleZ()).times(0.5F).times(this.top.getObjectToWorldMatrix()); + Point3Temp bottomctr = Point3Temp.make(this.bottom.getScaleX(), 0.0F, this.bottom.getScaleZ()) + .times(0.5F) + .times(this.bottom.getObjectToWorldMatrix()); + if (topctr.x == bottomctr.x) { + float t = (startpos.y - bottomctr.y) / (topctr.y - bottomctr.y); + if (t < 0.5F) { + startpos.y = bottomctr.y; + } else { + startpos.y = topctr.y; + } + + this.dzdx = 0.0F; + } else if (topctr.y == bottomctr.y) { + float t = (startpos.x - bottomctr.x) / (topctr.x - bottomctr.x); + if (t < 0.5F) { + startpos.x = bottomctr.x; + } else { + startpos.x = topctr.x; + } + + this.dzdy = 0.0F; + } else { + assert false; + } + + this.seenStarts.addElement(new Point3(startpos)); + i = this.seenThings.size() - 1; + + assert i == this.seenStarts.size() - 1; + } + + Point3Temp oldpos = this.seenStarts.elementAt(i); + Point3Temp pos = thing.getPosition(); + float deltaz = this.dzdx * (pos.x - oldpos.x) + this.dzdy * (pos.y - oldpos.y) + oldpos.z - pos.z; + if (deltaz != 0.0F) { + thing.raise(deltaz); + } + } + + return true; + } + + @Override + public void saveState(Saver s) throws IOException { + s.saveVersion(0, classCookie); + super.saveState(s); + s.saveFloat(this.dzdx); + s.saveFloat(this.dzdy); + s.save(this.bottom); + s.save(this.top); + } + + @Override + public void restoreState(Restorer r) throws IOException, TooNewException { + Stair s = new Stair(); + r.replace(this, s); + int version = r.restoreVersion(classCookie); + if (version != 0) { + throw new TooNewException(); + } else { + s.superRestoreState(r); + float dzdx = r.restoreFloat(); + float dzdy = r.restoreFloat(); + s.bottom = (Portal)r.restore(); + s.top = (Portal)r.restore(); + Point3Temp tllc = s.top.getPosition(); + Point3Temp bllc = s.bottom.getPosition(); + s.setRise(tllc.z - bllc.z); + if (dzdx == 0.0F) { + if (dzdy > 0.0F) { + s.setLengthwise(1); + s.setLength(tllc.y - bllc.y); + } else { + s.setLengthwise(3); + s.setLength(bllc.y - tllc.y); + } + } else { + assert dzdy == 0.0F; + + if (dzdx > 0.0F) { + s.setLengthwise(0); + s.setLength(tllc.x - bllc.x); + } else { + s.setLengthwise(2); + s.setLength(bllc.x - tllc.x); + } + } + } + } +} diff --git a/NET/worlds/console/Startup.java b/NET/worlds/console/Startup.java new file mode 100644 index 0000000..b2fafdf --- /dev/null +++ b/NET/worlds/console/Startup.java @@ -0,0 +1,12 @@ +package NET.worlds.console; + +public class Startup { + private Startup() { + } + + public static native boolean synchronizeStartup(String var0, boolean var1); + + public static native int getVolumeInfo(); + + public static native void computeVolumeInfo(String var0); +} diff --git a/NET/worlds/console/StatMan.java b/NET/worlds/console/StatMan.java new file mode 100644 index 0000000..f8567bc --- /dev/null +++ b/NET/worlds/console/StatMan.java @@ -0,0 +1,58 @@ +package NET.worlds.console; + +import java.awt.List; +import java.util.Vector; + +abstract class StatMan { + protected Vector<Object> _children; + protected List _grabbedList; + protected Tree _tree; + + void createList() { + this.updateList(); + } + + abstract void updateList(); + + void releaseList(boolean terminalCallback) { + this._grabbedList = null; + } + + void grabList(List list) { + assert this._grabbedList == null; + + this._grabbedList = list; + this._grabbedList.removeAll(); + this.createList(); + } + + void setTree(Tree tree) { + this._tree = tree; + if (this._children != null) { + for (int i = this._children.size() - 1; i >= 0; i--) { + StatMan child = (StatMan)this._children.elementAt(i); + child.setTree(this._tree); + } + } + } + + Vector<Object> getChildren() { + return this._children; + } + + void addChild(StatMan child) { + assert child != null; + + if (this._children == null) { + this._children = new Vector<Object>(); + } + + assert this._children.indexOf(child) == -1; + + this._children.addElement(child); + if (this._tree != null) { + child.setTree(this._tree); + this._tree.update(); + } + } +} diff --git a/NET/worlds/console/StatMemNode.java b/NET/worlds/console/StatMemNode.java new file mode 100644 index 0000000..1e3fc21 --- /dev/null +++ b/NET/worlds/console/StatMemNode.java @@ -0,0 +1,105 @@ +package NET.worlds.console; + +import NET.worlds.core.Std; +import java.awt.List; + +public class StatMemNode extends StatMan implements MainCallback { + private static StatMemNode _singleInstance = new StatMemNode(); + private int _lastTime; + private static final int TITLE = 0; + private static final int BLANK1 = 1; + private static final int TOTMEM = 2; + private static final int FREEMEM = 3; + private static final int BLANK2 = 4; + private static final int TOTPHYSMEM = 5; + private static final int AVAILPHYSMEM = 6; + private static final int SWAPUSED = 7; + private static final int AVAILVIRTMEM = 8; + private static final int TOTUSED = 9; + private long _lastTotMem; + public int _totPhysMem; + public int _availPhysMem; + public int _totPageMem; + public int _availPageMem; + + static { + nativeInit(); + } + + public static StatMemNode getNode() { + return _singleInstance; + } + + private StatMemNode() { + StatisticsRoot.getNode().addChild(this); + } + + public static native void nativeInit(); + + @Override + public String toString() { + return "System Memory"; + } + + @Override + synchronized void grabList(List list) { + super.grabList(list); + Main.register(this); + } + + @Override + synchronized void releaseList(boolean terminalCallback) { + if (!terminalCallback) { + Main.unregister(this); + } + + super.releaseList(terminalCallback); + } + + @Override + public synchronized void mainCallback() { + int thisTime = Std.getFastTime(); + if (thisTime - this._lastTime > 1000) { + this.updateList(); + this._lastTime = thisTime; + } + } + + public int getVMAvail() { + this.updateMemoryStatus(); + return this._availPageMem; + } + + @Override + void createList() { + this._grabbedList.add("System Memory Stats", 0); + this._grabbedList.add("", 1); + this._lastTotMem = Runtime.getRuntime().totalMemory(); + this._grabbedList.add("Total " + Std.getProductName() + " Memory Available: " + this._lastTotMem + " bytes", 2); + this.updateMemoryStatus(); + this._grabbedList.add(" Free " + Std.getProductName() + " Memory Available: " + Runtime.getRuntime().freeMemory() + " bytes", 3); + this._grabbedList.add("", 4); + this._grabbedList.add("Total System Physical Memory: " + this._totPhysMem + " bytes", 5); + this._grabbedList.add("Available System Physical Memory: " + this._availPhysMem + " bytes", 6); + this._grabbedList.add("Total System Swapfile Usage: " + (this._totPageMem - this._availPageMem) + " bytes", 7); + this._grabbedList.add("Available Virtual Memory: " + this._availPageMem + " bytes", 8); + } + + @Override + void updateList() { + long thisTotMem = Runtime.getRuntime().totalMemory(); + if (thisTotMem != this._lastTotMem) { + this._lastTotMem = thisTotMem; + this._grabbedList.replaceItem("Total " + Std.getProductName() + " Memory Available: " + this._lastTotMem + " bytes", 2); + } + + this.updateMemoryStatus(); + this._grabbedList.replaceItem(" Free " + Std.getProductName() + " Memory Available: " + Runtime.getRuntime().freeMemory() + " bytes", 3); + this._grabbedList.replaceItem("Total System Physical Memory: " + this._totPhysMem + " bytes", 5); + this._grabbedList.replaceItem("Available System Physical Memory: " + this._availPhysMem + " bytes", 6); + this._grabbedList.replaceItem("Total System Swapfile Usage: " + (this._totPageMem - this._availPageMem) + " bytes", 7); + this._grabbedList.replaceItem("Available Virtual Memory: " + this._availPageMem + " bytes", 8); + } + + public native void updateMemoryStatus(); +} diff --git a/NET/worlds/console/StatNetMUNode.java b/NET/worlds/console/StatNetMUNode.java new file mode 100644 index 0000000..b636341 --- /dev/null +++ b/NET/worlds/console/StatNetMUNode.java @@ -0,0 +1,92 @@ +package NET.worlds.console; + +import NET.worlds.core.Std; +import java.awt.List; + +public class StatNetMUNode extends StatMan implements MainCallback { + private static StatNetMUNode _singleInstance = new StatNetMUNode(); + private int _totBytesSent; + private int _totBytesRcvd; + private int _totPacketsSent; + private int _totPacketsRcvd; + private int _lastTime; + private static final int TITLE = 0; + private static final int BLANK1 = 1; + private static final int TOTBYTESSENT = 2; + private static final int TOTBYTESRCVD = 3; + private static final int BLANK2 = 4; + private static final int TOTPKTSSENT = 5; + private static final int TOTPKTSRCVD = 6; + + public static StatNetMUNode getNode() { + return _singleInstance; + } + + private StatNetMUNode() { + StatNetNode.getNode().addChild(this); + } + + @Override + public String toString() { + return "Multiuser Server Connections"; + } + + public void addBytesSent(int bytesSent) { + this._totBytesSent += bytesSent; + } + + public void addBytesRcvd(int bytesRcvd) { + this._totBytesRcvd += bytesRcvd; + } + + public void addPacketsSent(int pktSent) { + this._totPacketsSent += pktSent; + } + + public void addPacketsRcvd(int pktRcvd) { + this._totPacketsRcvd += pktRcvd; + } + + @Override + void grabList(List list) { + super.grabList(list); + Main.register(this); + } + + @Override + void releaseList(boolean terminalCallback) { + if (!terminalCallback) { + Main.unregister(this); + } + + super.releaseList(terminalCallback); + } + + @Override + public void mainCallback() { + int thisTime = Std.getFastTime(); + if (thisTime - this._lastTime > 1000) { + this.updateList(); + this._lastTime = thisTime; + } + } + + @Override + void createList() { + this._grabbedList.add("Overall Multiuser Server Network Statistics:", 0); + this._grabbedList.add("", 1); + this._grabbedList.add(" Total bytes sent: " + this._totBytesSent + " bytes", 2); + this._grabbedList.add("Total bytes received: " + this._totBytesRcvd + " bytes", 3); + this._grabbedList.add("", 4); + this._grabbedList.add(" Total packets sent: " + this._totPacketsSent + " packets", 5); + this._grabbedList.add("Total packets received: " + this._totPacketsRcvd + " packets", 6); + } + + @Override + void updateList() { + this._grabbedList.replaceItem(" Total bytes sent: " + this._totBytesSent + " bytes", 2); + this._grabbedList.replaceItem("Total bytes received: " + this._totBytesRcvd + " bytes", 3); + this._grabbedList.replaceItem(" Total packets sent: " + this._totPacketsSent + " packets", 5); + this._grabbedList.replaceItem("Total packets received: " + this._totPacketsRcvd + " packets", 6); + } +} diff --git a/NET/worlds/console/StatNetNode.java b/NET/worlds/console/StatNetNode.java new file mode 100644 index 0000000..7c44856 --- /dev/null +++ b/NET/worlds/console/StatNetNode.java @@ -0,0 +1,23 @@ +package NET.worlds.console; + +class StatNetNode extends StatMan { + private static StatNetNode _singleInstance = new StatNetNode(); + + public static StatNetNode getNode() { + return _singleInstance; + } + + private StatNetNode() { + StatisticsRoot.getNode().addChild(this); + } + + @Override + public String toString() { + return "Network"; + } + + @Override + void updateList() { + this._grabbedList.add("Overall Networking Statistics"); + } +} diff --git a/NET/worlds/console/StatNetRefNode.java b/NET/worlds/console/StatNetRefNode.java new file mode 100644 index 0000000..9ce6fe2 --- /dev/null +++ b/NET/worlds/console/StatNetRefNode.java @@ -0,0 +1,106 @@ +package NET.worlds.console; + +import NET.worlds.core.Std; +import NET.worlds.network.NetworkRoom; +import NET.worlds.network.WorldServer; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Room; +import java.awt.List; +import java.util.Vector; + +public class StatNetRefNode extends StatMan implements MainCallback { + private static StatNetRefNode _singleInstance = new StatNetRefNode(); + private int _totBytesSent; + private int _totBytesRcvd; + private int _totPacketsSent; + private int _totPacketsRcvd; + private int _lastTime; + private static final int TITLE = 0; + private static final int BLANK = 1; + private int _listCount = 0; + + public static StatNetRefNode getNode() { + return _singleInstance; + } + + private StatNetRefNode() { + StatNetNode.getNode().addChild(this); + } + + @Override + public String toString() { + return "Drone Referrers to Current Server"; + } + + public void addBytesSent(int bytesSent) { + this._totBytesSent += bytesSent; + } + + public void addBytesRcvd(int bytesRcvd) { + this._totBytesRcvd += bytesRcvd; + } + + public void addPacketsSent(int pktSent) { + this._totPacketsSent += pktSent; + } + + public void addPacketsRcvd(int pktRcvd) { + this._totPacketsRcvd += pktRcvd; + } + + @Override + void grabList(List list) { + super.grabList(list); + Main.register(this); + } + + @Override + void releaseList(boolean terminalCallback) { + if (!terminalCallback) { + Main.unregister(this); + } + + super.releaseList(terminalCallback); + } + + @Override + public void mainCallback() { + int thisTime = Std.getFastTime(); + if (thisTime - this._lastTime > 1000) { + this.updateList(); + this._lastTime = thisTime; + } + } + + @Override + void createList() { + this._grabbedList.add("Drones Referring to Current Server:", 0); + this._grabbedList.add("", 1); + Pilot p = Pilot.getActive(); + Room r = p.getRoom(); + NetworkRoom netRoom = null; + if (r != null) { + netRoom = r.getNetworkRoom(); + } + + WorldServer ws = null; + if (netRoom != null) { + ws = netRoom.getServer(); + } + + if (ws != null) { + Vector<String> list = ws.printDroneReferrers(); + + for (int i = list.size() - 1; i >= 0; i--) { + String name = list.elementAt(i); + this._grabbedList.add(name); + } + } + } + + @Override + void updateList() { + this._grabbedList.removeAll(); + this.createList(); + } +} diff --git a/NET/worlds/console/StatRateNode.java b/NET/worlds/console/StatRateNode.java new file mode 100644 index 0000000..84e33dd --- /dev/null +++ b/NET/worlds/console/StatRateNode.java @@ -0,0 +1,66 @@ +package NET.worlds.console; + +import NET.worlds.core.Std; +import java.awt.List; + +class StatRateNode extends StatMan implements MainCallback { + private static StatRateNode _singleInstance = new StatRateNode(); + private int _lastTime; + private static final int TITLE = 0; + private static final int BLANK1 = 1; + private static final int THREADS = 2; + private int lastQueueLength; + + public static StatRateNode getNode() { + return _singleInstance; + } + + private StatRateNode() { + StatisticsRoot.getNode().addChild(this); + } + + @Override + public String toString() { + return "Active Threads"; + } + + @Override + synchronized void grabList(List list) { + super.grabList(list); + Main.register(this); + } + + @Override + synchronized void releaseList(boolean terminalCallback) { + if (!terminalCallback) { + Main.unregister(this); + } + + super.releaseList(terminalCallback); + } + + @Override + public synchronized void mainCallback() { + int thisTime = Std.getFastTime(); + if (thisTime - this._lastTime > 1000) { + this.updateList(); + this._lastTime = thisTime; + } + } + + @Override + void createList() { + this._grabbedList.add("Active Thread Statistics", 0); + this._grabbedList.add("", 1); + this.lastQueueLength = Main.queueLength(); + this._grabbedList.add("Number main threads: " + this.lastQueueLength, 2); + } + + @Override + void updateList() { + if (Main.queueLength() != this.lastQueueLength) { + this.lastQueueLength = Main.queueLength(); + this._grabbedList.replaceItem("Number main threads: " + this.lastQueueLength, 2); + } + } +} diff --git a/NET/worlds/console/StatTreeNode.java b/NET/worlds/console/StatTreeNode.java new file mode 100644 index 0000000..18d9009 --- /dev/null +++ b/NET/worlds/console/StatTreeNode.java @@ -0,0 +1,43 @@ +package NET.worlds.console; + +import java.util.Vector; + +class StatTreeNode extends TreeNode { + private StatMan _obj; + + public StatTreeNode(StatMan obj, TreeNode parent) { + super(parent); + + assert obj != null; + + this._obj = obj; + } + + @Override + public Vector<Object> getChildren() { + Vector<Object> children = this._obj.getChildren(); + if (children == null) { + return new Vector<Object>(); + } else if (children.size() <= 0) { + return children; + } else { + Vector<Object> ret = new Vector<Object>(); + + for (int i = 0; i <= children.size() - 1; i++) { + ret.addElement(new StatTreeNode((StatMan)children.elementAt(i), this)); + } + + return ret; + } + } + + @Override + public Object getObject() { + return this._obj; + } + + @Override + public String toString() { + return this._obj.toString(); + } +} diff --git a/NET/worlds/console/StatisticsRoot.java b/NET/worlds/console/StatisticsRoot.java new file mode 100644 index 0000000..e2c170e --- /dev/null +++ b/NET/worlds/console/StatisticsRoot.java @@ -0,0 +1,21 @@ +package NET.worlds.console; + +class StatisticsRoot extends StatMan { + private static StatisticsRoot _singleInstance = new StatisticsRoot(); + + public static StatisticsRoot getNode() { + return _singleInstance; + } + + private StatisticsRoot() { + } + + @Override + void updateList() { + } + + @Override + public String toString() { + return "Statistics Root"; + } +} diff --git a/NET/worlds/console/StatisticsWindow.java b/NET/worlds/console/StatisticsWindow.java new file mode 100644 index 0000000..a206d6c --- /dev/null +++ b/NET/worlds/console/StatisticsWindow.java @@ -0,0 +1,91 @@ +package NET.worlds.console; + +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.List; +import java.awt.Point; + +public class StatisticsWindow extends Frame implements MainCallback, MainTerminalCallback, TreeCallback { + private static final long serialVersionUID = 2184104724858956037L; + Tree _tree = new Tree(this); + List _list = new List(10, false); + StatMan _lastStat; + + public StatisticsWindow(java.awt.Window parent) { + super("Statistics Manager"); + GridBagLayout gbag = new GridBagLayout(); + this.setLayout(gbag); + GridBagConstraints c = new GridBagConstraints(); + c.fill = 1; + c.weightx = 0.4; + c.weighty = 1.0; + c.gridwidth = 1; + c.gridheight = 0; + gbag.setConstraints(this._tree, c); + this.add(this._tree); + c.weightx = 0.6; + c.gridwidth = 0; + gbag.setConstraints(this._list, c); + this.add(this._list); + this.pack(); + Point loc = parent.location(); + Dimension size = parent.getSize(); + this.reshape(loc.x + (size.width - 512) / 2, loc.y + (size.height - 240) / 2, 512, 240); + this.show(); + StatisticsRoot root = StatisticsRoot.getNode(); + root.setTree(this._tree); + StatTreeNode rootNode = new StatTreeNode(root, null); + this._tree.change(rootNode, rootNode.getObject()); + StatMemNode.getNode(); + StatNetRefNode.getNode(); + this._tree.change(rootNode, StatRateNode.getNode()); + Main.register(this); + } + + @Override + public boolean handleEvent(Event ev) { + switch (ev.id) { + case 201: + if (this._lastStat != null) { + this._lastStat.releaseList(false); + } + + this._lastStat = null; + this.dispose(); + return true; + default: + return super.handleEvent(ev); + } + } + + @Override + public void treeChange(Object obj) { + if (this._lastStat != null) { + this._lastStat.releaseList(false); + } + + this._lastStat = (StatMan)obj; + this._lastStat.grabList(this._list); + } + + @Override + public void treeFocusChanged(boolean hasFocus) { + } + + @Override + public void mainCallback() { + } + + @Override + public void terminalCallback() { + if (this._lastStat != null) { + this._lastStat.releaseList(true); + } + + this._lastStat = null; + Main.unregister(this); + } +} diff --git a/NET/worlds/console/StyledTextCanvas.java b/NET/worlds/console/StyledTextCanvas.java new file mode 100644 index 0000000..9472734 --- /dev/null +++ b/NET/worlds/console/StyledTextCanvas.java @@ -0,0 +1,209 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Scrollbar; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; + +class StyledTextCanvas extends Canvas { + private static final long serialVersionUID = -2680423246934436331L; + private MouseEvent delayedMouseEvent = null; + protected int mouseX = -1; + protected int mouseY = -1; + protected int startX = -1; + protected int startY = -1; + protected int endX = -1; + protected int endY = -1; + protected long mouseWhen = 0L; + protected boolean mouseActive = false; + protected boolean mouseDoubleClick = false; + protected static long doubleClickSpeed = IniFile.override().getIniInt("DoubleClickSpeed", 300); + + public StyledTextCanvas() { + this.enableEvents(61L); + this.setEnabled(true); + } + + public void sendDelayedMouseEvent(MouseEvent e) { + synchronized (this.getParent()) { + this.delayedMouseEvent = e; + } + } + + @Override + public void setBounds(int x, int y, int w, int h) { + if (this.getParent() != null && w >= 0 && h >= 0) { + synchronized (this.getParent()) { + if (this.getParent() instanceof GammaTextArea) { + GammaTextArea gta = (GammaTextArea)this.getParent(); + gta.setWidth(w); + gta.setHeight(h); + gta.rewrap(); + } + + super.setBounds(x, y, w, h); + } + } + } + + @Override + protected void processMouseMotionEvent(MouseEvent e) { + if (e.getID() == 506 && this.mouseActive) { + this.processMouseEvent(e); + } + + super.processMouseMotionEvent(e); + } + + @Override + protected void processMouseEvent(MouseEvent e) { + synchronized (this.getParent()) { + if (e.getID() == 500) { + if (this.mouseWhen > 0L && e.getWhen() - this.mouseWhen <= doubleClickSpeed) { + this.mouseDoubleClick = true; + this.mouseWhen = 0L; + this.mouseX = this.startX = this.endX = e.getX(); + this.mouseY = this.startY = this.endY = e.getY(); + ((GammaTextArea)this.getParent()).selectionConversion = true; + this.getParent().repaint(); + } else { + this.mouseDoubleClick = false; + this.mouseWhen = e.getWhen(); + if (e.getButton() == 1 && !this.mouseActive && (e.getModifiers() & 1) == 0) { + ((GammaTextArea)this.getParent()).selectionStart = -1; + ((GammaTextArea)this.getParent()).selectionEnd = -1; + } + } + + this.getParent().requestFocus(); + } else if (e.getID() == 501) { + if (e.getButton() == 1) { + if ((e.getModifiers() & 1) == 0) { + if (((GammaTextArea)this.getParent()).selectionStart >= 0 + && ((GammaTextArea)this.getParent()).selectionEnd > ((GammaTextArea)this.getParent()).selectionStart) { + ((GammaTextArea)this.getParent()).selectionStart = -1; + ((GammaTextArea)this.getParent()).selectionEnd = -1; + } else { + this.mouseX = this.startX = this.endX = e.getX(); + this.mouseY = this.startY = this.endY = e.getY(); + this.mouseActive = true; + ((GammaTextArea)this.getParent()).selectionConversion = true; + } + } else { + this.mouseX = this.startX = this.endX = e.getX(); + this.mouseY = this.startY = this.endY = e.getY(); + this.mouseActive = true; + ((GammaTextArea)this.getParent()).selectionConversion = true; + } + + this.getParent().repaint(); + } + + this.getParent().requestFocus(); + } else if (this.mouseActive && (e.getID() == 506 || e.getID() == 507 || e.getID() == 507)) { + if ((e.getModifiers() & 16) != 0) { + this.mouseX = this.endX = e.getX(); + this.mouseY = this.endY = e.getY(); + ((GammaTextArea)this.getParent()).selectionConversion = true; + this.getParent().repaint(); + } + + this.getParent().requestFocus(); + } else if (e.getID() == 502) { + if (e.getButton() == 1 && this.mouseActive) { + this.mouseX = this.endX = e.getX(); + this.mouseY = this.endY = e.getY(); + this.mouseActive = false; + ((GammaTextArea)this.getParent()).selectionConversion = false; + this.getParent().repaint(); + } + + this.getParent().requestFocus(); + } + + ((GammaTextArea)this.getParent()).processMouseEvent(e); + super.processMouseEvent(e); + } + } + + @Override + public void update(Graphics g) { + this.paint(g); + } + + @Override + protected void processKeyEvent(KeyEvent e) { + synchronized (this.getParent()) { + if (e.getID() == 401) { + Scrollbar s = null; + if (this.getParent() instanceof GammaTextArea) { + GammaTextArea gta = (GammaTextArea)this.getParent(); + s = gta.getVertScrollbar(); + } + + if (e.getKeyCode() == 33) { + if (s != null && s.isEnabled()) { + s.dispatchEvent(e); + } + } else if (e.getKeyCode() == 34 && s != null && s.isEnabled()) { + s.dispatchEvent(e); + } + } + + super.processKeyEvent(e); + } + } + + @Override + public void paint(Graphics g) { + synchronized (this.getParent()) { + if (this.getParent().isEnabled()) { + GammaTextArea gta = (GammaTextArea)this.getParent(); + Rectangle r = this.getBounds(); + if (r.width <= 0 || r.height <= 0) { + return; + } + + Image offImage = this.createImage(r.width, r.height); + Graphics offGraphic = offImage.getGraphics(); + offGraphic.setColor(GammaTextArea.getBackgroundColor()); + offGraphic.fillRect(r.x, r.y, r.width, r.height); + offGraphic.setColor(Color.black); + if (gta.getHasFocus()) { + offGraphic.setColor(Color.blue); + offGraphic.drawRect(r.x, r.y, r.width - 1, r.height - 1); + offGraphic.drawRect(r.x + 1, r.y + 1, r.width - 2, r.height - 2); + offGraphic.setColor(Color.black); + } + + offGraphic.setFont(gta.getFont()); + FontMetrics fm = offGraphic.getFontMetrics(gta.getFont()); + gta._curpos = 0; + if (gta.getNumLines() <= gta.getCanvasLines()) { + for (int i = 0; i < gta.getNumLines(); i++) { + gta.drawLine(offGraphic, i, (i + 1) * fm.getHeight() - fm.getDescent()); + } + } else { + int i = gta.getScrollLine(); + + for (int j = 1; i < gta.getNumLines(); j++) { + gta.drawLine(offGraphic, i, j * fm.getHeight() - fm.getDescent()); + i++; + } + } + + g.drawImage(offImage, 0, 0, this); + if (this.delayedMouseEvent != null) { + this.processMouseEvent(this.delayedMouseEvent); + this.delayedMouseEvent = null; + } + } + } + } +} diff --git a/NET/worlds/console/TextCanvas.java b/NET/worlds/console/TextCanvas.java new file mode 100644 index 0000000..382c69c --- /dev/null +++ b/NET/worlds/console/TextCanvas.java @@ -0,0 +1,82 @@ +package NET.worlds.console; + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Toolkit; +import java.util.Vector; + +public class TextCanvas extends Canvas { + private static final long serialVersionUID = 2808978760046610505L; + private Dimension calcSize; + private Font font; + private FontMetrics metrics; + private Vector<String> lines = new Vector<String>(); + + public TextCanvas(String text, int width) { + this.font = new Font(Console.message("CanvasFont"), 0, 12); + this.metrics = Toolkit.getDefaultToolkit().getFontMetrics(this.font); + char[] chars = text.toCharArray(); + int start = 0; + int end = 0; + int prevEnd = 0; + int lineWidth = 0; + end = start; + + while (end < chars.length) { + char c = chars[end]; + boolean isEOL = c == '\n'; + if (!isEOL && end == chars.length - 1) { + isEOL = true; + end++; + } + + if (c != ' ' && !isEOL) { + end++; + } else { + lineWidth = this.metrics.charsWidth(chars, start, end - start); + if (width != -1 && lineWidth > width) { + end = prevEnd; + } else if ((width == -1 || lineWidth < width) && !isEOL) { + prevEnd = end++; + continue; + } + + this.lines.addElement(new String(chars, start, end - start)); + start = end + 1; + + while (start < chars.length && chars[start] == ' ') { + start++; + } + + end = start; + prevEnd = start; + } + } + + this.calcSize = new Dimension(width == -1 ? lineWidth : width, this.metrics.getHeight() * this.lines.size()); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + g.setFont(this.font); + g.setColor(Color.black); + int height = this.metrics.getHeight(); + int y = this.metrics.getAscent() + this.metrics.getLeading(); + + for (int i = 0; i < this.lines.size(); i++) { + String line = this.lines.elementAt(i); + g.drawString(line, 0, y); + y += height; + } + } + + @Override + public Dimension preferredSize() { + return this.calcSize; + } +} diff --git a/NET/worlds/console/TextImageButtons.java b/NET/worlds/console/TextImageButtons.java new file mode 100644 index 0000000..3f9b36b --- /dev/null +++ b/NET/worlds/console/TextImageButtons.java @@ -0,0 +1,77 @@ +package NET.worlds.console; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Toolkit; + +class TextImageButtons extends ImageButtons { + private static final long serialVersionUID = -3744924750348174006L; + private int buttonCount; + private int[] xText; + private String[] texts; + private int[] buttonBottoms; + private Font font; + private static Font defFont = new Font(Console.message("ButtonFont"), 0, 9); + private static final int yBaseline = 4; + + public static Dimension measure(String text, Font f) { + Dimension sz = new Dimension(); + FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(f); + sz.width = fm.stringWidth(text); + sz.height = fm.getHeight(); + return sz; + } + + public TextImageButtons(String imageName, int buttonWidth, int[] buttonHeights, int[] textLefts, String[] texts, ImageButtonsCallback handler) { + this(imageName, buttonWidth, buttonHeights, textLefts, texts, handler, defFont); + } + + public TextImageButtons(String imageName, int buttonWidth, int[] buttonHeights, int[] textLefts, String[] texts, ImageButtonsCallback handler, Font f) { + super(imageName, buttonWidth, buttonHeights, handler); + this.xText = textLefts; + this.texts = texts; + this.buttonCount = buttonHeights.length; + this.font = f; + this.buttonBottoms = new int[this.buttonCount]; + int lastBottom = 0; + + for (int i = 0; i < this.buttonCount; i++) { + lastBottom += buttonHeights[i]; + this.buttonBottoms[i] = lastBottom; + } + } + + public void setTexts(String[] newTexts) { + assert newTexts.length == this.texts.length; + + this.texts = newTexts; + this.repaint(); + } + + public String getText(int i) { + return this.texts[i]; + } + + @Override + protected Graphics drawButton(Graphics g, int button, int state) { + return this.drawButton(g, button, state, Color.white); + } + + protected Graphics drawButton(Graphics g, int button, int state, Color c) { + if (button >= 0 && button < this.buttonCount && this.texts[button] != null) { + g = super.drawButton(g, button, state); + if (g != null || (g = this.getGraphics()) != null) { + g.setColor(c); + g.setFont(this.font); + g.drawString(this.texts[button], this.xText[button], this.buttonBottoms[button] - 4); + } + } else { + g = super.drawButton(g, button, 0); + } + + return g; + } +} diff --git a/NET/worlds/console/TradeDialog.java b/NET/worlds/console/TradeDialog.java new file mode 100644 index 0000000..44dbdf2 --- /dev/null +++ b/NET/worlds/console/TradeDialog.java @@ -0,0 +1,526 @@ +package NET.worlds.console; + +import NET.worlds.scape.InventoryItem; +import NET.worlds.scape.InventoryManager; +import NET.worlds.scape.Pilot; +import java.awt.BorderLayout; +import java.awt.Checkbox; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.GridLayout; +import java.awt.Insets; +import java.awt.Label; +import java.awt.Panel; +import java.awt.ScrollPane; +import java.awt.TextField; +import java.text.MessageFormat; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +public class TradeDialog extends WhisperDialog { + private static final long serialVersionUID = -6745488915622839369L; + public static final String tradeServerName = "TRADE"; + private Checkbox confirmBox = new Checkbox(Console.message("Its-a-Deal")); + ScrollPane scrollPane; + private static Font font = new Font(Console.message("DialogFont"), 0, 12); + private String lastOfferSent = ""; + private String lastOfferReceived = ""; + private Vector<TextField> fieldList; + private int keyChange; + protected Panel hisOffer = new Panel(); + protected Panel yourOffer = new Panel(); + + public TradeDialog(java.awt.Window parent, String partner) { + super(parent, partner); + } + + public static void sendTradeMessage(final String msg) { + Main.register(new MainCallback() { + @Override + public void mainCallback() { + Pilot.sendText("TRADE", msg); + Main.unregister(this); + } + }); + } + + public synchronized void setTrading(boolean f) { + this.lastOfferReceived = ""; + this.lastOfferSent = ""; + this.isTrading = f; + if (this.isTrading) { + Object[] arguments = new Object[]{new String(this.partner)}; + Console.println(MessageFormat.format(Console.message("Trade-with"), arguments)); + } else { + Object[] arguments = new Object[]{new String(this.partner)}; + Console.println(MessageFormat.format(Console.message("Whisper-to-from"), arguments)); + } + + if (this.built && !this.building) { + this.building = true; + Main.register(new MainCallback() { + @Override + public void mainCallback() { + TradeDialog.this.build(); + TradeDialog.this.pack(); + Main.unregister(this); + } + }); + } + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.confirmBox && this.confirmBox.getState()) { + this.sendOffer(true, false); + return true; + } else { + return false; + } + } + + @Override + protected synchronized void activeCallback() { + if (this.keyChange > 0 && --this.keyChange == 0) { + this.sendOffer(false, true); + } + } + + private void displayOffer(String offerStr, Panel p) { + InventoryManager im = InventoryManager.getInventoryManager(); + Hashtable<String, InventoryItem> shorts = im.parseInventoryString(offerStr); + p.removeAll(); + GridBagConstraints c = new GridBagConstraints(); + GridBagLayout gbag = new GridBagLayout(); + p.setLayout(gbag); + c.weightx = 1.0; + c.weighty = 0.0; + c.gridheight = 1; + c.gridwidth = 0; + c.insets = new Insets(6, 3, 0, 8); + c.anchor = 17; + if (shorts.size() == 0) { + c.gridwidth = -1; + c.insets = new Insets(36, 20, 36, 3); + Label lab = new Label(Console.message("Nothing")); + gbag.setConstraints(lab, c); + p.add(lab); + } + + if (shorts.size() > 0) { + Enumeration<InventoryItem> shortEnum = shorts.elements(); + + while (shortEnum.hasMoreElements()) { + InventoryItem invItem = shortEnum.nextElement(); + c.gridwidth = -1; + c.insets = new Insets(6, 3, 0, 8); + ImageCanvas imcv = new ImageCanvas(invItem.getItemGraphicLocation()); + gbag.setConstraints(imcv, c); + p.add(imcv); + c.gridwidth = 0; + c.insets = new Insets(3, 3, 0, 3); + Label lab = new Label(InventoryManager.getInventoryManager().itemName(invItem)); + gbag.setConstraints(lab, c); + p.add(lab); + } + } + + p.invalidate(); + p.doLayout(); + p.validate(); + p.repaint(); + Container par = p.getParent(); + if (par != null) { + par.invalidate(); + par.doLayout(); + par.validate(); + par.repaint(); + } + } + + private synchronized void clearOffer() { + int len = this.fieldList.size(); + + for (int i = 0; i < len; i++) { + TextField tf = this.fieldList.elementAt(i); + tf.setFont(font); + tf.setText(""); + } + } + + private synchronized void sendOffer(boolean isDeal, boolean onlyIfChanged) { + String offer = ""; + InventoryManager im = InventoryManager.getInventoryManager(); + Hashtable<String, InventoryItem> invHash = im.getInventoryItems(); + if (invHash.size() > 0) { + Enumeration<InventoryItem> invEnum = invHash.elements(); + + for (int i = 0; invEnum.hasMoreElements(); i++) { + InventoryItem invItem = invEnum.nextElement(); + TextField tf = this.fieldList.elementAt(i); + tf.setFont(font); + String nm = invItem.getItemId(); + int count = -1; + if (tf.getText().trim().length() == 0) { + count = 0; + } else { + try { + count = Integer.parseInt(tf.getText()); + } catch (NumberFormatException var13) { + } + } + + int maxCount = invItem.getItemQuantity(); + if (count < 0 || count > maxCount) { + this.whisperPart.println("*** Invalid number of " + InventoryManager.getInventoryManager().getPlural(nm) + ": " + tf.getText() + "."); + return; + } + + if (count > 0) { + offer = offer + nm; + if (count > 1) { + offer = offer + Integer.toString(count); + } + } + } + } + + String ourPartOfOffer = offer; + if (isDeal) { + int commaPos = this.lastOfferReceived.indexOf(","); + if (commaPos < 0 || !offer.equals(this.lastOfferReceived.substring(commaPos + 1))) { + Object[] arguments = new Object[]{new String(this.partner)}; + this.whisperPart.println(MessageFormat.format(Console.message("proposed-deal"), arguments)); + if (commaPos < 0) { + commaPos = this.lastOfferReceived.length(); + if (this.lastOfferReceived.equals("cancel")) { + commaPos = 0; + } + } + } + + String newOffer = this.lastOfferReceived.substring(0, commaPos) + "," + offer; + this.lastOfferSent = newOffer; + offer = offer + "," + this.lastOfferReceived.substring(0, commaPos); + } else { + String lastSent = this.lastOfferSent; + int commaPos = lastSent.indexOf(","); + if (onlyIfChanged && offer.equals(lastSent.substring(commaPos + 1))) { + return; + } + + this.lastOfferSent = offer; + } + + this.displayOffer(ourPartOfOffer, this.yourOffer); + this.whisperPart.say("&|+trade>" + offer); + if (isDeal) { + sendTradeMessage("&|+deal>" + this.whisperPart.getPartner() + " " + offer); + } + } + + public static String buildInvDesc(Hashtable<String, InventoryItem> inv) { + String str = ""; + Enumeration<InventoryItem> invEnum = inv.elements(); + InventoryManager im = InventoryManager.getInventoryManager(); + if (invEnum.hasMoreElements()) { + Object obj = invEnum.nextElement(); + if (obj != null) { + InventoryItem invItem = (InventoryItem)obj; + str = str + im.itemName(invItem); + } + + while (invEnum.hasMoreElements()) { + obj = invEnum.nextElement(); + InventoryItem invItem = (InventoryItem)obj; + str = str + ", "; + str = str + im.itemName(invItem); + } + } + + return str; + } + + protected void cancelTrading() { + if (this.isTrading && this.isActive()) { + this.whisperPart.say("&|+trade>cancel"); + if (this.lastOfferSent.indexOf(",") >= 0) { + sendTradeMessage("&|+deal>cancel"); + } + + this.lastOfferSent = ""; + } + } + + @Override + protected synchronized boolean done(boolean confirmed) { + this.cancelTrading(); + WhisperManager.whisperManager().remove(this.partner); + return super.done(confirmed); + } + + protected void doneDeal() { + String tradeTerms = ""; + InventoryManager im = InventoryManager.getInventoryManager(); + int commaPos = this.lastOfferSent.indexOf(","); + if (commaPos >= 0) { + Hashtable<String, InventoryItem> lost = im.parseInventoryString(this.lastOfferSent.substring(commaPos + 1)); + tradeTerms = buildInvDesc(lost); + if (tradeTerms.length() == 0) { + tradeTerms = "nothing"; + } + + Hashtable<String, InventoryItem> got = im.parseInventoryString(this.lastOfferSent.substring(0, commaPos)); + String gotTerms = buildInvDesc(got); + if (gotTerms.length() == 0) { + gotTerms = "nothing"; + } + + tradeTerms = ": " + tradeTerms + " for " + gotTerms; + this.setTrading(true); + Object[] arguments = new Object[]{new String(tradeTerms)}; + this.whisperPart.println(MessageFormat.format(Console.message("Trans-complete"), arguments)); + } + } + + protected void processOffer(boolean startUp) { + if (this.lastOfferReceived.equals("cancel")) { + this.lastOfferReceived = ""; + this.cancelTrading(); + this.setTrading(true); + Object[] arguments = new Object[]{new String(this.partner)}; + this.whisperPart.println(MessageFormat.format(Console.message("Trans-complete"), arguments)); + } else { + String offer = this.lastOfferReceived; + int lastComma = 0; + int commaPos = offer.indexOf(","); + Object[] arguments = new Object[]{new String(this.partner)}; + if (commaPos < 0) { + if (!startUp) { + this.whisperPart.println(MessageFormat.format(Console.message("offer-changed"), arguments)); + } + } else if (!offer.equals(this.lastOfferSent)) { + lastComma = this.lastOfferSent.indexOf(","); + if (lastComma < 0) { + lastComma = this.lastOfferSent.length(); + } + + if (offer.substring(commaPos + 1).equals(this.lastOfferSent.substring(0, lastComma))) { + this.whisperPart.println(MessageFormat.format(Console.message("proposed-this"), arguments)); + } else { + this.whisperPart.println(MessageFormat.format(Console.message("proposed-new"), arguments)); + } + } + + if (commaPos < 0) { + commaPos = offer.length(); + } + + this.displayOffer(offer.substring(0, commaPos), this.hisOffer); + } + } + + @Override + protected synchronized void build() { + if (this.lastOfferSent.equals("")) { + this.displayOffer("", this.yourOffer); + } + + if (this.lastOfferReceived.equals("") || this.lastOfferReceived.equals("cancel")) { + this.displayOffer("", this.hisOffer); + } + + this.building = false; + if (this.built) { + this.removeAll(); + } + + this.built = true; + Color bg1 = new Color(0, 0, 0); + Color bg2 = new Color(0, 192, 192); + Color bg2b = new Color(0, 160, 160); + Color fg1 = new Color(255, 255, 255); + this.setBackground(this.isTrading ? bg1 : Color.white); + this.setForeground(Color.black); + Panel borderPanel = null; + if (this.isTrading) { + borderPanel = new InsetPanel(new BorderLayout(), 6, 10, 12, 11); + borderPanel.setBackground(bg1); + InventoryManager iMgr = InventoryManager.getInventoryManager(); + Hashtable<String, InventoryItem> inv = iMgr.getInventoryItems(); + Enumeration<InventoryItem> invEnum = inv.elements(); + int len = inv.size(); + this.fieldList = new Vector<TextField>(len); + Panel yourInv = new Panel(new GridLayout(1, len == 0 ? 1 : len)); + yourInv.setBackground(bg2); + int i = 0; + if (inv.size() > 0) { + while (invEnum.hasMoreElements()) { + InventoryItem invItem = invEnum.nextElement(); + Panel p = new Panel(new BorderLayout()); + p.setFont(font); + p.setBackground((i & 1) == 1 ? bg2 : bg2b); + MultiLineLabel nm = new MultiLineLabel(iMgr.itemName(invItem), 3, 0); + p.add("North", nm); + ImageCanvas im = new ImageCanvas(invItem.getItemGraphicLocation()); + Panel ins = new InsetPanel(new BorderLayout(), 5, 15, 5, 15); + ins.add("Center", im); + ins.setBackground((i & 1) == 1 ? bg2 : bg2b); + p.add("Center", ins); + Panel p2 = new Panel(new BorderLayout()); + p2.setFont(font); + TextField tf = new TextField("", 1); + tf.setFocusable(true); + tf.setFont(font); + this.fieldList.addElement(tf); + p2.add("West", tf); + nm = new MultiLineLabel("of " + invItem.getItemQuantity(), 3, 0); + p2.add("Center", nm); + p2.add("South", new FixedSizePanel(5, 25)); + p.add("South", p2); + yourInv.add(p); + i++; + } + } else { + Label nm = new Label(Console.message("You-have-nothing")); + yourInv.add(nm); + } + + this.scrollPane = new WideScrollPane(yourInv, true); + this.scrollPane.setBackground(bg2); + Panel invLabelPanel = new Panel(new BorderLayout()); + invLabelPanel.setFont(font); + Label invLabel = new Label(Console.message("Your-inventory")); + invLabel.setBackground(bg1); + invLabel.setForeground(fg1); + invLabelPanel.add("North", invLabel); + invLabelPanel.add("Center", this.scrollPane); + borderPanel.add("North", invLabelPanel); + Panel offers = new Panel(new GridLayout(1, 2)); + this.scrollPane = new WideScrollPane(this.yourOffer, true); + this.scrollPane.setBackground(bg2); + Panel labeledYour = new InsetPanel(new BorderLayout(), 0, 0, 8, 9); + Label labelYour = new Label(Console.message("Your-offer")); + labelYour.setBackground(bg1); + labelYour.setForeground(fg1); + labeledYour.add("North", labelYour); + labeledYour.add("Center", this.scrollPane); + offers.add(labeledYour); + this.scrollPane = new WideScrollPane(this.hisOffer, true); + this.scrollPane.setBackground(bg2); + Panel labeledHis = new InsetPanel(new BorderLayout(), 0, 9, 8, 0); + Object[] arguments = new Object[]{new String(this.partner)}; + Label labelHis = new Label(MessageFormat.format(Console.message("partner-offer"), arguments)); + labelHis.setBackground(bg1); + labelHis.setForeground(fg1); + labeledHis.add("North", labelHis); + labeledHis.add("Center", this.scrollPane); + offers.add(labeledHis); + Panel insDeal = new InsetPanel(new BorderLayout(), 8, 18, 8, 18); + insDeal.setBackground(bg1); + insDeal.add("Center", offers); + insDeal.add("South", this.confirmBox); + borderPanel.add("Center", insDeal); + this.processOffer(true); + } + + this.whisperPart.line.setBackground(this.isTrading ? bg2 : Color.white); + if (this.isTrading) { + if (!this.isBroadcast) { + Panel listenPane = new Panel(new BorderLayout()); + this.whisperPart.listen.setBackground(bg2); + Object[] arguments = new Object[]{new String(this.partner)}; + Label whispLabel = new Label(MessageFormat.format(Console.message("Whispers-with"), arguments)); + whispLabel.setBackground(bg1); + whispLabel.setForeground(fg1); + listenPane.add("North", whispLabel); + listenPane.add("Center", this.whisperPart.listen.getComponent()); + listenPane.add("South", this.whisperPart.line); + borderPanel.add("South", listenPane); + } else { + borderPanel.add("South", this.whisperPart.line); + } + + this.add(borderPanel); + } else { + this.whisperPart.listen.setBackground(Color.lightGray); + Panel insListen = new InsetPanel(new BorderLayout(), 3, 1, 1, 1); + insListen.setBackground(Color.lightGray); + insListen.add("Center", this.whisperPart.listen.getComponent()); + this.add("Center", insListen); + Panel insLine = new InsetPanel(new BorderLayout(), 2, 1, 2, 1); + insLine.setBackground(Color.lightGray); + insLine.add("Center", this.whisperPart.line); + this.add("South", insLine); + } + + this.validate(); + } + + @Override + protected synchronized void print(String msg) { + if (msg.startsWith("&|+trade>")) { + if (!this.isTrading) { + this.setTrading(true); + } + + this.lastOfferReceived = msg.substring(9); + if (!this.building) { + this.processOffer(false); + } + } else if (!msg.startsWith("&|+")) { + this.whisperPart.println("> " + msg); + } + } + + @Override + public synchronized boolean keyDown(Event event, int key) { + if (!this.isTrading) { + this.whisperPart.line.requestFocus(); + } else { + this.keyChange = 2; + } + + if (key == 10) { + this.whisperPart.trigger(); + return true; + } else { + return false; + } + } + + @Override + public Dimension preferredSize() { + Dimension d = super.preferredSize(); + if (d.width < 400) { + d.width = 400; + } + + if (d.height < 400) { + d.height = 400; + } + + return d; + } + + @Override + public Dimension minimumSize() { + Dimension d = super.minimumSize(); + if (d.width < 400) { + d.width = 400; + } + + if (d.height < 400) { + d.height = 400; + } + + return d; + } +} diff --git a/NET/worlds/console/Tree.java b/NET/worlds/console/Tree.java new file mode 100644 index 0000000..b6f6d0c --- /dev/null +++ b/NET/worlds/console/Tree.java @@ -0,0 +1,282 @@ +package NET.worlds.console; + +import NET.worlds.scape.LibraryDropTarget; +import java.util.Hashtable; +import java.util.Vector; + +public class Tree extends TreePanel implements MainCallback, LibraryDropTarget { + private static final long serialVersionUID = -1919976160954835913L; + private int openItem = -1; + private int changeItem = -1; + private TreeCallback owner; + private boolean registered; + + public Tree() { + } + + public Tree(TreeCallback owner) { + this(); + this.setOwner(owner); + } + + public void setOwner(TreeCallback owner) { + this.owner = owner; + } + + public void change(TreeNode root, Object current) { + this.delayRepaints(true); + this.removeAllElements(); + this.addElement(root); + int index = this.search(0, current, new Hashtable<TreeNode, TreeNode>()); + + assert index != -1; + + this.sync(index); + } + + public void change(TreeNode root, Vector<TreeNode> lineage) { + this.delayRepaints(true); + this.removeAllElements(); + TreeNode parent = root; + this.addElement(root); + int index = 1; + + for (int j = 0; j < lineage.size(); j++) { + Object lookingFor = lineage.elementAt(j); + Vector<TreeNode> v = this.getSortedChildren(parent); + parent.setOpen(true); + int count = v.size(); + int foundIndex = -1; + + for (int i = 0; i < count; i++) { + TreeNode child = v.elementAt(i); + int tmp = index + i; + this.insertElementAt(child, tmp); + if (foundIndex == -1 && child.getObject().equals(lookingFor)) { + foundIndex = tmp; + parent = child; + } + } + + assert foundIndex != -1; + + index = foundIndex + 1; + } + + this.sync(index - 1); + } + + public void update() { + Vector<TreeNode> newTree = new Vector<TreeNode>(); + int count = this.countElements(); + + for (int i = 0; i < count; i++) { + TreeNode e1 = this.elementAt(i); + if (e1.getParent() == null) { + newTree.addElement(e1); + this.recurseAddChildren(newTree, e1); + } + } + + TreeNode selected = this.getSelectedNode(); + count = newTree.size(); + int ix = 0; + + while (ix < count && !newTree.elementAt(ix).equals(selected)) { + ix++; + } + + int hitem = ix < count ? ix : Math.min(count - 1, this.getSelectedIndex()); + this.delayRepaints(true); + this.reset(newTree); + this.sync(hitem); + } + + private void sync(int selected) { + try { + this.select(selected); + Object treeNode = this.getSelectedNode().getObject(); + if (treeNode != null) { + this.owner.treeChange(treeNode); + this.delayRepaints(false); + } + } catch (Exception var3) { + } + } + + private Vector<TreeNode> getSortedChildren(TreeNode parent) { + Vector<TreeNode> unsorted = (Vector<TreeNode>)parent.getChildren(); + Vector<TreeNode> sorted = new Vector<TreeNode>(unsorted.size()); + if (unsorted != null) { + int icount = unsorted.size(); + + for (int i = 0; i < icount; i++) { + TreeNode e = unsorted.elementAt(i); + if (!parent.shouldSort()) { + sorted.insertElementAt(e, i); + } else { + int jcount = sorted.size(); + int j = 0; + + while (j < jcount && sorted.elementAt(j).toString().compareTo(e.toString()) <= 0) { + j++; + } + + sorted.insertElementAt(e, j); + } + } + } + + return sorted; + } + + private Vector<TreeNode> getCurrentChildren(TreeNode parent) { + Vector<TreeNode> ret = new Vector<TreeNode>(); + int count = this.countElements(); + + for (int i = 0; i < count; i++) { + TreeNode ele = this.elementAt(i); + if (ele.getParent() == parent) { + ret.addElement(ele); + } + } + + return ret; + } + + private static TreeNode maybeUseOldChild(TreeNode newChild, Vector<TreeNode> oldChildren) { + int count = oldChildren.size(); + + for (int i = 0; i < count; i++) { + TreeNode oldChild = oldChildren.elementAt(i); + if (oldChild.equals(newChild)) { + return oldChild; + } + } + + return newChild; + } + + private void recurseAddChildren(Vector<TreeNode> newTree, TreeNode oldEle) { + if (oldEle.isOpen()) { + Vector<TreeNode> oldChildren = this.getCurrentChildren(oldEle); + Vector<TreeNode> newChildren = this.getSortedChildren(oldEle); + int count = newChildren.size(); + + for (int i = 0; i < count; i++) { + TreeNode child = newChildren.elementAt(i); + child = maybeUseOldChild(child, oldChildren); + newTree.addElement(child); + this.recurseAddChildren(newTree, child); + } + } + } + + private int search(int index, Object obj, Hashtable<TreeNode, TreeNode> lookedAt) { + TreeNode e = this.elementAt(index); + if (e.getObject().equals(obj)) { + return index; + } else { + if (!lookedAt.containsKey(e)) { + lookedAt.put(e, e); + index++; + Vector<TreeNode> v = this.getSortedChildren(e); + e.setOpen(true); + if (v != null) { + int count = v.size(); + + for (int i = 0; i < count; i++) { + this.insertElementAt(v.elementAt(i), index + i); + } + + for (int i = 0; i < count; i++) { + int found = this.search(index + i, obj, lookedAt); + if (found != -1) { + return found; + } + } + + for (int ix = 0; ix < count; ix++) { + this.removeElementAt(index); + } + } + + e.setOpen(false); + } + + return -1; + } + } + + private void register() { + if (!this.registered) { + Main.register(this); + this.registered = true; + } + } + + @Override + public void treeSelect(int item) { + if (item != this.getSelectedIndex()) { + this.select(item); + this.changeItem = item; + this.register(); + } + } + + @Override + public void treeOpen(int item) { + if (this.openItem == -1) { + this.openItem = item; + this.register(); + } + } + + @Override + public void setFocus(boolean hasFocus) { + boolean hadFocus = this.hasFocus(); + super.setFocus(hasFocus); + if (hadFocus != hasFocus) { + this.owner.treeFocusChanged(hasFocus); + } + } + + @Override + public synchronized void mainCallback() { + this.delayRepaints(true); + int i = this.changeItem; + this.changeItem = -1; + if (i != -1) { + this.owner.treeChange(this.elementAt(i).getObject()); + } + + i = this.openItem; + this.openItem = -1; + if (i != -1) { + TreeNode e = this.elementAt(i); + boolean isOpen = !e.isOpen(); + e.setOpen(isOpen); + i++; + if (isOpen) { + Vector<TreeNode> v = this.getSortedChildren(e); + if (v != null) { + int count = v.size(); + + for (int j = 0; j < count; j++) { + this.insertElementAt(v.elementAt(j), i++); + } + } + } else { + while (i < this.countElements() && e.isDescendant(this.elementAt(i))) { + this.removeElementAt(i); + } + } + + this.repaint(); + } + + this.delayRepaints(false); + this.registered = false; + Main.unregister(this); + } +} diff --git a/NET/worlds/console/TreeCallback.java b/NET/worlds/console/TreeCallback.java new file mode 100644 index 0000000..ec6d5ea --- /dev/null +++ b/NET/worlds/console/TreeCallback.java @@ -0,0 +1,7 @@ +package NET.worlds.console; + +public interface TreeCallback { + void treeChange(Object var1); + + void treeFocusChanged(boolean var1); +} diff --git a/NET/worlds/console/TreeNode.java b/NET/worlds/console/TreeNode.java new file mode 100644 index 0000000..f424f12 --- /dev/null +++ b/NET/worlds/console/TreeNode.java @@ -0,0 +1,64 @@ +package NET.worlds.console; + +import java.util.Vector; + +public abstract class TreeNode { + private int level; + private TreeNode parent; + private boolean isOpen; + + protected TreeNode(TreeNode parent) { + this.parent = parent; + if (parent != null) { + this.level = parent.getLevel() + 1; + } + } + + public int getLevel() { + return this.level; + } + + public TreeNode getParent() { + return this.parent; + } + + public boolean isDescendant(TreeNode e) { + while (e != null) { + if ((e = e.getParent()) == this) { + return true; + } + } + + return false; + } + + public boolean isOpen() { + return this.isOpen; + } + + public void setOpen(boolean isOpen) { + this.isOpen = isOpen; + } + + public boolean displayAsTitle() { + return false; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof TreeNode && this.getObject().equals(((TreeNode)obj).getObject()); + } + + @Override + public int hashCode() { + return this.getObject().hashCode(); + } + + public abstract Vector<?> getChildren(); + + public boolean shouldSort() { + return true; + } + + public abstract Object getObject(); +} diff --git a/NET/worlds/console/TreePanel.java b/NET/worlds/console/TreePanel.java new file mode 100644 index 0000000..3737f20 --- /dev/null +++ b/NET/worlds/console/TreePanel.java @@ -0,0 +1,315 @@ +package NET.worlds.console; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Event; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Point; +import java.awt.Scrollbar; +import java.util.Vector; + +public class TreePanel extends ExposedPanel implements DialogDisabled { + private static final long serialVersionUID = -5534860983354876334L; + private Vector<TreeNode> items = new Vector<TreeNode>(); + private boolean delayRepaints; + private boolean needRepaint; + private boolean needRecalc; + private boolean needMakeVisible; + private Scrollbar scrollbar = new WiderScrollbar(); + private int scrollPos = 0; + private int linesVisible; + private int selectedIndex = -1; + private boolean hasFocus = true; + private Font nFont = new Font(Console.message("TreeFont"), 0, 13); + private FontMetrics nFontMetrics = this.getFontMetrics(this.nFont); + private Font bFont = new Font(Console.message("TreeFont"), 1, 11); + private FontMetrics bFontMetrics = this.getFontMetrics(this.bFont); + private int fontHeight = Math.max(this.nFontMetrics.getHeight(), this.bFontMetrics.getHeight()); + private int itemHeight = this.fontHeight; + private boolean isDialogDisabled; + private static final int[] cxs = new int[]{0, 0, 6}; + private static final int[] cys = new int[]{6, -6, 0}; + private MoveablePolygon closedIcon = new MoveablePolygon(cxs, cys); + private static final int[] oxs = new int[]{-5, 6, 0}; + private static final int[] oys = new int[]{0, 0, 6}; + private MoveablePolygon openedIcon = new MoveablePolygon(oxs, oys); + private static final Color normBGColor = new Color(80, 80, 80); + private static final Color normFGColor = new Color(190, 190, 190); + private static final Color selFGColor = new Color(255, 255, 175); + private static final int indentPixels = 14; + + public TreePanel() { + this.setBackground(normBGColor); + this.setLayout(new BorderLayout()); + this.add("East", this.scrollbar); + this.scrollbar.hide(); + } + + public synchronized void delayRepaints(boolean state) { + if (!(this.delayRepaints = state)) { + if (this.needRecalc) { + this.recalc(); + } + + if (this.needMakeVisible) { + this.makeVisible(this.selectedIndex); + } + + if (this.needRepaint) { + this.repaint(); + } + } + } + + private synchronized void needRepaint(boolean needRecalc, boolean needMakeVisible) { + this.needRepaint = true; + this.needRecalc |= needRecalc; + this.needMakeVisible |= needMakeVisible; + this.delayRepaints(this.delayRepaints); + } + + public synchronized int getSelectedIndex() { + return this.selectedIndex; + } + + public synchronized void select(int item) { + this.selectedIndex = item; + this.needRepaint(false, true); + } + + public void setFocus(boolean hasFocus) { + if (this.hasFocus != hasFocus) { + this.hasFocus = hasFocus; + this.needRepaint(false, false); + } + } + + @Override + public boolean hasFocus() { + return this.hasFocus; + } + + @Override + public synchronized void reshape(int x, int y, int w, int h) { + super.reshape(x, y, w, h); + this.needRepaint(true, false); + } + + public synchronized TreeNode getSelectedNode() { + return this.selectedIndex != -1 ? this.items.elementAt(this.selectedIndex) : null; + } + + public synchronized void reset(Vector<TreeNode> items) { + this.items = items; + this.needRepaint(true, false); + } + + public synchronized void removeAllElements() { + this.items.removeAllElements(); + this.needRepaint(true, false); + } + + public synchronized void insertElementAt(TreeNode ele, int index) { + this.items.insertElementAt(ele, index); + this.needRepaint(true, false); + } + + public synchronized void removeElementAt(int index) { + this.items.removeElementAt(index); + this.needRepaint(true, false); + } + + public synchronized void addElement(TreeNode ele) { + this.items.addElement(ele); + this.needRepaint(true, false); + } + + public int countElements() { + return this.items.size(); + } + + public TreeNode elementAt(int index) { + return this.items.elementAt(index); + } + + public TreeNode elementAt(Point p) { + int item = this.scrollPos + p.y / this.itemHeight; + return item < this.items.size() ? this.items.elementAt(item) : null; + } + + private void makeVisible(int item) { + int count = this.items.size(); + if (count > this.linesVisible && (item < this.scrollPos || item >= this.scrollPos + this.linesVisible)) { + this.setScrollValue(Math.min(item * this.itemHeight, this.scrollbar.getMaximum())); + } + + this.needMakeVisible = false; + } + + private void add(GridBagLayout gbag, Component comp, GridBagConstraints c) { + gbag.setConstraints(comp, c); + this.add(comp); + } + + public synchronized void recalc() { + int height = this.getSize().height; + this.linesVisible = Math.max(1, height / this.itemHeight); + int count = this.items.size(); + if (count > this.linesVisible) { + if (!this.scrollbar.isVisible()) { + this.scrollbar.setVisible(true); + this.validate(); + } + + this.scrollbar.setValues(this.scrollPos * this.itemHeight, this.linesVisible * this.itemHeight, 0, count * this.itemHeight); + this.scrollbar.setPageIncrement(this.linesVisible * this.itemHeight); + this.scrollbar.setLineIncrement(this.itemHeight); + } else { + if (this.scrollbar.isVisible()) { + this.scrollbar.hide(); + this.validate(); + } + + this.scrollPos = 0; + } + + this.needRecalc = false; + } + + @Override + public synchronized void paint(Graphics g) { + super.paint(g); + int width = this.getSize().width; + int height = this.getSize().height; + int count = this.items.size(); + int y = 0; + + for (int i = this.scrollPos; i < count; i++) { + TreeNode node = this.elementAt(i); + String name = node.toString(); + boolean isTitle = node.displayAsTitle(); + Font font = this.nFont; + FontMetrics metrics = this.nFontMetrics; + if (isTitle) { + font = this.bFont; + metrics = this.bFontMetrics; + } + + g.setFont(font); + int ascent = metrics.getAscent(); + int x = node.getLevel() * 14; + g.setColor(normFGColor); + if (node.isOpen()) { + this.openedIcon.drawFilled(g, x + 5, y + ascent - 5); + } else { + this.closedIcon.drawFilled(g, x + 5, y + ascent - 5); + } + + if (i == this.selectedIndex) { + g.setColor(selFGColor); + } + + g.drawString(name, x + 11 + 5, y + ascent); + if (i == this.selectedIndex && this.hasFocus) { + g.drawRect(x + 11 + 3, y, metrics.stringWidth(name) + 3, this.itemHeight); + } + + y += this.itemHeight; + if (y >= height) { + break; + } + } + + this.needRepaint = false; + } + + @Override + public boolean handleEvent(Event e) { + if (this.isDialogDisabled) { + return false; + } else { + switch (e.id) { + case 601: + return this.scrollLineUp(); + case 602: + return this.scrollLineDown(); + case 603: + return this.scrollPageUp(); + case 604: + return this.scrollPageDown(); + case 605: + return this.scrollAbsolute(); + default: + return super.handleEvent(e); + } + } + } + + @Override + public void dialogDisable(boolean disable) { + this.isDialogDisabled = disable; + } + + @Override + public synchronized boolean mouseDown(Event e, int x, int y) { + this.setFocus(true); + int item = this.scrollPos + y / this.itemHeight; + if (item >= 0 && item < this.items.size()) { + if (e.clickCount == 1) { + this.treeSelect(item); + int yStart = y / this.itemHeight * this.itemHeight; + TreeNode node = this.elementAt(item); + MoveablePolygon widget = node.isOpen() ? this.openedIcon : this.closedIcon; + FontMetrics metrics = node.displayAsTitle() ? this.nFontMetrics : this.bFontMetrics; + widget.moveTo(node.getLevel() * 14 + 5, yStart + metrics.getAscent() - 5); + if (widget.getBoundingBox().inside(x, y)) { + this.treeOpen(item); + } + } else { + this.treeOpen(item); + } + } + + return true; + } + + public void treeSelect(int item) { + } + + public void treeOpen(int item) { + } + + private boolean setScrollValue(int value) { + value = Math.max(this.scrollbar.getMinimum(), value); + value = Math.min(this.scrollbar.getMaximum(), value); + this.scrollPos = value / this.itemHeight; + this.scrollbar.setValue(this.scrollPos * this.itemHeight); + this.needRepaint(false, false); + return true; + } + + private boolean scrollLineUp() { + return this.setScrollValue(this.scrollPos * this.itemHeight - this.scrollbar.getLineIncrement()); + } + + private boolean scrollLineDown() { + return this.setScrollValue(this.scrollPos * this.itemHeight + this.scrollbar.getLineIncrement()); + } + + private boolean scrollPageUp() { + return this.setScrollValue(this.scrollPos * this.itemHeight - this.scrollbar.getPageIncrement()); + } + + private boolean scrollPageDown() { + return this.setScrollValue(this.scrollPos * this.itemHeight + this.scrollbar.getPageIncrement()); + } + + private boolean scrollAbsolute() { + return this.setScrollValue(this.scrollbar.getValue()); + } +} diff --git a/NET/worlds/console/URLLine.java b/NET/worlds/console/URLLine.java new file mode 100644 index 0000000..7f4772f --- /dev/null +++ b/NET/worlds/console/URLLine.java @@ -0,0 +1,184 @@ +package NET.worlds.console; + +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.TeleportAction; +import NET.worlds.scape.TeleportStatus; +import java.awt.Container; +import java.awt.Event; +import java.awt.Label; +import java.awt.Menu; +import java.awt.TextField; +import java.util.Vector; + +public class URLLine extends TextField implements FramePart, TeleportStatus, DialogDisabled { + private static final long serialVersionUID = -4154943921462354673L; + protected static String nonloadSign = "URL: "; + public Label label = new Label(nonloadSign); + public Menu historyMenu; + public boolean beingEdited = false; + public String lastTextSet = ""; + private String currentText = ""; + private boolean okToCallGetText; + private boolean isDialogDisabled; + protected boolean teleporting; + protected int lastURLUpdate; + public static Vector<String> historyItems = new Vector<String>(); + + @Override + public synchronized String getText() { + return this.okToCallGetText ? super.getText() : this.currentText; + } + + private synchronized void syncCurrentText() { + this.okToCallGetText = true; + this.currentText = this.getText(); + this.okToCallGetText = false; + } + + @Override + public synchronized void setText(String s) { + if (!this.beingEdited) { + if (!this.currentText.equals(this.lastTextSet)) { + this.beingEdited = true; + } else { + this.lastTextSet = s; + if (!this.currentText.equals(s)) { + int p = this.getSelectionStart(); + super.setText(this.currentText = s); + this.select(p, p); + } + } + } + } + + public void cancelEdit() { + this.beingEdited = false; + this.lastTextSet = this.getText(); + this.select(1000, 1000); + this.lastURLUpdate = 0; + } + + @Override + public boolean keyDown(Event event, int key) { + if (key != 27) { + return super.keyDown(event, key); + } else { + this.cancelEdit(); + return true; + } + } + + @Override + public void activate(Console c, Container f, Console prev) { + this.historyMenu = new Menu("History"); + this.copyBackupToHistoryMenu(); + Console.getMenuBar().add(this.historyMenu); + } + + @Override + public void deactivate() { + } + + @Override + public void dialogDisable(boolean disable) { + this.isDialogDisabled = disable; + } + + @Override + public boolean handleEvent(Event event) { + if (this.isDialogDisabled) { + return false; + } else { + boolean ret = super.handleEvent(event); + if (event.target == this) { + this.syncCurrentText(); + } + + return ret; + } + } + + @Override + public boolean action(Event event, Object what) { + if (event.target == this) { + what = this.getText(); + if (((String)what).length() != 0) { + TeleportAction.teleport((String)what, null); + this.cancelEdit(); + } + + return true; + } else { + return true; + } + } + + @Override + public void teleportStatus(String err, String url) { + this.teleporting = err != null && err.length() == 0; + if (err == null) { + this.addHistoryItem(getCurrentPositionURL()); + this.setText(url); + } + } + + @Override + public boolean handle(FrameEvent f) { + if (f.time < this.lastURLUpdate + 500) { + return true; + } else { + this.lastURLUpdate = f.time; + this.setText(getCurrentPositionURL()); + if (this.teleporting) { + if (this.label.getText().equals("LOAD ")) { + this.label.setText("_____ "); + } else { + this.label.setText("LOAD "); + } + } else if (!this.label.getText().equals(nonloadSign)) { + this.label.setText(nonloadSign); + } + + return true; + } + } + + public static String getCurrentPositionURL() { + Pilot pilot = Pilot.getActive(); + if (pilot == null) { + return ""; + } else { + String newURL = pilot.getURL(); + return newURL == null ? "" : newURL; + } + } + + private void addHistoryItem(String url) { + if (url.length() != 0) { + historyItems.insertElementAt(url, 0); + int cnt = historyItems.size(); + + while (cnt > 10) { + historyItems.removeElementAt(--cnt); + } + + this.copyBackupToHistoryMenu(); + } + } + + private void copyBackupToHistoryMenu() { + while (this.historyMenu.getItemCount() > 0) { + this.historyMenu.remove(0); + } + + int cnt = historyItems.size(); + if (cnt == 0) { + this.historyMenu.add(""); + } + + for (int i = 0; i < cnt; i++) { + this.historyMenu.add(historyItems.elementAt(i)); + } + } +} diff --git a/NET/worlds/console/UniverseImage.java b/NET/worlds/console/UniverseImage.java new file mode 100644 index 0000000..f327adf --- /dev/null +++ b/NET/worlds/console/UniverseImage.java @@ -0,0 +1,24 @@ +package NET.worlds.console; + +import java.awt.event.MouseEvent; + +class UniverseImage extends ImageCanvas { + private static final long serialVersionUID = -8851169169042918014L; + + public UniverseImage(String fname) { + super(fname); + this.enableEvents(16L); + } + + @Override + public void processMouseEvent(MouseEvent e) { + if (e.getID() != 501) { + super.processMouseEvent(e); + } else { + Console cons = Console.getActive(); + if (cons != null && cons instanceof DefaultConsole) { + ((DefaultConsole)cons).startDrive(); + } + } + } +} diff --git a/NET/worlds/console/UniversePanel.java b/NET/worlds/console/UniversePanel.java new file mode 100644 index 0000000..856b00d --- /dev/null +++ b/NET/worlds/console/UniversePanel.java @@ -0,0 +1,407 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.core.Std; +import NET.worlds.network.NetUpdate; +import NET.worlds.network.ProgressDialog; +import NET.worlds.network.URL; +import NET.worlds.scape.BGLoaded; +import NET.worlds.scape.BackgroundLoader; +import NET.worlds.scape.Room; +import NET.worlds.scape.World; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.Panel; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.StringTokenizer; +import java.util.Vector; + +public class UniversePanel extends Panel implements MainCallback, ImageButtonsCallback, BGLoaded { + private static final long serialVersionUID = 4029344486393517219L; + UniverseImage bg; + int xOff = 0; + int yOff = 0; + ImageButtons backButton; + DefaultConsole owningConsole; + private static String datName = "universe/universe.dat"; + private static String bgName = "universe/universe.jpg"; + static String lastCacheDat; + static String lastCacheBg; + static Object locker = new Object(); + Image offscreen; + private boolean registered; + int upDownState; + int leftRightState; + int lastKeyTime; + Vector<WorldButton> buttons = new Vector<WorldButton>(); + Vector<WorldButtonBullet> bullets = new Vector<WorldButtonBullet>(); + + public UniversePanel(DefaultConsole cons) { + this.owningConsole = cons; + this.setLayout(null); + this.backButton = new ImageButtons(Console.message("back.gif"), 60, 22, this); + String rbgName = IniFile.override().getIniString("UniverseBgFile", bgName); + String rdatName = IniFile.override().getIniString("UniverseDatFile", datName); + if (!new File(datName).exists()) { + lastCacheDat = ""; + if (!ProgressDialog.copyFile("universe.dat", datName)) { + ProgressDialog.copyFile("../universe.dat", datName); + } + } + + this.readUniverseFile(datName); + if (!new File(bgName).exists()) { + lastCacheBg = ""; + if (!ProgressDialog.copyFile("universe.jpg", bgName)) { + ProgressDialog.copyFile("../universe.jpg", bgName); + } + } + + this.bg = new UniverseImage(bgName); + this.add(this.bg); + Dimension image = this.bg.imageSize(); + this.bg.setSize(image.width, image.height); + String serv = NetUpdate.getUpgradeServerURL(); + BackgroundLoader.get(this, URL.make(serv + rbgName)); + BackgroundLoader.get(this, URL.make(serv + rdatName)); + } + + private boolean safeCopyFile(String name) { + synchronized (locker) { + if (name.endsWith("dat") && !name.equals(lastCacheDat)) { + lastCacheDat = name; + if (ProgressDialog.copyFile(name, datName)) { + this.readUniverseFile(datName); + this.add(this.bg); + return true; + } + } else if (name.endsWith("jpg") && !name.equals(lastCacheBg)) { + lastCacheBg = name; + if (ProgressDialog.copyFile(name, bgName)) { + this.remove(this.bg); + this.bg.flushImage(); + this.add(this.bg = new UniverseImage(bgName)); + Dimension image = this.bg.imageSize(); + this.bg.setSize(image.width, image.height); + return true; + } + } + + return false; + } + } + + public void flushImage() { + this.remove(this.bg); + this.bg.flushImage(); + } + + @Override + public synchronized Object asyncBackgroundLoad(String localName, URL remoteURL) { + return localName; + } + + @Override + public boolean syncBackgroundLoad(Object obj, URL remoteURL) { + String localName = (String)obj; + if (localName != null && new File(localName).exists() && this.safeCopyFile(localName)) { + this.invalidate(); + this.validate(); + this.doLayout(); + this.repaint(); + } + + return false; + } + + @Override + public Room getBackgroundLoadRoom() { + return null; + } + + public synchronized void setViewportPos() { + Dimension viewport = this.getSize(); + Dimension image = this.bg.imageSize(); + int centerToLeft = image.width - viewport.width >> 1; + int centerToTop = image.height - viewport.height >> 1; + if (centerToLeft < 0) { + this.xOff = 0; + } + + if (centerToTop < 0) { + this.yOff = 0; + } + + int x = this.xOff + centerToLeft; + int y = this.yOff + centerToTop; + Dimension backSize = this.backButton.preferredSize(); + this.backButton.setSize(backSize); + this.backButton.setLocation(viewport.width - backSize.width - 5, viewport.height - backSize.height - 3); + this.bg.setLocation(-x, -y); + int i = this.buttons.size(); + + while (--i >= 0) { + WorldButton b = this.buttons.elementAt(i); + b.setLocation(-x + b.buttonX, -y + b.buttonY); + WorldButtonBullet bl = this.bullets.elementAt(i); + bl.setLocation(-x + bl.circleX, -y + bl.circleY); + } + } + + @Override + public void invalidate() { + super.invalidate(); + this.offscreen = null; + } + + @Override + public void update(Graphics g) { + this.paint(g); + } + + @Override + public synchronized void paint(Graphics g) { + this.setViewportPos(); + if (this.offscreen == null) { + this.offscreen = this.createImage(this.getSize().width, this.getSize().height); + } + + Graphics og = this.offscreen.getGraphics(); + og.setClip(0, 0, this.getSize().width, this.getSize().height); + super.paint(og); + + try { + g.drawImage(this.offscreen, 0, 0, this); + } catch (NullPointerException var4) { + this.offscreen = null; + } + + og.dispose(); + this.startWatch(); + } + + public synchronized void startWatch() { + if (!this.registered) { + Main.register(this); + this.registered = true; + } + } + + public synchronized void stopWatch() { + if (this.registered) { + Main.unregister(this); + this.registered = false; + } + } + + public void setOffset(int x, int y) { + if (this.owningConsole.isUniverseMode()) { + Dimension viewport = this.getSize(); + Dimension image = this.bg.imageSize(); + int centerToLeft = image.width - viewport.width >> 1; + int centerToTop = image.height - viewport.height >> 1; + x += centerToLeft; + y += centerToTop; + if (x < 0) { + x = 0; + } else if (x + viewport.width > image.width) { + x = image.width - viewport.width; + } + + if (y < 0) { + y = 0; + } else if (y + viewport.height > image.height) { + y = image.height - viewport.height; + } + + x -= centerToLeft; + y -= centerToTop; + if (viewport.width > image.width) { + x = 0; + } + + if (viewport.height > image.height) { + y = 0; + } + + if (x != this.xOff || y != this.yOff) { + this.xOff = x; + this.yOff = y; + this.repaint(); + } + } + } + + public void addOffset(int dx, int dy) { + this.setOffset(this.xOff + dx, this.yOff + dy); + } + + @Override + public boolean keyUp(Event event, int key) { + if (key != 1004 && key != 1005 && key != 1006 && key != 1007) { + return super.keyUp(event, key); + } else { + if (this.upDownState != 0 || this.leftRightState != 0) { + this.mainCallback(); + this.upDownState = 0; + this.leftRightState = 0; + } + + return true; + } + } + + @Override + public synchronized void mainCallback() { + int now = Std.getRealTime(); + int xDiff = 0; + int yDiff = 0; + if (this.upDownState != 0) { + yDiff = this.upDownState * (now - this.lastKeyTime) / 5; + } + + if (this.leftRightState != 0) { + xDiff = this.leftRightState * (now - this.lastKeyTime) / 5; + } + + if (xDiff < -50) { + xDiff = -50; + } + + if (xDiff > 50) { + xDiff = 50; + } + + if (yDiff < -50) { + yDiff = -50; + } + + if (yDiff > 50) { + yDiff = 50; + } + + String curpkg = WorldsMarkPart.getCurrentPackageName(); + if (curpkg != null && !curpkg.equals(WorldButton.currentPackageName)) { + WorldButton.currentPackageName = curpkg; + if (xDiff == 0 && yDiff == 0) { + this.repaint(); + } + } + + if (xDiff != 0 || yDiff != 0) { + this.addOffset(xDiff, yDiff); + } + + this.lastKeyTime = now; + if (this.owningConsole != Console.getActive() || !this.owningConsole.isUniverseMode()) { + this.stopWatch(); + } + } + + @Override + public synchronized boolean keyDown(Event event, int key) { + boolean changed = false; + if (key == 1004) { + if (this.upDownState != -1) { + this.upDownState = -1; + changed = true; + } + } else if (key == 1005) { + if (this.upDownState != 1) { + this.upDownState = 1; + changed = true; + } + } else if (key == 1006) { + if (this.leftRightState != -1) { + this.leftRightState = -1; + changed = true; + } + } else { + if (key != 1007) { + return super.keyDown(event, key); + } + + if (this.leftRightState != 1) { + this.leftRightState = 1; + changed = true; + } + } + + if (changed) { + this.startWatch(); + this.lastKeyTime = Std.getRealTime() - 20; + } + + return true; + } + + private synchronized void readUniverseFile(String localName) { + this.removeAll(); + this.buttons = new Vector<WorldButton>(); + this.bullets = new Vector<WorldButtonBullet>(); + boolean showAll = IniFile.gamma().getIniInt("ShowAllWorlds", 0) != 0; + this.add(this.backButton); + + try { + FileInputStream in = new FileInputStream(localName); + DataInputStream dis = new DataInputStream(in); + + String line; + while ((line = dis.readLine()) != null) { + StringTokenizer st = new StringTokenizer(line); + if (st.hasMoreTokens() && line.charAt(0) != ';') { + int circleX = Integer.parseInt(st.nextToken()); + int circleY = Integer.parseInt(st.nextToken()); + int buttonX = Integer.parseInt(st.nextToken()); + int buttonY = Integer.parseInt(st.nextToken()); + String pkg = st.nextToken(); + int privacy = Integer.parseInt(st.nextToken()); + String text = st.nextToken("").trim(); + Dimension sz = WorldButton.measure(text); + String[] texts = new String[]{text}; + boolean isLoaded = WorldsMarkPart.findPackage(pkg) != null; + if (showAll + || privacy == 0 + || privacy == 1 && !World.isCloistered() + || privacy <= 2 && isLoaded + || privacy == 3 && !World.isWorldsStoreProscribed()) { + WorldButton button = new WorldButton(isLoaded, buttonX, buttonY, sz.width, sz.height, texts, pkg, privacy, this.owningConsole, this); + this.add(button); + this.buttons.addElement(button); + WorldButtonBullet bullet = new WorldButtonBullet(circleX, circleY, button); + if (circleX > 0 || circleY > 0) { + this.add(bullet); + } + + this.bullets.addElement(bullet); + } + } + } + + dis.close(); + in.close(); + } catch (FileNotFoundException var19) { + System.out.println(var19); + } catch (IOException var20) { + System.out.println(var20); + } + } + + @Override + public Object imageButtonsCallback(Component who, int which) { + if (who instanceof WorldButton) { + ((WorldButton)who).doAction(); + } else if (who == this.backButton) { + this.owningConsole.toggleUniverseMode(); + } + + return null; + } +} diff --git a/NET/worlds/console/UnpaddedLabel.java b/NET/worlds/console/UnpaddedLabel.java new file mode 100644 index 0000000..436f63e --- /dev/null +++ b/NET/worlds/console/UnpaddedLabel.java @@ -0,0 +1,22 @@ +package NET.worlds.console; + +import java.awt.Dimension; +import java.awt.Label; + +class UnpaddedLabel extends Label { + private static final long serialVersionUID = -5960236197854637006L; + + UnpaddedLabel(String text, int align) { + super(text, align); + } + + @Override + public Dimension preferredSize() { + return new Dimension(1, 1); + } + + @Override + public Dimension minimumSize() { + return this.preferredSize(); + } +} diff --git a/NET/worlds/console/UpdateableDialog.java b/NET/worlds/console/UpdateableDialog.java new file mode 100644 index 0000000..9ba965e --- /dev/null +++ b/NET/worlds/console/UpdateableDialog.java @@ -0,0 +1,170 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +public class UpdateableDialog extends PolledDialog { + private static final long serialVersionUID = 8859312510212567551L; + protected Button okButton = new Button(Console.message("OK")); + protected Button cancelButton = new Button(Console.message("Cancel")); + protected GridBagLayout gbag = new GridBagLayout(); + private String prompt; + private MultiLineLabel promptLabel; + private static Font font = new Font(Console.message("MenuFont"), 0, 12); + private static Font bfont = new Font(Console.message("ButtonFont"), 0, 12); + protected int cancelKey = 27; + protected int confirmKey = 10; + + protected UpdateableDialog(java.awt.Window parent, String title) { + this(parent, (DialogReceiver)parent, title); + } + + protected UpdateableDialog(java.awt.Window parent, String title, String cancel, String ok) { + this(parent, (DialogReceiver)parent, title, cancel, ok); + } + + protected UpdateableDialog(java.awt.Window parent, DialogReceiver target, String title) { + this(parent, target, title, true); + } + + protected UpdateableDialog(java.awt.Window parent, DialogReceiver target, String title, boolean modal) { + super(parent, target, title, modal); + this.setLayout(this.gbag); + } + + protected UpdateableDialog(java.awt.Window parent, DialogReceiver target, String title, String cancel, String ok) { + this(parent, target, title, cancel, ok, true); + } + + protected UpdateableDialog(java.awt.Window parent, DialogReceiver target, String title, String cancel, String ok, boolean modal) { + this(parent, target, title, modal); + if (ok != null) { + this.okButton.setLabel(ok); + } else { + this.okButton = null; + } + + if (cancel != null) { + this.cancelButton.setLabel(cancel); + } else { + this.cancelButton = null; + } + } + + public UpdateableDialog(java.awt.Window parent, DialogReceiver target, String title, String cancel, String ok, String prompt) { + this(parent, target, title, cancel, ok, prompt, true); + } + + public UpdateableDialog(java.awt.Window parent, DialogReceiver target, String title, String cancel, String ok, String prompt, boolean modal) { + this(parent, target, title, cancel, ok, modal); + this.setFont(font); + this.prompt = prompt; + this.ready(); + } + + public UpdateableDialog(java.awt.Window parent, DialogReceiver target, String title, String cancel, String ok, String prompt, boolean modal, int alignment) { + this(parent, target, title, cancel, ok, modal); + this.prompt = prompt; + this.setAlignment(alignment); + this.ready(); + } + + @Override + protected void build() { + GridBagConstraints c = new GridBagConstraints(); + if (this.prompt != null) { + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 0; + this.promptLabel = new MultiLineLabel(this.prompt, 5, 5); + this.promptLabel.setFont(font); + this.add(this.gbag, this.promptLabel, c); + } + + int count = 0; + if (this.okButton != null) { + count++; + } + + if (this.cancelButton != null) { + count++; + } + + c.gridwidth = count; + c.weightx = 1.0; + c.weighty = 0.0; + if (this.okButton != null) { + this.okButton.setFont(bfont); + this.add(this.gbag, this.okButton, c); + } + + if (this.cancelButton != null) { + this.cancelButton.setFont(bfont); + this.add(this.gbag, this.cancelButton, c); + } + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.okButton && this.setValue()) { + return this.done(true); + } else { + return target == this.cancelButton ? this.done(false) : false; + } + } + + protected boolean setValue() { + return true; + } + + public void setCancelKey(int key) { + this.cancelKey = key; + } + + public void setConfirmKey(int key) { + this.confirmKey = key; + } + + @Override + public boolean keyDown(Event event, int key) { + if (key == this.cancelKey) { + return this.done(false); + } else { + if (key == this.confirmKey) { + if (this.okButton == null) { + return this.done(false); + } + + if (this.setValue()) { + return this.done(true); + } + } + + return super.keyDown(event, key); + } + } + + public void setPrompt(String text) { + GridBagConstraints c = new GridBagConstraints(); + this.prompt = text; + if (this.promptLabel != null) { + this.gbag.removeLayoutComponent(this.promptLabel); + } + + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 0; + this.promptLabel = new MultiLineLabel(this.prompt, 5, 5); + this.add(this.gbag, this.promptLabel, c); + this.show(); + } + + @Override + public void closeIt(boolean state) { + this.done(state); + } +} diff --git a/NET/worlds/console/UserInventoryCallback.java b/NET/worlds/console/UserInventoryCallback.java new file mode 100644 index 0000000..3ad0b50 --- /dev/null +++ b/NET/worlds/console/UserInventoryCallback.java @@ -0,0 +1,26 @@ +package NET.worlds.console; + +import NET.worlds.scape.InventoryCallback; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Point3Temp; +import NET.worlds.scape.Room; +import NET.worlds.scape.WObject; + +public class UserInventoryCallback implements InventoryCallback { + UserInventoryCallback() { + } + + @Override + public void droppedInventoryItem(Object item) { + WObject w = (WObject)item; + w.detach(); + w.setVisible(true); + Pilot pilot = Pilot.getActive(); + Room r = pilot.getRoom(); + Point3Temp pos = Point3Temp.make(0.0F, 180.0F, 0.0F); + pos.times(pilot); + pos.z = w.getPosition().z + pilot.getPosition().z; + w.moveTo(pos); + r.add(w); + } +} diff --git a/NET/worlds/console/VCTimerThread.java b/NET/worlds/console/VCTimerThread.java new file mode 100644 index 0000000..8c0a3f5 --- /dev/null +++ b/NET/worlds/console/VCTimerThread.java @@ -0,0 +1,24 @@ +package NET.worlds.console; + +class VCTimerThread extends Thread { + private long _wait; + public VoiceChat _vc; + + VCTimerThread(VoiceChat vc, long wait) { + this._vc = vc; + this._wait = wait; + } + + @Override + public void run() { + try { + Thread.sleep(this._wait); + } catch (InterruptedException var2) { + this.stop(); + } + + if (this._vc != null) { + this._vc.checkConnected(); + } + } +} diff --git a/NET/worlds/console/VoiceChat.java b/NET/worlds/console/VoiceChat.java new file mode 100644 index 0000000..bf52f71 --- /dev/null +++ b/NET/worlds/console/VoiceChat.java @@ -0,0 +1,395 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.network.URL; +import NET.worlds.scape.CDAudio; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.WavSoundPlayer; +import java.io.File; +import java.io.IOException; +import java.net.InetAddress; +import java.text.MessageFormat; + +public class VoiceChat implements DialogReceiver { + private static final String SPEAKFREELY = "sfmain.exe"; + private static final int INITIAL_STATE = 0; + private static final int BEGINNING_CONNECTION = 1; + private static final int REQUESTING_CONNECTION = 2; + private static final int ATTEMPTING_CONNECTION = 3; + private static final int SUCCESSFULLY_CONNECTED = 4; + private static final int CONNECTION_FAILED_RESETTING = 5; + private static final int CLOSING_CONNECTION = 6; + private static final int CONNECTION_CLOSED_RESETTING = 7; + private static final String[] _stateStrs = new String[]{ + "Initial State", + "Beginning Connection", + "Attempting Connection", + "Successfully Connected", + "Resetting (Connection Failed)", + "Closing Connection", + "Resetting (Connection Closed)" + }; + private int _state = 0; + private String _error = ""; + private static boolean _selfWhisper = false; + public static String VCdebugCommand = "&|+debug>VCcommand="; + public static String VCdebugCommandReset = "&|+debug>VCcommandReset="; + private static String _extraCommand = ""; + private static GammaPhoneMonitor chatMonitor = null; + private String _who = null; + public static UpdateableDialog voiceChatDialog; + private static UpdateableDialog voiceChatQueryDialog; + private static String voiceChatQueryIP; + private static String voiceChatQueryWho; + public static boolean voiceChatEnabled = IniFile.gamma().getIniInt("VoiceChat", voiceChatAvailable() ? 1 : 0) != 0; + private static boolean voiceChatExeChecked = false; + private static boolean voiceChatExists = false; + private int _gammaphoneWindow = 0; + DefaultConsole _console = null; + VCTimerThread _vtimer = null; + private static final String voiceChatQuery = "&|+voicechat?"; + private static final String voiceChatAccept = "&|+voicechat>accept"; + private static final String voiceChatReject = "&|+voicechat>reject"; + private static final String voiceChatBusy = "&|+voicechat>busy"; + private static final String voiceChatNotVIP = "&|+voicechat>notvip"; + private static final String voiceChatDisabled = "&|+voicechat>disabled"; + + public int getState() { + return this._state; + } + + public String getStateString() { + return _stateStrs[this._state]; + } + + public String getLastError() { + return this._error; + } + + public static void activateSelfWhisper() { + _selfWhisper = true; + Console.println(Console.message("Selfwhisper-on")); + } + + public static void deactivateSelfWhisper() { + _selfWhisper = false; + Console.println(Console.message("Selfwhisper-off")); + } + + public static void setExtra(String text) { + int start = text.indexOf(34) + 1; + int end = text.lastIndexOf(34); + _extraCommand = text.substring(start, end); + Object[] arguments = new Object[]{new String(_extraCommand)}; + Console.println(MessageFormat.format(Console.message("Add-VoiceChat"), arguments)); + } + + public static void resetExtra() { + _extraCommand = ""; + Console.println(Console.message("VoiceChat-reset")); + } + + public String who() { + return this._who; + } + + public static void setVoiceChatEnabled(boolean f) { + if (!voiceChatAvailable()) { + f = false; + } + + voiceChatEnabled = f; + IniFile.gamma().setIniInt("VoiceChat", f ? 1 : 0); + } + + public static boolean voiceChatAvailable() { + if (voiceChatExeChecked) { + return voiceChatExists; + } else { + URL vcexe = URL.make("home:sfmain.exe"); + String fname = vcexe.unalias(); + File f = new File(fname); + voiceChatExists = f.exists(); + voiceChatExeChecked = true; + return voiceChatExists; + } + } + + public void registerProcess(int id) { + this._gammaphoneWindow = id; + } + + public void beginChat(String friendName, DefaultConsole console) { + this._state = 1; + this._console = console; + if (!console.getVIP()) { + this.resetConnection(Console.message("must-be-VIP")); + } else { + String ip = null; + + try { + InetAddress localAddr = console.getServerNew().getLocalAddress(); + ip = localAddr != null ? localAddr.toString() : null; + ip = ip.substring(ip.indexOf(47) + 1); + } catch (SecurityException var7) { + this.resetConnection(Console.message("sec-violation")); + } + + if (ip == null) { + this.resetConnection(Console.message("cant-determine-IP")); + } else { + if (voiceChatDialog != null) { + if (friendName.equals(this._who)) { + Object[] arguments = new Object[]{new String(this._who)}; + Console.println(MessageFormat.format(Console.message("already-VoiceChat"), arguments)); + return; + } + + this.resetConnection(Console.message("chat-ended")); + } + + if (voiceChatQueryDialog != null && voiceChatQueryWho.equals(friendName)) { + Object[] arguments = new Object[]{new String(friendName)}; + Console.println(MessageFormat.format(Console.message("already-calling"), arguments)); + return; + } + + while (ConnectionRecord.checkList(this._who)) { + Object[] arguments = new Object[]{new String(this._who)}; + Console.println(MessageFormat.format(Console.message("wait-a-few"), arguments)); + + try { + Thread.sleep(2000L); + } catch (InterruptedException var6) { + } + } + + if (this.initiateVoiceChat(friendName, null)) { + Object[] arguments = new Object[]{new String(friendName), new String(ip)}; + Console.println(MessageFormat.format(Console.message("Asking-to-call"), arguments)); + this._state = 2; + this.sendWhisper(friendName, "&|+voicechat?" + ip); + this._vtimer = new VCTimerThread(this, 30000L); + this._vtimer.start(); + } + } + } + } + + private static native void terminateVC(int var0); + + private boolean initiateVoiceChat(String friendName, String ip) { + this._who = friendName; + int hWnd = Window.getHWnd(); + String startString = URL.make( + "home:sfmain.exe" + (ip == null ? " -a " : " -c " + ip) + " -g " + hWnd + " -p " + Window.getGammaProcessID() + " " + _extraCommand + " " + ) + .unalias(); + WavSoundPlayer.pauseSystem(); + CDAudio.get().setEnabled(false); + if (tryToRun(startString)) { + Object[] arguments = new Object[]{new String(this._who)}; + voiceChatDialog = new UpdateableDialog( + Console.getFrame(), + this, + Console.message("Voice-connect"), + null, + Console.message("Terminate"), + MessageFormat.format(Console.message("end-VoiceChat"), arguments), + false + ); + if (chatMonitor == null) { + chatMonitor = new GammaPhoneMonitor(this); + chatMonitor.start(); + } + + return true; + } else { + WavSoundPlayer.resumeSystem(); + CDAudio.get().setEnabled(true); + Object[] arguments = new Object[]{new String(this._who), new String(startString)}; + voiceChatDialog = new UpdateableDialog( + Console.getFrame(), + this, + Console.message("Voice-Chat-199"), + null, + Console.message("Continue"), + MessageFormat.format(Console.message("Unable-to-chat"), arguments), + false + ); + return false; + } + } + + public void inform(int msgid, String msg) { + if (msgid >= 900) { + if (voiceChatDialog == null) { + return; + } + + voiceChatDialog.setTitle(Console.message("VoiceChat-Connected")); + this._state = 4; + } else { + this.resetConnection(msg); + } + } + + public boolean handleChatRequest(String user, String text, DefaultConsole console) { + Object[] arguments = new Object[]{new String(user)}; + if (!console.getVIP()) { + Console.println(MessageFormat.format(Console.message("reject-chat"), arguments)); + this.sendWhisper(user, "&|+voicechat>notvip"); + } else if (!voiceChatEnabled) { + Console.println(MessageFormat.format(Console.message("chat-disabled"), arguments)); + this.sendWhisper(user, "&|+voicechat>disabled"); + } else if (voiceChatQueryDialog != null) { + this.sendWhisper(user, "&|+voicechat>busy"); + } else { + voiceChatQueryIP = text.substring("&|+voicechat?".length()); + voiceChatQueryWho = user; + voiceChatQueryDialog = new UpdateableDialog( + Console.getFrame(), + this, + Console.message("Accept-voice"), + Console.message("Reject"), + Console.message("Accept"), + MessageFormat.format(Console.message("do-you-voice"), arguments), + false + ); + } + + return true; + } + + public boolean handleChatWhisper(String user, String whisper, DefaultConsole console) { + Object[] arguments = new Object[]{new String(user)}; + if (whisper.startsWith("&|+voicechat?")) { + this.handleChatRequest(user, whisper, console); + return true; + } else { + if (whisper.startsWith("&|+voicechat>accept")) { + if (this._state != 2) { + this.sendWhisper(user, "&|+voicechat>reject"); + return false; + } + + Console.println(MessageFormat.format(Console.message("chat-accepted"), arguments)); + synchronized (this._vtimer) { + this._vtimer._vc = null; + } + + this._vtimer = null; + this._state = 3; + this._vtimer = new VCTimerThread(this, 15000L); + this._vtimer.start(); + } else if (whisper.startsWith("&|+voicechat>notvip")) { + if (voiceChatDialog != null && this._who.equals(user)) { + this.resetConnection(MessageFormat.format(Console.message("cannot-voice"), arguments)); + } + } else if (whisper.startsWith("&|+voicechat>disabled")) { + if (voiceChatDialog != null && this._who.equals(user)) { + this.resetConnection(MessageFormat.format(Console.message("user-voice-dis"), arguments)); + } + } else if (whisper.startsWith("&|+voicechat>busy")) { + if (voiceChatDialog != null && this._who.equals(user)) { + this.resetConnection(MessageFormat.format(Console.message("receiving-Voice"), arguments)); + } + } else if (whisper.startsWith("&|+voicechat>reject")) { + if (voiceChatDialog != null && this._who.equals(user)) { + this.resetConnection(MessageFormat.format(Console.message("Voice-terminated"), arguments)); + } + + if (voiceChatQueryDialog != null && voiceChatQueryWho != null && voiceChatQueryWho.equals(user)) { + voiceChatQueryDialog.closeIt(false); + voiceChatQueryWho = null; + this.resetConnection(MessageFormat.format(Console.message("Voice-terminated"), arguments)); + } + } + + return false; + } + } + + public static boolean tryToRun(String s) { + try { + Runtime.getRuntime().exec(s); + return true; + } catch (IOException var2) { + return false; + } + } + + public void checkConnected() { + if (this.getState() == 2) { + this.resetConnection(Console.message("never-answered")); + this.sendWhisper(this.who(), "&|+voicechat>reject"); + } else { + if (this.getState() != 4) { + this.resetConnection(Console.message("VoiceChat-failed")); + } + } + } + + public void resetConnection(String err) { + this._error = err; + if (err != null) { + this._state = 5; + Console.println(this._error); + } + + if (voiceChatDialog != null) { + voiceChatDialog.closeIt(true); + } + } + + public void terminate() { + if (this._vtimer != null) { + synchronized (this._vtimer) { + this._vtimer._vc = null; + } + + this._vtimer = null; + } + + CDAudio.get().setEnabled(true); + ConnectionRecord.getList().addElement(new ConnectionRecord(this.who())); + this._state = 0; + } + + public void release() { + if (chatMonitor != null) { + chatMonitor.stop(); + chatMonitor = null; + } + } + + @Override + public synchronized void dialogDone(Object who, boolean confirmed) { + if (who == voiceChatQueryDialog) { + voiceChatQueryDialog = null; + if (confirmed) { + this.sendWhisper(voiceChatQueryWho, "&|+voicechat>accept"); + this.initiateVoiceChat(voiceChatQueryWho, voiceChatQueryIP); + } else if (voiceChatQueryWho != null) { + this.sendWhisper(voiceChatQueryWho, "&|+voicechat>reject"); + } + } else if (who == voiceChatDialog) { + this._state = 6; + String stopString = URL.make("home:sfmain.exe -q").unalias(); + tryToRun(stopString); + voiceChatDialog = null; + this.sendWhisper(this._who, "&|+voicechat>reject"); + this.terminate(); + } else { + String stopString = URL.make("home:sfmain.exe -q").unalias(); + tryToRun(stopString); + } + } + + private void sendWhisper(String destination, String text) { + Pilot.sendText(destination, text); + if (_selfWhisper) { + this.handleChatWhisper(destination, text, this._console); + } + } +} diff --git a/NET/worlds/console/WebBrowser.java b/NET/worlds/console/WebBrowser.java new file mode 100644 index 0000000..d73c04f --- /dev/null +++ b/NET/worlds/console/WebBrowser.java @@ -0,0 +1,340 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Stack; + +public class WebBrowser { + private static Stack<WebBrowser> browsers = new Stack<WebBrowser>(); + private static boolean disabled = IniFile.gamma().getIniInt("DISABLEIE", 0) != 0; + private static boolean everWorked; + private int nativeBrowserPointer; + private InternetExplorer _activeX; + private static boolean toolbarON = true; + private static boolean windowFrameON = true; + private static boolean _stayMinimized = false; + private String browserTag = null; + + public static WebBrowser reuseOrMake(String url, String postData) throws IOException { + return reuseOrMake(url, postData, defaultPlacement()); + } + + public static void useToolbar() { + toolbarON = true; + } + + public static void dontUseToolbar() { + toolbarON = false; + } + + public static void useWindowFrame() { + windowFrameON = true; + } + + public static void dontUseWindowFrame() { + windowFrameON = false; + } + + public static void forceMinimized(boolean force) { + _stayMinimized = force; + } + + public static WebBrowser findTag(String tag) { + Enumeration<WebBrowser> e = browsers.elements(); + + while (e.hasMoreElements()) { + WebBrowser browser = e.nextElement(); + if (tag != null) { + if (tag.equals(browser.getTag())) { + return browser; + } + } else if (browser.getTag() == null) { + return browser; + } + } + + return null; + } + + public static WebBrowser reuseOrMake(String url, String postData, Rectangle placement) throws IOException { + Enumeration<WebBrowser> e = browsers.elements(); + + while (e.hasMoreElements()) { + WebBrowser browser = e.nextElement(); + if (browser.getTag() == null) { + try { + browser.browse(url, postData, null); + return browser; + } catch (IOException var6) { + } + } + } + + return new WebBrowser(url, postData, placement); + } + + private String getTag() { + return this.browserTag; + } + + public static WebBrowser reuseOrMake(String url, String postData, Rectangle placement, String tag) throws IOException { + Enumeration<WebBrowser> e = browsers.elements(); + + while (e.hasMoreElements()) { + WebBrowser browser = e.nextElement(); + if (tag.equals(browser.getTag())) { + try { + browser.browse(url, postData, null); + return browser; + } catch (IOException var7) { + } + } + } + + return new WebBrowser(url, postData, placement, tag); + } + + public static Rectangle defaultPlacement() { + Console c = Console.getActive(); + return c instanceof DefaultConsole ? ((DefaultConsole)c).getBrowserPlacement() : new Rectangle(0, 0, 200, 200); + } + + public static boolean isDisabled() { + return disabled; + } + + public static void setDisabled(boolean be) { + IniFile.gamma().setIniInt("DISABLEIE", be ? 1 : 0); + disabled = be; + } + + public WebBrowser(String url, String postData) throws IOException { + this(url, postData, defaultPlacement()); + } + + public WebBrowser(String url, String postData, Rectangle placement) throws IOException { + this(url, postData, placement, null); + } + + public WebBrowser(String url, String postData, Rectangle placement, String tag) throws IOException { + if (!disabled) { + this._activeX = new InternetExplorer(this); + + try { + this.nativeBrowserPointer = openBrowser(); + } catch (IOException var9) { + try { + this._activeX.Release(); + } catch (OLEInvalidObjectException var8) { + assert false; + } + + this._activeX = null; + disabled = true; + throw var9; + } + + browsers.push(this); + if (tag != null) { + this.browserTag = tag; + } + + try { + this.browse(url, postData, placement); + everWorked = true; + } catch (IOException var7) { + if (!everWorked) { + disabled = true; + } + + throw var7; + } + } else { + throw new IOException(); + } + } + + public void browse(String url, String postData, Rectangle placement) throws IOException { + if (this.nativeBrowserPointer != 0) { + int x = -1; + int y = -1; + int w = -1; + int h = -1; + if (placement != null) { + x = placement.x; + y = placement.y; + w = placement.width; + h = placement.height; + } + + try { + browse(url, postData, x, y, w, h, this.nativeBrowserPointer); + } catch (IOException var9) { + this.close(); + throw var9; + } + } else { + throw new IOException(); + } + } + + public void close() { + if (this.nativeBrowserPointer != 0) { + closeBrowser(this.nativeBrowserPointer); + this.nativeBrowserPointer = 0; + + try { + this._activeX.Release(); + } catch (OLEInvalidObjectException var2) { + assert false; + } + + this._activeX = null; + browsers.removeElement(this); + } + } + + private static native void browse(String var0, String var1, int var2, int var3, int var4, int var5, int var6) throws IOException; + + private static native int openBrowser() throws IOException; + + private static native void closeBrowser(int var0); + + public static Rectangle getMapPartPlacement() { + Rectangle placement = null; + Console c = Console.getActive(); + if (c != null) { + MapPart ap = null; + Enumeration<FramePart> e = c.getParts(); + + while (e.hasMoreElements()) { + Object o = e.nextElement(); + if (o instanceof MapPart) { + ap = (MapPart)o; + break; + } + } + + if (ap != null) { + placement = new Rectangle(ap.getLocationOnScreen(), ap.getSize()); + placement.grow(0, 10); + placement.translate(0, -9); + } + } + + return placement; + } + + public static Rectangle getAdPartPlacement() { + Rectangle placement = null; + Console c = Console.getActive(); + if (c != null) { + AdPart ap = null; + Enumeration<FramePart> e = c.getParts(); + + while (e.hasMoreElements()) { + Object o = e.nextElement(); + if (o instanceof AdPart) { + ap = (AdPart)o; + break; + } + } + + if (ap != null) { + placement = new Rectangle(ap.getLocationOnScreen(), ap.getSize()); + placement.grow(0, 10); + placement.translate(0, -9); + } + } + + return placement; + } + + public static Rectangle getRenderPartPlacement() { + Rectangle placement = null; + Console c = Console.getActive(); + if (c != null) { + RenderCanvas ap = null; + Enumeration<FramePart> e = c.getParts(); + + while (e.hasMoreElements()) { + Object o = e.nextElement(); + if (o instanceof RenderCanvas) { + ap = (RenderCanvas)o; + break; + } + } + + if (ap != null) { + placement = new Rectangle(ap.getLocationOnScreen(), ap.getSize()); + placement.grow(2, 10); + placement.translate(-1, 7); + } + } + + return placement; + } + + public static Rectangle getLeftRenderPartPlacement() { + Rectangle placement = null; + Console c = Console.getActive(); + if (c != null) { + RenderCanvas ap = null; + Enumeration<FramePart> e = c.getParts(); + + while (e.hasMoreElements()) { + Object o = e.nextElement(); + if (o instanceof RenderCanvas) { + ap = (RenderCanvas)o; + break; + } + } + + if (ap != null) { + placement = new Rectangle(ap.getLocationOnScreen(), ap.getSize()); + placement.grow(2, 10); + placement.translate(-1, 7); + Dimension d = placement.getSize(); + placement.setSize(d.width / 2, d.height); + } + } + + return placement; + } + + public static Rectangle getOutsidePlacement() { + Rectangle placement = null; + Console c = Console.getActive(); + if (c != null) { + RenderCanvas ap = null; + Enumeration<FramePart> e = c.getParts(); + + while (e.hasMoreElements()) { + Object o = e.nextElement(); + if (o instanceof RenderCanvas) { + ap = (RenderCanvas)o; + break; + } + } + + if (ap != null) { + Point ploc = ap.getLocationOnScreen(); + Dimension d = new Dimension(250, 500); + Point bloc = new Point(0, ploc.y); + if (ploc.x > 254) { + bloc.x = ploc.x - 254; + } else { + bloc.x = 0; + } + + placement = new Rectangle(bloc, d); + } + } + + return placement; + } +} diff --git a/NET/worlds/console/WebControl.java b/NET/worlds/console/WebControl.java new file mode 100644 index 0000000..588c453 --- /dev/null +++ b/NET/worlds/console/WebControl.java @@ -0,0 +1,91 @@ +package NET.worlds.console; + +public class WebControl extends RenderCanvasOverlay { + private final int ID_GO_BACK = 32768; + private final int ID_GO_FORWARD = 32769; + private final int ID_VIEW_STOP = 32770; + private final int ID_VIEW_REFRESH = 32771; + private final int ID_GO_HOME = 32772; + private final int ID_EXIT = 32773; + private WebControlImp imp = null; + + public WebControl(RenderCanvas pCanvas, boolean hasToolbar) throws NoWebControlException { + super(pCanvas); + + try { + this.imp = WebControlFactory.createWebControlImp(this.getNativeWindowHandle(), hasToolbar, false); + } catch (NoWebControlException var4) { + super.detach(); + throw var4; + } + } + + public WebControl(RenderCanvas pCanvas, int xPer, int yPer, boolean hasToolbar, boolean isFixedSize, boolean isBanner) throws NoWebControlException { + super(pCanvas, xPer, yPer, isFixedSize, !isBanner); + this.imp = WebControlFactory.createWebControlImp(this.getNativeWindowHandle(), hasToolbar, isBanner); + } + + public boolean setURL(String pURL) { + if (this.imp == null) { + System.out.println("Null implementation in WebControl.setURL"); + return false; + } else { + return this.imp.setURL(pURL); + } + } + + public boolean setURL(String pURL, String pPostData) { + if (this.imp == null) { + System.out.println("Null implementation in WebControl.setURL"); + return false; + } else { + return pPostData != null && !pPostData.equals("") ? this.imp.setURL(pURL, pPostData) : this.imp.setURL(pURL); + } + } + + @Override + protected void handleCommand(int commandID) { + if (this.imp == null) { + System.out.println("Now this should be impossible. Null imp in WebControl.handleCommand."); + } else { + switch (commandID) { + case 32768: + this.imp.goBack(); + break; + case 32769: + this.imp.goForward(); + break; + case 32770: + this.imp.stop(); + break; + case 32771: + this.imp.refresh(); + break; + case 32772: + this.imp.home(); + break; + case 32773: + this.detach(); + } + } + } + + @Override + void detach() { + if (this.imp != null) { + this.imp.detach(); + } + + super.detach(); + } + + @Override + void canvasResized(int parentX, int parentY) { + super.canvasResized(parentX, parentY); + if (this.imp == null) { + System.out.println("Null imp in WebControl.canvasResized"); + } else { + this.imp.resize(parentX, parentY, this.getXPercent(), this.getYPercent()); + } + } +} diff --git a/NET/worlds/console/WebControlFactory.java b/NET/worlds/console/WebControlFactory.java new file mode 100644 index 0000000..fbb0bd6 --- /dev/null +++ b/NET/worlds/console/WebControlFactory.java @@ -0,0 +1,12 @@ +package NET.worlds.console; + +public class WebControlFactory { + public static WebControlImp createWebControlImp(int hwnd, boolean hasToolbar, boolean isBanner) throws NoWebControlException { + try { + return new IEWebControlImp(hwnd, hasToolbar, isBanner); + } catch (Exception var4) { + System.out.println("WebControlImp blew chow: " + var4.toString()); + throw new NoWebControlException(); + } + } +} diff --git a/NET/worlds/console/WebControlImp.java b/NET/worlds/console/WebControlImp.java new file mode 100644 index 0000000..45cbfde --- /dev/null +++ b/NET/worlds/console/WebControlImp.java @@ -0,0 +1,122 @@ +package NET.worlds.console; + +import NET.worlds.core.Std; +import NET.worlds.network.NetUpdate; +import NET.worlds.network.WorldServer; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Room; +import NET.worlds.scape.TextureSurfaceRenderer; +import java.util.Enumeration; +import java.util.Vector; + +public abstract class WebControlImp implements TextureSurfaceRenderer { + public static final int downloadBegin = 0; + public static final int downloadEnd = 1; + public static final int titleChanged = 2; + public static final int propertyChanged = 3; + public static final int statusChanged = 4; + public static final int commandStateChanged = 5; + Vector<WebControlListener> listeners = new Vector<WebControlListener>(); + + WebControlImp(int hwnd) { + } + + public static String processURL(String pURL) { + if (pURL.indexOf("$USERNAME") == -1 + && pURL.indexOf("$UPGRADESERVER") == -1 + && pURL.indexOf("$SCRIPTSERVER") == -1 + && pURL.indexOf("$SERIALNUM") == -1 + && pURL.indexOf("$WORLD") == -1 + && pURL.indexOf("$ROOM") == -1) { + return pURL; + } else { + pURL = Std.replaceStr(pURL, "$UPGRADESERVER", NetUpdate.getUpgradeServerURL()); + if (Console.getActive() != null) { + pURL = Std.replaceStr(pURL, "$SCRIPTSERVER", Console.getActive().getScriptServer()); + } else if (pURL.indexOf("$SCRIPTSERVER") != -1) { + return null; + } + + if (Pilot.getActive() != null) { + Pilot p = Pilot.getActive(); + if (p != null && p.getWorld() != null) { + pURL = Std.replaceStr(pURL, "$WORLD", p.getWorld().toString()); + } + + Room r = Pilot.getActiveRoom(); + if (r != null) { + pURL = Std.replaceStr(pURL, "$ROOM", Pilot.getActiveRoom().toString()); + } + + WorldServer w = Pilot.getActive().getServer(); + if (w != null && w.getGalaxy() != null) { + String name = w.getGalaxy().getChatname(); + if (pURL.indexOf("$USERNAME") != -1) { + if (name == null || name.equals("")) { + return null; + } + + pURL = Std.replaceStr(pURL, "$USERNAME", name); + } + + String serial = w.getGalaxy().getSerialNum(); + if (pURL.indexOf("$SERIALNUM") != -1) { + if (serial == null || serial.equals("")) { + return null; + } + + pURL = Std.replaceStr(pURL, "$SERIALNUM", serial); + } + } else if (pURL.indexOf("$SERIALNUM") != -1 || pURL.indexOf("$USERNAME") != -1) { + return null; + } + } + + return pURL.indexOf("$SERIALNUM") == -1 && pURL.indexOf("$USERNAME") == -1 ? pURL : null; + } + } + + public abstract boolean setURL(String var1); + + public abstract boolean setURL(String var1, String var2); + + public abstract void goBack(); + + public abstract void goForward(); + + public abstract void stop(); + + public abstract void refresh(); + + public abstract void home(); + + public abstract void resize(int var1, int var2, int var3, int var4); + + public abstract int getHWND(); + + @Override + public abstract void renderTo(int var1); + + public void addListener(WebControlListener l) { + this.listeners.addElement(l); + } + + public void removeListener(WebControlListener l) { + this.listeners.removeElement(l); + } + + void receiveEvent(int eventID) { + Enumeration<WebControlListener> e = this.listeners.elements(); + + while (e.hasMoreElements()) { + WebControlListener l = e.nextElement(); + if (l != null) { + l.webControlEvent(eventID); + } + } + } + + public void detach() { + this.listeners.removeAllElements(); + } +} diff --git a/NET/worlds/console/WebControlListener.java b/NET/worlds/console/WebControlListener.java new file mode 100644 index 0000000..d582b53 --- /dev/null +++ b/NET/worlds/console/WebControlListener.java @@ -0,0 +1,5 @@ +package NET.worlds.console; + +public interface WebControlListener { + void webControlEvent(int var1); +} diff --git a/NET/worlds/console/WhisperDialog.java b/NET/worlds/console/WhisperDialog.java new file mode 100644 index 0000000..fd3e3f4 --- /dev/null +++ b/NET/worlds/console/WhisperDialog.java @@ -0,0 +1,135 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.scape.Pilot; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Panel; + +public class WhisperDialog extends PolledDialog { + private static final long serialVersionUID = -5767168735798633258L; + protected static java.awt.Window parent; + protected boolean building; + protected boolean isTrading = false; + protected WhisperPart whisperPart; + protected String partner; + protected boolean isBroadcast; + protected boolean built; + protected static int counter = 0; + protected static final int OFFSET = 20; + protected static final int OFF_TOT = 6; + + static void setParent(java.awt.Window p) { + parent = p; + } + + static void sendTalkMessage(final String msg) { + Main.register(new MainCallback() { + @Override + public void mainCallback() { + System.out.println("Sending a Text Message: " + msg); + Pilot.sendText(msg); + Main.unregister(this); + } + }); + } + + protected WhisperDialog(java.awt.Window parent, String partner) { + super(parent, null, Console.message("Whisper-to-from2") + Console.parseExtended(partner), false); + this.partner = partner; + this.isBroadcast = true; + if (partner.equals("room")) { + this.setTitle(Console.message("Broadcast-Users")); + } else if (partner.equals("world")) { + this.setTitle(Console.message("Broadcast-All")); + } else { + this.isBroadcast = false; + } + + this.whisperPart = new WhisperPart(partner); + Console active = Console.getActive(); + if (active != null) { + active.addPart(this.whisperPart); + } + + int tier = counter / 6; + int pos = counter % 6; + this.setAlignment(1, ((pos + tier) % 12 - 5) * 20, (pos % 6 - 5) * 20); + counter++; + } + + protected void takeFocus() { + this.whisperPart.forceTakeFocus(); + } + + @Override + public void show() { + super.show(); + this.whisperPart.scrollToBottom(); + int toFront = IniFile.override().getIniInt("whispersToFront", 0); + if (toFront != 0) { + this.toFront(); + } + } + + protected void send(String msg) { + this.whisperPart.println("< " + msg); + } + + protected synchronized void print(String msg) { + this.whisperPart.println("> " + msg); + } + + @Override + protected synchronized void build() { + this.building = false; + if (this.built) { + this.removeAll(); + } + + this.built = true; + Color bg1 = new Color(0, 0, 0); + Color bg2 = new Color(0, 192, 192); + Color fg1 = new Color(255, 255, 255); + this.setBackground(fg1); + this.setForeground(bg1); + this.whisperPart.line.setBackground(this.isTrading ? bg2 : fg1); + this.whisperPart.listen.setBackground(fg1); + Panel insListen = new InsetPanel(new BorderLayout(), 3, 1, 1, 1); + insListen.setBackground(Color.lightGray); + insListen.add("Center", this.whisperPart.listen.getComponent()); + this.add("Center", insListen); + Panel insLine = new InsetPanel(new BorderLayout(), 2, 1, 2, 1); + insLine.setBackground(Color.lightGray); + insLine.add("Center", this.whisperPart.line); + this.add("South", insLine); + this.validate(); + } + + protected boolean setValue() { + return true; + } + + @Override + public synchronized boolean keyDown(Event event, int key) { + this.whisperPart.line.requestFocus(); + if (key == 10) { + this.whisperPart.trigger(); + return true; + } else { + return false; + } + } + + @Override + public Dimension preferredSize() { + return super.preferredSize(); + } + + @Override + public Dimension minimumSize() { + return super.minimumSize(); + } +} diff --git a/NET/worlds/console/WhisperManager.java b/NET/worlds/console/WhisperManager.java new file mode 100644 index 0000000..180fa10 --- /dev/null +++ b/NET/worlds/console/WhisperManager.java @@ -0,0 +1,143 @@ +package NET.worlds.console; + +import NET.worlds.network.NetUpdate; +import NET.worlds.scape.InventoryManager; +import java.util.Enumeration; +import java.util.Hashtable; + +public class WhisperManager { + private static WhisperManager manager_; + private Hashtable<String, WhisperDialog> dialogs_; + private Hashtable<String, TradeDialog> tradeDialogs_; + private java.awt.Window parent; + private String inventory = ""; + final String tradeServerName = "TRADE"; + static GiftDialog outstandingGift; + + private WhisperManager() { + this.dialogs_ = new Hashtable<String, WhisperDialog>(); + this.tradeDialogs_ = new Hashtable<String, TradeDialog>(); + } + + public static WhisperManager whisperManager() { + if (manager_ == null) { + manager_ = new WhisperManager(); + } + + return manager_; + } + + void setParent(java.awt.Window p) { + this.parent = p; + } + + public Hashtable<String, WhisperDialog> dialogs() { + return this.dialogs_; + } + + public Hashtable<String, TradeDialog> tradeDialogs() { + return this.tradeDialogs_; + } + + private WhisperDialog findWhisperDialog(String to) { + return !this.dialogs_.containsKey(to) ? null : this.dialogs_.get(to); + } + + private TradeDialog findTradeDialog(String to) { + return !this.tradeDialogs_.containsKey(to) ? null : this.tradeDialogs_.get(to); + } + + private WhisperDialog start(String to, boolean takeFocus) { + WhisperDialog wd = this.findWhisperDialog(to); + if (wd == null) { + this.dialogs_.put(to, wd = new WhisperDialog(this.parent, to)); + } + + if (takeFocus) { + wd.takeFocus(); + } + + wd.ready(); + return wd; + } + + public void remove(String name) { + this.dialogs_.remove(name); + } + + public void startTo(String to) { + WhisperDialog wd = this.start(to, true); + } + + public TradeDialog startToTrade(String to) { + TradeDialog wd = this.findTradeDialog(to); + if (wd == null) { + this.tradeDialogs_.put(to, wd = new TradeDialog(this.parent, to)); + } + + wd.takeFocus(); + wd.ready(); + wd.setTrading(true); + wd.whisperPart.println(Console.message("trade-start")); + return wd; + } + + public void printFrom(String from, String msg) { + if (!msg.startsWith("&|+")) { + WhisperDialog it = this.findWhisperDialog(from); + if (msg.equals("&|+trade>cancel") && (it == null || !it.isActive() || !it.isTrading)) { + return; + } + + it = this.start(from, false); + it.print(msg); + } else if (msg.startsWith("&|+gift>") && from.equalsIgnoreCase("TRADE")) { + maybeQueryGift(msg.substring(8)); + } else if (msg.startsWith("&|+inv>") && from.equalsIgnoreCase("TRADE")) { + this.tradeMsg(msg.substring(7)); + } else if (msg.startsWith("&|+trade>")) { + TradeDialog it = this.findTradeDialog(from); + if (msg.equals("&|+trade>cancel") && (it == null || !it.isActive() || !it.isTrading)) { + return; + } + + it = this.startToTrade(from); + it.print(msg); + } + } + + public void tradeMsg(String newInv) { + if (!newInv.equals(this.inventory)) { + Enumeration<TradeDialog> e = this.tradeDialogs_.elements(); + + while (e.hasMoreElements()) { + TradeDialog wd = e.nextElement(); + wd.doneDeal(); + } + + InventoryManager.getInventoryManager().setInventory(newInv); + } + } + + public void printTo(String to, String msg) { + if (!to.equals("world") && !to.equals("TRADE")) { + if (!msg.startsWith("&|+") || msg.startsWith("&|+trade>")) { + WhisperDialog it = this.start(to, false); + it.send(msg); + } + } + } + + public void giftDialogDone() { + outstandingGift = null; + } + + public static void maybeQueryGift(String inv) { + if (NetUpdate.isInternalVersion()) { + Console c = Console.getActive(); + if (c != null && outstandingGift == null && !c.isSleeping()) { + outstandingGift = new GiftDialog(inv, 3000000); + } + } + } +} diff --git a/NET/worlds/console/WhisperPart.java b/NET/worlds/console/WhisperPart.java new file mode 100644 index 0000000..bdb5a18 --- /dev/null +++ b/NET/worlds/console/WhisperPart.java @@ -0,0 +1,21 @@ +package NET.worlds.console; + +import NET.worlds.scape.Pilot; + +public class WhisperPart extends DuplexPart { + private String partner; + + public WhisperPart(String partner) { + super(false, 4); + this.partner = partner; + } + + public String getPartner() { + return this.partner; + } + + @Override + protected void sendText(String s) { + Pilot.sendText(this.partner, Console.parseUnicode(s)); + } +} diff --git a/NET/worlds/console/WideScrollPane.java b/NET/worlds/console/WideScrollPane.java new file mode 100644 index 0000000..01a14b7 --- /dev/null +++ b/NET/worlds/console/WideScrollPane.java @@ -0,0 +1,32 @@ +package NET.worlds.console; + +import java.awt.Dimension; +import java.awt.Panel; +import java.awt.ScrollPane; + +class WideScrollPane extends ScrollPane { + private static final long serialVersionUID = -7035034239249038255L; + Panel p; + + public WideScrollPane(Panel p, boolean asNeeded) { + super(asNeeded ? 0 : 1); + this.p = p; + this.add(p); + } + + @Override + public Dimension preferredSize() { + Dimension d = this.p.preferredSize(); + d.width += 5; + d.height += 5; + return d; + } + + @Override + public Dimension minimumSize() { + Dimension d = this.p.minimumSize(); + d.width += 5; + d.height += 5; + return d; + } +} diff --git a/NET/worlds/console/WiderScrollbar.java b/NET/worlds/console/WiderScrollbar.java new file mode 100644 index 0000000..0262f1d --- /dev/null +++ b/NET/worlds/console/WiderScrollbar.java @@ -0,0 +1,22 @@ +package NET.worlds.console; + +import java.awt.Dimension; +import java.awt.Scrollbar; + +public class WiderScrollbar extends Scrollbar { + private static final long serialVersionUID = -5982901695832721377L; + + @Override + public Dimension preferredSize() { + Dimension d = super.preferredSize(); + d.width += 2; + return d; + } + + @Override + public Dimension minimumSize() { + Dimension d = super.minimumSize(); + d.width += 2; + return d; + } +} diff --git a/NET/worlds/console/Window.java b/NET/worlds/console/Window.java new file mode 100644 index 0000000..04d61c2 --- /dev/null +++ b/NET/worlds/console/Window.java @@ -0,0 +1,195 @@ +package NET.worlds.console; + +import NET.worlds.scape.Camera; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.TextArea; + +public class Window { + private static Window activeWindow; + private int hWndGamma; + private int hWndFrame; + private static int hInstGamma; + private static int hWndFrameStatic; + public static final int NORMAL = 0; + public static final int MINIMIZED = 1; + public static final int MAXIMIZED = 2; + private int windowInstancePtr; + + public Window(String frameTitle, Point loc, Dimension dim, Camera cam, boolean interceptEvents) throws WindowNotFoundException { + nativeInit(); + if (hWndFrameStatic != 0) { + this.hWndFrame = hWndFrameStatic; + } else { + this.hWndFrame = findWindow(frameTitle); + } + + if (this.hWndFrame != 0) { + this.hWndGamma = findOrMakeChildWindow(this.hWndFrame, loc.x, loc.y, dim.width, dim.height); + } + + if (this.hWndGamma == 0) { + throw new WindowNotFoundException("No such window"); + } else { + if (hWndFrameStatic == 0) { + hWndFrameStatic = this.hWndFrame; + } + + hInstGamma = this.install(interceptEvents); + this.maybeResize(dim.width, dim.height); + if (interceptEvents) { + activeWindow = this; + } + } + } + + public void hookChatLine(Component chatLine) throws WindowNotFoundException { + assert activeWindow == this; + + Dimension dim = chatLine.getSize(); + + try { + Point loc = chatLine.getLocationOnScreen(); + int hwndChatLine = findChildWindow(hWndFrameStatic, loc.x, loc.y, dim.width, dim.height); + if (hwndChatLine != 0) { + setChatLine(hwndChatLine); + return; + } + } catch (Exception var5) { + } + + throw new WindowNotFoundException(); + } + + private static native void setChatLine(int var0); + + public static native int getVoiceChatWParam(); + + public static native int getVoiceChatLParam(); + + public static native void resetVoiceChatMsg(); + + public static native void doMicrosoftVMHacks(); + + public static native boolean usingMicrosoftVMHacks(); + + public static native boolean getActivated(); + + public static native boolean isActivated(); + + public static native int getGammaProcessID(); + + public native void dispose(); + + public static Window getMainWindow() { + return activeWindow; + } + + public native int getHwnd(); + + public void hideNativeWindow() { + if (this.hWndGamma != 0) { + this.nativeHideChildWindow(this.hWndGamma); + } + } + + public void showNativeWindow() { + if (this.hWndGamma != 0) { + this.nativeShowChildWindow(this.hWndGamma); + } + } + + native void nativeHideChildWindow(int var1); + + native void nativeShowChildWindow(int var1); + + public static int getHWnd() { + return activeWindow == null ? 0 : activeWindow.hWndGamma; + } + + public static int getHInst() { + return hInstGamma; + } + + public native void maybeResize(int var1, int var2); + + public native void setDeltaMode(boolean var1); + + public static native int getAndResetUserActionCount(); + + public native boolean getDeltaMode(); + + public static native void makeJavaReleaseCapture(); + + public native void reShape(int var1, int var2, int var3, int var4); + + public native int fullWidth(); + + public native int fullHeight(); + + public static native int findWindow(String var0); + + public static native int getFrameWindow(); + + public static native void hideCursor(); + + public static native int[] getHiddenCursorDelta(); + + public static native void setCursor(int var0); + + public static native int getWindowState(int var0); + + public static native void setWindowState(int var0, int var1); + + public static native void setForegroundWindow(int var0); + + public static native void setVideoMode(int var0, int var1, int var2); + + public static native void nativeInit(); + + private native int install(boolean var1); + + static synchronized int findChildWindow(int hWndParent, int x, int y, int w, int h) { + return nativeFindChildWindow(hWndParent, x, y, w, h); + } + + static synchronized int findOrMakeChildWindow(int hWndParent, int x, int y, int w, int h) { + return nativeFindOrMakeChildWindow(hWndParent, x, y, w, h); + } + + public static boolean isLastLineVisible(int hwnd, TextArea ta) { + Dimension s = ta.getSize(); + return nativeIsLastLineVisible(hwnd, s.width, s.height) != 0; + } + + private static native int nativeIsLastLineVisible(int var0, int var1, int var2); + + private static native int nativeFindChildWindow(int var0, int var1, int var2, int var3, int var4); + + private static native int nativeFindOrMakeChildWindow(int var0, int var1, int var2, int var3, int var4); + + public static int playVideoClip(Component c, String name) { + Point p = c.getLocationOnScreen(); + Dimension s = c.getSize(); + return playVideoClip(name, findChildWindow(activeWindow.hWndFrame, p.x, p.y, s.width, s.height)); + } + + public static native boolean isVideoPlaying(int var0); + + private static native int playVideoClip(String var0, int var1); + + public static native void hookWinAPIs(String var0); + + public static native int getWindowWidth(int var0); + + public static native int getWindowHeight(int var0); + + public static native void allowFGJavaPalette(boolean var0); + + public static int getFrameHandle() { + return hWndFrameStatic; + } + + public static native int getSystemMetrics(int var0); +} diff --git a/NET/worlds/console/WindowNotFoundException.java b/NET/worlds/console/WindowNotFoundException.java new file mode 100644 index 0000000..5cc63bd --- /dev/null +++ b/NET/worlds/console/WindowNotFoundException.java @@ -0,0 +1,12 @@ +package NET.worlds.console; + +public class WindowNotFoundException extends Exception { + private static final long serialVersionUID = -5486368094848985833L; + + public WindowNotFoundException() { + } + + public WindowNotFoundException(String s) { + super(s); + } +} diff --git a/NET/worlds/console/WorldButton.java b/NET/worlds/console/WorldButton.java new file mode 100644 index 0000000..8aba031 --- /dev/null +++ b/NET/worlds/console/WorldButton.java @@ -0,0 +1,125 @@ +package NET.worlds.console; + +import NET.worlds.network.NetUpdate; +import NET.worlds.scape.TeleportAction; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Event; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.MenuItem; +import java.awt.PopupMenu; + +class WorldButton extends TextImageButtons { + private static final long serialVersionUID = 8349532719484982330L; + int buttonX; + int buttonY; + String pkg; + int privacyLevel; + boolean isLoaded; + String readableName; + DefaultConsole console; + static String currentPackageName = ""; + private static Font wfont = new Font(Console.message("UniverseFont"), 0, 10); + private static final int[] xText = new int[1]; + PopupMenu lastPackageMenu; + + public WorldButton( + boolean isLoaded, + int buttonX, + int buttonY, + int buttonWidth, + int buttonHeight, + String[] texts, + String pkg, + int privacy, + DefaultConsole console, + ImageButtonsCallback handler + ) { + super(null, buttonWidth, intToInts(buttonHeight), xText, texts, handler, wfont); + this.readableName = texts[0]; + this.buttonX = buttonX; + this.buttonY = buttonY; + this.pkg = pkg; + this.isLoaded = isLoaded; + this.privacyLevel = privacy; + this.console = console; + this.setSize(buttonWidth, buttonHeight); + this.setWidth(buttonWidth); + this.setHeight(buttonHeight); + } + + public static Dimension measure(String text) { + return TextImageButtons.measure(text, wfont); + } + + public void doAction() { + if (this.console == null || !this.showPackageMenu()) { + NetUpdate.loadWorld(this.pkg, true); + } + } + + public boolean showPackageMenu() { + if (this.lastPackageMenu != null) { + this.remove(this.lastPackageMenu); + this.lastPackageMenu = null; + } + + this.lastPackageMenu = WorldsMarkPart.getPackageMenu(this.pkg); + if (this.lastPackageMenu != null && this.lastPackageMenu.getItemCount() != 0) { + MenuItem first = this.lastPackageMenu.getItem(0); + if (first instanceof BookmarkMenuItem) { + BookmarkMenuItem title = new BookmarkMenuItem(this.readableName + " World:", ((BookmarkMenuItem)first).getTarget()); + this.lastPackageMenu.insert(title, 0); + this.lastPackageMenu.insertSeparator(1); + } + + this.add(this.lastPackageMenu); + + try { + this.lastPackageMenu.show(this, -15, -7); + } catch (RuntimeException var3) { + System.out.println("Warning - could not show teleport location menu."); + } + + return true; + } else { + return false; + } + } + + @Override + public void update(Graphics g) { + this.paint(g); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target instanceof BookmarkMenuItem) { + TeleportAction.teleport(((BookmarkMenuItem)target).getTarget(), null); + this.console.toggleUniverseMode(); + return true; + } else { + return super.action(event, what); + } + } + + @Override + protected Graphics drawButton(Graphics g, int button, int state) { + Color c; + if (state == 1) { + if (this.isLoaded) { + c = currentPackageName.equalsIgnoreCase(this.pkg) ? new Color(192, 255, 192) : Color.white; + } else { + c = Color.red; + } + } else if (state == 2) { + c = new Color(255, 192, 192); + } else { + c = Color.green; + } + + return super.drawButton(g, button, state, c); + } +} diff --git a/NET/worlds/console/WorldButtonBullet.java b/NET/worlds/console/WorldButtonBullet.java new file mode 100644 index 0000000..f033aa4 --- /dev/null +++ b/NET/worlds/console/WorldButtonBullet.java @@ -0,0 +1,74 @@ +package NET.worlds.console; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.event.MouseEvent; + +class WorldButtonBullet extends Component { + private static final long serialVersionUID = -3330973936286182409L; + int circleX; + int circleY; + WorldButton button; + + public WorldButtonBullet(int x, int y, WorldButton button) { + this.circleX = x - 2; + this.circleY = y - 2; + this.button = button; + this.setSize(6, 6); + this.enableEvents(16L); + this.enableEvents(32L); + } + + @Override + public void update(Graphics g) { + this.paint(g); + } + + @Override + public void paint(Graphics g) { + if (g != null) { + if (this.button.isLoaded) { + if (WorldButton.currentPackageName.equalsIgnoreCase(this.button.pkg)) { + g.setColor(Color.green); + } else { + g.setColor(Color.red); + } + + g.drawOval(0, 0, 3, 3); + g.fillOval(0, 0, 3, 3); + } else { + g.setColor(Color.red); + g.drawOval(0, 0, 3, 3); + } + } + } + + @Override + public void processMouseMotionEvent(MouseEvent e) { + switch (e.getID()) { + case 503: + case 506: + this.button.buttonAction(0, e.getID()); + case 504: + case 505: + default: + super.processMouseEvent(e); + } + } + + @Override + public void processMouseEvent(MouseEvent e) { + switch (e.getID()) { + case 501: + case 502: + case 504: + case 505: + this.button.buttonAction(0, e.getID()); + return; + case 503: + default: + super.processMouseEvent(e); + } + } +} diff --git a/NET/worlds/console/WorldsMarkPart.java b/NET/worlds/console/WorldsMarkPart.java new file mode 100644 index 0000000..d9afcab --- /dev/null +++ b/NET/worlds/console/WorldsMarkPart.java @@ -0,0 +1,647 @@ +package NET.worlds.console; + +import NET.worlds.core.IniFile; +import NET.worlds.network.NetUpdate; +import NET.worlds.network.RemoteFileConst; +import NET.worlds.network.URL; +import NET.worlds.scape.FrameEvent; +import NET.worlds.scape.Pilot; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Room; +import NET.worlds.scape.Saver; +import NET.worlds.scape.TeleportAction; +import NET.worlds.scape.TeleportStatus; +import NET.worlds.scape.World; +import java.awt.Container; +import java.awt.Event; +import java.awt.Font; +import java.awt.Menu; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.io.File; +import java.util.Hashtable; +import java.util.Locale; +import java.util.Vector; + +public class WorldsMarkPart implements FramePart, DialogReceiver, TeleportStatus, RemoteFileConst { + private static final String worldsMarksFileName = "Gamma.worldsmarks"; + private static final int MAX_HISTORY = 10; + private static URL userMarksURL = URL.make("home:Gamma.worldsmarks"); + private String name; + private Menu menu; + private Menu letsMenu; + private MenuItem addItem = new MenuItem(Console.message("Add-WorldsMark")); + private MenuItem deleteItem = new MenuItem(Console.message("Delete-WorldsMark")); + private MenuItem editItem = new MenuItem(Console.message("Edit-WorldsMark")); + private MenuItem locationItem = new MenuItem(Console.message("Change-Location")); + private Menu historyMenu = new Menu(Console.message("Back")); + private static Font font; + private boolean teleporting = false; + private boolean startLocationDialog = false; + static Vector<String> systemMarksNames; + private static Vector<Vector<BookmarkMenuItem>> systemMarks; + private static Vector<BookmarkMenuItem> userMarks; + private static Vector<BookmarkMenuItem> historyItems; + private static int firstUserItem; + private static Hashtable<String, String> renamed; + private static Vector<String> excludes; + private static Vector<String> sequence; + + static { + Locale currentLocale = Locale.getDefault(); + System.out.println("System Locale is " + currentLocale); + String defLang = IniFile.gamma().getIniString("DEFAULTLANGUAGE", ""); + if (!defLang.equals("")) { + String code1 = null; + String code2 = null; + if (defLang.length() >= 2) { + code1 = defLang.substring(0, 2); + } + + if (defLang.length() >= 5) { + code2 = defLang.substring(3, 5); + } + + if (code1 != null && code2 != null) { + Locale.setDefault(new Locale(code1, code2)); + currentLocale = Locale.getDefault(); + System.out.println("New Locale is " + currentLocale); + } else { + System.out.println("ERROR: DEFAULTLANGUAGE mustbe in the form xx_XX"); + } + } + + font = new Font(Console.message("MenuFont"), 0, 12); + historyItems = new Vector<BookmarkMenuItem>(); + historyItems.addElement(new BookmarkMenuItem(Console.message("end-of-last"), "world:restart")); + renamed = new Hashtable<String, String>(); + renamed.put("lets", "Hang"); + renamed.put("worldschat", "WorldsCenter"); + renamed.put("polygram", "WorldsStore.com"); + renamed.put("stadium", "NY Yankees"); + renamed.put("bowie", "Bowie I"); + renamed.put("texas", "Texas"); + renamed.put("hanson", "Hanson I"); + excludes = new Vector<String>(); + excludes.addElement("funhouse"); + excludes.addElement("chaos"); + sequence = new Vector<String>(); + sequence.addElement(getFirstWorld().toLowerCase()); + sequence.addElement("avatargallery"); + sequence.addElement("dressingroom"); + } + + public WorldsMarkPart() { + this(null); + } + + public WorldsMarkPart(String name) { + this.name = name; + } + + public boolean isTeleporting() { + return this.teleporting; + } + + public static String getExternalName(String name) { + String extName = renamed.get(name.toLowerCase()); + return extName != null ? extName : name; + } + + public Menu getMenu() { + if (this.menu == null) { + if (this.name != null) { + this.menu = new Menu(this.name); + } else { + this.menu = new PopupMenu(); + } + + this.letsMenu = new PopupMenu(); + this.historyMenu.setFont(font); + this.letsMenu.add(this.historyMenu); + this.letsMenu.addSeparator(); + if (userMarks == null) { + loadMarks(); + } + + if (systemMarks.size() != 0) { + for (int i = 0; i < systemMarks.size(); i++) { + String subName = systemMarksNames.elementAt(i); + Menu subMenu = new Menu(getExternalName(subName)); + addItems(subMenu, systemMarks.elementAt(i)); + subMenu.setFont(font); + this.letsMenu.add(subMenu); + } + } + + this.addMainMenuItem(this.addItem); + this.addMainMenuItem(this.deleteItem); + this.addMainMenuItem(this.editItem); + this.addMainMenuItem(this.locationItem); + this.addMainMenuSeparator(); + addItems(this.menu, userMarks); + addItems(this.historyMenu, historyItems); + } + + return this.menu; + } + + public Menu getLetsMenu() { + if (this.letsMenu == null) { + this.getMenu(); + } + + return this.letsMenu; + } + + public static PopupMenu getPackageMenu(String pname) { + int p = findPackageNum(pname); + if (p < 0) { + return null; + } else { + PopupMenu m = new PopupMenu(); + Vector<BookmarkMenuItem> v = systemMarks.elementAt(p); + + for (int i = 0; i < v.size(); i++) { + MenuItem mi = v.elementAt(i); + if (mi instanceof BookmarkMenuItem) { + BookmarkMenuItem bmi = v.elementAt(i); + String name = bmi.getLabel(); + String targ = bmi.getTarget(); + URL u = URL.make(TeleportAction.toURLString(targ)); + String pkg = TeleportAction.getPackageNameOfWorld(u); + if (pkg != null && findPackage(pkg) == null) { + String dirName = URL.make("home:" + pkg).unalias(); + if (!new File(dirName).isDirectory()) { + name = "Download " + name; + } + } + + m.add(new BookmarkMenuItem(name, targ)); + } + } + + boolean isFirst = true; + + for (int ix = 0; ix < userMarks.size(); ix++) { + URL u = URL.make(TeleportAction.toURLString(getBookmarkTarget(ix))); + String s = TeleportAction.getPackageNameOfWorld(u); + if (s != null && s.equalsIgnoreCase(pname)) { + if (isFirst) { + isFirst = false; + m.addSeparator(); + } + + BookmarkMenuItem item = new BookmarkMenuItem(getBookmarkName(ix), getBookmarkTarget(ix)); + m.add(item); + } + } + + return m; + } + } + + private static void addItems(Menu m, Vector<BookmarkMenuItem> v) { + for (int i = 0; i < v.size(); i++) { + MenuItem mItem = v.elementAt(i); + mItem.setFont(font); + m.add(mItem); + } + } + + private void addMainMenuItem(MenuItem item) { + item.setFont(font); + this.menu.add(item); + firstUserItem++; + } + + private void addMainMenuSeparator() { + this.menu.addSeparator(); + firstUserItem++; + } + + public static String getFirstWorld() { + IniFile ini = new IniFile("InstalledWorlds"); + return ini.getIniString("InstalledWorld0", ""); + } + + public static String getFirstSystemMarkURL() { + if (userMarks == null) { + loadMarks(); + } + + for (int i = 0; i < systemMarks.size(); i++) { + Vector<BookmarkMenuItem> v = systemMarks.elementAt(i); + if (v.size() > 0) { + return v.elementAt(0).getTarget(); + } + } + + int j = 0; + return j < userMarks.size() ? userMarks.elementAt(j).getTarget() : null; + } + + private static void shortenNames(String prefix, Vector<BookmarkMenuItem> v) { + int count = v.size(); + int pfxlen = prefix.length(); + + for (int i = 0; i < count; i++) { + MenuItem item = v.elementAt(i); + String label = item.getLabel(); + if (label.startsWith(prefix)) { + item.setLabel(label.substring(pfxlen).trim()); + } + } + } + + private static int findPackageNum(String pname) { + Vector<String> v = systemMarksNames; + if (v != null) { + int i = v.size(); + + while (--i >= 0) { + String s = v.elementAt(i); + if (s.equalsIgnoreCase(pname)) { + return i; + } + } + } + + return -1; + } + + public static String findPackage(String pname) { + int i = findPackageNum(pname); + return i < 0 ? null : systemMarksNames.elementAt(i); + } + + private static void loadMarks() { + systemMarks = new Vector<Vector<BookmarkMenuItem>>(); + systemMarksNames = new Vector<String>(); + IniFile ini = new IniFile("InstalledWorlds"); + String[] sequenced = new String[sequence.size()]; + + for (int count = 0; count < NetUpdate.maxInstalledWorlds(); count++) { + String curvalue = ini.getIniString("InstalledWorld" + count, ""); + if (!curvalue.equals("")) { + NetUpdate.maxInstalledWorld(count); + String pkgLower = curvalue.toLowerCase(); + if (!excludes.contains(pkgLower) && (!pkgLower.equals("polygram") || !World.isWorldsStoreProscribed())) { + int index = sequence.indexOf(pkgLower); + if (index != -1) { + sequenced[index] = curvalue; + } else { + systemMarksNames.addElement(curvalue); + } + } + } + } + + for (int i = sequenced.length - 1; i >= 0; i--) { + if (sequenced[i] != null) { + systemMarksNames.insertElementAt(sequenced[i], 0); + } + } + + int ix = 0; + + while (ix < systemMarksNames.size()) { + String worldName = systemMarksNames.elementAt(ix); + Vector<BookmarkMenuItem> v = (Vector<BookmarkMenuItem>)loadVector(URL.make("home:" + worldName + "/" + "Gamma.worldsmarks")); + if (v.size() != 0) { + shortenNames(worldName, v); + systemMarks.addElement(v); + ix++; + } else { + systemMarksNames.removeElementAt(ix); + } + } + + userMarks = (Vector<BookmarkMenuItem>)loadVector(userMarksURL); + } + + private static Vector<?> loadVector(URL url) { + Vector<?> v = null; + + try { + Restorer r = new Restorer(url); + v = r.restoreVector(); + r.done(); + } catch (Exception var3) { + if (v != null) { + saveVector(url, (Vector<BookmarkMenuItem>)v); + } else { + v = new Vector(); + } + } + + return v; + } + + private static void saveMarks() { + saveVector(userMarksURL, userMarks); + } + + private static void saveVector(URL url, Vector<BookmarkMenuItem> v) { + try { + Saver s = new Saver(url); + s.saveVector(v); + s.done(); + } catch (Exception var3) { + } + } + + static void gotoBookmark(int index) { + TeleportAction.teleport(getBookmarkTarget(index), null); + } + + static int getBookmarkCount() { + return userMarks.size(); + } + + private static BookmarkMenuItem getBookmark(int index) { + return userMarks.elementAt(index); + } + + static String getBookmarkName(int index) { + return getBookmark(index).getLabel(); + } + + static String getBookmarkTarget(int index) { + return getBookmark(index).getTarget(); + } + + void addBookmark(String name, String target) { + BookmarkMenuItem item = new BookmarkMenuItem(name, target); + this.menu.add(item); + userMarks.addElement(item); + saveMarks(); + } + + void removeBookmark(int index) { + userMarks.removeElementAt(index); + this.menu.remove(index + firstUserItem); + saveMarks(); + } + + void changeBookmark(int index, String name, String target) { + BookmarkMenuItem item = getBookmark(index); + item.setLabel(name); + item.setTarget(target); + saveMarks(); + } + + @Override + public void dialogDone(Object who, boolean confirmed) { + if (confirmed) { + if (who instanceof LocationDialog) { + LocationDialog locationDialog = (LocationDialog)who; + String location = locationDialog.getLocationURL(); + if (location.length() != 0) { + TeleportAction.teleport(location, null); + } + } else { + BookmarkAddDialog adder = (BookmarkAddDialog)who; + BookmarkEditDialog editor = adder.getEditor(); + this.addBookmark(editor.getName(), editor.getTarget()); + } + } + } + + private static BookmarkMenuItem getHistory(int index) { + return historyItems.elementAt(index); + } + + private static BookmarkMenuItem getItemFromTarget(String target, Vector<BookmarkMenuItem> vec) { + for (int i = 0; i < vec.size(); i++) { + BookmarkMenuItem item = vec.elementAt(i); + if (item.getTarget().equals(target)) { + return item; + } + } + + return null; + } + + private static BookmarkMenuItem getItemFromName(String name, Vector<BookmarkMenuItem> vec) { + for (int i = 0; i < vec.size(); i++) { + BookmarkMenuItem item = vec.elementAt(i); + if (item.getLabel().equals(name)) { + return item; + } + } + + return null; + } + + private static String getWorldName(String url) { + int rindex = url.toLowerCase().lastIndexOf(".world"); + int windex; + return rindex == -1 || (windex = url.lastIndexOf(47, rindex)) == -1 && (windex = url.lastIndexOf(58, rindex)) == -1 + ? null + : url.substring(windex + 1, rindex); + } + + public static String getCurrentPackageName() { + Pilot pilot = Pilot.getActive(); + if (pilot == null) { + return null; + } else { + World world = pilot.getWorld(); + if (world == null) { + return null; + } else { + URL url = world.getSourceURL(); + return url == null ? null : TeleportAction.getPackageNameOfWorld(url); + } + } + } + + private static String getCurrentURLName() { + String name = ""; + Pilot pilot = Pilot.getActive(); + if (pilot != null) { + World world = pilot.getWorld(); + if (world != null) { + URL url = world.getSourceURL(); + if (url != null) { + String worldFileName = getWorldName(url.getAbsolute()); + if (worldFileName != null) { + name = worldFileName; + } + } + + String worldName = world.getName(); + if (worldName != null) { + if (!name.equals("")) { + name = name + " "; + } + + name = name + worldName; + } + + Room room = pilot.getRoom(); + if (room != null) { + String roomName = room.getName(); + if (roomName != null) { + if (!name.equals("")) { + name = name + " "; + } + + name = name + roomName; + } + } + } + } + + return name; + } + + static String getCurrentPositionName() { + return getCurrentPositionName(userMarks); + } + + static String getCurrentPositionName(Vector<BookmarkMenuItem> v) { + String position = getCurrentPositionURL(false); + int count = systemMarks.size(); + + for (int i = 0; i < count; i++) { + BookmarkMenuItem item; + if ((item = getItemFromTarget(position, systemMarks.elementAt(i))) != null) { + return systemMarksNames.elementAt(i) + " " + item.getLabel(); + } + } + + BookmarkMenuItem item; + if ((item = getItemFromTarget(position, userMarks)) == null && (item = getItemFromTarget(position, historyItems)) == null) { + String defaultName = getCurrentURLName(); + String name = defaultName; + int number = 1; + + while (getItemFromName(name, v) != null) { + name = defaultName + "-" + ++number; + } + + return name; + } else { + return item.getLabel(); + } + } + + static String getCurrentPositionURL(boolean mustHaveChannel) { + Pilot pilot = Pilot.getActive(); + if (pilot == null) { + return ""; + } else { + String newURL = pilot.getURL(); + if (newURL == null) { + return ""; + } else { + if (!mustHaveChannel) { + int dynamicChannelIndex = newURL.indexOf("<dimension-"); + if (dynamicChannelIndex < 0) { + dynamicChannelIndex = newURL.indexOf("<>@"); + } + + int channelEndIndex = newURL.indexOf(">@"); + if (dynamicChannelIndex > 0 && dynamicChannelIndex < channelEndIndex) { + newURL = newURL.substring(0, dynamicChannelIndex) + newURL.substring(channelEndIndex + 1); + } + } + + return newURL; + } + } + } + + @Override + public void teleportStatus(String err, String url) { + this.teleporting = err != null && err.length() == 0; + if (err == null) { + url = getCurrentPositionURL(true); + if (url.length() == 0) { + return; + } + + Menu menu = this.getMenu(); + + for (int i = 0; i < historyItems.size(); i++) { + if (getHistory(i).getTarget().equals(url)) { + historyItems.removeElementAt(i); + this.historyMenu.remove(i); + break; + } + } + + BookmarkMenuItem item = new BookmarkMenuItem(getCurrentPositionName(historyItems), url); + historyItems.insertElementAt(item, 0); + this.historyMenu.insert(item, 0); + + while (historyItems.size() > 10) { + historyItems.removeElementAt(10); + this.historyMenu.remove(10); + } + } + } + + @Override + public void activate(Console c, Container f, Console prev) { + } + + @Override + public void deactivate() { + if (this.menu != null) { + this.menu.removeAll(); + } + + this.menu = null; + this.letsMenu = null; + firstUserItem = 0; + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (this.menu != null) { + if (target == this.addItem) { + if (Pilot.getActive().getRoom().getAllowTeleport()) { + new BookmarkAddDialog(Console.getFrame(), this); + } else { + Console.println(Console.message("no-teleport")); + } + } else if (target == this.deleteItem) { + new BookmarkDeleteDialog(this); + } else if (target == this.editItem) { + new BookmarkListDialog(this); + } else if (target == this.locationItem) { + this.startLocationDialog = true; + } else { + if (!(target instanceof BookmarkMenuItem)) { + return false; + } + + TeleportAction.teleport(((BookmarkMenuItem)target).getTarget(), null); + } + + return true; + } else { + return false; + } + } + + @Override + public boolean handle(FrameEvent f) { + if (this.startLocationDialog) { + this.startLocationDialog = false; + String url = ""; + Pilot pilot = Pilot.getActive(); + if (pilot != null) { + url = pilot.getURL(); + } + + new LocationDialog(Console.getFrame(), this, Console.message("Change-Location"), url); + } + + return true; + } +} diff --git a/NET/worlds/console/YesNoCancelDialog.java b/NET/worlds/console/YesNoCancelDialog.java new file mode 100644 index 0000000..a057214 --- /dev/null +++ b/NET/worlds/console/YesNoCancelDialog.java @@ -0,0 +1,89 @@ +package NET.worlds.console; + +import java.awt.Button; +import java.awt.Event; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +public class YesNoCancelDialog extends PolledDialog { + private static final long serialVersionUID = 4497394464783317237L; + private Button yesButton = new Button(Console.message("Yes")); + private Button noButton = new Button(Console.message("No")); + private Button cancelButton = new Button(Console.message("Cancel")); + private GridBagLayout gbag = new GridBagLayout(); + private String prompt; + private int choice = -2; + public static final int UNDECIDED = -2; + public static final int CANCEL = -1; + public static final int NO = 0; + public static final int YES = 1; + + public YesNoCancelDialog(java.awt.Window parent, DialogReceiver receiver, String title, String prompt) { + super(parent, receiver, title, true); + this.prompt = prompt; + this.setLayout(this.gbag); + this.ready(); + } + + public int getChoice() { + return this.choice; + } + + @Override + protected void build() { + GridBagConstraints c = new GridBagConstraints(); + c.weightx = 1.0; + c.weighty = 1.0; + c.gridwidth = 0; + this.add(this.gbag, new MultiLineLabel(this.prompt, 5, 5), c); + c.gridwidth = 3; + c.weightx = 1.0; + c.weighty = 0.0; + this.add(this.gbag, this.yesButton, c); + this.add(this.gbag, this.noButton, c); + this.add(this.gbag, this.cancelButton, c); + } + + @Override + public void show() { + super.show(); + this.yesButton.requestFocus(); + } + + private boolean yes() { + this.choice = 1; + return this.done(true); + } + + private boolean no() { + this.choice = 0; + return this.done(false); + } + + private boolean cancel() { + this.choice = -1; + return this.done(false); + } + + @Override + public boolean handleEvent(Event event) { + return event.id == 201 ? this.cancel() : super.handleEvent(event); + } + + @Override + public boolean action(Event event, Object what) { + Object target = event.target; + if (target == this.yesButton) { + return this.yes(); + } else if (target == this.noButton) { + return this.no(); + } else { + return target == this.cancelButton ? this.cancel() : false; + } + } + + @Override + public boolean keyDown(Event event, int key) { + return key == 27 ? this.cancel() : super.keyDown(event, key); + } +} |