⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 terminalwindow.java

📁 ErGo是一个很早的Java通用围棋服务器(IGS/NNGS)客户端程序。有全部源码和文档
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
      ((GameWindow) gameWindows.elementAt(i)).adjourn();
    }
  }

  /*
   * Find a game window that matches by the names of the players.
   * The reason the game number can't be used is that when games
   * are adjourned and restarted on the server sometimes they are
   * assigned a new number.  
   */
  public GameWindow getGameWindowByName(String white, String black) {
    return getGameWindowByName(white, black, -1);
  }

  public GameWindow getGameWindowByName(String white, String black,
					int number) {
    for(Enumeration e = gameWindows.elements(); e.hasMoreElements(); ) {
      GameWindow w = (GameWindow) e.nextElement();
      if(w.game.whiteName.equals(white)
	 && w.game.blackName.equals(black)) {
	// Update the game number for this game and invalidate
	// any other game with this number, if there is one.
	// also, cooperate with SGC to maintain consistency - AMB at 0.7
	if (number > 0) {
	  GameWindow old = getGameWindowByNumber(number);
	  if (old != null && old != w)
	    old.gameNumber = 0;
	  String oldtitle = w.title();
	  if (w.gameNumber != number) {
	    w.gameNumber = number;
	    w.updateTitle();
	    registrar.updateWindowTitle(w);
	  }
	  // inform now performed by ensureActive().
	  // always inform sgc, even if number is the same.
	  //	conn.control.sgc.inform(w);
	}
	return w;
      }
    }
    return null;
  }


  // Find a game window that matches the given game number.
  // See getGameWindowByName for explanation.
  //
  // Fix for case for situation where game finishes,
  // the window hangs around, and then the user starts to observe
  // new server game with same number. This function preferentially
  // returns the window corresponding to the active game, if there is
  // a choice. AMB at 0.8

  public GameWindow getGameWindowByNumber (int number) {
    GameWindow stashedgw = null;
    for(Enumeration e = gameWindows.elements(); e.hasMoreElements(); ) {
      GameWindow w = (GameWindow) e.nextElement();
      if (w.gameNumber == number) {
        if (w.isOnServer())
	  stashedgw = w;
        else if (stashedgw == null)
	  stashedgw = w;
      }
    }
    return stashedgw;
  }
	  
  public GameWindow getGameBeingPlayed() {
    for(Enumeration e = gameWindows.elements(); e.hasMoreElements(); ) {
      GameWindow w = (GameWindow) e.nextElement();
      if (w.isParticipating())
	return w;
    }
    return null;
  }

  /*************************************************
   * Event handling                                *
   *************************************************/

  class menuListener extends urMenuListener {
    public void itemSelected (MenuItem source) {
      // The user has chosen a menu item.
      if (source == loadItem)
	load();
      else if (source == saveOutputItem)
	saveTerminalOutput(mainArea);
      else if (source == clearOutputItem) {
	mainArea.clearAll();
	messageArea.clearAll();
      }
      else if (source == observeItem) {
	if (observeDialog == null)
	  observeDialog = new ObserveDialog(TerminalWindow.this, conn);
	observeDialog.show();
      }
      else if (source == matchItem)
	new MatchDialog(TerminalWindow.this, false).open(conn);
      else if (source == localGameItem)
	startLocalGame();
      else if (source == saveOptionsItem) {
	String error = (ergo.inApplet
			? "Can't write init file when running as an applet."
			: opser.rewriteFile());
	if (error != null) {
	  new InformDialog(TerminalWindow.this, "Error", error).open();
	}
      }
      else if (source == aboutItem)
	new AboutDialog(TerminalWindow.this, "About Ergo").open();
      else if (source == docItem) {
	// docItem is disabled when running as an app, but just in case...
	if (ergo.inApplet)
	  ergo.getAppletContext().showDocument(ergo.getDocumentBase(),
					       "doc.html");
      }
      else if (source == newServerItem)
	new NewServerDialog().open();
    }
  }

  // This is called when a CheckboxMenuItem is clicked.
  class checkboxListener extends urCheckboxListener {
    public void itemStateChanged (ItemEvent e) {
      Object mi = e.getSource();
      if (mi == debugItem) {
	boolean state = debugItem.getState();
	Debug.setDebug(state);
	opser.updateOption(GlobalOptions.debugmodeString, new Boolean(state));
      }
      else if (mi == rawItem) {
	rawMode = !rawMode;
	rawItem.setState(rawMode);
      }
      else if (mi == logicItem) {
	Debug.debugGameLogicp = !Debug.debugGameLogicp;
	logicItem.setState(Debug.debugGameLogicp);
      }
      else if (mi == soundItem) {
	soundEnabled = !soundEnabled;
	opser.updateOption(GlobalOptions.soundString,
			   new Boolean(soundEnabled));
	soundItem.setState(soundEnabled);
      }
    }
  }

  /**********************************
   *  Command-line input processing *
   **********************************/

  private void send (String text) {
    if (conn != null && conn.isConnected())
      conn.send(text);
    else {
      displayString(text);
      displayString(">>> Ergo: No server connection.  Message not sent.");
    }
  }

  private void processKibitzCommand (String command, ParsedMessage pm,
				     GameWindow gwin, boolean isLocal) {
    String rest = pm.rest();
    int gameNum = (gwin == null) ? -1 : gwin.gameNumber;
    try {
      pm.continueParse("%i ");
      gameNum = ((Integer) pm.matchAt(1)).intValue();
      rest = pm.rest();	// strip off the game number
    }
    catch (ParseException pe2) { }
    GameWindow w = getGameWindowByNumber(gameNum);
    if (w == null) w = gwin; // reasonable default?
    if (w == null) {
      // If there's a single active game, then use it.
      GameWindow it = null;
      int count = 0;
      for (int i = 0; i < gameWindows.size(); i++) {
	GameWindow g = (GameWindow) gameWindows.elementAt(i);
	if (g.gameStatus != GameWindow.ADJOURNED
	    && g.gameStatus != GameWindow.GAMEOVER) {
	  it = g;
	  ++count;
	}
      }
      if (count == 1)
	w = it;
      else
	displayString(">>> Ergo: Kibitz not added to local game record since no game# was specified.  Try kibitzing from the game window instead.");
    }
    if (w != null) {
      if (!isLocal && w.isNetGame())
	conn.send("kibitz " + w.gameNumber + " " + rest, false);
      // When playing a teaching game kibitzes are sent to the players
      // also.  This tries to prevent those kibitzes from being displayed
      // twice.
      if (isLocal
	  || !w.isNetGame()
	  || !(w.isTeachingGame() && w.isParticipating())) {
	w.addKibitz(getAccountName(), getRank(), rest, isLocal);
      }
    }
    else
      send(command);	// No game specified.  Just send command.
  }

  // When commands with one arg, the game number, are issued from a
  // game window and no game number is specified, add the game number
  // of the game window since that's undoubtedly what the user
  // intended.
  private void processGameArgCommand (String command, ParsedMessage pm,
				  GameWindow gwin) {
    if (gwin == null)		// command came from main window
      send(command);
    else {   // add the game number if not already there.
      String rest = pm.rest();
      boolean hasMore = false;
      for (int i = 0; i < rest.length(); i++)
	if (!Character.isWhitespace(rest.charAt(i))) {
	  hasMore = true;
	  break;
	}
      if (hasMore)
	send(command);
      else
	send(command + " " + gwin.gameNumber);
    }
  }

  private boolean isWord(String word, String maximal, String minimal) {
    if (conn == null || !conn.isConnected() || !conn.server.matchCase()) {
      word = word.toLowerCase();
      maximal = maximal.toLowerCase();
      minimal = minimal.toLowerCase();
    }
    return (maximal.startsWith(word) && word.startsWith(minimal));
  }

  private boolean stringEqual (String s1, String s2) {
    return ((conn == null || !conn.isConnected() || !conn.server.matchCase())
	    ? s1.equalsIgnoreCase(s2)
	    : s1.equals(s2));
  }
      
  // Process commands entered into the inputField.
  public void processCommand (String text, GameWindow gwin) {
    CommandHistory hist
      = (gwin == null) ? commandHistory : gwin.getCommandHistory();
    if (hist != null && text != null && !"".equals(text))
      hist.addElement(text);
    try {
      ParsedMessage pmess = new ParsedMessage(text, " %s ");
      String firstWord = (String) pmess.matchAt(0);
      if ("'".equals(firstWord)
	  || isWord(firstWord, "kibitz ", "kib"))
	processKibitzCommand(text, pmess, gwin, false);
      else if (stringEqual("say", firstWord)) {
	conn.send(text);
	GameWindow w = getGameBeingPlayed();
	if (w != null && !w.isTeachingGame())
	  w.addKibitz1("*" + getAccountName() + "*: " + pmess.rest(), false);
      }
      else if (stringEqual(firstWord, "all"))
	processGameArgCommand(text, pmess, gwin);
      else if (stringEqual(firstWord, "time"))
	processGameArgCommand(text, pmess, gwin);
      else if (stringEqual(firstWord, "moves"))
	processGameArgCommand(text, pmess, gwin);
      else if (stringEqual(firstWord, "score"))
	processGameArgCommand(text, pmess, gwin);
      else if (isWord(firstWord, "localkibitz ", "loc")
	       || stringEqual(firstWord, "lkib")
	       || "$".equals(firstWord))
	processKibitzCommand(text, pmess, gwin, true);
      else		// No special processing for the command.
	send(text);
    }
    catch (ParseException pe) {
      // If there was a ParseException then there must be no first word.
      send(text);
    }
  }


  /****************************
   * Miscellaneous code       *
   ****************************/

  public boolean getSoundEnabled () {
    return soundEnabled;
  }

  public void setDefaultDirectory (String dir) {
    defaultDirectory = dir;
  }

  public String getDefaultDirectory () {
    return defaultDirectory;
  }

  public boolean saveTerminalOutput (TextArea area) {
    // Ask the user for a pathname.
    FileDialog saveDialog
      = new FileDialog(this, "Save Terminal Output...", FileDialog.SAVE);
    if (getDefaultDirectory() != null)
      saveDialog.setDirectory(getDefaultDirectory());
    saveDialog.setFile("output.txt");
    saveDialog.show();
    if (saveDialog.getFile() == null)
      return true;
    else {
      String filename = saveDialog.getDirectory() + saveDialog.getFile();
      try {
	PrintWriter out = new PrintWriter(new FileWriter(filename));
	area.save(out);
	out.close();
	setDefaultDirectory(saveDialog.getDirectory());
	return false;
      }
      catch (IOException e) {
	displayString("Error during save: " + e);
      }
    }
    return false;
  }

  // Load an SGF file.
  public void load () {
    FileDialog fd = new FileDialog(this, "Load SGF file");
    if (defaultDirectory != null)
      fd.setDirectory(getDefaultDirectory());
    fd.setFilenameFilter(new FilenameFilter() {
      public boolean accept (File dir, String filename) {
	return filename.toLowerCase().endsWith("sgf");
      }
    });
    fd.show();
    String filename = fd.getFile();
    if (filename != null) {
      setDefaultDirectory(fd.getDirectory());
      filename = fd.getDirectory() + filename;
      SGF parser = new SGF(this);
      try {
	Vector games = parser.readSGFFile(filename);
	for (int i = 0; i < games.size(); i++) {
	  Game game = (Game) games.elementAt(i);
	  try {
	    GameWindow gwin = new GameWindow(game, this);
	    game.setWindow(gwin);
	    addGameWindow(gwin);
	    gwin.setKibitzState(true, true);
	  }
	  catch (ErgoException e) {
	    Debug.backtrace(e);
	  }
	}
      }
      catch (Exception e) {
	Debug.backtrace(e);
	new InformDialog(this, "Error", "Invalid SGF file: \n"
			 + e.getMessage()).open();
      }
    }
  }
    

  // +++ This uses package scope rather than private to workaround
  //     Java bug 4034664.  Fixed in Java 1.2.
  //     I don't know what code the above comment refers to anymore.


  private void exit () {
    if (conn.isConnected()) {
      ActionListener listener = new ActionListener () {
	public void actionPerformed (ActionEvent e) {
	  String cmd = e.getActionCommand();
	  if ("yes".equalsIgnoreCase(cmd))
	    actuallyExit();
	}
      };
      new YNCDialog(this, "Really quit?", true,
		    "You are still connected to " + conn + ".  Disconnect and quit?",
		    listener, false).open();
    }
    else
      actuallyExit();
  }

  private void actuallyExit() {
    if (conn.isConnected()) 
      conn.close();
    if (ergo.inApplet)
      setVisible(false);		// hides game windows also.
    else {
      if (opser.getBooleanOption(exitString))
	opser.rewriteFile(); 
      System.exit(0);
    }
  }

  public void setVisible (boolean visible) {
    if (!visible) {
      super.setVisible(visible);
      for (int i = 0; i < gameWindows.size(); i++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -