Merge branch 'develop' of https://github.com/DFHack/dfhack into develop

develop
Japa 2015-10-09 23:35:39 +05:30
commit 46f6afada7
17 changed files with 309 additions and 195 deletions

@ -2,15 +2,24 @@ sudo: false
addons: addons:
apt: apt:
packages: packages:
- gcc-multilib
- g++-multilib
- lua5.2 - lua5.2
- libxml-libxml-perl
- libxml-libxslt-perl
- zlib1g-dev:i386
language: cpp language: cpp
before_install: before_install:
pip install --user sphinx pip install --user sphinx
script: script:
- git tag tmp-travis-build
- python travis/pr-check-base.py - python travis/pr-check-base.py
- python travis/lint.py - python travis/lint.py
- python travis/script-in-readme.py - python travis/script-in-readme.py
- python travis/script-syntax.py --ext=lua --cmd="luac5.2 -p" - python travis/script-syntax.py --ext=lua --cmd="luac5.2 -p"
- python travis/script-syntax.py --ext=rb --cmd="ruby -c" - python travis/script-syntax.py --ext=rb --cmd="ruby -c"
- mkdir build-travis
- cd build-travis
- cmake .. && make -j3
notifications: notifications:
email: false email: false

@ -230,6 +230,7 @@ if (BUILD_DOCS)
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/*/*/*/*/*/*/*/*/*.lua" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/*/*/*/*/*/*/*/*/*.lua"
"${CMAKE_CURRENT_SOURCE_DIR}/scripts/*/*/*/*/*/*/*/*/*/*.lua" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/*/*/*/*/*/*/*/*/*/*.lua"
) )
set(SPHINX_DEPS ${SPHINX_DEPS} LICENSE NEWS README.rst)
set(SPHINX_OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/docs/html/.buildinfo") set(SPHINX_OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/docs/html/.buildinfo")
set_source_files_properties(${SPHINX_OUTPUT} PROPERTIES GENERATED TRUE) set_source_files_properties(${SPHINX_OUTPUT} PROPERTIES GENERATED TRUE)

@ -23,9 +23,117 @@ Copyright (c) 2009-2012 Petr Mrázek (peterix@gmail.com)
3. This notice may not be removed or altered from any source 3. This notice may not be removed or altered from any source
distribution. distribution.
clsocket license
================
::
Copyright (c) 2007-2009 CarrierLabs, LLC. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
4. The name "CarrierLabs" must not be used to
endorse or promote products derived from this software without
prior written permission. For written permission, please contact
mark@carrierlabs.com.
THIS SOFTWARE IS PROVIDED BY MARK CARRIER ``AS IS'' AND ANY
EXPRESSED 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 MARK CARRIER OR
ITS 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.
Lua license
===========
Lua is licensed under the terms of the MIT license reproduced below.
This means that Lua is free software and can be used for both academic
and commercial purposes at absolutely no cost.
For details and rationale, see http://www.lua.org/license.html .
::
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
License of the used XML reader library Permission is hereby granted, free of charge, to any person obtaining a copy
====================================== of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Protobuf license
================
::
Copyright 2008, Google Inc.
All rights reserved.
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 Google Inc. 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.
Code generated by the Protocol Buffer compiler is owned by the owner
of the input file used when generating it. This code is not
standalone and requires a support library to be linked with it. This
support library is itself covered by the above license.
License of tinyxml (XML reader library)
=======================================
http://www.sourceforge.net/projects/tinyxml http://www.sourceforge.net/projects/tinyxml
Original code, 2.0 and earlier, copyright 2000-2006 Lee Thomason (http://www.grinninglizard.com) Original code, 2.0 and earlier, copyright 2000-2006 Lee Thomason (http://www.grinninglizard.com)
@ -50,12 +158,61 @@ Original code, 2.0 and earlier, copyright 2000-2006 Lee Thomason (http://www.gri
3. This notice may not be removed or altered from any source 3. This notice may not be removed or altered from any source
distribution. distribution.
tinythread license
==================
::
Copyright (c) 2010 Marcus Geelnard
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.
zlib license
============
::
Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
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.
dirent.h - dirent API for Microsoft Visual Studio dirent.h - dirent API for Microsoft Visual Studio
================================================= =================================================
Copyright (C) 2006 Toni Ronkko
:: ::
Copyright (C) 2006 Toni Ronkko
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including "Software"), to deal in the Software without restriction, including

@ -114,6 +114,7 @@ DFHack Future
plug: plug:
- lists all plugins - lists all plugins
- shows state and number of commands in plugins - shows state and number of commands in plugins
prospect: works from within command-prompt
quicksave: Restricted to fortress mode quicksave: Restricted to fortress mode
remotefortressreader: Exposes more information remotefortressreader: Exposes more information
search: search:

@ -1 +1 @@
Subproject commit 5f80ee324b8f82f9a0d093fbf0485f3b276139ee Subproject commit dc7ff5dadf7b1bf96a82149b201d3674c97631d9

@ -12,7 +12,7 @@ IF(CMAKE_COMPILER_IS_GNUCC)
# SET(STL_HASH_OLD_GCC 1) # SET(STL_HASH_OLD_GCC 1)
#ENDIF() #ENDIF()
#SET(CMAKE_CXX_FLAGS "-std=c++0x") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
SET(HAVE_HASH_MAP 0) SET(HAVE_HASH_MAP 0)
SET(HASH_MAP_CLASS unordered_map) SET(HASH_MAP_CLASS unordered_map)

@ -4,73 +4,6 @@ How to contribute to DFHack
.. contents:: .. contents::
You can help without coding
===========================
DFHack is a software project, but there's a lot more to it than programming.
If you're not comfortable pregramming, you can help by:
* reporting bugs and incomplete documentation,
* improving the documentation,
* finding third-party scripts to add,
* writing tutorials for newbies
All those things are crucial, and all under-represented. So if that's
your thing, the rest of this document is about contributing code - go get started!
Documentation Standards
=======================
Whether you're adding new code or just fixing old documentation (and there's plenty),
there are a few important standards for completeness and consistent style. Treat
this section as a guide rather than iron law, match the surrounding text, and you'll
be fine.
Every script, plugin, or command should be documented. This is an active project,
and the best place to put this documentation might change. For now, it's usually
either ``docs/Scripts.rst`` or ``docs/Plugins.rst``.
Where the heading for a section is also the name of a command, the spelling
and case should exactly match the command to enter in the DFHack command line.
Try to keep lines within 80-100 characters, so it's readable in plain text -
Sphinx (our documentation system) will make sure paragraphs flow.
If there aren't many options or examples to show, they can go in a paragraph of
text. Use double-backticks to put commands in monospaced font, like this::
You can use ``cleanall scattered x`` to dump tattered or abandoned items.
If the command takes more than three arguments, format the list as a table
called Options. The table *only* lists arguments, not full commands.
Input values are specified in angle brackets. Example::
Options:
:arg1: A simple argument.
:arg2 <input>: Does something based on the input value.
:Very long argument:
Is very specific.
To demonstrate usage - useful mainly when the syntax is complicated, list the
full command with arguments in monospaced font, then indent the next line and
describe the effect::
``resume all``
Resumes all suspended constructions.
If it would be helpful to mention another DFHack command, don't just type the
name - add a hyperlink! Specify the link target in backticks, and it will be
replaced with the corresponding title and linked: eg ```plugins/autolabor```
=> `plugins/autolabor`. Link targets should be the path to the file
described (without file extension), and placed above the heading of that
section like this::
.. _plugins/autolabor:
autolabor
=========
Add link targets if you need them, but otherwise plain headings are preferred.
Contributing Code Contributing Code
================= =================
@ -96,10 +29,10 @@ How to get new code into DFHack
* Submit pull requests to the ``develop`` branch, not the master branch. The master branch always points at the most recent release. * Submit pull requests to the ``develop`` branch, not the master branch. The master branch always points at the most recent release.
* Use new branches for each feature/fix so that your changes can be merged independently (i.e. not the master or develop branch of your fork). * Use new branches for each feature/fix so that your changes can be merged independently (i.e. not the master or develop branch of your fork).
* If possible, compile on multiple platforms when changing anything that compiles * If possible, compile on multiple platforms when changing anything that compiles
* Update NEWS and doc/Authors.rst when applicable * Update ``NEWS`` and ``docs/Authors.rst`` when applicable
* Create a Github Pull Request once finished * Create a GitHub pull request once finished
* Work done against Github issues tagged "bug report" get priority * Work done against GitHub issues tagged "bug" get priority
* Submit ideas and bug reports as issues on Github. Posts in the forum thread can easily get missed or forgotten. * Submit ideas and bug reports as issues on GitHub. Posts in the forum thread can easily get missed or forgotten.
.. _contributing-memory-research: .. _contributing-memory-research:
@ -145,15 +78,15 @@ The most important parts of DFHack are the Core, Console, Modules and Plugins.
that will be called each DF game tick. that will be called each DF game tick.
Rudimentary API documentation can be built using doxygen (see build options Rudimentary API documentation can be built using doxygen (see build options
with ``ccmake`` or ``cmake-gui``). The full DFHack documentation is built in ``CMakeCache.txt`` or with ``ccmake`` or ``cmake-gui``). The full DFHack
with Sphinx, which runs automatically at compile time. documentation is built with Sphinx, which runs automatically at compile time.
DFHack consists of variously licensed code, but invariably weak copyleft. DFHack consists of variously licensed code, but invariably weak copyleft.
The main license is zlib/libpng, some bits are MIT licensed, and some are The main license is zlib/libpng, some bits are MIT licensed, and some are
BSD licensed. See the `license` document for more information. BSD licensed. See the ``LICENSE`` document for more information.
Feel free to add your own extensions and plugins. Contributing back to Feel free to add your own extensions and plugins. Contributing back to
the dfhack repository is welcome and the right thing to do :) the DFHack repository is welcome and the right thing to do :)
DF data structure definitions DF data structure definitions
----------------------------- -----------------------------
@ -182,3 +115,71 @@ Currently the supported set of requests is limited, because the developers don't
know what exactly is most useful. ``remotefortressreader`` provides a fairly know what exactly is most useful. ``remotefortressreader`` provides a fairly
comprehensive interface for visualisers such as Armok Vision. comprehensive interface for visualisers such as Armok Vision.
Documentation Standards
=======================
Whether you're adding new code or just fixing old documentation (and there's plenty),
there are a few important standards for completeness and consistent style. Treat
this section as a guide rather than iron law, match the surrounding text, and you'll
be fine.
Every script, plugin, or command should be documented. This is an active project,
and the best place to put this documentation might change. For now, it's usually
either ``docs/Scripts.rst`` or ``docs/Plugins.rst``.
Where the heading for a section is also the name of a command, the spelling
and case should exactly match the command to enter in the DFHack command line.
Try to keep lines within 80-100 characters, so it's readable in plain text -
Sphinx (our documentation system) will make sure paragraphs flow.
If there aren't many options or examples to show, they can go in a paragraph of
text. Use double-backticks to put commands in monospaced font, like this::
You can use ``cleanall scattered x`` to dump tattered or abandoned items.
If the command takes more than three arguments, format the list as a table
called Options. The table *only* lists arguments, not full commands.
Input values are specified in angle brackets. Example::
Options:
:arg1: A simple argument.
:arg2 <input>: Does something based on the input value.
:Very long argument:
Is very specific.
To demonstrate usage - useful mainly when the syntax is complicated, list the
full command with arguments in monospaced font, then indent the next line and
describe the effect::
``resume all``
Resumes all suspended constructions.
If it would be helpful to mention another DFHack command, don't just type the
name - add a hyperlink! Specify the link target in backticks, and it will be
replaced with the corresponding title and linked: eg ```plugins/autolabor```
=> `plugins/autolabor`. Link targets should be the path to the file
described (without file extension), and placed above the heading of that
section like this::
.. _plugins/autolabor:
autolabor
=========
Add link targets if you need them, but otherwise plain headings are preferred.
Other ways to help
==================
DFHack is a software project, but there's a lot more to it than programming.
If you're not comfortable programming, you can help by:
* reporting bugs and incomplete documentation
* improving the documentation
* finding third-party scripts to add
* writing tutorials for newbies
All those things are crucial, and often under-represented. So if that's
your thing, go get started!

@ -127,7 +127,7 @@ directory.
gui/advfort gui/advfort
=========== ===========
This script allows to perform jobs in adventure mode. For more complete help This script allows to perform jobs in adventure mode. For more complete help
press '?' while script is running. It's most confortable to use this as a press '?' while script is running. It's most comfortable to use this as a
keybinding. (e.g. keybinding set Ctrl-T gui/advfort). Possible arguments: keybinding. (e.g. keybinding set Ctrl-T gui/advfort). Possible arguments:
* -a or --nodfassign - uses different method to assign items. * -a or --nodfassign - uses different method to assign items.
@ -622,6 +622,11 @@ These scripts are not stored in any subdirectory, and can be invoked directly.
.. include:: ../scripts/include-all.rst .. include:: ../scripts/include-all.rst
add-thought
===========
Adds a thought or emotion to the selected unit. Can be used by other scripts,
or the gui invoked by running ``add-thought gui`` with a unit selected.
adaptation adaptation
========== ==========
View or set level of cavern adaptation for the selected unit or the whole fort. View or set level of cavern adaptation for the selected unit or the whole fort.

@ -14,9 +14,10 @@
# serve to show the default. # serve to show the default.
import fnmatch import fnmatch
import sys import io
import os import os
import shlex import shlex
import sys
from os import listdir from os import listdir
from os.path import isfile, join, isdir from os.path import isfile, join, isdir
@ -33,7 +34,7 @@ def makeIncludeAll(directory, extension):
for f in files: for f in files:
#TODO: check if the file contains the BEGIN_DOCS string #TODO: check if the file contains the BEGIN_DOCS string
#print(join(directory,f)) #print(join(directory,f))
fstream = open(join(directory,f), 'r', encoding='utf8') fstream = io.open(join(directory,f), 'r', encoding='utf8')
data = fstream.read().replace('\n','') data = fstream.read().replace('\n','')
fstream.close() fstream.close()
if 'BEGIN_DOCS' in data: if 'BEGIN_DOCS' in data:

@ -855,14 +855,14 @@ command_result Core::runCommand(color_ostream &con, const std::string &first_, v
} }
else if (builtin == "plug") else if (builtin == "plug")
{ {
const char *header_format = "%25s %10s %4s\n"; const char *header_format = "%25s %10s %4s %8s\n";
const char *row_format = "%25s %10s %4i\n"; const char *row_format = "%25s %10s %4i %8s\n";
con.print(header_format, "Name", "State", "Cmds"); con.print(header_format, "Name", "State", "Cmds", "Enabled");
plug_mgr->refresh(); plug_mgr->refresh();
for (auto it = plug_mgr->begin(); it != plug_mgr->end(); ++it) for (auto it = plug_mgr->begin(); it != plug_mgr->end(); ++it)
{ {
const Plugin * plug = it->second; Plugin * plug = it->second;
if (!plug) if (!plug)
continue; continue;
if (parts.size() && std::find(parts.begin(), parts.end(), plug->getName()) == parts.end()) if (parts.size() && std::find(parts.begin(), parts.end(), plug->getName()) == parts.end())
@ -891,7 +891,10 @@ command_result Core::runCommand(color_ostream &con, const std::string &first_, v
con.print(row_format, con.print(row_format,
plug->getName().c_str(), plug->getName().c_str(),
Plugin::getStateDescription(plug->getState()), Plugin::getStateDescription(plug->getState()),
plug->size() plug->size(),
(plug->can_be_enabled()
? (plug->is_enabled() ? "enabled" : "disabled")
: "n/a")
); );
con.color(COLOR_RESET); con.color(COLOR_RESET);
} }

@ -156,6 +156,15 @@ namespace DFHack
/// Get the current top-level view-screen /// Get the current top-level view-screen
DFHACK_EXPORT df::viewscreen *getCurViewscreen(bool skip_dismissed = false); DFHACK_EXPORT df::viewscreen *getCurViewscreen(bool skip_dismissed = false);
DFHACK_EXPORT df::viewscreen *getViewscreenByIdentity(virtual_identity &id, int n = 1);
/// Get the top-most viewscreen of the given type from the top `n` viewscreens (or all viewscreens if n < 1)
/// returns NULL if none match
template <typename T>
inline T *getViewscreenByType (int n = 1) {
return strict_virtual_cast<T>(getViewscreenByIdentity(T::_identity, n));
}
inline std::string getCurFocus(bool skip_dismissed = false) { inline std::string getCurFocus(bool skip_dismissed = false) {
return getFocusString(getCurViewscreen(skip_dismissed)); return getFocusString(getCurViewscreen(skip_dismissed));
} }

@ -1326,6 +1326,21 @@ df::viewscreen *Gui::getCurViewscreen(bool skip_dismissed)
return ws; return ws;
} }
df::viewscreen *Gui::getViewscreenByIdentity (virtual_identity &id, int n)
{
bool limit = (n > 0);
df::viewscreen *screen = Gui::getCurViewscreen();
while (screen)
{
if (limit && n-- <= 0)
break;
if (id.is_instance(screen))
return screen;
screen = screen->parent;
}
return NULL;
}
df::coord Gui::getViewportPos() df::coord Gui::getViewportPos()
{ {
if (!df::global::window_x || !df::global::window_y || !df::global::window_z) if (!df::global::window_x || !df::global::window_y || !df::global::window_z)

@ -23,52 +23,6 @@ DFHACK_PLUGIN("dfstream");
REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(gps);
REQUIRE_GLOBAL(enabler); REQUIRE_GLOBAL(enabler);
// The error messages are taken from the clsocket source code
const char * translate_socket_error(CSimpleSocket::CSocketError err) {
switch (err) {
case CSimpleSocket::SocketError:
return "Generic socket error translates to error below.";
case CSimpleSocket::SocketSuccess:
return "No socket error.";
case CSimpleSocket::SocketInvalidSocket:
return "Invalid socket handle.";
case CSimpleSocket::SocketInvalidAddress:
return "Invalid destination address specified.";
case CSimpleSocket::SocketInvalidPort:
return "Invalid destination port specified.";
case CSimpleSocket::SocketConnectionRefused:
return "No server is listening at remote address.";
case CSimpleSocket::SocketTimedout:
return "Timed out while attempting operation.";
case CSimpleSocket::SocketEwouldblock:
return "Operation would block if socket were blocking.";
case CSimpleSocket::SocketNotconnected:
return "Currently not connected.";
case CSimpleSocket::SocketEinprogress:
return "Socket is non-blocking and the connection cannot be completed immediately";
case CSimpleSocket::SocketInterrupted:
return "Call was interrupted by a signal that was caught before a valid connection arrived.";
case CSimpleSocket::SocketConnectionAborted:
return "The connection has been aborted.";
case CSimpleSocket::SocketProtocolError:
return "Invalid protocol for operation.";
case CSimpleSocket::SocketFirewallError:
return "Firewall rules forbid connection.";
case CSimpleSocket::SocketInvalidSocketBuffer:
return "The receive buffer point outside the process's address space.";
case CSimpleSocket::SocketConnectionReset:
return "Connection was forcibly closed by the remote host.";
case CSimpleSocket::SocketAddressInUse:
return "Address already in use.";
case CSimpleSocket::SocketInvalidPointer:
return "Pointer type supplied as argument is invalid.";
case CSimpleSocket::SocketEunknown:
return "Unknown error please report to mark@carrierlabs.com";
default:
return "No such CSimpleSocket error";
}
}
// Owns the thread that accepts TCP connections and forwards messages to clients; // Owns the thread that accepts TCP connections and forwards messages to clients;
// has a mutex // has a mutex
class client_pool { class client_pool {
@ -88,7 +42,7 @@ class client_pool {
std::cout << "Listening on a socket" << std::endl; std::cout << "Listening on a socket" << std::endl;
} else { } else {
std::cout << "Not listening: " << socket.GetSocketError() << std::endl; std::cout << "Not listening: " << socket.GetSocketError() << std::endl;
std::cout << translate_socket_error(socket.GetSocketError()) << std::endl; std::cout << socket.DescribeError() << std::endl;
} }
while (true) { while (true) {
CActiveSocket * client = socket.Accept(); CActiveSocket * client = socket.Accept();

@ -29,51 +29,7 @@ typedef std::map<int,CActiveSocket*> clients_map;
clients_map clients; //free clients, i.e. non-server spawned clients clients_map clients; //free clients, i.e. non-server spawned clients
DFHACK_PLUGIN("luasocket"); DFHACK_PLUGIN("luasocket");
// The error messages are taken from the clsocket source code
const char * translate_socket_error(CSimpleSocket::CSocketError err) {
switch (err) {
case CSimpleSocket::SocketError:
return "Generic socket error translates to error below.";
case CSimpleSocket::SocketSuccess:
return "No socket error.";
case CSimpleSocket::SocketInvalidSocket:
return "Invalid socket handle.";
case CSimpleSocket::SocketInvalidAddress:
return "Invalid destination address specified.";
case CSimpleSocket::SocketInvalidPort:
return "Invalid destination port specified.";
case CSimpleSocket::SocketConnectionRefused:
return "No server is listening at remote address.";
case CSimpleSocket::SocketTimedout:
return "Timed out while attempting operation.";
case CSimpleSocket::SocketEwouldblock:
return "Operation would block if socket were blocking.";
case CSimpleSocket::SocketNotconnected:
return "Currently not connected.";
case CSimpleSocket::SocketEinprogress:
return "Socket is non-blocking and the connection cannot be completed immediately";
case CSimpleSocket::SocketInterrupted:
return "Call was interrupted by a signal that was caught before a valid connection arrived.";
case CSimpleSocket::SocketConnectionAborted:
return "The connection has been aborted.";
case CSimpleSocket::SocketProtocolError:
return "Invalid protocol for operation.";
case CSimpleSocket::SocketFirewallError:
return "Firewall rules forbid connection.";
case CSimpleSocket::SocketInvalidSocketBuffer:
return "The receive buffer point outside the process's address space.";
case CSimpleSocket::SocketConnectionReset:
return "Connection was forcibly closed by the remote host.";
case CSimpleSocket::SocketAddressInUse:
return "Address already in use.";
case CSimpleSocket::SocketInvalidPointer:
return "Pointer type supplied as argument is invalid.";
case CSimpleSocket::SocketEunknown:
return "Unknown error please report to mark@carrierlabs.com";
default:
return "No such CSimpleSocket error";
}
}
void server::close() void server::close()
{ {
for(auto it=clients.begin();it!=clients.end();it++) for(auto it=clients.begin();it!=clients.end();it++)
@ -114,7 +70,7 @@ void handle_error(CSimpleSocket::CSocketError err,bool skip_timeout=true)
return; return;
if (err == CSimpleSocket::SocketEwouldblock && skip_timeout) if (err == CSimpleSocket::SocketEwouldblock && skip_timeout)
return; return;
throw std::runtime_error(translate_socket_error(err)); throw std::runtime_error(CSimpleSocket::DescribeError(err));
} }
static int lua_socket_bind(std::string ip,int port) static int lua_socket_bind(std::string ip,int port)
{ {
@ -171,7 +127,7 @@ static void lua_client_close(int server_id,int client_id)
delete sock; delete sock;
if(err!=CSimpleSocket::SocketSuccess) if(err!=CSimpleSocket::SocketSuccess)
{ {
throw std::runtime_error(translate_socket_error(err)); throw std::runtime_error(CSimpleSocket::DescribeError(err));
} }
} }
static void lua_server_close(int server_id) static void lua_server_close(int server_id)
@ -198,7 +154,7 @@ static std::string lua_client_receive(int server_id,int client_id,int bytes,std:
{ {
if(sock->Receive(bytes)<=0) if(sock->Receive(bytes)<=0)
{ {
throw std::runtime_error(translate_socket_error(sock->GetSocketError())); throw std::runtime_error(sock->DescribeError());
} }
return std::string((char*)sock->GetData(),bytes); return std::string((char*)sock->GetData(),bytes);
} }
@ -269,7 +225,7 @@ static void lua_client_send(int server_id,int client_id,std::string data)
CActiveSocket *sock=(*target)[client_id]; CActiveSocket *sock=(*target)[client_id];
if(sock->Send((const uint8_t*)data.c_str(),data.size())!=data.size()) if(sock->Send((const uint8_t*)data.c_str(),data.size())!=data.size())
{ {
throw std::runtime_error(translate_socket_error(sock->GetSocketError())); throw std::runtime_error(sock->DescribeError());
} }
} }
static int lua_socket_connect(std::string ip,int port) static int lua_socket_connect(std::string ip,int port)
@ -280,13 +236,13 @@ static int lua_socket_connect(std::string ip,int port)
{ {
CSimpleSocket::CSocketError err=sock->GetSocketError(); CSimpleSocket::CSocketError err=sock->GetSocketError();
delete sock; delete sock;
throw std::runtime_error(translate_socket_error(err)); throw std::runtime_error(CSimpleSocket::DescribeError(err));
} }
if(!sock->Open((const uint8_t*)ip.c_str(),port)) if(!sock->Open((const uint8_t*)ip.c_str(),port))
{ {
CSimpleSocket::CSocketError err=sock->GetSocketError(); CSimpleSocket::CSocketError err=sock->GetSocketError();
delete sock; delete sock;
throw std::runtime_error(translate_socket_error(err)); throw std::runtime_error(CSimpleSocket::DescribeError(err));
} }
sock->SetNonblocking(); sock->SetNonblocking();
last_client_id++; last_client_id++;
@ -325,7 +281,7 @@ static void lua_socket_set_timeout(int server_id,int client_id,int32_t sec,int32
!sock->SetSendTimeout(sec, msec)) !sock->SetSendTimeout(sec, msec))
{ {
CSimpleSocket::CSocketError err = sock->GetSocketError(); CSimpleSocket::CSocketError err = sock->GetSocketError();
throw std::runtime_error(translate_socket_error(err)); throw std::runtime_error(CSimpleSocket::DescribeError(err));
} }
} }
static bool lua_socket_select(int server_id, int client_id, int32_t sec, int32_t msec) static bool lua_socket_select(int server_id, int client_id, int32_t sec, int32_t msec)
@ -348,7 +304,7 @@ static void lua_socket_set_blocking(int server_id, int client_id, bool value)
if (!ok) if (!ok)
{ {
CSimpleSocket::CSocketError err = sock->GetSocketError(); CSimpleSocket::CSocketError err = sock->GetSocketError();
throw std::runtime_error(translate_socket_error(err)); throw std::runtime_error(CSimpleSocket::DescribeError(err));
} }
} }
static bool lua_socket_is_blocking(int server_id, int client_id) static bool lua_socket_is_blocking(int server_id, int client_id)

@ -18,6 +18,7 @@ using namespace std;
#include "Console.h" #include "Console.h"
#include "Export.h" #include "Export.h"
#include "PluginManager.h" #include "PluginManager.h"
#include "modules/Gui.h"
#include "modules/MapCache.h" #include "modules/MapCache.h"
#include "MiscUtils.h" #include "MiscUtils.h"
@ -575,7 +576,8 @@ command_result prospector (color_ostream &con, vector <string> & parameters)
CoreSuspender suspend; CoreSuspender suspend;
// Embark screen active: estimate using world geology data // Embark screen active: estimate using world geology data
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_choose_start_sitest, Core::getTopViewscreen())) auto screen = Gui::getViewscreenByType<df::viewscreen_choose_start_sitest>(0);
if (screen)
return embark_prospector(con, screen, showHidden, showValue); return embark_prospector(con, screen, showHidden, showValue);
if (!Maps::IsValid()) if (!Maps::IsValid())

@ -1 +1 @@
Subproject commit 4ba65d9db72fd48f99df23b92e7e356d7313f6c4 Subproject commit 8121de557102eb11cb805f8a25b43ba43077a967

@ -13,7 +13,7 @@ ENDMACRO()
MACRO(DFHACK_3RDPARTY_SCRIPT_REPO repo_path) MACRO(DFHACK_3RDPARTY_SCRIPT_REPO repo_path)
if(NOT EXISTS ${dfhack_SOURCE_DIR}/scripts/3rdparty/${repo_path}/CMakeLists.txt) if(NOT EXISTS ${dfhack_SOURCE_DIR}/scripts/3rdparty/${repo_path}/CMakeLists.txt)
MESSAGE(SEND_ERROR "Script submodule scripts/3rdparty/${repo_path} does not exist - run `git submodule update`.") MESSAGE(SEND_ERROR "Script submodule scripts/3rdparty/${repo_path} does not exist - run `git submodule update --init`.")
endif() endif()
add_subdirectory(3rdparty/${repo_path}) add_subdirectory(3rdparty/${repo_path})
ENDMACRO() ENDMACRO()