]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/fg_commands.cxx
apt.dat parser: clearer log and exception messages
[flightgear.git] / src / Main / fg_commands.cxx
index e936b3a383919cb1c65a1c88fc4d248db77ed45e..1e93a0b7b70e6cd32a12381c525c1646e5ab3f25 100644 (file)
@@ -23,7 +23,7 @@
 #include <simgear/structure/event_mgr.hxx>
 #include <simgear/sound/soundmgr_openal.hxx>
 #include <simgear/timing/sg_time.hxx>
-#include <simgear/io/HTTPMemoryRequest.hxx>
+#include <Network/RemoteXMLRequest.hxx>
 
 #include <FDM/flight.hxx>
 #include <GUI/gui.h>
@@ -37,8 +37,9 @@
 #include <Airports/xmlloader.hxx>
 #include <Network/HTTPClient.hxx>
 #include <Viewer/viewmgr.hxx>
-#include <Viewer/viewer.hxx>
+#include <Viewer/view.hxx>
 #include <Environment/presets.hxx>
+#include <Navaids/NavDataCache.hxx>
 
 #include "fg_init.hxx"
 #include "fg_io.hxx"
 # include <google/profiler.h>
 #endif
 
+#if defined(HAVE_QT)
+#include <GUI/QtLauncher.hxx>
+#endif
+
 using std::string;
 using std::ifstream;
 using std::ofstream;
@@ -209,6 +214,19 @@ do_reset (const SGPropertyNode * arg)
     return true;
 }
 
+
+/**
+ * Change aircraft
+ */
+static bool
+do_switch_aircraft (const SGPropertyNode * arg)
+{
+    fgSetString("/sim/aircraft", arg->getStringValue("aircraft"));
+    // start a reset
+    fgResetIdleState();
+    return true;
+}
+
 /**
  */
 static bool
@@ -234,7 +252,14 @@ do_replay (const SGPropertyNode * arg)
 static bool
 do_pause (const SGPropertyNode * arg)
 {
+    bool forcePause = arg->getBoolValue("force-pause", false );
+    bool forcePlay = arg->getBoolValue("force-play", false );
+
     bool paused = fgGetBool("/sim/freeze/master",true) || fgGetBool("/sim/freeze/clock",true);
+
+    if(forcePause) paused = false;
+    if(forcePlay) paused = true;
+
     if (paused && (fgGetInt("/sim/freeze/replay-state",0)>0))
     {
         do_replay(NULL);
@@ -245,15 +270,7 @@ do_pause (const SGPropertyNode * arg)
         fgSetBool("/sim/freeze/clock",!paused);
     }
   
-    SGPropertyNode_ptr args(new SGPropertyNode);
-    args->setStringValue("id", "sim-pause");
-    if (!paused && fgGetBool("/sim/view-name-popup")) {
-      args->setStringValue("label", "Simulation is paused");
-      globals->get_commands()->execute("show-message", args);
-    } else {
-      globals->get_commands()->execute("clear-message", args);
-    }
-  
+    syncPausePopupState();
     return true;
 }
 
@@ -266,17 +283,19 @@ do_pause (const SGPropertyNode * arg)
 static bool
 do_load (const SGPropertyNode * arg)
 {
-    string file = arg->getStringValue("file", "fgfs.sav");
-    if (file.size() < 4 || file.substr(file.size() - 4) != ".sav")
-        file += ".sav";
+    SGPath file(arg->getStringValue("file", "fgfs.sav"));
+
+    if (file.extension() != "sav")
+        file.concat(".sav");
 
-    if (!fgValidatePath(file.c_str(), false)) {
+    std::string validated_path = fgValidatePath(file, false);
+    if (validated_path.empty()) {
         SG_LOG(SG_IO, SG_ALERT, "load: reading '" << file << "' denied "
                 "(unauthorized access)");
         return false;
     }
 
-    ifstream input(file.c_str());
+    ifstream input(validated_path.c_str());
     if (input.good() && fgLoadFlight(input)) {
         input.close();
         SG_LOG(SG_INPUT, SG_INFO, "Restored flight from " << file);
@@ -297,11 +316,13 @@ do_load (const SGPropertyNode * arg)
 static bool
 do_save (const SGPropertyNode * arg)
 {
-    string file = arg->getStringValue("file", "fgfs.sav");
-    if (file.size() < 4 || file.substr(file.size() - 4) != ".sav")
-        file += ".sav";
+    SGPath file(arg->getStringValue("file", "fgfs.sav"));
 
-    if (!fgValidatePath(file.c_str(), false)) {
+    if (file.extension() != "sav")
+        file.concat(".sav");
+
+    std::string validated_path = fgValidatePath(file, true);
+    if (validated_path.empty()) {
         SG_LOG(SG_IO, SG_ALERT, "save: writing '" << file << "' denied "
                 "(unauthorized access)");
         return false;
@@ -309,7 +330,7 @@ do_save (const SGPropertyNode * arg)
 
     bool write_all = arg->getBoolValue("write-all", false);
     SG_LOG(SG_INPUT, SG_INFO, "Saving flight");
-    ofstream output(file.c_str());
+    ofstream output(validated_path.c_str());
     if (output.good() && fgSaveFlight(output, write_all)) {
         output.close();
         SG_LOG(SG_INPUT, SG_INFO, "Saved flight to " << file);
@@ -967,6 +988,21 @@ do_open_browser (const SGPropertyNode * arg)
     return openBrowser(path);
 }
 
+static bool
+do_open_launcher(const SGPropertyNode *)
+{
+#if defined(HAVE_QT)
+    bool ok = flightgear::runInAppLauncherDialog();
+    if (ok) {
+        // start a full reset
+        fgResetIdleState();
+    }
+    return ok;
+#else
+    return false;
+#endif
+}
+
 /**
  * Apply a value in the active XML-configured dialog.
  *
@@ -1025,46 +1061,6 @@ do_add_model (const SGPropertyNode * arg)
     return true;
 }
 
-/**
- * Built-in command: play an audio message (i.e. a wav file) This is
- * fire and forget.  Call this once per message and it will get dumped
- * into a queue.  Messages are played sequentially so they do not
- * overlap.
- */
-static bool
-do_play_audio_sample (const SGPropertyNode * arg)
-{
-    SGSoundMgr *smgr = globals->get_soundmgr();
-    if (!smgr) {
-        SG_LOG(SG_GENERAL, SG_WARN, "play-audio-sample: sound-manager not running");
-        return false;
-    }
-  
-    string path = arg->getStringValue("path");
-    string file = arg->getStringValue("file");
-    float volume = arg->getFloatValue("volume");
-    // cout << "playing " << path << " / " << file << endl;
-    try {
-        FGSampleQueue *queue = globals->get_chatter_queue();
-        if ( !queue ) {
-            queue = new FGSampleQueue(smgr, "chatter");
-            queue->tie_to_listener();
-            globals->set_chatter_queue(queue);
-        }
-
-        SGSoundSample *msg = new SGSoundSample(file.c_str(), path);
-        msg->set_volume( volume );
-        queue->add( msg );
-
-        return true;
-
-    } catch (const sg_io_exception&) {
-        SG_LOG(SG_GENERAL, SG_ALERT, "play-audio-sample: "
-                "failed to load" << path << '/' << file);
-        return false;
-    }
-}
-
 /**
  * Built-in command: commit presets (read from in /sim/presets/)
  */
@@ -1152,9 +1148,10 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
         }
     }
     
-    if (!fgValidatePath(file.c_str(), false)) {
+    std::string validated_path = fgValidatePath(file, false);
+    if (validated_path.empty()) {
         SG_LOG(SG_IO, SG_ALERT, "loadxml: reading '" << file.str() << "' denied "
-                "(unauthorized access)");
+                "(unauthorized directory - authorization no longer follows symlinks; to authorize reading additional directories, add them to --fg-aircraft)");
         return false;
     }
 
@@ -1165,7 +1162,7 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
         targetnode = const_cast<SGPropertyNode *>(arg)->getNode("data", true);
 
     try {
-        readProperties(file.c_str(), targetnode, true);
+        readProperties(validated_path.c_str(), targetnode, true);
     } catch (const sg_exception &e) {
         SG_LOG(SG_IO, SG_WARN, "loadxml: " << e.getFormattedMessage());
         return false;
@@ -1174,70 +1171,6 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
     return true;
 }
 
-class RemoteXMLRequest:
-  public simgear::HTTP::MemoryRequest
-{
-public:
-    SGPropertyNode_ptr _complete;
-    SGPropertyNode_ptr _status;
-    SGPropertyNode_ptr _failed;
-    SGPropertyNode_ptr _target;
-
-    RemoteXMLRequest(const std::string& url, SGPropertyNode* targetNode) :
-      simgear::HTTP::MemoryRequest(url),
-      _target(targetNode)
-    {
-    }
-    
-    void setCompletionProp(SGPropertyNode_ptr p)
-    {
-        _complete = p;
-    }
-    
-    void setStatusProp(SGPropertyNode_ptr p)
-    {
-        _status = p;
-    }
-    
-    void setFailedProp(SGPropertyNode_ptr p)
-    {
-        _failed = p;
-    }
-    
-protected:
-    
-    virtual void onFail()
-    {
-        SG_LOG(SG_IO, SG_INFO, "network level failure in RemoteXMLRequest");
-        if (_failed) {
-            _failed->setBoolValue(true);
-        }
-    }
-    
-    virtual void onDone()
-    {
-        int response = responseCode();
-        bool failed = false;
-        if (response == 200) {
-            try {
-                const char* buffer = responseBody().c_str();
-                readProperties(buffer, responseBody().size(), _target, true);
-            } catch (const sg_exception &e) {
-                SG_LOG(SG_IO, SG_WARN, "parsing XML from remote, failed: " << e.getFormattedMessage());
-                failed = true;
-                response = 406; // 'not acceptable', anything better?
-            }
-        } else {
-            failed = true;
-        }
-    // now the response data is output, signal Nasal / listeners
-        if (_complete) _complete->setBoolValue(true);
-        if (_status) _status->setIntValue(response);
-        if (_failed && failed) _failed->setBoolValue(true);
-    }
-};
-
-
 static bool
 do_load_xml_from_url(const SGPropertyNode * arg)
 {
@@ -1298,9 +1231,10 @@ do_save_xml_from_proptree(const SGPropertyNode * arg)
     if (file.extension() != "xml")
         file.concat(".xml");
 
-    if (!fgValidatePath(file.c_str(), true)) {
+    std::string validated_path = fgValidatePath(file, true);
+    if (validated_path.empty()) {
         SG_LOG(SG_IO, SG_ALERT, "savexml: writing to '" << file.str() << "' denied "
-                "(unauthorized access)");
+                "(unauthorized directory - authorization no longer follows symlinks)");
         return false;
     }
 
@@ -1313,7 +1247,7 @@ do_save_xml_from_proptree(const SGPropertyNode * arg)
         return false;
 
     try {
-        writeProperties (file.c_str(), sourcenode, true);
+        writeProperties (validated_path.c_str(), sourcenode, true);
     } catch (const sg_exception &e) {
         SG_LOG(SG_IO, SG_WARN, "savexml: " << e.getFormattedMessage());
         return false;
@@ -1407,6 +1341,38 @@ do_profiler_stop(const SGPropertyNode *arg)
 }
 
 
+static bool
+do_set_scenery_paths(const SGPropertyNode* arg)
+{
+  globals->clear_fg_scenery();
+  
+  std::string terrasyncPath(fgGetString("/sim/terrasync/scenery-dir"));
+  bool seenTerrasyncPath = false;
+  
+  simgear::PropertyList paths = arg->getChildren("path");
+  for (size_t i = 0; i < paths.size(); ++i) {
+    std::string s = paths[i]->getStringValue();
+    if (s == terrasyncPath) {
+      seenTerrasyncPath = true;
+    }
+    
+    globals->append_fg_scenery(s);
+  }
+  
+  if (fgGetBool("/sim/terrasync/enabled") && !seenTerrasyncPath) {
+    globals->append_fg_scenery(terrasyncPath);
+  }
+  
+  if (paths.empty()) {
+    // no scenery paths set *at all*, use the data in FG_ROOT
+    SGPath root(globals->get_fg_root());
+    root.append("Scenery");
+    globals->append_fg_scenery(root.str());
+  }
+
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////////
 // Command setup.
 ////////////////////////////////////////////////////////////////////////
@@ -1427,6 +1393,7 @@ static struct {
     { "exit", do_exit },
     { "reset", do_reset },
     { "reposition", do_reposition },
+    { "switch-aircraft", do_switch_aircraft },
     { "pause", do_pause },
     { "load", do_load },
     { "save", do_save },
@@ -1463,10 +1430,10 @@ static struct {
     { "open-browser", do_open_browser },
     { "gui-redraw", do_gui_redraw },
     { "add-model", do_add_model },
-    { "play-audio-sample", do_play_audio_sample },
     { "presets-commit", do_presets_commit },
     { "log-level", do_log_level },
     { "replay", do_replay },
+    { "open-launcher", do_open_launcher },
     /*
     { "decrease-visibility", do_decrease_visibility },
     { "increase-visibility", do_increase_visibility },
@@ -1481,7 +1448,8 @@ static struct {
     { "print-visible-scene", do_print_visible_scene_info },
     { "reload-shaders", do_reload_shaders },
     { "reload-materials", do_materials_reload },
-
+    { "set-scenery-paths", do_set_scenery_paths },
+  
     { "profiler-start", do_profiler_start },
     { "profiler-stop",  do_profiler_stop },