develop
commit
293eb53677
@ -0,0 +1,488 @@
|
|||||||
|
/*
|
||||||
|
https://github.com/peterix/dfhack
|
||||||
|
Copyright (c) 2011 Petr Mrázek <peterix@gmail.com>
|
||||||
|
|
||||||
|
A thread-safe logging console with a line editor for windows.
|
||||||
|
|
||||||
|
Based on linenoise win32 port,
|
||||||
|
copyright 2010, Jon Griffiths <jon_p_griffiths at yahoo dot com>.
|
||||||
|
All rights reserved.
|
||||||
|
Based on linenoise, copyright 2010, Salvatore Sanfilippo <antirez at gmail dot com>.
|
||||||
|
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 <stdarg.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <istream>
|
||||||
|
#include <string>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "RemoteTools.h"
|
||||||
|
#include "PluginManager.h"
|
||||||
|
#include "MiscUtils.h"
|
||||||
|
|
||||||
|
#include "modules/Materials.h"
|
||||||
|
#include "modules/Translation.h"
|
||||||
|
#include "modules/Units.h"
|
||||||
|
|
||||||
|
#include "DataDefs.h"
|
||||||
|
#include "df/ui.h"
|
||||||
|
#include "df/unit.h"
|
||||||
|
#include "df/unit_soul.h"
|
||||||
|
#include "df/unit_skill.h"
|
||||||
|
#include "df/material.h"
|
||||||
|
#include "df/matter_state.h"
|
||||||
|
#include "df/inorganic_raw.h"
|
||||||
|
#include "df/creature_raw.h"
|
||||||
|
#include "df/plant_raw.h"
|
||||||
|
#include "df/historical_figure.h"
|
||||||
|
#include "df/historical_entity.h"
|
||||||
|
#include "df/squad.h"
|
||||||
|
#include "df/squad_position.h"
|
||||||
|
|
||||||
|
#include "BasicApi.pb.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
using namespace DFHack;
|
||||||
|
using namespace df::enums;
|
||||||
|
using namespace dfproto;
|
||||||
|
|
||||||
|
using google::protobuf::MessageLite;
|
||||||
|
|
||||||
|
void DFHack::strVectorToRepeatedField(RepeatedPtrField<std::string> *pf,
|
||||||
|
const std::vector<std::string> &vec)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < vec.size(); ++i)
|
||||||
|
*pf->Add() = vec[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFHack::describeEnum(RepeatedPtrField<EnumItemName> *pf, int base,
|
||||||
|
int size, const char* const *names)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
auto item = pf->Add();
|
||||||
|
item->set_value(base+i);
|
||||||
|
const char *key = names[i];
|
||||||
|
if (key)
|
||||||
|
item->set_name(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFHack::describeBitfield(RepeatedPtrField<EnumItemName> *pf,
|
||||||
|
int size, const bitfield_item_info *items)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
auto item = pf->Add();
|
||||||
|
item->set_value(i);
|
||||||
|
const char *key = items[i].name;
|
||||||
|
if (key)
|
||||||
|
item->set_name(key);
|
||||||
|
if (items[i].size > 1)
|
||||||
|
{
|
||||||
|
item->set_bit_size(items[i].size);
|
||||||
|
i += items[i].size-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFHack::describeMaterial(BasicMaterialInfo *info, df::material *mat,
|
||||||
|
const BasicMaterialInfoMask *mask)
|
||||||
|
{
|
||||||
|
info->set_token(mat->id);
|
||||||
|
|
||||||
|
if (mask && mask->flags())
|
||||||
|
flagarray_to_ints(info->mutable_flags(), mat->flags);
|
||||||
|
|
||||||
|
if (!mat->prefix.empty())
|
||||||
|
info->set_name_prefix(mat->prefix);
|
||||||
|
|
||||||
|
if (!mask || mask->states_size() == 0)
|
||||||
|
{
|
||||||
|
df::matter_state state = matter_state::Solid;
|
||||||
|
int temp = (mask && mask->has_temperature()) ? mask->temperature() : 10015;
|
||||||
|
|
||||||
|
if (temp >= mat->heat.melting_point)
|
||||||
|
state = matter_state::Liquid;
|
||||||
|
if (temp >= mat->heat.boiling_point)
|
||||||
|
state = matter_state::Gas;
|
||||||
|
|
||||||
|
info->add_state_color(mat->state_color[state]);
|
||||||
|
info->add_state_name(mat->state_name[state]);
|
||||||
|
info->add_state_adj(mat->state_adj[state]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mask->states_size(); i++)
|
||||||
|
{
|
||||||
|
info->add_state_color(mat->state_color[i]);
|
||||||
|
info->add_state_name(mat->state_name[i]);
|
||||||
|
info->add_state_adj(mat->state_adj[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask && mask->reaction())
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < mat->reaction_class.size(); i++)
|
||||||
|
info->add_reaction_class(*mat->reaction_class[i]);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < mat->reaction_product.id.size(); i++)
|
||||||
|
{
|
||||||
|
auto ptr = info->add_reaction_product();
|
||||||
|
ptr->set_id(*mat->reaction_product.id[i]);
|
||||||
|
ptr->set_type(mat->reaction_product.material.mat_type[i]);
|
||||||
|
ptr->set_index(mat->reaction_product.material.mat_index[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFHack::describeMaterial(BasicMaterialInfo *info, const MaterialInfo &mat,
|
||||||
|
const BasicMaterialInfoMask *mask)
|
||||||
|
{
|
||||||
|
assert(mat.isValid());
|
||||||
|
|
||||||
|
info->set_type(mat.type);
|
||||||
|
info->set_index(mat.index);
|
||||||
|
|
||||||
|
describeMaterial(info, mat.material, mask);
|
||||||
|
|
||||||
|
switch (mat.mode) {
|
||||||
|
case MaterialInfo::Inorganic:
|
||||||
|
info->set_token(mat.inorganic->id);
|
||||||
|
if (mask && mask->flags())
|
||||||
|
flagarray_to_ints(info->mutable_inorganic_flags(), mat.inorganic->flags);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MaterialInfo::Creature:
|
||||||
|
info->set_subtype(mat.subtype);
|
||||||
|
if (mat.figure)
|
||||||
|
{
|
||||||
|
info->set_histfig_id(mat.index);
|
||||||
|
info->set_creature_id(mat.figure->race);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
info->set_creature_id(mat.index);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MaterialInfo::Plant:
|
||||||
|
info->set_plant_id(mat.index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFHack::describeName(NameInfo *info, df::language_name *name)
|
||||||
|
{
|
||||||
|
if (!name->first_name.empty())
|
||||||
|
info->set_first_name(name->first_name);
|
||||||
|
if (!name->nickname.empty())
|
||||||
|
info->set_nickname(name->nickname);
|
||||||
|
|
||||||
|
if (name->language >= 0)
|
||||||
|
info->set_language_id(name->language);
|
||||||
|
|
||||||
|
std::string lname = Translation::TranslateName(name, false, true);
|
||||||
|
if (!lname.empty())
|
||||||
|
info->set_last_name(lname);
|
||||||
|
lname = Translation::TranslateName(name, true, true);
|
||||||
|
if (!lname.empty())
|
||||||
|
info->set_english_name(lname);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DFHack::describeUnit(BasicUnitInfo *info, df::unit *unit,
|
||||||
|
const BasicUnitInfoMask *mask)
|
||||||
|
{
|
||||||
|
info->set_unit_id(unit->id);
|
||||||
|
|
||||||
|
info->set_pos_x(unit->pos.x);
|
||||||
|
info->set_pos_y(unit->pos.y);
|
||||||
|
info->set_pos_z(unit->pos.z);
|
||||||
|
|
||||||
|
auto name = Units::GetVisibleName(unit);
|
||||||
|
if (name->has_name)
|
||||||
|
describeName(info->mutable_name(), name);
|
||||||
|
|
||||||
|
info->set_flags1(unit->flags1.whole);
|
||||||
|
info->set_flags2(unit->flags2.whole);
|
||||||
|
info->set_flags3(unit->flags3.whole);
|
||||||
|
|
||||||
|
info->set_race(unit->race);
|
||||||
|
info->set_caste(unit->caste);
|
||||||
|
|
||||||
|
if (unit->sex >= 0)
|
||||||
|
info->set_gender(unit->sex);
|
||||||
|
if (unit->civ_id >= 0)
|
||||||
|
info->set_civ_id(unit->civ_id);
|
||||||
|
if (unit->hist_figure_id >= 0)
|
||||||
|
info->set_histfig_id(unit->hist_figure_id);
|
||||||
|
|
||||||
|
if (mask && mask->labors())
|
||||||
|
{
|
||||||
|
for (int i = 0; i < sizeof(unit->status.labors)/sizeof(bool); i++)
|
||||||
|
if (unit->status.labors[i])
|
||||||
|
info->add_labors(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask && mask->skills() && unit->status.current_soul)
|
||||||
|
{
|
||||||
|
auto &vec = unit->status.current_soul->skills;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < vec.size(); i++)
|
||||||
|
{
|
||||||
|
auto skill = vec[i];
|
||||||
|
auto item = info->add_skills();
|
||||||
|
item->set_id(skill->id);
|
||||||
|
item->set_level(skill->rating);
|
||||||
|
item->set_experience(skill->experience);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static command_result ListEnums(color_ostream &stream,
|
||||||
|
const EmptyMessage *, ListEnumsOut *out)
|
||||||
|
{
|
||||||
|
#define ENUM(name) describe_enum<df::name>(out->mutable_##name());
|
||||||
|
#define BITFIELD(name) describe_bitfield<df::name>(out->mutable_##name());
|
||||||
|
ENUM(material_flags);
|
||||||
|
ENUM(inorganic_flags);
|
||||||
|
BITFIELD(unit_flags1);
|
||||||
|
BITFIELD(unit_flags2);
|
||||||
|
BITFIELD(unit_flags3);
|
||||||
|
ENUM(unit_labor);
|
||||||
|
ENUM(job_skill);
|
||||||
|
#undef ENUM
|
||||||
|
#undef BITFIELD
|
||||||
|
}
|
||||||
|
|
||||||
|
static void listMaterial(ListMaterialsOut *out, int type, int index, const BasicMaterialInfoMask *mask)
|
||||||
|
{
|
||||||
|
MaterialInfo info(type, index);
|
||||||
|
if (info.isValid())
|
||||||
|
describeMaterial(out->add_value(), info, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
static command_result ListMaterials(color_ostream &stream,
|
||||||
|
const ListMaterialsIn *in, ListMaterialsOut *out)
|
||||||
|
{
|
||||||
|
CoreSuspender suspend;
|
||||||
|
|
||||||
|
auto mask = in->has_mask() ? &in->mask() : NULL;
|
||||||
|
|
||||||
|
for (int i = 0; i < in->id_list_size(); i++)
|
||||||
|
{
|
||||||
|
auto &elt = in->id_list(i);
|
||||||
|
listMaterial(out, elt.type(), elt.index(), mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in->builtin())
|
||||||
|
{
|
||||||
|
for (int i = 0; i < MaterialInfo::NUM_BUILTIN; i++)
|
||||||
|
listMaterial(out, i, -1, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in->inorganic())
|
||||||
|
{
|
||||||
|
auto &vec = df::inorganic_raw::get_vector();
|
||||||
|
for (size_t i = 0; i < vec.size(); i++)
|
||||||
|
listMaterial(out, 0, i, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in->creatures())
|
||||||
|
{
|
||||||
|
auto &vec = df::creature_raw::get_vector();
|
||||||
|
for (size_t i = 0; i < vec.size(); i++)
|
||||||
|
{
|
||||||
|
auto praw = vec[i];
|
||||||
|
|
||||||
|
for (size_t j = 0; j < praw->material.size(); j++)
|
||||||
|
listMaterial(out, MaterialInfo::CREATURE_BASE+j, i, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in->plants())
|
||||||
|
{
|
||||||
|
auto &vec = df::plant_raw::get_vector();
|
||||||
|
for (size_t i = 0; i < vec.size(); i++)
|
||||||
|
{
|
||||||
|
auto praw = vec[i];
|
||||||
|
|
||||||
|
for (size_t j = 0; j < praw->material.size(); j++)
|
||||||
|
listMaterial(out, MaterialInfo::PLANT_BASE+j, i, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out->value_size() ? CR_OK : CR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static command_result ListUnits(color_ostream &stream,
|
||||||
|
const ListUnitsIn *in, ListUnitsOut *out)
|
||||||
|
{
|
||||||
|
CoreSuspender suspend;
|
||||||
|
|
||||||
|
auto mask = in->has_mask() ? &in->mask() : NULL;
|
||||||
|
|
||||||
|
if (in->id_list_size() > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < in->id_list_size(); i++)
|
||||||
|
{
|
||||||
|
auto unit = df::unit::find(in->id_list(i));
|
||||||
|
if (unit)
|
||||||
|
describeUnit(out->add_value(), unit, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto &vec = df::unit::get_vector();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < vec.size(); i++)
|
||||||
|
{
|
||||||
|
auto unit = vec[i];
|
||||||
|
|
||||||
|
if (in->has_race() && unit->race != in->race())
|
||||||
|
continue;
|
||||||
|
if (in->civ_id() && unit->civ_id != in->civ_id())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
describeUnit(out->add_value(), unit, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out->value_size() ? CR_OK : CR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static command_result ListSquads(color_ostream &stream,
|
||||||
|
const ListSquadsIn *in, ListSquadsOut *out)
|
||||||
|
{
|
||||||
|
auto entity = df::historical_entity::find(df::global::ui->group_id);
|
||||||
|
if (!entity)
|
||||||
|
return CR_NOT_FOUND;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < entity->squads.size(); i++)
|
||||||
|
{
|
||||||
|
auto squad = df::squad::find(entity->squads[i]);
|
||||||
|
if (!squad)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto item = out->add_value();
|
||||||
|
item->set_squad_id(squad->id);
|
||||||
|
|
||||||
|
if (squad->name.has_name)
|
||||||
|
describeName(item->mutable_name(), &squad->name);
|
||||||
|
if (!squad->alias.empty())
|
||||||
|
item->set_alias(squad->alias);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < squad->positions.size(); j++)
|
||||||
|
item->add_members(squad->positions[j]->occupant);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
addFunction("ListEnums", ListEnums, SF_CALLED_ONCE);
|
||||||
|
addFunction("ListMaterials", ListMaterials, SF_CALLED_ONCE);
|
||||||
|
addFunction("ListUnits", ListUnits);
|
||||||
|
addFunction("ListSquads", ListSquads);
|
||||||
|
}
|
||||||
|
|
||||||
|
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<std::string> 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;
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
|
||||||
|
#include "DataDefs.h"
|
||||||
|
|
||||||
|
#include "Basic.pb.h"
|
||||||
|
|
||||||
|
namespace df
|
||||||
|
{
|
||||||
|
struct material;
|
||||||
|
struct unit;
|
||||||
|
struct language_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace DFHack
|
||||||
|
{
|
||||||
|
class MaterialInfo;
|
||||||
|
|
||||||
|
using google::protobuf::RepeatedField;
|
||||||
|
using google::protobuf::RepeatedPtrField;
|
||||||
|
|
||||||
|
DFHACK_EXPORT void strVectorToRepeatedField(RepeatedPtrField<std::string> *pf,
|
||||||
|
const std::vector<std::string> &vec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent bitfield bits as a repeated string field.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
inline void bitfield_to_string(RepeatedPtrField<std::string> *pf, const T &val) {
|
||||||
|
std::vector<std::string> tmp;
|
||||||
|
bitfield_to_string<T>(&tmp, val);
|
||||||
|
strVectorToRepeatedField(pf, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent flagarray bits as a repeated string field.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
inline void flagarray_to_string(RepeatedPtrField<std::string> *pf, const BitArray<T> &val) {
|
||||||
|
std::vector<std::string> tmp;
|
||||||
|
flagarray_to_string<T>(&tmp, val);
|
||||||
|
strVectorToRepeatedField(pf, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent flagarray bits as a repeated int field.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
void flagarray_to_ints(RepeatedField<google::protobuf::int32> *pf, const BitArray<T> &val) {
|
||||||
|
for (int i = 0; i < val.size*8; i++)
|
||||||
|
if (val.is_set(T(i)))
|
||||||
|
pf->Add(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
using dfproto::EnumItemName;
|
||||||
|
|
||||||
|
DFHACK_EXPORT void describeEnum(RepeatedPtrField<EnumItemName> *pf, int base,
|
||||||
|
int size, const char* const *names);
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void describe_enum(RepeatedPtrField<EnumItemName> *pf)
|
||||||
|
{
|
||||||
|
typedef df::enum_traits<T> traits;
|
||||||
|
int base = traits::first_item;
|
||||||
|
int size = traits::last_item - base + 1;
|
||||||
|
describeEnum(pf, base, size, traits::key_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
DFHACK_EXPORT void describeBitfield(RepeatedPtrField<EnumItemName> *pf,
|
||||||
|
int size, const bitfield_item_info *items);
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void describe_bitfield(RepeatedPtrField<EnumItemName> *pf)
|
||||||
|
{
|
||||||
|
typedef df::bitfield_traits<T> traits;
|
||||||
|
describeBitfield(pf, traits::bit_count, traits::bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////
|
||||||
|
|
||||||
|
using dfproto::BasicMaterialInfo;
|
||||||
|
using dfproto::BasicMaterialInfoMask;
|
||||||
|
|
||||||
|
DFHACK_EXPORT void describeMaterial(BasicMaterialInfo *info, df::material *mat,
|
||||||
|
const BasicMaterialInfoMask *mask = NULL);
|
||||||
|
DFHACK_EXPORT void describeMaterial(BasicMaterialInfo *info, const MaterialInfo &mat,
|
||||||
|
const BasicMaterialInfoMask *mask = NULL);
|
||||||
|
|
||||||
|
using dfproto::NameInfo;
|
||||||
|
|
||||||
|
DFHACK_EXPORT void describeName(NameInfo *info, df::language_name *name);
|
||||||
|
|
||||||
|
using dfproto::BasicUnitInfo;
|
||||||
|
using dfproto::BasicUnitInfoMask;
|
||||||
|
|
||||||
|
DFHACK_EXPORT void describeUnit(BasicUnitInfo *info, df::unit *unit,
|
||||||
|
const BasicUnitInfoMask *mask = NULL);
|
||||||
|
|
||||||
|
/////
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,114 @@
|
|||||||
|
package dfproto;
|
||||||
|
|
||||||
|
option optimize_for = LITE_RUNTIME;
|
||||||
|
|
||||||
|
message EnumItemName {
|
||||||
|
required int32 value = 1;
|
||||||
|
optional string name = 2;
|
||||||
|
optional int32 bit_size = 3 [default = 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
message BasicMaterialId {
|
||||||
|
required int32 type = 1;
|
||||||
|
required sint32 index = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
message BasicMaterialInfo {
|
||||||
|
required int32 type = 1;
|
||||||
|
required sint32 index = 2;
|
||||||
|
required string token = 3;
|
||||||
|
|
||||||
|
repeated int32 flags = 4; // of material_flags
|
||||||
|
|
||||||
|
optional int32 subtype = 5 [default = -1];
|
||||||
|
optional int32 creature_id = 6 [default = -1];
|
||||||
|
optional int32 plant_id = 7 [default = -1];
|
||||||
|
optional int32 histfig_id = 8 [default = -1];
|
||||||
|
|
||||||
|
optional string name_prefix = 9 [default = ""];
|
||||||
|
|
||||||
|
repeated fixed32 state_color = 10;
|
||||||
|
repeated string state_name = 11;
|
||||||
|
repeated string state_adj = 12;
|
||||||
|
|
||||||
|
message Product {
|
||||||
|
required string id = 1;
|
||||||
|
required int32 type = 2;
|
||||||
|
required sint32 index = 3;
|
||||||
|
};
|
||||||
|
repeated string reaction_class = 13;
|
||||||
|
repeated Product reaction_product = 14;
|
||||||
|
|
||||||
|
repeated int32 inorganic_flags = 15;
|
||||||
|
};
|
||||||
|
|
||||||
|
message BasicMaterialInfoMask {
|
||||||
|
enum StateType {
|
||||||
|
Solid = 0;
|
||||||
|
Liquid = 1;
|
||||||
|
Gas = 2;
|
||||||
|
Powder = 3;
|
||||||
|
Paste = 4;
|
||||||
|
Pressed = 5;
|
||||||
|
};
|
||||||
|
repeated StateType states = 1;
|
||||||
|
optional int32 temperature = 4 [default = 10015];
|
||||||
|
|
||||||
|
optional bool flags = 2 [default = false];
|
||||||
|
optional bool reaction = 3 [default = false];
|
||||||
|
};
|
||||||
|
|
||||||
|
message NameInfo {
|
||||||
|
optional string first_name = 1;
|
||||||
|
optional string nickname = 2;
|
||||||
|
|
||||||
|
optional int32 language_id = 3 [default = -1];
|
||||||
|
|
||||||
|
optional string last_name = 4;
|
||||||
|
optional string english_name = 5;
|
||||||
|
};
|
||||||
|
|
||||||
|
message SkillInfo {
|
||||||
|
required int32 id = 1;
|
||||||
|
required int32 level = 2;
|
||||||
|
required int32 experience = 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
message BasicUnitInfo {
|
||||||
|
required int32 unit_id = 1;
|
||||||
|
|
||||||
|
optional NameInfo name = 2;
|
||||||
|
|
||||||
|
required fixed32 flags1 = 3;
|
||||||
|
required fixed32 flags2 = 4;
|
||||||
|
required fixed32 flags3 = 5;
|
||||||
|
|
||||||
|
required int32 race = 6;
|
||||||
|
required int32 caste = 7;
|
||||||
|
optional int32 gender = 8 [default = -1];
|
||||||
|
|
||||||
|
optional int32 civ_id = 9 [default = -1];
|
||||||
|
optional int32 histfig_id = 10 [default = -1];
|
||||||
|
|
||||||
|
repeated int32 labors = 11;
|
||||||
|
|
||||||
|
repeated SkillInfo skills = 12;
|
||||||
|
|
||||||
|
required int32 pos_x = 13;
|
||||||
|
required int32 pos_y = 14;
|
||||||
|
required int32 pos_z = 15;
|
||||||
|
};
|
||||||
|
|
||||||
|
message BasicUnitInfoMask {
|
||||||
|
optional bool labors = 1 [default = false];
|
||||||
|
optional bool skills = 2 [default = false];
|
||||||
|
};
|
||||||
|
|
||||||
|
message BasicSquadInfo {
|
||||||
|
required int32 squad_id = 1;
|
||||||
|
|
||||||
|
optional NameInfo name = 2;
|
||||||
|
optional string alias = 3;
|
||||||
|
|
||||||
|
repeated sint32 members = 4;
|
||||||
|
};
|
@ -0,0 +1,45 @@
|
|||||||
|
package dfproto;
|
||||||
|
|
||||||
|
option optimize_for = LITE_RUNTIME;
|
||||||
|
|
||||||
|
import "Basic.proto";
|
||||||
|
|
||||||
|
message ListEnumsOut {
|
||||||
|
repeated EnumItemName material_flags = 1;
|
||||||
|
repeated EnumItemName inorganic_flags = 2;
|
||||||
|
|
||||||
|
repeated EnumItemName unit_flags1 = 3;
|
||||||
|
repeated EnumItemName unit_flags2 = 4;
|
||||||
|
repeated EnumItemName unit_flags3 = 5;
|
||||||
|
|
||||||
|
repeated EnumItemName unit_labor = 6;
|
||||||
|
repeated EnumItemName job_skill = 7;
|
||||||
|
};
|
||||||
|
|
||||||
|
message ListMaterialsIn {
|
||||||
|
optional BasicMaterialInfoMask mask = 1;
|
||||||
|
repeated BasicMaterialId id_list = 2;
|
||||||
|
optional bool builtin = 3;
|
||||||
|
optional bool inorganic = 4;
|
||||||
|
optional bool creatures = 5;
|
||||||
|
optional bool plants = 6;
|
||||||
|
};
|
||||||
|
message ListMaterialsOut {
|
||||||
|
repeated BasicMaterialInfo value = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
message ListUnitsIn {
|
||||||
|
optional BasicUnitInfoMask mask = 1;
|
||||||
|
repeated int32 id_list = 2;
|
||||||
|
|
||||||
|
optional int32 race = 3;
|
||||||
|
optional int32 civ_id = 4;
|
||||||
|
};
|
||||||
|
message ListUnitsOut {
|
||||||
|
repeated BasicUnitInfo value = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
message ListSquadsIn {}
|
||||||
|
message ListSquadsOut {
|
||||||
|
repeated BasicSquadInfo value = 1;
|
||||||
|
}
|
Loading…
Reference in New Issue