示例#1
0
bool Mineserver::init()
{
  // expand '~', '~user' in next vars
  bool error = false;
  const char* const vars[] =
  {
    "system.path.data",
    "system.path.plugins",
    "system.path.home",
    "system.pid_file",
  };
  for (size_t i = 0; i < sizeof(vars) / sizeof(vars[0]); i++)
  {
    ConfigNode::Ptr node = config()->mData(vars[i]);
    if (!node)
    {
      LOG2(ERROR, std::string("Variable is missing: ") + vars[i]);
      error = true;
      continue;
    }
    if (node->type() != CONFIG_NODE_STRING)
    {
      LOG2(ERROR, std::string("Variable is not string: ") + vars[i]);
      error = true;
      continue;
    }

    const std::string newvalue = relativeToAbsolute(node->sData());

    node->setData(newvalue);
    LOG2(INFO, std::string(vars[i]) + " = \"" + newvalue + "\"");
  }

  if (error)
  {
    return false;
  }

  const std::string str = config()->sData("system.path.home");
#ifdef WIN32
  if (_chdir(str.c_str()) != 0)
#else
  if (chdir(str.c_str()) != 0)
#endif
  {
    LOG2(ERROR, "Failed to change working directory to: " + str);
    return false;
  }

  // Write PID to file
  std::ofstream pid_out((config()->sData("system.pid_file")).c_str());
  if (!pid_out.fail())
  {
#ifdef WIN32
    pid_out << _getpid();
#else
    pid_out << getpid();
#endif
  }
  pid_out.close();


  // screen::init() needs m_plugin
  m_plugin = new Plugin;

  init_plugin_api();

  if (config()->bData("system.interface.use_cli"))
  {
    // Init our Screen
    screen()->init(VERSION);
  }


  LOG2(INFO, "Welcome to Mineserver v" + VERSION);

  MapGen* mapgen = new MapGen;
  MapGen* nethergen = new NetherGen;
  MapGen* heavengen = new HeavenGen;
  MapGen* biomegen = new BiomeGen;
  MapGen* eximgen = new EximGen;
  m_mapGenNames.push_back(mapgen);
  m_mapGenNames.push_back(nethergen);
  m_mapGenNames.push_back(heavengen);
  m_mapGenNames.push_back(biomegen);
  m_mapGenNames.push_back(eximgen);

  m_saveInterval = m_config->iData("map.save_interval");

  m_only_helmets = m_config->bData("system.armour.helmet_strict");
  m_pvp_enabled = m_config->bData("system.pvp.enabled");
  m_damage_enabled = m_config->bData("system.damage.enabled");

  const char* key = "map.storage.nbt.directories"; // Prefix for worlds config
  if (m_config->has(key) && (m_config->type(key) == CONFIG_NODE_LIST))
  {
    std::list<std::string> tmp = m_config->mData(key)->keys();
    int n = 0;
    for (std::list<std::string>::const_iterator it = tmp.begin(); it != tmp.end(); ++it)
    {
      m_map.push_back(new Map());
      Physics* phy = new Physics;
      phy->map = n;
      m_physics.push_back(phy);
      int k = m_config->iData((std::string(key) + ".") + (*it));
      if ((uint32_t)k >= m_mapGenNames.size())
      {
        std::ostringstream s;
        s << "Error! Mapgen number " << k << " in config. " << m_mapGenNames.size() << " Mapgens known";
        LOG2(INFO, s.str());
      }
      // WARNING: if k is too big this will be an access error! -- louisdx
      MapGen* m = m_mapGenNames[k];
      m_mapGen.push_back(m);
      n++;

    }
  }
  else
  {
    LOG2(WARNING, "Cannot find map.storage.nbt.directories.*");
  }

  if (m_map.size() == 0)
  {
    LOG2(ERROR, "No worlds in Config!");
    return false;
  }

  m_chat           = new Chat;
  m_furnaceManager = new FurnaceManager;
  m_packetHandler  = new PacketHandler;
  m_inventory      = new Inventory(m_config->sData("system.path.data") + '/' + "recipes", ".recipe", "ENABLED_RECIPES.cfg");
  m_mobs           = new Mobs;

  return true;
}
示例#2
0
bool ConfigParser::parse(std::istream& data, ConfigNode::Ptr ptr)
{
  ConfigScanner scanner;
  ConfigLexer lexer(scanner);
  ConfigNode::Ptr root = ptr;

  data.seekg(0, std::ios::end);
  const size_t data_size = size_t(data.tellg());
  data.seekg(0, std::ios::beg);

  char* buf = new char[data_size];
  data.read(buf, data_size);
  std::string data_str(buf, data_size);
  delete[] buf;

  if (!scanner.read(data_str))
  {
    std::cerr << "Couldn't read data!\n";
    return false;
  }

  int token_type;
  std::string token_data;
  std::string token_label;
  std::stack<ConfigNode::Ptr> nodeStack;
  ConfigNode::Ptr currentNode = root;
  nodeStack.push(currentNode);

  while (lexer.get_token(token_type, token_data))
  {
    if (!token_type)
    {
      std::cerr << "Unrecognised data!\n";
      return false;
    }

    // Include other files only if we're in the root node
    if (token_type == CONFIG_TOKEN_ENTITY && token_data == "include" && currentNode == root)
    {
      int tmp_type;
      std::string tmp_data;

      lexer.get_token(tmp_type, tmp_data);
      if (tmp_type == CONFIG_TOKEN_STRING)
      {
        if (m_includes >= MAX_INCLUDES)
        {
          std::cerr << "reached maximum number of include directives: " << m_includes << "\n";
          return false;
        }

        // allow only filename without path
        if ((tmp_data.find('/')  != std::string::npos)
            || (tmp_data.find('\\') != std::string::npos))
        {
          std::cerr << "include directive accepts only filename: " << tmp_data << "\n";
          return false;
        }

        // prepend home path
        const std::string var  = "system.path.home";
        const ConfigNode::Ptr node = root->get(var, false);
        std::string home;
        if (!node || (home = node->sData()).empty())
        {
          std::cerr << "include directive is not allowed before: " << var << "\n";
          return false;
        }

        tmp_data = relativeToAbsolute(home) + PATH_SEPARATOR + tmp_data;

        if (!parse(tmp_data, root))
        {
          return false;
        }
        m_includes++;

        continue;
      }
      else
      {
        lexer.put_token(tmp_type, tmp_data);
      }
    }

    if (token_type == CONFIG_TOKEN_ENTITY || token_type == CONFIG_TOKEN_LABEL)
    {
      token_label = token_data;
    }

    else if (token_type == CONFIG_TOKEN_OPERATOR_ASSIGN)
    {
      if (currentNode != root)
      {
        currentNode->clear();
      }
    }

    else if (token_type == CONFIG_TOKEN_BOOLEAN)
    {
      ConfigNode::Ptr newNode(!token_label.empty() && currentNode->has(token_label) ? currentNode->get(token_label) : ConfigNode::Ptr(new ConfigNode));

      newNode->setData(token_data == "true");

      if (!token_label.empty())
      {
        currentNode->set(token_label, newNode, true);
        token_label.clear();
      }
      else
      {
        currentNode->add(newNode);
      }
    }

    else if (token_type == CONFIG_TOKEN_STRING)
    {
      ConfigNode::Ptr newNode(!token_label.empty() && currentNode->has(token_label) ? currentNode->get(token_label) : ConfigNode::Ptr(new ConfigNode));

      newNode->setData(token_data);

      if (!token_label.empty())
      {
        currentNode->set(token_label, newNode, true);
        token_label.clear();
      }
      else
      {
        currentNode->add(newNode);
      }
    }

    else if (token_type == CONFIG_TOKEN_NUMBER)
    {
      ConfigNode::Ptr newNode(token_label.size() && currentNode->has(token_label) ? currentNode->get(token_label) : ConfigNode::Ptr(new ConfigNode));

      newNode->setData((double)::atof(token_data.c_str()));

      if (!token_label.empty())
      {
        currentNode->set(token_label, newNode, true);
        token_label.clear();
      }
      else
      {
        currentNode->add(newNode);
      }
    }

    else if (token_type == CONFIG_TOKEN_LIST_OPEN)
    {
      ConfigNode::Ptr newNode(token_label.size() && currentNode->has(token_label) ? currentNode->get(token_label) : ConfigNode::Ptr(new ConfigNode));

      newNode->setType(CONFIG_NODE_LIST);

      if (!token_label.empty())
      {
        currentNode->set(token_label, newNode, true);

        newNode = currentNode->get(token_label, true);

        token_label.clear();
      }
      else
      {
        currentNode->add(newNode);
      }

      nodeStack.push(currentNode);
      currentNode = newNode;
    }

    else if (token_type == CONFIG_TOKEN_LIST_CLOSE)
    {
      currentNode = nodeStack.top();
      nodeStack.pop();
    }
  }

  return true;
}