diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index f062be875..0db0042e6 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -44,6 +44,7 @@ include/VersionInfoFactory.h include/Virtual.h include/RemoteClient.h include/RemoteServer.h +include/RemoteTools.h ) SET(MAIN_HEADERS_WINDOWS @@ -63,6 +64,7 @@ VersionInfoFactory.cpp Virtual.cpp RemoteClient.cpp RemoteServer.cpp +RemoteTools.cpp ) SET(MAIN_SOURCES_WINDOWS diff --git a/library/RemoteServer.cpp b/library/RemoteServer.cpp index e7ab0cbad..ae8b0024c 100644 --- a/library/RemoteServer.cpp +++ b/library/RemoteServer.cpp @@ -46,6 +46,8 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "RemoteServer.h" +#include "RemoteTools.h" + #include "PassiveSocket.h" #include "PluginManager.h" #include "MiscUtils.h" @@ -65,77 +67,6 @@ using dfproto::CoreTextNotification; using dfproto::CoreTextFragment; using google::protobuf::MessageLite; -CoreService::CoreService() { - suspend_depth = 0; - - // These 2 methods must be first, so that they get id 0 and 1 - addMethod("BindMethod", &CoreService::BindMethod); - addMethod("RunCommand", &CoreService::RunCommand); - - // Add others here: - addMethod("CoreSuspend", &CoreService::CoreSuspend); - addMethod("CoreResume", &CoreService::CoreResume); -} - -CoreService::~CoreService() -{ - while (suspend_depth-- > 0) - Core::getInstance().Resume(); -} - -command_result CoreService::BindMethod(color_ostream &stream, - const dfproto::CoreBindRequest *in, - dfproto::CoreBindReply *out) -{ - ServerFunctionBase *fn = connection()->findFunction(stream, in->plugin(), in->method()); - - if (!fn) - { - stream.printerr("RPC method not found: %s::%s\n", - in->plugin().c_str(), in->method().c_str()); - return CR_FAILURE; - } - - if (fn->p_in_template->GetTypeName() != in->input_msg() || - fn->p_out_template->GetTypeName() != in->output_msg()) - { - stream.printerr("Requested wrong signature for RPC method: %s::%s\n", - in->plugin().c_str(), in->method().c_str()); - return CR_FAILURE; - } - - out->set_assigned_id(fn->getId()); - return CR_OK; -} - -command_result CoreService::RunCommand(color_ostream &stream, - const dfproto::CoreRunCommandRequest *in) -{ - std::string cmd = in->command(); - std::vector args; - for (int i = 0; i < in->arguments_size(); i++) - args.push_back(in->arguments(i)); - - return Core::getInstance().plug_mgr->InvokeCommand(stream, cmd, args); -} - -command_result CoreService::CoreSuspend(color_ostream &stream, const EmptyMessage*, IntMessage *cnt) -{ - Core::getInstance().Suspend(); - cnt->set_value(++suspend_depth); - return CR_OK; -} - -command_result CoreService::CoreResume(color_ostream &stream, const EmptyMessage*, IntMessage *cnt) -{ - if (suspend_depth <= 0) - return CR_WRONG_USAGE; - - Core::getInstance().Resume(); - cnt->set_value(--suspend_depth); - return CR_OK; -} - RPCService::RPCService() { owner = NULL; diff --git a/library/RemoteTools.cpp b/library/RemoteTools.cpp new file mode 100644 index 000000000..a3e3c9e4d --- /dev/null +++ b/library/RemoteTools.cpp @@ -0,0 +1,133 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2011 Petr Mrázek + +A thread-safe logging console with a line editor for windows. + +Based on linenoise win32 port, +copyright 2010, Jon Griffiths . +All rights reserved. +Based on linenoise, copyright 2010, Salvatore Sanfilippo . +The original linenoise can be found at: http://github.com/antirez/linenoise + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Redis nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "RemoteTools.h" +#include "PluginManager.h" +#include "MiscUtils.h" + +#include +#include +#include + +#include + +using namespace DFHack; + +using dfproto::CoreTextNotification; +using dfproto::CoreTextFragment; +using google::protobuf::MessageLite; + +CoreService::CoreService() { + suspend_depth = 0; + + // These 2 methods must be first, so that they get id 0 and 1 + addMethod("BindMethod", &CoreService::BindMethod); + addMethod("RunCommand", &CoreService::RunCommand); + + // Add others here: + addMethod("CoreSuspend", &CoreService::CoreSuspend); + addMethod("CoreResume", &CoreService::CoreResume); +} + +CoreService::~CoreService() +{ + while (suspend_depth-- > 0) + Core::getInstance().Resume(); +} + +command_result CoreService::BindMethod(color_ostream &stream, + const dfproto::CoreBindRequest *in, + dfproto::CoreBindReply *out) +{ + ServerFunctionBase *fn = connection()->findFunction(stream, in->plugin(), in->method()); + + if (!fn) + { + stream.printerr("RPC method not found: %s::%s\n", + in->plugin().c_str(), in->method().c_str()); + return CR_FAILURE; + } + + if (fn->p_in_template->GetTypeName() != in->input_msg() || + fn->p_out_template->GetTypeName() != in->output_msg()) + { + stream.printerr("Requested wrong signature for RPC method: %s::%s\n", + in->plugin().c_str(), in->method().c_str()); + return CR_FAILURE; + } + + out->set_assigned_id(fn->getId()); + return CR_OK; +} + +command_result CoreService::RunCommand(color_ostream &stream, + const dfproto::CoreRunCommandRequest *in) +{ + std::string cmd = in->command(); + std::vector args; + for (int i = 0; i < in->arguments_size(); i++) + args.push_back(in->arguments(i)); + + return Core::getInstance().plug_mgr->InvokeCommand(stream, cmd, args); +} + +command_result CoreService::CoreSuspend(color_ostream &stream, const EmptyMessage*, IntMessage *cnt) +{ + Core::getInstance().Suspend(); + cnt->set_value(++suspend_depth); + return CR_OK; +} + +command_result CoreService::CoreResume(color_ostream &stream, const EmptyMessage*, IntMessage *cnt) +{ + if (suspend_depth <= 0) + return CR_WRONG_USAGE; + + Core::getInstance().Resume(); + cnt->set_value(--suspend_depth); + return CR_OK; +} diff --git a/library/include/Core.h b/library/include/Core.h index f4c2c2ae7..10b95a47d 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -142,7 +142,7 @@ namespace DFHack Core(); - class Private; + struct Private; Private *d; bool Init(); diff --git a/library/include/RemoteServer.h b/library/include/RemoteServer.h index 274d2bcda..7e45ba560 100644 --- a/library/include/RemoteServer.h +++ b/library/include/RemoteServer.h @@ -34,7 +34,10 @@ class CSimpleSocket; namespace DFHack { - class DFHACK_EXPORT ServerConnection; + class Plugin; + class CoreService; + class ServerConnection; + class DFHACK_EXPORT RPCService; class DFHACK_EXPORT ServerFunctionBase : public RPCFunctionBase { @@ -130,8 +133,6 @@ namespace DFHack function_type fptr; }; - class Plugin; - class DFHACK_EXPORT RPCService { friend class ServerConnection; friend class Plugin; @@ -190,24 +191,7 @@ namespace DFHack } }; - class CoreService : public RPCService { - int suspend_depth; - public: - CoreService(); - ~CoreService(); - - command_result BindMethod(color_ostream &stream, - const dfproto::CoreBindRequest *in, - dfproto::CoreBindReply *out); - command_result RunCommand(color_ostream &stream, - const dfproto::CoreRunCommandRequest *in); - - // For batching - command_result CoreSuspend(color_ostream &stream, const EmptyMessage*, IntMessage *cnt); - command_result CoreResume(color_ostream &stream, const EmptyMessage*, IntMessage *cnt); - }; - - class DFHACK_EXPORT ServerConnection { + class ServerConnection { class connection_ostream : public buffered_color_ostream { ServerConnection *owner; @@ -237,7 +221,7 @@ namespace DFHack ServerFunctionBase *findFunction(color_ostream &out, const std::string &plugin, const std::string &name); }; - class DFHACK_EXPORT ServerMain { + class ServerMain { CPassiveSocket *socket; tthread::thread *thread; diff --git a/library/include/RemoteTools.h b/library/include/RemoteTools.h new file mode 100644 index 000000000..9c5a9b069 --- /dev/null +++ b/library/include/RemoteTools.h @@ -0,0 +1,48 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#pragma once +#include "Pragma.h" +#include "Export.h" +#include "RemoteServer.h" + +namespace DFHack +{ + class CoreService : public RPCService { + int suspend_depth; + public: + CoreService(); + ~CoreService(); + + command_result BindMethod(color_ostream &stream, + const dfproto::CoreBindRequest *in, + dfproto::CoreBindReply *out); + command_result RunCommand(color_ostream &stream, + const dfproto::CoreRunCommandRequest *in); + + // For batching + command_result CoreSuspend(color_ostream &stream, const EmptyMessage*, IntMessage *cnt); + command_result CoreResume(color_ostream &stream, const EmptyMessage*, IntMessage *cnt); + }; +} diff --git a/plugins/Plugins.cmake b/plugins/Plugins.cmake index 78892967d..a8252e706 100644 --- a/plugins/Plugins.cmake +++ b/plugins/Plugins.cmake @@ -72,18 +72,23 @@ MACRO(DFHACK_PLUGIN) ADD_LIBRARY(${PLUGIN_NAME} MODULE ${PLUGIN_SOURCES}) IDE_FOLDER(${PLUGIN_NAME} "Plugins") + LIST(LENGTH PLUGIN_PROTOBUFS NUM_PROTO) IF(NUM_PROTO) TARGET_LINK_LIBRARIES(${PLUGIN_NAME} dfhack protobuf-lite ${PLUGIN_LINK_LIBRARIES}) + IF(UNIX) + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES COMPILE_FLAGS "-include Export.h") + ELSE() + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES COMPILE_FLAGS "/FI\"Export.h\"") + ENDIF() ELSE() TARGET_LINK_LIBRARIES(${PLUGIN_NAME} dfhack ${PLUGIN_LINK_LIBRARIES}) ENDIF() + IF(UNIX) SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES SUFFIX .plug.so PREFIX "") - SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES COMPILE_FLAGS "-include Export.h") ELSE() SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES SUFFIX .plug.dll) - SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES COMPILE_FLAGS "/FI\"Export.h\"") ENDIF() install(TARGETS ${PLUGIN_NAME}