Package oculus

Source Code of oculus.Application

package oculus;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Set;

import oculus.commport.AbstractArduinoComm;
import oculus.commport.Discovery;
import oculus.commport.LightsComm;

import org.red5.server.adapter.MultiThreadedApplicationAdapter;
import org.red5.server.api.IConnection;
import org.red5.server.api.Red5;
import org.red5.server.api.service.IServiceCapableConnection;
import org.jasypt.util.password.*;
import org.red5.io.amf3.ByteArray;

import developer.SendMail;
import developer.UpdateFTP;
import developer.image.motionDetect;


/** red5 application */
public class Application extends MultiThreadedApplicationAdapter {

  private static final int STREAM_CONNECT_DELAY = 2000;
  private ConfigurablePasswordEncryptor passwordEncryptor = new ConfigurablePasswordEncryptor();

  private static String salt;
  private IConnection grabber = null;
  private IConnection player = null;
  private AbstractArduinoComm comport = null;
  private LightsComm light = null;
  private BatteryLife battery = null;
  private Settings settings = Settings.getReference();
  private IConnection pendingplayer = null;
  private AutoDock docker = null;
  private State state = State.getReference();
  private LoginRecords loginRecords = new LoginRecords();
  private boolean pendingplayerisnull = true;
  private String authtoken = null;
  private boolean initialstatuscalled = false;

  public TelnetServer commandServer = null;
  public developer.OpenNIRead openNIRead = null;
  public Speech speech = new Speech();
  public static byte[] framegrabimg  = null;
  public Boolean passengerOverride = false;
  public long lastcommandtime = 0;
  public static BufferedImage processedImage = null;
 
  public Application() {
    super();
    passwordEncryptor.setAlgorithm("SHA-1");
    passwordEncryptor.setPlainDigest(true);
    FrameGrabHTTP.setApp(this);
    RtmpPortRequest.setApp(this);
    AuthGrab.setApp(this);
    initialize();
  }

  @Override
  public boolean appConnect(IConnection connection, Object[] params) {

    String logininfo[] = ((String) params[0]).split(" ");

    // always accept local grabber
    if ((connection.getRemoteAddress()).equals("127.0.0.1") && logininfo[0].equals(""))
      return true;

    if (logininfo.length == 1) { // test for cookie auth
      String username = logintest("", logininfo[0]);
      if (username != null) {
        state.set(State.values.pendinguserconnected, username);
        return true;
      }
    }
    if (logininfo.length > 1) { // test for user/pass/remember
      String encryptedPassword = (passwordEncryptor.encryptPassword(logininfo[0] + salt + logininfo[1])).trim();
      if (logintest(logininfo[0], encryptedPassword) != null) {
        if (logininfo[2].equals("remember")) {
          authtoken = encryptedPassword;
        }
        state.set(State.values.pendinguserconnected, logininfo[0]);
        return true;
      }
    }
    String str = "login from: " + connection.getRemoteAddress() + " failed";
    Util.log("appConnect(): " + str);
    messageGrabber(str, "");
    return false;
  }

  @Override
  public void appDisconnect(IConnection connection) {
    if(connection==null) { return; }
    if (connection.equals(player)) {
      String str = state.get(State.values.driver.name()) + " disconnected";
      Util.log("appDisconnect(): " + str);

      messageGrabber(str, "connection awaiting connection");
      loginRecords.signoutDriver();

      if (!state.getBoolean(State.values.autodocking)) { //if autodocking, keep autodocking
        if (state.get(State.values.stream) != null) {
          if (!state.get(State.values.stream).equals("stop")) {
            publish("stop");
          }
        }

        if (light.isConnected()) { // && light.lightLevel != 0) {
          if (light.spotLightBrightness() > 0)
            light.setSpotLightBrightness(0);
          if (light.floodLightOn())
            light.floodLight("off");
        }

        if (comport != null) {
          comport.stopGoing();
          comport.releaseCameraServo();
        }
       
        if (state.getBoolean(State.values.driverstream)) {
          state.set(State.values.driverstream, false);
          grabberPlayPlayer(0);
          messageGrabber("playerbroadcast", "0");
        }
       
        // this needs to be before player = null
        if (state.get(State.values.pendinguserconnected) != null) {
          assumeControl(state.get(State.values.pendinguserconnected));
          state.delete(State.values.pendinguserconnected);
          return;
        }
      }
     
      player = null;
    }
   
    if (connection.equals(grabber)) {
      grabber = null;
      // log.info("grabber disconnected");
      // wait a bit, see if still no grabber, THEN reload
      new Thread(new Runnable() {
        public void run() {
          try {
            Thread.sleep(8000);
            if (grabber == null) {
              grabberInitialize();
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }).start();
      return;
    }
   
    state.delete(State.values.pendinguserconnected);
    //TODO: extend IConnection class, associate loginRecord  (to get passenger info)
    // currently no username info when passenger disconnects
  }

  public void grabbersignin(String mode) {
    if (mode.equals("init")) {
      state.delete(State.values.stream);
    } else {
      state.set(State.values.stream, "stop");
    }
    grabber = Red5.getConnectionLocal();
    String str = "awaiting connection";
    if (state.get(State.values.driver.name()) != null) {
      str = state.get(State.values.driver.name()) + " connected";
    }
    str += " stream " + state.get(State.values.stream);
    messageGrabber("connected to subsystem", "connection " + str);
    Util.log("grabber signed in from " + grabber.getRemoteAddress(), this);
    if (state.getBoolean(State.values.driverstream)) {
      grabberPlayPlayer(1);
      messageGrabber("playerbroadcast", "1");
    }

    // eliminate any other grabbers
    Collection<Set<IConnection>> concollection = getConnections();
    for (Set<IConnection> cc : concollection) {
      for (IConnection con : cc) {
        if (con instanceof IServiceCapableConnection && con != grabber && con != player
            && (con.getRemoteAddress()).equals("127.0.0.1")) {
          con.close();
        }
      }
    }
   
    // set video, audio quality mode in grabber flash, depending on server/client OS
    String videosoundmode=state.get(State.values.videosoundmode.name());
    if (videosoundmode == null) {
      videosoundmode="high"
      if (Settings.os.equals("linux")) { // TODO: or motion/sound activity threshold enabled
        videosoundmode="low";
      }
    }
    setGrabberVideoSoundMode(videosoundmode);

    docker = new AutoDock(this, grabber, comport, light);
    loginRecords.setApplication(this);
  }
  /** */
  public void initialize() {
    settings.writeFile();
    salt = settings.readSetting("salt");

    // must be blocking search of all ports, but only once!
    Discovery discovery = new Discovery();
    comport = discovery.getMotors(this);
    light = discovery.getLights(this);
   
    state.set(State.values.httpPort, settings.readRed5Setting("http.port"));
    state.set(State.values.muteOnROVmove, settings.getBoolean(GUISettings.muteonrovmove));
    initialstatuscalled = false;
    pendingplayerisnull = true;
   
    if (settings.getBoolean(ManualSettings.developer.name())) {
     
      openNIRead = new developer.OpenNIRead(this);

    }
   
   
 
    if ( ! settings.readSetting(ManualSettings.commandport).equals(Settings.DISABLED))
      commandServer = new oculus.TelnetServer(this);
   
    if (UpdateFTP.configured()) new developer.UpdateFTP();

    Util.setSystemVolume(settings.getInteger(GUISettings.volume), this);
    state.set(State.values.volume, settings.getInteger(GUISettings.volume));

    grabberInitialize();
    battery = BatteryLife.getReference();
    new SystemWatchdog();
    Util.debug("initialize done", this);

  }

  /**
   * battery init steps separated here since battery has to be called after
   * delay and delay can't be in main app, is in server.js instead
   *
   * @param mode
   *            is this required, not really used?
   */
  private void checkForBattery(String mode) {
    if (mode.equals("init")) {
      battery.init(this);
    } else {
      new Thread(new Runnable() {
        public void run() {
          if (battery.batteryPresent())
            messageGrabber("populatevalues battery yes", null);
          else
            messageGrabber("populatevalues battery nil", null);
        }
      }).start();
    }
  }

  private void grabberInitialize() {
    if (settings.getBoolean(GUISettings.skipsetup)) {
      grabber_launch();
    } else {
      initialize_launch();
    }
  }

  public void initialize_launch() {
    new Thread(new Runnable() {
      public void run() {
        try {
          // stream = null;
          String address = "127.0.0.1:" + state.get(State.values.httpPort);
          if (Settings.os.equals("linux")) {
            Runtime.getRuntime().exec("xdg-open http://" + address + "/oculus/initialize.html");
          }
          else { // win
            Runtime.getRuntime().exec("cmd.exe /c start http://" + address + "/oculus/initialize.html");
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }).start();
  }

  public void grabber_launch() {
    new Thread(new Runnable() {
      public void run() {
        try {

          // stream = "stop";
          String address = "127.0.0.1:" + state.get(State.values.httpPort);
          if (Settings.os.equals("linux")) {
            Runtime.getRuntime().exec("xdg-open http://" + address + "/oculus/server.html");
          }
          else { // win
            Runtime.getRuntime().exec("cmd.exe /c start http://" + address + "/oculus/server.html");
          }

        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }).start();
  }

  /** */
  public void playersignin() {   
    // set video, audio quality mode in grabber flash, depending on server/client OS
    String videosoundmode="high"; // windows, default
    if (Settings.os.equals("linux")) {
      videosoundmode="low";
    }

    if (player != null) {
      pendingplayer = Red5.getConnectionLocal();
      pendingplayerisnull = false;

      if (pendingplayer instanceof IServiceCapableConnection) {
        IServiceCapableConnection sc = (IServiceCapableConnection) pendingplayer;
        String str = "connection PENDING user " + state.get(State.values.pendinguserconnected);
        if (authtoken != null) {
          // System.out.println("sending store cookie");
          str += " storecookie " + authtoken;
          authtoken =  null;
        }
        str += " someonealreadydriving " + state.get(State.values.driver.name());

        // this has to be last to above variables are already set in java script
        sc.invoke("message", new Object[] { null, "green", "multiple", str });
        str = state.get(State.values.pendinguserconnected) + " pending connection from: "
            + pendingplayer.getRemoteAddress();
       
        Util.log("playersignin(): " + str);
        messageGrabber(str, null);
        sc.invoke("videoSoundMode", new Object[] { videosoundmode });
      }
    } else {
      player = Red5.getConnectionLocal();
      state.set(State.values.driver.name(), state.get(State.values.pendinguserconnected));
      state.delete(State.values.pendinguserconnected);
      String str = "connection connected user " + state.get(State.values.driver.name());
      if (authtoken != null) {
        str += " storecookie " + authtoken;
        authtoken = null;
      }
      str += " streamsettings " + streamSettings();
      messageplayer(state.get(State.values.driver.name()) + " connected to OCULUS", "multiple", str);
      initialstatuscalled = false;
     
      str = state.get(State.values.driver.name()) + " connected from: " + player.getRemoteAddress();
      messageGrabber(str, "connection " + state.get(State.values.driver.name()) + "&nbsp;connected");
      Util.log("playersignin(), " + str, this);
      loginRecords.beDriver();
     
      if (settings.getBoolean(GUISettings.loginnotify)) {
        saySpeech("lawg inn " + state.get(State.values.driver));
      }
     
      IServiceCapableConnection sc = (IServiceCapableConnection) player;
      sc.invoke("videoSoundMode", new Object[] { videosoundmode });
      Util.log("player video sound mode = "+videosoundmode, this);
    }
  }


//  public void dockGrab() {
//    if (grabber instanceof IServiceCapableConnection) {
//      IServiceCapableConnection sc = (IServiceCapableConnection) grabber;
//      sc.invoke("dockgrab", new Object[] { 0, 0, "find" });
//      state.set(oculus.State.values.dockgrabbusy.name(), true);
//    }
//  }

  /**
   * distribute commands from pla
   *
   * @param fn
   *            is the function to call
   *
   * @param str
   *            is the parameter to pass onto the function
   */
  public void playerCallServer(final String fn, final String str) {
//    Util.debug("from player flash: "+fn+", "+str, this);
   
    if (fn == null) return;
    if (fn.equals("")) return;
   
    PlayerCommands cmd = null;
    try {
      cmd = PlayerCommands.valueOf(fn);
    } catch (Exception e) {
      Util.debug("playerCallServer() command not found:" + fn, this);
      messageplayer("error: unknown command, "+fn,null,null);
      return;
    }
    if (cmd != null) playerCallServer(cmd, str)
  }

  /**
   * distribute commands from player
   *
   * @param fn
   *            to call in flash player [file name].swf
   * @param str
   *            is the argument string to pass along
   */
  public void playerCallServer(final PlayerCommands fn, final String str) {
    if (PlayerCommands.requiresAdmin(fn.name()) && !passengerOverride){
      if ( ! loginRecords.isAdmin()){
        Util.debug("playerCallServer(), must be an admin to do: " + fn.name() + " curent driver: " + state.get(State.values.driver), this);
        return;
      }
    }
   
    if(fn != PlayerCommands.statuscheck)
      lastcommandtime = System.currentTimeMillis();
//      state.set(State.values.usercommand.name(), System.currentTimeMillis());

    String[] cmd = null;
    if(str!=null) cmd = str.split(" ");

    switch (fn) {
    case chat: chat(str) ;return;
    case beapassenger: beAPassenger(str);return;
    case assumecontrol: assumeControl(str); return;
    }
   
    // must be driver/non-passenger for all commands below
    if(!passengerOverride){
      if (Red5.getConnectionLocal() != player && player != null) {
        Util.log("passenger, command dropped: " + fn.toString(), this);
        return;
      }
    }
   
    switch (fn) {
   
    case writesetting:
      Util.log("setting: " + str);
      if (settings.readSetting(cmd[0]) == null) {
        settings.newSetting(cmd[0], cmd[1]);
        messageplayer("new setting: " + cmd[1], null, null);
      } else {
        settings.writeSettings(cmd[0], cmd[1]);
        messageplayer(cmd[0] + " " + cmd[1], null, null);
      }
      settings.writeFile();
      break;

    case speedset:
      comport.speedset(str);
      messageplayer("speed set: " + str, "speed", str.toUpperCase());
      break;

    case slide:
      if (!state.getBoolean(State.values.motionenabled.name())) {
        messageplayer("motion disabled", "motion", "disabled");
        break;
      }
      if (state.getBoolean(State.values.autodocking.name())) {
        messageplayer("command dropped, autodocking", null, null);
        break;
      }
      moveMacroCancel();
      comport.slide(str);
      messageplayer("command received: " + fn + str, null, null);
      break;

    case systemcall:
      Util.log("received: " + str);
      messageplayer("system command received", null, null);
      Util.systemCall(str);
      break;

    case relaunchgrabber:
      grabber_launch();
      messageplayer("relaunching grabber", null, null);
      break;

    case docklineposupdate:
      settings.writeSettings("vidctroffset", str);
      messageplayer("vidctroffset set to : " + str, null, null);
      break;

    case arduinoecho:
      if (str.equalsIgnoreCase("true"))comport.setEcho(true);
      else comport.setEcho(false);
      messageplayer("echo set to: " + str, null, null);
      break;

    case arduinoreset:
      comport.reset();
      messageplayer("resetting arduinoculus", null, null);
      break;

    case move:move(str); break;
    case nudge:nudge(str); break;
     
    case speech:
      messageplayer("synth voice: " + str, null, null);
      messageGrabber("synth voice: " + str, null);
      saySpeech(str);
      break;
     
    case dock:docker.dock(str);break;
    case battstats:battery.battStats();break;
    case cameracommand:cameraCommand(str);break;
    case gettiltsettings:getTiltSettings();break;
    case getdrivingsettings:getDrivingSettings();break;
    case motionenabletoggle:motionEnableToggle();break;
    case drivingsettingsupdate:drivingSettingsUpdate(str);break;
    case tiltsettingsupdate:tiltSettingsUpdate(str);break;
    case tilttest:tiltTest(str);break;
    case clicksteer:clickSteer(str);break;
    case streamsettingscustom:streamSettingsCustom(str);break;
    case streamsettingsset:streamSettingsSet(str);break;
    case playerexit: appDisconnect(player); break;
    case playerbroadcast: playerBroadCast(str); break;
    case password_update: account("password_update", str); break;
    case new_user_add: account("new_user_add", str); break;
    case user_list: account("user_list", ""); break;
    case delete_user: account("delete_user", str); break;
//    case framegrab: frameGrab(); break;
    case statuscheck: statusCheck(str); break;
   
    /*case emailgrab:
      frameGrab();
      emailgrab = true;
      break;*/
    //TODO: disabled currently
    case extrauser_password_update: account("extrauser_password_update", str); break;
    case username_update: account("username_update", str); break;
    case disconnectotherconnections: disconnectOtherConnections(); break;
    case monitor: monitor(str); break;
    case showlog: showlog(str); break;
    case dockgrab: docker.dockGrab("start",0,0); break;
    case publish: publish(str); break;
    case autodock: docker.autoDock(str); break;
    case autodockcalibrate: docker.autoDock("calibrate " + str); break;
    case restart: restart(); break;
    case softwareupdate: softwareUpdate(str); break;
    case muterovmiconmovetoggle: muteROVMicOnMoveToggle(); break;
    case spotlightsetbrightness: // deprecated, maintained for mobile client compatibility
    case spotlight: light.setSpotLightBrightness(Integer.parseInt(str)); break;
    case floodlight: light.floodLight(str); break;
    case setsystemvolume:
      Util.setSystemVolume(Integer.parseInt(str), this);
      messageplayer("ROV volume set to "+str+"%", null, null);
      state.set(State.values.volume, str);
      break;   
    case holdservo:
      Util.debug("holdservo: " + str,this);
      if (str.equalsIgnoreCase("true")) {
        comport.holdservo = true;
        settings.writeSettings(GUISettings.holdservo.toString(), "true");
      } else {
        comport.holdservo = false;
        settings.writeSettings(GUISettings.holdservo.toString(), "false");
     
      settings.writeFile();
      messageplayer("holdservo " + str, null, null);
      break;
    case opennisensor:
      if(str.equals("on")) { openNIRead.startDepthCam(); }
      else { openNIRead.stopDepthCam(); }     
      messageplayer("openNI camera "+str, null, null);
      break;
    case videosoundmode:
      setGrabberVideoSoundMode(str);
      messageplayer("video/sound mode set to: "+str, null, null);
      break;
    case pushtotalktoggle:
      settings.writeSettings("pushtotalk", str);
      messageplayer("self mic push T to talk "+str, null, null);
      break;
    case shutdown: quit(); break;
    case setstreamactivitythreshold: setStreamActivityThreshold(str); break;
    case getlightlevel: docker.getLightLevel(); break;
    case email: new SendMail(str, this); break;
    case uptime: messageplayer(state.getUpTime() + " ms", null, null); break;
    case help: messageplayer(PlayerCommands.help(str),null,null); break;
    case framegrabtofile: FrameGrabHTTP.saveToFile(str); break;
    case memory: messageplayer(Util.memory(), null, null); break;
    case state:
      String s[] = str.split(" ");
      if (s.length == 2) { state.set(s[0], s[1]); }
      else
        if (s[0].matches("\\S+")) {
          messageplayer("<state> "+s[0]+" "+state.get(s[0]), null, null);
        }
        else { messageplayer("<state> "+state.toString(), null, null); }
      }
      break;
    case who: messageplayer(loginRecords.who(), null, null); break;
    case loginrecords: messageplayer(loginRecords.toString(), null, null); break;
    case settings: messageplayer(settings.toString(), null, null); break;
    case messageclients: messageplayer(str, null,null); Util.log("messageclients: "+str,this); break;
    case dockgrabtest: docker.dockGrab("test", 0, 0); break;
    case digitalread: comport.digitalRead(str); break;
    case analogwrite: comport.AnalogWrite(str); break;
    case reloadserverhtml: messageGrabber("server html reload",null); break;
    case motiondetectgo: new motionDetect(this, grabber, Integer.parseInt(str)); break;
    case motiondetectcancel: state.delete(State.values.motiondetectwatching); break;
    case rssadd: RssFeed feed = new RssFeed(); feed.newItem(str);

    }
  }

  /** put all commands here */
  public enum grabberCommands {
    streammode, saveandlaunch, populatesettings, systemcall, chat, dockgrabbed, autodock,
    restart, checkforbattery, factoryreset, shutdown, streamactivitydetected;
    @Override
    public String toString() {
      return super.toString();
    }
  }

  /**
   * turn string input to command id
   *
   * @param fn
   *            is the funct ion to call
   * @param str
   *            is the parameters to pass on to the function.
   */
  public void grabberCallServer(String fn, String str) {
    grabberCommands cmd = null;
    try {
      cmd = grabberCommands.valueOf(fn);
    } catch (Exception e) {
      return;
    }

    if (cmd == null) return;
    else grabberCallServer(cmd, str);
  }

  /**
   * distribute commands from grabber
   *
   * @param fn
   *            is the function to call in xxxxxx.swf ???
   * @param str
   *            is the parameters to pass on to the function.
   */
  public void grabberCallServer(final grabberCommands cmd, final String str) {
   
    switch (cmd) {
    case streammode:
      grabberSetStream(str);
      break;
    case saveandlaunch:
      saveAndLaunch(str);
      break;
    case populatesettings:
      populateSettings();
      break;
    case systemcall:
      Util.systemCall(str);
      break;
    case chat:
      chat(str);
      break;
    case dockgrabbed:
      docker.autoDock("dockgrabbed " + str);
      state.set(State.values.dockgrabbusy.name(), false);
      break;
    case autodock:
      docker.autoDock(str);
      break;
    case checkforbattery:
      checkForBattery(str);
      break;
    case factoryreset:
      factoryReset();
      break;
    case restart:
      restart();
      break;
    case shutdown:
      quit();
      break;
    case streamactivitydetected:
      streamActivityDetected(str);
      break;
    }
  }

  private void grabberSetStream(String str) {
    final String stream = str;
    state.set(State.values.stream, str);

    if (str.equals("camera") || str.equals("camandmic")) {
      if (comport != null && comport.holdservo) {
        comport.camToPos(comport.camservopos);
      }
    }

    if (str.equals("stop") || str.equals("mic")) {
      if (comport != null && comport.holdservo)
        comport.releaseCameraServo();
//      state.delete(PlayerCommands.publish);
    }



    // messageplayer("streaming "+str,"stream",stream);
    messageGrabber("streaming " + stream, "stream " + stream);
    Util.log("streaming " + stream, this);
    new Thread(new Runnable() {
      public void run() {
        try {
          Thread.sleep(STREAM_CONNECT_DELAY);
          Collection<Set<IConnection>> concollection = getConnections();
          for (Set<IConnection> cc : concollection) {
            for (IConnection con : cc) {
              if (con instanceof IServiceCapableConnection
                  && con != grabber
                  && !(con == pendingplayer && !pendingplayerisnull)) {
                IServiceCapableConnection n = (IServiceCapableConnection) con;
                n.invoke("message", new Object[] {
                    "streaming " + stream, "green",
                    "stream", stream });
                Util.debug("message all players: streaming " + stream +" stream " +stream,this);
              }
            }
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }).start();
  }

  private void setGrabberVideoSoundMode(String str) {
   
    if (state.getBoolean(State.values.autodocking.name())) {
      messageplayer("command dropped, autodocking", null, null);
      return;
    }

    if (state.get(State.values.stream) == null) {
      messageplayer("stream control unavailable, server may be in setup mode", null, null);
      return;
    }
   
    IServiceCapableConnection sc = (IServiceCapableConnection) grabber;
    sc.invoke("videoSoundMode", new Object[] { str });
    state.set(State.values.videosoundmode.name(), str);
    Util.log("grabber video sound mode = "+str, this);
  }
 
  public void publish(String str) {
   
    if (state.getBoolean(State.values.autodocking.name())) {
      messageplayer("command dropped, autodocking", null, null);
      return;
    }

    if (state.get(State.values.stream== null) {
      messageplayer("stream control unavailable, server may be in setup mode", null, null);
      return;
    }

    try {
      // commands: camandmic camera mic stop
      if (grabber instanceof IServiceCapableConnection) {
        IServiceCapableConnection sc = (IServiceCapableConnection) grabber;
        String current = settings.readSetting("vset");
        String vals[] = (settings.readSetting(current)).split("_");
        int width = Integer.parseInt(vals[0]);
        int height = Integer.parseInt(vals[1]);
        int fps = Integer.parseInt(vals[2]);
        int quality = Integer.parseInt(vals[3]);
        sc.invoke("publish", new Object[] { str, width, height, fps, quality });
        // messageGrabber("stream "+str);
        messageplayer("command received: publish " + str, null, null);
//        state.set(PlayerCommands.publish, str);
//        state.set(State.values.stream, str);
        Util.log("publish: " + str, this);
      }
    } catch (NumberFormatException e) {
      Util.log("publish() " + e.getMessage());
      e.printStackTrace();
    }
  }

  public void muteROVMic() {
    String stream = state.get(State.values.stream);
    if (grabber == null) return;
    if (stream == null) return;
    if (grabber instanceof IServiceCapableConnection
        && (stream.equals("camandmic") || stream.equals("mic"))) {
      IServiceCapableConnection sc = (IServiceCapableConnection) grabber;
      sc.invoke("muteROVMic", new Object[] {});
    }
  }

  public void unmuteROVMic() {
    String stream = state.get(State.values.stream);
    if (grabber == null) return;
    if (stream == null) return;
    if (grabber instanceof IServiceCapableConnection
        && (stream.equals("camandmic") || stream.equals("mic"))) {
      IServiceCapableConnection sc = (IServiceCapableConnection) grabber;
      sc.invoke("unmuteROVMic", new Object[] {});
    }
  }

  private void muteROVMicOnMoveToggle() {
    if (state.getBoolean(State.values.muteOnROVmove)) {
      state.set(State.values.muteOnROVmove, false);
      settings.writeSettings("muteonrovmove", "false");
      messageplayer("mute ROV onmove off", null, null);
    } else {
      state.set(State.values.muteOnROVmove, true);
      settings.writeSettings("muteonrovmove", "true");
      messageplayer("mute ROV onmove on", null, null);
    }
  }

  /**  */
  public boolean frameGrab() {

     if(state.getBoolean(State.values.framegrabbusy.name()) ||
         !(state.get(State.values.stream).equals("camera") ||
             state.get(State.values.stream).equals("camandmic"))) {
       messageplayer("stream unavailable or framegrab busy, command dropped", null, null);
       return false;
     }

    if (grabber instanceof IServiceCapableConnection) {
      IServiceCapableConnection sc = (IServiceCapableConnection) grabber;
      sc.invoke("framegrab", new Object[] {});
      state.set(State.values.framegrabbusy.name(), true);
    }
    return true;
  }

  /** */
  public void frameGrabbed(ByteArray _RAWBitmapImage) { // , final String
                              // filename) {
    /*
    // Use functionality in org.red5.io.amf3.ByteArray to get parameters of
    // the ByteArray
    int BCurrentlyAvailable = _RAWBitmapImage.bytesAvailable();
    int BWholeSize = _RAWBitmapImage.length(); // Put the Red5 ByteArray
                          // into a standard Java
                          // array of bytes
    byte c[] = new byte[BWholeSize];
    _RAWBitmapImage.readBytes(c);

    // Transform the byte array into a java buffered image
    ByteArrayInputStream db = new ByteArrayInputStream(c);

    if (BCurrentlyAvailable > 0) {
      // System.out.println("The byte Array currently has "
      // + BCurrentlyAvailable + " bytes. The Buffer has " +
      // db.available());
      try {
        BufferedImage JavaImage = ImageIO.read(db);
        // Now lets try and write the buffered image out to a file
        if (JavaImage != null) {
          // If you sent a jpeg to the server, just change PNG to JPEG
          // and Red5ScreenShot.png to .jpeg
          ImageIO.write(JavaImage, "JPEG", new File(Settings.framefile));
          if (emailgrab) {
            emailgrab = false;
            new developer.SendMail("Oculus Screen Shot",
                "image attached", Settings.framefile, this);
          }
        }
      } catch (IOException e) {
        //log.info("Save_ScreenShot: Writing of screenshot failed " + e);
        System.out.println("OCULUS: IO Error " + e);
      }
    }
    */
    int BCurrentlyAvailable = _RAWBitmapImage.bytesAvailable();
    int BWholeSize = _RAWBitmapImage.length(); // Put the Red5 ByteArray
                          // into a standard Java
                          // array of bytes
    byte c[] = new byte[BWholeSize];
    _RAWBitmapImage.readBytes(c);
    if (BCurrentlyAvailable > 0) {
      state.set(State.values.framegrabbusy.name(), false);
//      FrameGrabHTTP.img = c;
//      AuthGrab.img = c;
      framegrabimg = c;
    }
  }

  private void messageplayer(String str, String status, String value) {
   
    if (player instanceof IServiceCapableConnection) {
      IServiceCapableConnection sc = (IServiceCapableConnection) player;
      sc.invoke("message", new Object[] { str, "green", status, value });
    }
   
    if(commandServer!=null) {
      if(str!=null){
        if(! str.equals("status check received")) // basic ping from client, ignore
        commandServer.sendToGroup(TelnetServer.MSGPLAYERTAG + " " + str);
      }
      if (status !=null) {
        commandServer.sendToGroup(TelnetServer.MSGPLAYERTAG + " <status> " + status + " " + value);
      }
    }
   
    if(str!=null){
      if(! str.equals("status check received")) // basic ping from client, ignore
        Util.debug("messageplayer: "+str+", "+status+", "+value, this);
    }

  }

  public void sendplayerfunction(String fn, String params) {
    if (player instanceof IServiceCapableConnection) {
      IServiceCapableConnection sc = (IServiceCapableConnection) player;
      sc.invoke("playerfunction", new Object[] { fn, params });
    }
    if(commandServer!=null) {
      commandServer.sendToGroup(TelnetServer.MSGPLAYERTAG + " javascript function: " + fn + " "+ params);
    }
  }

  public void saySpeech(String str) {
//    if (Settings.os.equals("linux")) {
//      messageplayer("unsupported in linux",null,null);
//      return;
//    }
    //Speech speech = new Speech();   // DONT initialize each time here, takes too long
    Util.debug("SPEECH sayspeech: "+str, this);
    if (Settings.os.equals("linux")) {
      try {
        String strarr[] = {"espeak",str};
        Runtime.getRuntime().exec(strarr);
      } catch (IOException e) { e.printStackTrace(); }
    }
    else { speech.mluv(str); }
   
  }

  private void getDrivingSettings() {
    if (loginRecords.isAdmin()) {
      String str = comport.speedslow + " " + comport.speedmed + " "
          + comport.nudgedelay + " " + comport.maxclicknudgedelay
          + " " + comport.clicknudgemomentummult + " "
          + comport.steeringcomp;
      sendplayerfunction("drivingsettingsdisplay", str);
    }
  }

  private void drivingSettingsUpdate(String str) {
    if (loginRecords.isAdmin()) {
      String comps[] = str.split(" ");
      comport.speedslow = Integer.parseInt(comps[0]);
      settings.writeSettings("speedslow",
          Integer.toString(comport.speedslow));
      comport.speedmed = Integer.parseInt(comps[1]);
      settings.writeSettings("speedmed",
          Integer.toString(comport.speedmed));
      comport.nudgedelay = Integer.parseInt(comps[2]);
      settings.writeSettings("nudgedelay",
          Integer.toString(comport.nudgedelay));
      comport.maxclicknudgedelay = Integer.parseInt(comps[3]);
      settings.writeSettings("maxclicknudgedelay",
          Integer.toString(comport.maxclicknudgedelay));
      comport.clicknudgemomentummult = Double.parseDouble(comps[4]);
      settings.writeSettings("clicknudgemomentummult",
          Double.toString(comport.clicknudgemomentummult));
      int n = Integer.parseInt(comps[5]);
      if (n > 255) {
        n = 255;
      }
      if (n < 0) {
        n = 0;
      }
      comport.steeringcomp = n;
      settings.writeSettings("steeringcomp",
          Integer.toString(comport.steeringcomp));
      comport.updateSteeringComp();
      String s = comport.speedslow + " " + comport.speedmed + " "
          + comport.nudgedelay + " " + comport.maxclicknudgedelay
          + " " + comport.clicknudgemomentummult + " "
          + (comport.steeringcomp - 128);
      messageplayer("driving settings set to: " + s, null, null);
    }
  }

  public void message(String str, String status, String value) {
    messageplayer(str, status, value);
  }

  private void getTiltSettings() {
    if (loginRecords.isAdmin()) {
      String str = comport.camservohoriz + " " + comport.camposmax + " "
          + comport.camposmin + " " + comport.maxclickcam + " "
          + settings.readSetting("videoscale");
      sendplayerfunction("tiltsettingsdisplay", str);
    }
  }

  private void tiltSettingsUpdate(String str) {
    if (loginRecords.isAdmin()) {
      String comps[] = str.split(" ");
      comport.camservohoriz = Integer.parseInt(comps[0]);
      settings.writeSettings("camservohoriz",
          Integer.toString(comport.camservohoriz));
      comport.camposmax = Integer.parseInt(comps[1]);
      settings.writeSettings("camposmax",
          Integer.toString(comport.camposmax));
      comport.camposmin = Integer.parseInt(comps[2]);
      settings.writeSettings("camposmin",
          Integer.toString(comport.camposmin));
      comport.maxclickcam = Integer.parseInt(comps[3]);
      settings.writeSettings("maxclickcam",
          Integer.toString(comport.maxclickcam));
      settings.writeSettings("videoscale", comps[4]);
      String s = comport.camservohoriz + " " + comport.camposmax + " "
          + comport.camposmin + " " + comport.maxclickcam + " " + comps[4];
      messageplayer("cam settings set to: " + s, "videoscale", comps[4]);
    }
  }

  private void tiltTest(String str) {
    comport.camToPos(Integer.parseInt(str));
    messageplayer("cam position: " + str, null, null);
  }

  private void moveMacroCancel() {
    if (state.getBoolean(State.values.docking.name())) {
      String str = "";
            if (!state.equals(State.values.dockstatus.name(), AutoDock.DOCKED)) {
                state.set(State.values.dockstatus, AutoDock.UNDOCKED);
                str += "dock " + AutoDock.UNDOCKED;
            }
      messageplayer("docking cancelled by movement", "multiple", str);
      state.set(State.values.docking, false);
    }
    if (state.getBoolean(State.values.sliding))
      comport.slidecancel();
  }

  private void cameraCommand(String str) {

    if (state.getBoolean(State.values.autodocking)) {
      messageplayer("command dropped, autodocking", null, null);
      return;
    }

    comport.camCommand(str);
    messageplayer("tilt command received: " + str, null, null);
    if (!str.equals("up") && !str.equals("down") && !str.equals("horiz")) {
      messageplayer(null, "cameratilt", camTiltPos());
    }
    if (str.equals("horiz")) {
      messageplayer(null, "cameratilt", "0");
    }
  }

  public String camTiltPos() {
    int n = comport.camservohoriz - comport.camservopos;
    n *= -1;
    String s = "";
    if (n > 0) {
      s = "+";
    }
    return s + Integer.toString(n);// + "&deg;";
  }

  private void statusCheck(String s) {
    if (initialstatuscalled == false || s.equals("intial")) {
      initialstatuscalled = true;
      battery.battStats();

      // build string
      String str = "";
      if (comport != null) {
        String spd = "FAST";
        if (state.getInteger(State.values.speed) == comport.speedmed)
          spd = "MED";
        if (state.getInteger(State.values.speed) == comport.speedslow)
          spd = "SLOW";

        String mov = "STOPPED";
        if (!state.getBoolean(State.values.motionenabled))
          mov = "DISABLED";
        if (state.getBoolean(State.values.moving))
          mov = "MOVING";
        str += " speed " + spd + " cameratilt " + camTiltPos()
            + " motion " + mov;
      }

      str += " vidctroffset " + settings.readSetting("vidctroffset");
      str += " rovvolume " + settings.readSetting(GUISettings.volume);
      str += " stream " + state.get(State.values.stream) + " selfstream stop";
      str += " pushtotalk " + settings.readSetting("pushtotalk");
      if (loginRecords.isAdmin())
        str += " admin true";
      if (state.get(State.values.dockstatus) != null) {
        str += " dock "+ state.get(State.values.dockstatus);
      }
      if (light.isConnected()) {
        str += " light " + light.spotLightBrightness();
        str += " floodlight " + state.get(State.values.floodlighton).toString();
      }
      if (settings.getBoolean(ManualSettings.developer.name()) == true) {
        str += " developer true";
      }

      String videoScale = settings.readSetting("videoscale");
      if (videoScale != null) {
        str += " videoscale " + videoScale;
      }

      messageplayer("status check received", "multiple", str.trim());

    } else {
      messageplayer("status check received", null, null);
    }

    if (s.equals("battcheck"))
      battery.battStats();
  }

  private void streamSettingsCustom(String str) {
    settings.writeSettings("vset", "vcustom");
    settings.writeSettings("vcustom", str);
    String s = "custom stream set to: " + str;
    if (!state.get(State.values.stream).equals("stop") && !state.getBoolean(State.values.autodocking)) {
      publish(state.get(State.values.stream));
      s += "<br>restarting stream";
    }
    messageplayer(s, null, null);
    Util.log("stream changed to " + str);
  }

  private void streamSettingsSet(String str) {
    Util.debug("streamSettingsSet: "+str, this);
    settings.writeSettings("vset", "v" + str);
    String s = "stream set to: " + str;
    if (!state.get(State.values.stream).equals("stop") && !state.getBoolean(State.values.autodocking)) {
      publish(state.get(State.values.stream));
      s += "<br>restarting stream";
    }
    messageplayer(s, null, null);
    Util.log("stream changed to " + str);
  }

  private String streamSettings() {
    String result = "";
    result += settings.readSetting("vset") + "_";
    result += settings.readSetting("vlow") + "_"
        + settings.readSetting("vmed") + "_";
    result += settings.readSetting("vhigh") + "_"
        + settings.readSetting("vfull") + "_";
    result += settings.readSetting("vcustom");
    return result;
  }

  public void restart() {
//    if (Settings.os.equals("linux")) {
//      messageplayer("unsupported in linux",null,null);
//      messageGrabber("unsupported in linux", null);
//      return;
//    }

    messageplayer("restarting server application", null, null);
    messageGrabber("restarting server application", null);
    if(commandServer!=null) { commandServer.sendToGroup(TelnetServer.TELNETTAG+" shutdown"); }
    File f;
//    f = new File(System.getenv("RED5_HOME") + "\\restart"); // windows
    f = new File(Settings.redhome + Settings.sep + "restart"); // windows & linux
    try {
      if (!f.exists()) {
        f.createNewFile();
      }
      if (Settings.os.equals("linux")) {
        Runtime.getRuntime().exec(Settings.redhome+Settings.sep+"red5-shutdown.sh");
      }
      else { Runtime.getRuntime().exec("red5-shutdown.bat"); }
     
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 
  public void quit() {
    messageplayer("server shutting down",null,null);
    if(commandServer!=null) { commandServer.sendToGroup(TelnetServer.TELNETTAG+" shutdown"); }
    try {
      if (Settings.os.equalsIgnoreCase("linux")) {
        Runtime.getRuntime().exec(Settings.redhome+Settings.sep+"red5-shutdown.sh");
      }
      else { Runtime.getRuntime().exec("red5-shutdown.bat"); }
    } catch (Exception e) { e.printStackTrace(); }
  }

  public void monitor(String str) {
    // uses nircmd.exe from http://www.nirsoft.net/utils/nircmd.html
//    if (Settings.os.equals("linux")) {
//      // messageplayer("unsupported in linux",null,null);
//      return;
//    }
    messageplayer("monitor " + str, null, null);
    str = str.trim();
    try {

      if (str.equals("on")) {
        if (Settings.os.equals("linux")) {
          str = "xset -display :0 dpms force on";
          Runtime.getRuntime().exec(str);
          str = "gnome-screensaver-command -d";
        }
        else { str = "cmd.exe /c start monitoron.bat"; }
      } else {
        if (Settings.os.equals("linux")) {
          str = "xset -display :0 dpms force off";
        }
        else { str = "nircmdc.exe monitor async_off"; }
      }
      Runtime.getRuntime().exec(str);
     
    } catch (Exception e) { e.printStackTrace(); }
  }

  public void move(String str) {

    if (str == null)
      return;

    if (str.equals("stop")) {
      if (state.getBoolean(State.values.autodocking))
        docker.autoDock("cancel");

      comport.stopGoing();
      moveMacroCancel();
      message("command received: " + str, "motion", "STOPPED");
      ///if (moves != null) moves.append("move " + str);
      return;
    }

    moveMacroCancel();

    // Issue#4 - use autodock cancel if needed
    if (state.getBoolean(State.values.autodocking)) {
      messageplayer("command dropped, autodocking", null, null);
      return;
    }

    if (!state.getBoolean(State.values.motionenabled)) {
      messageplayer("motion disabled (try un-dock)", "motion", "DISABLED");
      return;
    }

    if (str.equals("forward"))
      comport.goForward();
    else if (str.equals("backward"))
      comport.goBackward();
    else if (str.equals("right"))
      comport.turnRight();
    else if (str.equals("left"))
      comport.turnLeft();

    messageplayer("command received: " + str, "motion", "MOVING");
    ///if (moves != null) moves.append("move " + str);

  }

  public void nudge(String str) {

    if (str == null) return;
    if (!state.getBoolean(State.values.motionenabled)) {
      messageplayer("motion disabled", "motion", "disabled");
      return;
    }

    if (state.getBoolean(State.values.autodocking)) {
      messageplayer("command dropped, autodocking", null, null);
      return;
    }

    comport.nudge(str);
    messageplayer("command received: nudge" + str, null, null);
    //moves.append("nudge " + str);
    if (state.getBoolean(State.values.docking|| state.getBoolean(State.values.autodocking))
      moveMacroCancel();
  }

  private void motionEnableToggle() {
    if (state.getBoolean(State.values.motionenabled)) {
      state.set(State.values.motionenabled, "false");
      messageplayer("motion disabled", "motion", "disabled");
    } else {
      state.set(State.values.motionenabled, "true");
      messageplayer("motion enabled", "motion", "enabled");
    }
  }

 
  private void clickSteer(String str) {

    if (str == null)
      return;
    if (!state.getBoolean(State.values.motionenabled)) {
      messageplayer("motion disabled", "motion", "disabled");
      return;
    }

    if (state.getBoolean(State.values.autodocking)) {
      messageplayer("command dropped, autodocking", null, null);
      return;
    }

    //if (moves != null) moves.append("clicksteer " + str);

    int n = comport.clickSteer(str);
    if (n != 999) {
      messageplayer("received: clicksteer " + str, "cameratilt",
          camTiltPos());
    } else {
      messageplayer("received: clicksteer " + str, null, null);
    }

    moveMacroCancel();

  }

  /** */
  public void messageGrabber(String str, String status) {
    Util.debug("TO grabber flash: "+str+", "+status, this)

    if (grabber instanceof IServiceCapableConnection) {
      IServiceCapableConnection sc = (IServiceCapableConnection) grabber;
      sc.invoke("message", new Object[] { str, status });
    }
   
    if(commandServer!=null) {
      if(str!=null){
//        if(! str.equals("status check received"))
        commandServer.sendToGroup(TelnetServer.MSGGRABBERTAG + " " + str);
      }
      if (status !=null) {
        commandServer.sendToGroup(TelnetServer.MSGGRABBERTAG + " <status> " + status );
      }
    }
  }

  public String logintest(String user, String pass) {
    int i;
    String value = "";
    String returnvalue = null;
    if (user.equals("")) {
      i = 0;
      while (true) {
        value = settings.readSetting("pass" + i);
        if (value == null) {
          break;
        } else {
          if (value.equals(pass)) {
            returnvalue = settings.readSetting("user" + i);
            break;
          }
        }
        i++;
      }
    } else {
      i = 0;
      while (true) {
        value = settings.readSetting("user" + i);
        if (value == null) {
          break;
        } else {
          if (value.equals(user)) {
            if ((settings.readSetting("pass" + i)).equals(pass)) {
              returnvalue = user;
            }
            break;
          }
        }
        i++;
      }
    }
    return returnvalue;
  }

  /** */
  private void assumeControl(String user) {
    messageplayer("controls hijacked", "hijacked", user);
    // TODO: BRAD... telnet calls this and pukes ..
    if(player==null) return;
    if(pendingplayer==null) { pendingplayerisnull = true; return; }
     
    IConnection tmp = player;
    player = pendingplayer;
    pendingplayer = tmp;
    state.set(State.values.driver, user);
    String str = "connection connected streamsettings " + streamSettings();
    messageplayer(state.get(State.values.driver) + " connected to OCULUS", "multiple", str);
    str = state.get(State.values.driver) + " connected from: " + player.getRemoteAddress();
    Util.log("assumeControl(), " + str);
    messageGrabber(str, null);
    initialstatuscalled = false;
    pendingplayerisnull = true;
    loginRecords.beDriver();
   
    if (settings.getBoolean(GUISettings.loginnotify)) {
      saySpeech("lawg inn " + state.get(State.values.driver));
    }
  }

  /** */
  private void beAPassenger(String user) {
    String stream = state.get(State.values.stream);
    pendingplayerisnull = true;
    String str = user + " added as passenger";
    messageplayer(str, null, null);
    Util.log(str);
    messageGrabber(str, null);
    if (!stream.equals("stop")) {
      Collection<Set<IConnection>> concollection = getConnections();
      for (Set<IConnection> cc : concollection) {
        for (IConnection con : cc) {
          if (con instanceof IServiceCapableConnection
              && con != grabber && con != player) {
            IServiceCapableConnection sc = (IServiceCapableConnection) con;
            sc.invoke("message", new Object[] {
                "streaming " + stream, "green", "stream", stream });
          }
        }
      }
    }
    loginRecords.bePassenger(user);
   
    if (settings.getBoolean(GUISettings.loginnotify)) {
      saySpeech("passenger lawg inn " + user);
    }
  }

  private void playerBroadCast(String str) {
    if (player instanceof IServiceCapableConnection) {
      IServiceCapableConnection sc = (IServiceCapableConnection) player;
      if (!str.equals("off")) {
        String vals[] = (settings.readSetting("vself")).split("_");
        int width = Integer.parseInt(vals[0]);
        int height = Integer.parseInt(vals[1]);
        int fps = Integer.parseInt(vals[2]);
        int quality = Integer.parseInt(vals[3]);
        boolean pushtotalk = settings.getBoolean(GUISettings.pushtotalk);
        sc.invoke("publish", new Object[] { str, width, height, fps,
            quality, pushtotalk });
        // sc.invoke("publish", new Object[] { str, 160, 120, 8, 85 });
        new Thread(new Runnable() {
          public void run() {
            try {
              Thread.sleep(STREAM_CONNECT_DELAY);
            } catch (Exception e) {
              e.printStackTrace();
            }
            grabberPlayPlayer(1);
            state.set(State.values.driverstream, true);
          }
        }).start();
        if (str.equals("camera") || str.equals("camandmic")) {
          monitor("on");
          Util.debug("monitor on", this);
        }
        Util.log("OCULUS: player broadcast start", this);
      } else {
        sc.invoke("publish", new Object[] { "stop", null, null, null,null,null });
        grabberPlayPlayer(0);
        state.set(State.values.driverstream, false);
        Util.log("OCULUS: player broadcast stop",this);
      }
    }
  }

  private void grabberPlayPlayer(int nostreams) {
    if (grabber instanceof IServiceCapableConnection) {
      IServiceCapableConnection sc = (IServiceCapableConnection) grabber;
      sc.invoke("play", new Object[] { nostreams });
      // messageGrabber("playerbroadcast",Integer.toString(nostreams));
    }
  }

  private void account(String fn, String str) {
    if (fn.equals("password_update")) {
      passwordChange(state.get(State.values.driver), str);
    }
    if (loginRecords.isAdmin()){ // admin) {
      if (fn.equals("new_user_add")) {
        String message = "";
        Boolean oktoadd = true;
        String u[] = str.split(" ");
        if (!u[0].matches("\\w+")) {
          message += "error: username must be letters/numbers only ";
          oktoadd = false;
        }
        if (!u[1].matches("\\w+")) {
          message += "error: password must be letters/numbers only ";
          oktoadd = false;
        }
        int i = 0;
        String s;
        while (true) {
          s = settings.readSetting("user" + i);
          if (s == null) {
            break;
          }
          if ((s.toUpperCase()).equals((u[0]).toUpperCase())) {
            message += "ERROR: user name already exists ";
            oktoadd = false;
          }
          i++;
        }
        // add check for existing user, user loop below to get i while
        // you're at it
        if (oktoadd) {
          message += "added user " + u[0];
          settings.newSetting("user" + i, u[0]);
          String p = u[0] + salt + u[1];
          String encryptedPassword = passwordEncryptor
              .encryptPassword(p);
          settings.newSetting("pass" + i, encryptedPassword);
        }
        messageplayer(message, null, null);
      }
      if (fn.equals("user_list")) {
        int i = 1;
        String users = "";
        String u;
        while (true) {
          u = settings.readSetting("user" + i);
          if (u == null) {
            break;
          } else {
            users += u + " ";
          }
          i++;
        }
        sendplayerfunction("userlistpopulate", users);
      }
      if (fn.equals("delete_user")) {
        int i = 1;
        int usernum = -1;
        int maxusernum = -1;
        String[] allusers = new String[999];
        String[] allpasswords = new String[999];
        String u;
        while (true) { // read & store all users+passwords, note number
                // to be deleted, and max number
          u = settings.readSetting("user" + i);
          if (u == null) {
            maxusernum = i - 1;
            break;
          }
          if (u.equals(str)) {
            usernum = i;
          }
          allusers[i] = u;
          allpasswords[i] = settings.readSetting("pass" + i);
          i++;
        }
        if (usernum > 0) {
          i = usernum;
          while (i <= maxusernum) { // delete user to be delted + all
                        // after
            settings.deleteSetting("user" + i);
            settings.deleteSetting("pass" + i);
            i++;
          }
          i = usernum + 1;
          while (i <= maxusernum) { // shuffle remaining past deleted
                        // one, down one
            settings.newSetting("user" + (i - 1), allusers[i]);
            settings.newSetting("pass" + (i - 1), allpasswords[i]);
            i++;
          }
        }
        messageplayer(str + " deleted.", null, null);
      }
      if (fn.equals("extrauser_password_update")) {
        String s[] = str.split(" ");
        passwordChange(s[0], s[1]);
      }
      if (fn.equals("username_update")) {
        String u[] = str.split(" ");
        String message = "";
        Boolean oktoadd = true;
        if (!u[0].matches("\\w+")) {
          message += "error: username must be letters/numbers only ";
          oktoadd = false;
        }
        int i = 1;
        String s;
        while (true) {
          s = settings.readSetting("user" + i);
          if (s == null) {
            break;
          }
          if ((s.toUpperCase()).equals(u[0].toUpperCase())) {
            message += "error: user name already exists ";
            oktoadd = false;
          }
          i++;
        }
        String encryptedPassword = (passwordEncryptor
            .encryptPassword(state.get(State.values.driver) + salt + u[1])).trim();
        if (logintest(state.get(State.values.driver), encryptedPassword) == null) {
          message += "error: wrong password";
          oktoadd = false;
        }
        if (oktoadd) {
          message += "username changed to: " + u[0];
          messageplayer("username changed to: " + u[0], "user", u[0]);
          settings.writeSettings("user0", u[0]);
          state.set(State.values.driver, u[0]);
          String p = u[0] + salt + u[1];
          encryptedPassword = passwordEncryptor.encryptPassword(p);
          settings.writeSettings("pass0", encryptedPassword);
        } else {
          messageplayer(message, null, null);
        }
      }
    }
  }

  private void passwordChange(String user, String pass) {
    Util.debug(user+" "+pass, this);
    String message = "password updated";
    // pass = pass.replaceAll("\\s+$", "");
    if (pass.matches("\\w+")) {
      String p = user + salt + pass;
      String encryptedPassword = passwordEncryptor.encryptPassword(p);
      int i = 0;
      String u;
      while (true) {
        u = settings.readSetting("user" + i);
        if (u == null) {
          break;
        } else {
          if (u.equals(user)) {
            settings.writeSettings("pass" + i, encryptedPassword);
            break;
          }
        }
        i++;
      }
    } else {
      message = "error: password must be alpha-numeric with no spaces";
    }
    messageplayer(message, null, null);
  }

  private void disconnectOtherConnections() {
    if (loginRecords.isAdmin()) {
      int i = 0;
      Collection<Set<IConnection>> concollection = getConnections();
      for (Set<IConnection> cc : concollection) {
        for (IConnection con : cc) {
          if (con instanceof IServiceCapableConnection
              && con != grabber && con != player) {
            con.close();
            i++;
          }
        }
      }
      messageplayer(i + " passengers eliminated", null, null);
    }
  }

  private void chat(String str) {
    Collection<Set<IConnection>> concollection = getConnections();
    for (Set<IConnection> cc : concollection) {
      for (IConnection con : cc) {
        if (con instanceof IServiceCapableConnection && con != grabber
            && !(con == pendingplayer && !pendingplayerisnull)) {
          IServiceCapableConnection n = (IServiceCapableConnection) con;
          n.invoke("message", new Object[] { str, "yellow", null, null });
        }
      }
    }
    Util.log("chat: " + str);
    messageGrabber("<CHAT>" + str, null);
    if(str!=null) if (commandServer != null) {
      str = str.replaceAll("</?i>", "");
      commandServer.sendToGroup(TelnetServer.TELNETTAG+" chat from "+ str);
    }
  }

  private void showlog(String str) {
    int lines = 100; //default 
    if (!str.equals("")) { lines = Integer.parseInt(str); }
    String header = "latest "+ Integer.toString(lines+" line(s) from "+Settings.stdout+" :<br>";
    sendplayerfunction("showserverlog", header + Util.tail(lines));
  }

  private void saveAndLaunch(String str) {
    Util.log("saveandlaunch: " + str);
    String message = "";
    Boolean oktoadd = true;
    Boolean restartrequired = false;
    String user = null;
    String password = null;
    String httpport = null;
    String rtmpport = null;
    String skipsetup = null;

    String s[] = str.split(" ");
    for (int n = 0; n < s.length; n = n + 2) {
      // user password comport httpport rtmpport skipsetup developer
      if (s[n].equals("user")) {
        user = s[n + 1];
      }
      if (s[n].equals("password")) {
        password = s[n + 1];
      }
      if (s[n].equals("httpport")) {
        httpport = s[n + 1];
      }
      if (s[n].equals("rtmpport")) {
        rtmpport = s[n + 1];
      }
      if (s[n].equals("skipsetup")) {
        skipsetup = s[n + 1];
      }
    }

    // user & password
    if (user != null) {
      if (!user.matches("\\w+")) {
        message += "Error: username must be letters/numbers only ";
        oktoadd = false;
      }
      if (!password.matches("\\w+")) {
        message += "Error: password must be letters/numbers only ";
        oktoadd = false;
      }
      int i = 1; // admin user = 0, start from 1 (non admin)
      String name;
      while (true) {
        name = settings.readSetting("user" + i);
        if (name == null) {
          break;
        }
        if ((name.toUpperCase()).equals((user).toUpperCase())) {
          message += "Error: non-admin user name already exists ";
          oktoadd = false;
        }
        i++;
      }
      if (oktoadd) {
        String p = user + salt + password;
        String encryptedPassword = passwordEncryptor.encryptPassword(p);
        if (settings.readSetting("user0") == null) {
          settings.newSetting("user0", user);
          settings.newSetting("pass0", encryptedPassword);
        } else {
          settings.writeSettings("user0", user);
          settings.writeSettings("pass0", encryptedPassword);
        }
      }
    } else {
      if (settings.readSetting("user0") == null) {
        oktoadd = false;
        message += "Error: admin user not defined ";
      }
    }

    // httpport
    if (httpport != null) {
      if (!(settings.readRed5Setting("http.port")).equals(httpport)) {
        restartrequired = true;
      }
      settings.writeRed5Setting("http.port", httpport);
    }
    // rtmpport
    if (rtmpport != null) {
      if (!(settings.readRed5Setting("rtmp.port")).equals(rtmpport)) {
        restartrequired = true;
      }
      settings.writeRed5Setting("rtmp.port", rtmpport);
    }

    if (oktoadd) {
      // skipsetup
      if (skipsetup != null) {
        settings.writeSettings("skipsetup", skipsetup);
      }

      message = "launch server";
      if (restartrequired) {
        message = "shutdown";
        // admin = true;
        restart();
      }
    }
    messageGrabber(message, null);
  }

  /** */
  private void populateSettings() {
    settings.writeSettings("skipsetup", "no");
    String result = "populatevalues ";

    // username
    String str = settings.readSetting("user0");
    if (str != null)
      result += "username " + str + " ";

    // comport
    if (state.get(State.values.serialport) == null)
      result += "comport nil ";
    else
      result += "comport " + state.get(State.values.serialport) + " ";

    // lights
    if (state.get(State.values.lightport) == null)
      result += "lightport nil ";
    else
      result += "lightport " + state.get(State.values.lightport) + " ";

    // law and wan
    String lan = state.get(State.values.localaddress);
    if (lan == null) result += "lanaddress error ";
    else result += "lanaddress " + lan + " ";

    String wan = state.get(State.values.externaladdress);
    if (wan == null) result += "wanaddress error ";
    else result += "wanaddress " + wan + " ";

    // http port
    result += "httpport " + settings.readRed5Setting("http.port") + " ";

    // rtmp port
    result += "rtmpport " + settings.readRed5Setting("rtmp.port") + " ";

//    settings.writeFile(); // why is this here
    messageGrabber(result, null);
  }

  public void softwareUpdate(String str) {
//    if (Settings.os.equals("linux")) {
//      messageplayer("unsupported in linux",null,null);
//      return;
//    }

    if (str.equals("check")) {
      messageplayer("checking for new software...", null, null);
      Updater updater = new Updater();
      int currver = updater.getCurrentVersion();
      String fileurl = updater.checkForUpdateFile();
      int newver = updater.versionNum(fileurl);
      if (newver > currver) {
        String message = "New version available: v." + newver + "\n";
        if (currver == -1) {
          message += "Current software version unknown\n";
        } else {
          message += "Current software is v." + currver + "\n";
        }
        message += "Do you want to download and install?";
        messageplayer("new version available", "softwareupdate",
            message);
      } else {
        messageplayer("no new version available", null, null);
      }
    }
    if (str.equals("download")) {
      messageplayer("downloading software update...", null, null);
      new Thread(new Runnable() {
        public void run() {
          Updater up = new Updater();
          final String fileurl = up.checkForUpdateFile();
          Util.log("downloading url: " + fileurl);
          Downloader dl = new Downloader();
          if (dl.FileDownload(fileurl, "update.zip", "download")) {
            messageplayer("update download complete, unzipping...",
                null, null);

            // this is a blocking call
            if (dl.unzipFolder("download"+Settings.sep+"update.zip", "webapps"))
              messageplayer("done.", "softwareupdate",
                  "downloadcomplete");

            // not needed now is unpacked
            dl.deleteDir(new File(Settings.redhome+Settings.sep+"download"));

          } else {
            messageplayer("update download failed", null, null);
          }
        }
      }).start();
    }
    if (str.equals("versiononly")) {
      int currver = new Updater().getCurrentVersion();
      String msg = "";
      if (currver == -1)
        msg = "version unknown";
      else
        msg = "version: v." + currver;
      messageplayer(msg, null, null);
    }
  }

  public void factoryReset() {

    final String backup = "conf"+Settings.sep+"backup_oculus_settings.txt";

    // backup
    new File(Settings.settingsfile).renameTo(new File(backup));

    // delete it, build on startup
    new File(Settings.settingsfile).delete();

    restart();
  }
 
  private void setStreamActivityThreshold(String str) {
    String stream = state.get(State.values.stream);
    String val[] = str.split("\\D+");
    if (val.length != 2) { return; }
    Integer videoThreshold = Integer.parseInt(val[0]);
    Integer audioThreshold = Integer.parseInt(val[1]);
//    Util.debug("threshold vals: "+videoThreshold+","+audioThreshold, this);
    state.set(State.values.streamActivityThreshold.name(), str);
   
    if (videoThreshold != 0 || audioThreshold != 0) {
      if (state.get(State.values.videosoundmode.name()).equals("high")) {
        setGrabberVideoSoundMode("low"); // videosoundmode needs to be low to for activity threshold to work
        if (stream != null) {
          if (!stream.equals("stop")) { // if stream already running,
            publish(stream); // restart, in low mode
          }
        }
      }
     
      if (stream != null) {
        if (stream.equals("stop")) {
          if (audioThreshold == 0 && videoThreshold > 0) { publish("camera"); }
          else if (audioThreshold > 0 && videoThreshold == 0) { publish("mic"); }
          else { publish("camandmic"); }
        }
      }
      state.set(State.values.streamActivityThresholdEnabled.name(), System.currentTimeMillis());
    }
    else {
      state.delete(State.values.streamActivityThresholdEnabled);
      state.delete(State.values.streamActivityThreshold);
    }

    IServiceCapableConnection sc = (IServiceCapableConnection) grabber;
    sc.invoke("setActivityThreshold", new Object[] { videoThreshold, audioThreshold });
    messageplayer("stream activity set to: "+str, null, null);

  }
 
  private void streamActivityDetected(String str) {
    if (System.currentTimeMillis() > state.getLong(State.values.streamActivityThresholdEnabled) + 5000.0) {
      messageplayer("streamactivity: "+str, "streamactivity", str);
      setStreamActivityThreshold("0 0"); // disable
    }
  }
 

}
TOP

Related Classes of oculus.Application

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.