diff --git a/.gitignore b/.gitignore index 09efb2d3f..187c7e027 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,6 @@ CMakeFiles CMakeCache.txt Makefile cmake*.cmake -openmw Ogre.log ogre.cfg build diff --git a/CMakeLists.txt b/CMakeLists.txt index eed7eea42..0a640dab3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,7 +180,8 @@ set(OPENMW_LIBS_HEADER) # Platform specific if (WIN32) -set(PLATFORM_INCLUDE_DIR "platform") + set(PLATFORM_INCLUDE_DIR "platform") + add_definitions(-DBOOST_ALL_NO_LIB) else (WIN32) set(PLATFORM_INCLUDE_DIR "") endif (WIN32) @@ -188,10 +189,11 @@ endif (WIN32) # Dependencies find_package(OGRE REQUIRED) -find_package(Boost REQUIRED COMPONENTS system filesystem program_options) +find_package(Boost REQUIRED COMPONENTS system filesystem program_options thread) find_package(OIS REQUIRED) include_directories("." - ${OGRE_INCLUDE_DIR} ${OIS_INCLUDE_DIR} ${Boost_INCLUDE_DIR} + ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre + ${OIS_INCLUDE_DIR} ${Boost_INCLUDE_DIR} ${PLATFORM_INCLUDE_DIR} ${CMAKE_HOME_DIRECTORY}/extern/caelum/include) link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR}) diff --git a/apps/clientconsole/CMakeLists.txt b/apps/clientconsole/CMakeLists.txt index f73610863..f030d9024 100644 --- a/apps/clientconsole/CMakeLists.txt +++ b/apps/clientconsole/CMakeLists.txt @@ -1,5 +1,3 @@ -project(clientconsole) -find_package(Boost REQUIRED COMPONENTS system) -link_directories(${Boost_LIBRARY_DIRS}) + add_executable(clientconsole client.cpp) target_link_libraries(clientconsole ${Boost_LIBRARIES}) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index e9c9a7074..12f585833 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -66,15 +66,15 @@ void OMW::Engine::processCommands() OMW::Engine::Engine() : mDebug (false), mVerboseScripts (false), mNewGame (false), mScriptManager (0), - mScriptContext (0) -{ - mspCommandServer.reset( - new OMW::CommandServer::Server(&mCommandQueue, kCommandServerPort)); + mScriptContext (0), mEnableCommandServer (false) +{ } OMW::Engine::~Engine() { -// mspCommandServer->stop(); + if (mspCommandServer.get()) + mspCommandServer->stop(); + delete mEnvironment.mWorld; delete mEnvironment.mSoundManager; delete mEnvironment.mGlobalScripts; @@ -142,6 +142,11 @@ void OMW::Engine::enableDebugMode() { mDebug = true; } + +void OMW::Engine::enableCommandServer() +{ + mEnableCommandServer = true; +} void OMW::Engine::enableVerboseScripts() { @@ -203,8 +208,14 @@ void OMW::Engine::go() MWInput::MWInputManager input(mOgre, mEnvironment.mWorld->getPlayerPos(), mDebug); // Launch the console server - std::cout << "Starting command server on port " << kCommandServerPort << std::endl; - mspCommandServer->start(); + if (mEnableCommandServer) + { + std::cout << "Starting command server on port " << kCommandServerPort << std::endl; + mspCommandServer.reset(new OMW::CommandServer::Server(&mCommandQueue, kCommandServerPort)); + mspCommandServer->start(); + } + else + std::cout << "Command server disabled" << std::endl; std::cout << "\nStart! Press Q/ESC or close window to exit.\n"; diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index f0b46c6ab..cf982ad0e 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -52,6 +52,7 @@ namespace OMW bool mNewGame; TsDeque mCommandQueue; + bool mEnableCommandServer; std::auto_ptr mspCommandServer; MWWorld::Environment mEnvironment; @@ -98,6 +99,10 @@ namespace OMW /// - non-exclusive input void enableDebugMode(); + /// Enable the command server so external apps can send commands to the console. + /// Must be set before go(). + void enableCommandServer(); + /// Enable verbose script output void enableVerboseScripts(); diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 70530c2ef..63ea7e427 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -32,6 +32,7 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) ( "debug", "debug mode" ) ( "script-verbose", "verbose script output" ) ( "new-game", "activate char gen/new game mechanics" ) + ( "disable-command-server", "turn off the command server" ) ; bpo::variables_map variables; @@ -62,6 +63,9 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) if (variables.count ("new-game")) engine.setNewGame(); + + if (variables.count("disable-command-server") == 0) + engine.enableCommandServer(); return true; } diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index d8a800597..31b351cb5 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -111,7 +111,7 @@ namespace MWScript void InterpreterContext::setGlobalLong (const std::string& name, int value) { // a global long is internally a float. - float value2 = value; + float value2 = float(value); mEnvironment.mWorld->getGlobalVariable (name) = *reinterpret_cast (&value2); diff --git a/apps/openmw/mwworld/environment.hpp b/apps/openmw/mwworld/environment.hpp index 1d8a59c9e..fe0fa47e7 100644 --- a/apps/openmw/mwworld/environment.hpp +++ b/apps/openmw/mwworld/environment.hpp @@ -16,10 +16,11 @@ namespace MWWorld class World; ///< Collection of script-accessable sub-systems - struct Environment + class Environment { - Environment() : mWorld (0), mSoundManager (0), mGlobalScripts (0), mFrameDuration (0) {} - + public: + Environment() : mWorld (0), mSoundManager (0), mGlobalScripts (0), mFrameDuration (0) {} + World *mWorld; MWSound::SoundManager *mSoundManager; MWScript::GlobalScripts *mGlobalScripts; diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 22bba6c53..01f03b641 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -166,8 +166,9 @@ namespace MWWorld iter->second->show(); // Optionally enable the sky -// if (mEnableSky) -// mpSkyManager = MWRender::SkyManager::create(renderer.getWindow(), mScene.getCamera()); + ///\todo FIXME + if (false) + mSkyManager = MWRender::SkyManager::create(renderer.getWindow(), mScene.getCamera()); } diff --git a/components/commandserver/server.cpp b/components/commandserver/server.cpp index c8bf34bfa..53d7b2bf2 100755 --- a/components/commandserver/server.cpp +++ b/components/commandserver/server.cpp @@ -1,10 +1,8 @@ - #include "server.hpp" +#include "libs/platform/strings.h" using boost::asio::ip::tcp; -#include - // // Namespace for containing implementation details that the // rest of OpenMW doesn't need to worry about @@ -55,6 +53,7 @@ namespace OMW { namespace CommandServer { namespace Detail { /// void Connection::stop() { + mSocket.shutdown(boost::asio::socket_base::shutdown_both); mSocket.close(); mpThread->join(); } @@ -105,7 +104,7 @@ namespace OMW { namespace CommandServer { namespace Detail { bDone = true; } else - throw str_exception("Unexpected header!"); + throw std::runtime_error("Unexpected header!"); } else bDone = true; @@ -120,12 +119,12 @@ namespace OMW { namespace CommandServer { using namespace Detail; Server::Server (Deque* pCommandQueue, const int port) - : mAcceptor (mIOService, tcp::endpoint(tcp::v4(), port)) + : mPort (port) + , mAcceptor (mIOService, tcp::endpoint(tcp::v4(), mPort)) , mbStopping (false) , mpCommandQueue (pCommandQueue) { } - void Server::start() { @@ -133,8 +132,41 @@ namespace OMW { namespace CommandServer { mpThread = new boost::thread(boost::bind(&Server::threadMain, this)); } + // + // Helper function - see Server::stop() + // + static void connectAndDisconnect (int port) + { + char portString[64]; + snprintf(portString, 64, "%d", port); + + boost::asio::io_service ioService; + tcp::resolver resolver(ioService); + tcp::resolver::query query("localhost", portString); + tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); + tcp::resolver::iterator end; + + tcp::socket socket(ioService); + boost::system::error_code error = boost::asio::error::host_not_found; + while (error && endpoint_iterator != end) + { + socket.close(); + socket.connect(*endpoint_iterator++, error); + } + + socket.close(); + ioService.stop(); + } + void Server::stop() { + // Boost.Asio doesn't have a way to cancel the blocking accept() call + // in the listening thread. Therefore, set an internal flag to let + // the server know it's stopping and then unblock it via a do-nothing + // connect/disconnect. + mbStopping = true; + connectAndDisconnect(mPort); + // (1) Stop accepting new connections // (2) Wait for the listener thread to finish mAcceptor.close(); @@ -144,7 +176,6 @@ namespace OMW { namespace CommandServer { // open connections { boost::mutex::scoped_lock lock(mConnectionsMutex); - mbStopping = true; for (ConnectionSet::iterator it = mConnections.begin(); it != mConnections.end(); ++it) @@ -186,7 +217,7 @@ namespace OMW { namespace CommandServer { std::auto_ptr spConnection(new Connection(mAcceptor.io_service(), this)); boost::system::error_code ec; mAcceptor.accept(spConnection->socket(), ec); - if (!ec) + if (!ec && !mbStopping) { boost::mutex::scoped_lock lock(mConnectionsMutex); mConnections.insert(spConnection.get()); diff --git a/components/commandserver/server.hpp b/components/commandserver/server.hpp index b53e0f23a..3d7665a14 100755 --- a/components/commandserver/server.hpp +++ b/components/commandserver/server.hpp @@ -45,6 +45,7 @@ namespace OMW { namespace CommandServer void threadMain(); // Objects used to set up the listening server + int mPort; boost::asio::io_service mIOService; boost::asio::ip::tcp::acceptor mAcceptor; boost::thread* mpThread; diff --git a/components/esm/loadscpt.hpp b/components/esm/loadscpt.hpp index 6025e528c..aa189c888 100644 --- a/components/esm/loadscpt.hpp +++ b/components/esm/loadscpt.hpp @@ -9,8 +9,9 @@ namespace ESM { * Script definitions */ -struct Script +class Script { +public: struct SCHDstruct { /* Script name. diff --git a/components/esm_store/cell_store.hpp b/components/esm_store/cell_store.hpp index 114a12e78..e1637b364 100644 --- a/components/esm_store/cell_store.hpp +++ b/components/esm_store/cell_store.hpp @@ -98,7 +98,7 @@ namespace ESMS CellRefList ingreds; CellRefList creatureLists; CellRefList itemLists; - CellRefList lights; + CellRefList lights; CellRefList lockpicks; CellRefList miscItems; CellRefList npcs; diff --git a/extern/caelum/CMakeLists.txt b/extern/caelum/CMakeLists.txt index 4226d8d4a..b95b3fd8c 100755 --- a/extern/caelum/CMakeLists.txt +++ b/extern/caelum/CMakeLists.txt @@ -1,7 +1,14 @@ project(Caelum) +IF(MSVC) + add_definitions("-D_SCL_SECURE_NO_WARNINGS /wd4305 /wd4244" ) +ENDIF(MSVC) + ADD_DEFINITIONS(-DCAELUM_LIB) -INCLUDE_DIRECTORIES( ${CMAKE_HOME_DIRECTORY}/extern/caelum/include ) +INCLUDE_DIRECTORIES( + ${CMAKE_HOME_DIRECTORY}/extern/caelum/include + ${OGRE_INCLUDE_DIR}/Ogre + ) file(GLOB_RECURSE CAELUM_SRC src/*) file(GLOB_RECURSE CAELUM_HDR include/*)