Example #1
0
void Animation::parsePrefab(json::Value& val)
{
	if(val.isMember("sequences") && !val["sequences"].empty())
	{
		json::Value sequences = val["sequences"];

		for(json::Value::iterator it = sequences.begin(); it != sequences.end(); ++it)
		{
			if(!(*it).isMember("start") || !(*it).isMember("end") || !(*it).isMember("fps"))
			{
				szerr << "Animation sequence definition must have start and end frame and fps value." << ErrorStream::error;
				continue;
			}

			sf::Uint32 start	= (*it)["start"].asUInt();
			sf::Uint32 end		= (*it)["end"].asUInt();
			sf::Uint32 fps		= (*it)["fps"].asUInt();

			bool looping		= (*it).get("looping", 0).asBool();
			std::string next	= (*it).get("next", "").asString();

			defineAnimation(it.memberName(), start, end, fps, looping, next);
		}
	}

	if(val.isMember("autoplay"))
	{
		if(val["autoplay"].isString())
		{
			play(val["autoplay"].asString());
		}
	}
}
Example #2
0
void Roster::update(const json::Value& data, bool whiny)
{
    if (data.isObject() &&
        data.isMember("id") &&
        data.isMember("user") &&
        data.isMember("name") //&&
        //data.isMember("type")
        ) {
        TraceS(this) << "Updating: " << json::stringify(data, true) << endl;
        std::string id = data["id"].asString();
        Peer* peer = get(id, false);
        if (!peer) {
            peer = new Peer(data);
            add(id, peer);
        } else
            static_cast<json::Value&>(*peer) = data;
    }
    else if (data.isArray()) {
        for (auto it = data.begin(); it != data.end(); it++) {
            update(*it, whiny);
        }
    }
    else {
        std::string error("Bad presence data: " + json::stringify(data));
        ErrorS(this) << error << endl;
        if (whiny)
            throw std::runtime_error(error);
    }
}
Example #3
0
  /// Returns a Smooth-format manifest file
  std::string BuildManifest(std::string & MovieId, JSON::Value & metadata){
    std::stringstream Result;
    Result << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
    Result << "<SmoothStreamingMedia MajorVersion=\"2\" MinorVersion=\"0\" TimeScale=\"10000000\" Duration=\"" << metadata["lastms"].asInt()
        << "\">\n";
    if (metadata.isMember("audio")){
      Result << "  <StreamIndex Type=\"audio\" QualityLevels=\"1\" Name=\"audio\" Chunks=\"" << metadata["keytime"].size()
          << "\" Url=\"Q({bitrate})/A({start time})\">\n";
      Result << "    <QualityLevel Index=\"0\" Bitrate=\"" << metadata["audio"]["bps"].asInt() * 8 << "\" CodecPrivateData=\"";
      Result << std::hex;
      for (int i = 0; i < metadata["audio"]["init"].asString().size(); i++){
        Result << std::setfill('0') << std::setw(2) << std::right << (int)metadata["audio"]["init"].asString()[i];
      }
      Result << std::dec;
      Result << "\" SamplingRate=\"" << metadata["audio"]["rate"].asInt()
          << "\" Channels=\"2\" BitsPerSample=\"16\" PacketSize=\"4\" AudioTag=\"255\" FourCC=\"AACL\"  />\n";
      for (int i = 0; i < metadata["keytime"].size() - 1; i++){
        Result << "    <c ";
        if (i == 0){
          Result << "t=\"0\" ";
        }
        Result << "d=\"" << 10000 * (metadata["keytime"][i + 1].asInt() - metadata["keytime"][i].asInt()) << "\" />\n";
      }
      Result << "    <c d=\"" << 10000 * (metadata["lastms"].asInt() - metadata["keytime"][metadata["keytime"].size() - 1].asInt()) << "\" />\n";
      Result << "   </StreamIndex>\n";
    }
    if (metadata.isMember("video")){
      Result << "  <StreamIndex Type=\"video\" QualityLevels=\"1\" Name=\"video\" Chunks=\"" << metadata["keytime"].size()
          << "\" Url=\"Q({bitrate})/V({start time})\" MaxWidth=\"" << metadata["video"]["width"].asInt() << "\" MaxHeight=\""
          << metadata["video"]["height"].asInt() << "\" DisplayWidth=\"" << metadata["video"]["width"].asInt() << "\" DisplayHeight=\""
          << metadata["video"]["height"].asInt() << "\">\n";
      Result << "    <QualityLevel Index=\"0\" Bitrate=\"" << metadata["video"]["bps"].asInt() * 8 << "\" CodecPrivateData=\"";
      MP4::AVCC avccbox;
      avccbox.setPayload(metadata["video"]["init"].asString());
      std::string tmpString = avccbox.asAnnexB();
      Result << std::hex;
      for (int i = 0; i < tmpString.size(); i++){
        Result << std::setfill('0') << std::setw(2) << std::right << (int)tmpString[i];
      }
      Result << std::dec;
      Result << "\" MaxWidth=\"" << metadata["video"]["width"].asInt() << "\" MaxHeight=\"" << metadata["video"]["height"].asInt()
          << "\" FourCC=\"AVC1\" />\n";
      for (int i = 0; i < metadata["keytime"].size() - 1; i++){
        Result << "    <c ";
        if (i == 0){
          Result << "t=\"0\" ";
        }
        Result << "d=\"" << 10000 * (metadata["keytime"][i + 1].asInt() - metadata["keytime"][i].asInt()) << "\" />\n";
      }
      Result << "    <c d=\"" << 10000 * (metadata["lastms"].asInt() - metadata["keytime"][metadata["keytime"].size() - 1].asInt()) << "\" />\n";
      Result << "   </StreamIndex>\n";
    }
    Result << "</SmoothStreamingMedia>\n";

#if DEBUG >= 8
    std::cerr << "Sending this manifest:" << std::endl << Result << std::endl;
#endif
    return Result.str();
  } //BuildManifest
  ///\brief Builds a bootstrap for use in HTTP Dynamic streaming.
  ///\param streamName The name of the stream.
  ///\param metadata The current metadata, used to generate the index.
  ///\param fragnum The index of the current fragment
  ///\return The generated bootstrap.
  std::string dynamicBootstrap(std::string & streamName, JSON::Value & metadata, int fragnum = 0){
    std::string empty;

    MP4::ASRT asrt;
    asrt.setUpdate(false);
    asrt.setVersion(1);
    //asrt.setQualityEntry(empty, 0);
    if (metadata.isMember("live")){
      asrt.setSegmentRun(1, 4294967295ul, 0);
    }else{
      asrt.setSegmentRun(1, metadata["keytime"].size(), 0);
    }

    MP4::AFRT afrt;
    afrt.setUpdate(false);
    afrt.setVersion(1);
    afrt.setTimeScale(1000);
    //afrt.setQualityEntry(empty, 0);
    MP4::afrt_runtable afrtrun;
    if (metadata.isMember("live")){
      // restrict data to last 2 fragments, unless an earlier fragment was expressly requested.
      int count = 0;
      unsigned int begin = std::max(0u, metadata["keynum"].size() - 3);
      while (begin > 0 && fragnum && metadata["keynum"][begin].asInt() > fragnum){
        begin--;
      }
      for (int i = begin; i < metadata["keynum"].size(); i++){
        afrtrun.firstFragment = metadata["keynum"][i].asInt();
        afrtrun.firstTimestamp = metadata["keytime"][i].asInt();
        afrtrun.duration = metadata["keylen"][i].asInt();
        afrt.setFragmentRun(afrtrun, count++);
      }
    }else{
      for (int i = 0; i < metadata["keynum"].size(); i++){
        afrtrun.firstFragment = metadata["keynum"][i].asInt();
        afrtrun.firstTimestamp = metadata["keytime"][i].asInt();
        afrtrun.duration = metadata["keylen"][i].asInt();
        afrt.setFragmentRun(afrtrun, i);
      }
    }

    MP4::ABST abst;
    abst.setVersion(1);
    abst.setBootstrapinfoVersion(1);
    abst.setProfile(0);
    abst.setUpdate(false);
    abst.setTimeScale(1000);
    abst.setLive(false);
    abst.setCurrentMediaTime(metadata["lastms"].asInt());
    abst.setSmpteTimeCodeOffset(0);
    abst.setMovieIdentifier(streamName);
    abst.setSegmentRunTable(asrt, 0);
    abst.setFragmentRunTable(afrt, 0);

#if DEBUG >= 8
    std::cout << "Sending bootstrap:" << std::endl << abst.toPrettyString(0) << std::endl;
#endif
    return std::string((char*)abst.asBox(), (int)abst.boxedSize());
  }
Example #5
0
/// Adds a single DTSC packet to the stream, updating the internal metadata if needed.
void DTSC::Stream::addPacket(JSON::Value & newPack) {
  livePos newPos;
  newPos.trackID = newPack["trackid"].asInt();
  newPos.seekTime = newPack["time"].asInt();
  if (!metadata.tracks.count(newPos.trackID) && (!newPack.isMember("mark") || newPack["mark"].asStringRef() != "pause")) {
    return;
  }
  if (buffercount > 1 && metadata.tracks[newPos.trackID].keys.size() > 1 && newPos.seekTime < (long long unsigned int)metadata.tracks[newPos.trackID].keys.rbegin()->getTime()) {
    resetStream();
  }
  while (buffers.count(newPos) > 0) {
    newPos.seekTime++;
  }
  while (buffercount == 1 && buffers.size() > 0) {
    cutOneBuffer();
  }
  buffers[newPos] = newPack;
  datapointertype = INVALID;
  std::string tmp = "";
  if (newPack.isMember("trackid") && newPack["trackid"].asInt() > 0) {
    tmp = metadata.tracks[newPack["trackid"].asInt()].type;
  }
  if (newPack.isMember("datatype")) {
    tmp = newPack["datatype"].asStringRef();
  }
  if (tmp == "video") {
    datapointertype = VIDEO;
  }
  if (tmp == "audio") {
    datapointertype = AUDIO;
  }
  if (tmp == "meta") {
    datapointertype = META;
  }
  if (tmp == "pause_marker" || (newPack.isMember("mark") && newPack["mark"].asStringRef() == "pause")) {
    datapointertype = PAUSEMARK;
  }
  if (buffercount > 1) {
    metadata.update(newPack);
    if (newPack.isMember("keyframe") || (long long unsigned int)metadata.tracks[newPos.trackID].keys.rbegin()->getTime() == newPos.seekTime) {
      keyframes[newPos.trackID].insert(newPos);
    }
    metadata.live = true;
    //throw away buffers if buffer time is met
    int trid = buffers.begin()->first.trackID;
    int firstTime = buffers.begin()->first.seekTime;
    int lastTime = buffers.rbegin()->first.seekTime - buffertime;
    while ((!metadata.tracks[trid].keys.size() && firstTime < lastTime) || (metadata.tracks[trid].keys.size() && metadata.tracks[trid].keys.rbegin()->getTime() < lastTime) || (metadata.tracks[trid].keys.size() > 2 && metadata.tracks[trid].keys.rbegin()->getTime() - firstTime > buffertime)) {
      cutOneBuffer();
      trid = buffers.begin()->first.trackID;
      firstTime = buffers.begin()->first.seekTime;
    }
    metadata.bufferWindow = buffertime;
  }

}
///\brief Parse a given stream configuration.
///\param in The requested configuration.
///\param out The new configuration after parsing.
void CheckStreams(JSON::Value & in, JSON::Value & out) {
    bool changed = false;

    //check for new streams and updates
    for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++) {
        if (out.isMember(jit->first)) {
            if ( !streamsEqual(jit->second, out[jit->first])) {
                Log("STRM", std::string("Updated stream ") + jit->first);
                Util::Procs::Stop(jit->first);
                startStream(jit->first, jit->second);
            }
        } else {
            Log("STRM", std::string("New stream ") + jit->first);
            startStream(jit->first, jit->second);
        }
    }

    //check for deleted streams
    for (JSON::ObjIter jit = out.ObjBegin(); jit != out.ObjEnd(); jit++) {
        if ( !in.isMember(jit->first)) {
            Log("STRM", std::string("Deleted stream ") + jit->first);
            Util::Procs::Stop(jit->first);
        }
    }

    //update old-style configurations to new-style
    for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++) {
        if (jit->second.isMember("channel")) {
            if ( !jit->second.isMember("source")) {
                jit->second["source"] = jit->second["channel"]["URL"];
            }
            jit->second.removeMember("channel");
        }
        if (jit->second.isMember("preset")) {
            jit->second.removeMember("preset");
        }
    }

    out = in;
}
 void CheckStreams(JSON::Value & in, JSON::Value & out){
   bool changed = false;
   for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++){
     if (out.isMember(jit->first)){
       if ( !streamsEqual(jit->second, out[jit->first])){
         Log("STRM", std::string("Updated stream ") + jit->first);
         Util::Procs::Stop(jit->first);
         startStream(jit->first, jit->second);
       }
     }else{
       Log("STRM", std::string("New stream ") + jit->first);
       startStream(jit->first, jit->second);
     }
   }
   for (JSON::ObjIter jit = out.ObjBegin(); jit != out.ObjEnd(); jit++){
     if ( !in.isMember(jit->first)){
       Log("STRM", std::string("Deleted stream ") + jit->first);
       Util::Procs::Stop(jit->first);
     }
   }
   out = in;
 }
  ///\brief Builds an index file for HTTP Dynamic streaming.
  ///\param streamName The name of the stream.
  ///\param metadata The current metadata, used to generate the index.
  ///\return The index file for HTTP Dynamic Streaming.
  std::string dynamicIndex(std::string & streamName, JSON::Value & metadata){
    std::string Result;
    if (metadata.isMember("vod")){
      Result =
          "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
              "<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n"
              "<id>" + streamName + "</id>\n"
              "<width>" + metadata["video"]["width"].asString() + "</width>\n"
              "<height>" + metadata["video"]["height"].asString() + "</height>\n"
              "<duration>" + metadata["length"].asString() + ".000</duration>\n"
              "<mimeType>video/mp4</mimeType>\n"
              "<streamType>recorded</streamType>\n"
              "<deliveryType>streaming</deliveryType>\n"
              "<bootstrapInfo profile=\"named\" id=\"bootstrap1\">" + Base64::encode(dynamicBootstrap(streamName, metadata)) + "</bootstrapInfo>\n"
              "<media streamId=\"1\" bootstrapInfoId=\"bootstrap1\" url=\"" + streamName + "/\">\n"
              "<metadata>AgAKb25NZXRhRGF0YQMAAAk=</metadata>\n"
              "</media>\n"
              "</manifest>\n";
    }else{
      Result =
          "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
              "<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n"
              "<id>" + streamName + "</id>\n"
              "<dvrInfo windowDuration=\"" + metadata["buffer_window"].asString().substr(0, metadata["buffer_window"].asString().size() - 3) + "\"></dvrInfo>"
              "<mimeType>video/mp4</mimeType>\n"
              "<streamType>live</streamType>\n"
              "<deliveryType>streaming</deliveryType>\n"
              "<media url=\"" + streamName + "/\">\n"
              "<metadata>AgAKb25NZXRhRGF0YQMAAAk=</metadata>\n"
              "</media>\n"
              "<bootstrapInfo profile=\"named\" url=\"" + streamName + ".abst\" />\n"
              "</manifest>\n";
    }
#if DEBUG >= 8
    std::cerr << "Sending this manifest:" << std::endl << Result << std::endl;
#endif
    return Result;
  } //BuildManifest
Example #9
0
std::pair<bool, Json::Value>
ripplePathFind(RippleLineCache::pointer const& cache, 
  RippleAddress const& raSrc, RippleAddress const& raDst,
    STAmount const& saDstAmount, Ledger::pointer const& lpLedger, 
      Json::Value const& jvSrcCurrencies, 
        boost::optional<Json::Value> const& contextPaths, int const& level)
{
    FindPaths fp(
        cache,
        raSrc.getAccountID(),
        raDst.getAccountID(),
        saDstAmount,
        level,
        4); // max paths

    Json::Value jvArray(Json::arrayValue);

    for (unsigned int i = 0; i != jvSrcCurrencies.size(); ++i)
    {
        Json::Value jvSource = jvSrcCurrencies[i];

        Currency uSrcCurrencyID;
        Account uSrcIssuerID;

        if (!jvSource.isObject())
            return std::make_pair(false, rpcError(rpcINVALID_PARAMS));

        // Parse mandatory currency.
        if (!jvSource.isMember(jss::currency)
            || !to_currency(
            uSrcCurrencyID, jvSource[jss::currency].asString()))
        {
            WriteLog(lsINFO, RPCHandler) << "Bad currency.";

            return std::make_pair(false, rpcError(rpcSRC_CUR_MALFORMED));
        }

        if (uSrcCurrencyID.isNonZero())
            uSrcIssuerID = raSrc.getAccountID();

        // Parse optional issuer.
        if (jvSource.isMember(jss::issuer) &&
            ((!jvSource[jss::issuer].isString() ||
            !to_issuer(uSrcIssuerID, jvSource[jss::issuer].asString())) ||
            (uSrcIssuerID.isZero() != uSrcCurrencyID.isZero()) ||
            (noAccount() == uSrcIssuerID)))
        {
            WriteLog(lsINFO, RPCHandler) << "Bad issuer.";
            return std::make_pair(false, rpcError(rpcSRC_ISR_MALFORMED));
        }

        STPathSet spsComputed;
        if (contextPaths)
        {
            Json::Value pathSet = Json::objectValue;
            pathSet[jss::Paths] = contextPaths.get();
            STParsedJSONObject paths("pathSet", pathSet);
            if (paths.object.get() == nullptr)
                return std::make_pair(false, paths.error);
            else
            {
                spsComputed = paths.object.get()->getFieldPathSet(sfPaths);
                WriteLog(lsTRACE, RPCHandler) << "ripple_path_find: Paths: " <<
                    spsComputed.getJson(0);
            }
        }

        STPath fullLiquidityPath;
        auto valid = fp.findPathsForIssue(
            { uSrcCurrencyID, uSrcIssuerID },
            spsComputed,
            fullLiquidityPath);
        if (!valid)
        {
            WriteLog(lsWARNING, RPCHandler)
                << "ripple_path_find: No paths found.";
        }
        else
        {
            auto& issuer =
                isXRP(uSrcIssuerID) ?
                isXRP(uSrcCurrencyID) ? // Default to source account.
                xrpAccount() :
                Account(raSrc.getAccountID())
                : uSrcIssuerID;            // Use specifed issuer.

            STAmount saMaxAmount({ uSrcCurrencyID, issuer }, 1);
            saMaxAmount.negate();

            LedgerEntrySet lesSandbox(lpLedger, tapNONE);

            auto rc = path::RippleCalc::rippleCalculate(
                lesSandbox,
                saMaxAmount,            // --> Amount to send is unlimited
                //     to get an estimate.
                saDstAmount,            // --> Amount to deliver.
                raDst.getAccountID(),  // --> Account to deliver to.
                raSrc.getAccountID(),  // --> Account sending from.
                spsComputed);           // --> Path set.

            WriteLog(lsWARNING, RPCHandler)
                << "ripple_path_find:"
                << " saMaxAmount=" << saMaxAmount
                << " saDstAmount=" << saDstAmount
                << " saMaxAmountAct=" << rc.actualAmountIn
                << " saDstAmountAct=" << rc.actualAmountOut;

            if (fullLiquidityPath.size() > 0 &&
                (rc.result() == terNO_LINE || rc.result() == tecPATH_PARTIAL))
            {
                WriteLog(lsDEBUG, PathRequest)
                    << "Trying with an extra path element";

                spsComputed.push_back(fullLiquidityPath);
                lesSandbox.clear();
                rc = path::RippleCalc::rippleCalculate(
                    lesSandbox,
                    saMaxAmount,            // --> Amount to send is unlimited
                    //     to get an estimate.
                    saDstAmount,            // --> Amount to deliver.
                    raDst.getAccountID(),  // --> Account to deliver to.
                    raSrc.getAccountID(),  // --> Account sending from.
                    spsComputed);         // --> Path set.
                WriteLog(lsDEBUG, PathRequest)
                    << "Extra path element gives "
                    << transHuman(rc.result());
            }

            if (rc.result() == tesSUCCESS)
            {
                Json::Value jvEntry(Json::objectValue);

                STPathSet   spsCanonical;

                // Reuse the expanded as it would need to be calcuated
                // anyway to produce the canonical.  (At least unless we
                // make a direct canonical.)

                jvEntry[jss::source_amount] = rc.actualAmountIn.getJson(0);
                jvEntry[jss::paths_canonical] = Json::arrayValue;
                jvEntry[jss::paths_computed] = spsComputed.getJson(0);

                jvArray.append(jvEntry);
            }
            else
            {
                std::string strToken;
                std::string strHuman;

                transResultInfo(rc.result(), strToken, strHuman);

                WriteLog(lsDEBUG, RPCHandler)
                    << "ripple_path_find: "
                    << strToken << " "
                    << strHuman << " "
                    << spsComputed.getJson(0);
            }
        }
    }

    return std::make_pair(true, jvArray);
}
/// This takes a "totals" request, and fills in the response data.
/// 
/// \api
/// `"totals"` requests take the form of:
/// ~~~~~~~~~~~~~~~{.js}
/// {
///   //array of streamnames to accumulate. Empty means all.
///   "streams": ["streama", "streamb", "streamc"],
///   //array of protocols to accumulate. Empty means all.
///   "protocols": ["HLS", "HSS"],
///   //list of requested data fields. Empty means all.
///   "fields": ["clients", "downbps", "upbps"],
///   //unix timestamp of data start. Negative means X seconds ago. Empty means earliest available.
///   "start": 1234567
///   //unix timestamp of data end. Negative means X seconds ago. Empty means latest available (usually 'now').
///   "end": 1234567
/// }
/// ~~~~~~~~~~~~~~~
/// and are responded to as:
/// ~~~~~~~~~~~~~~~{.js}
/// {
///   //unix timestamp of start of data. Always present, always absolute.
///   "start": 1234567,
///   //unix timestamp of end of data. Always present, always absolute.
///   "end": 1234567,
///   //array of actually represented data fields.
///   "fields": [...]
///   // Time between datapoints. Here: 10 points with each 5 seconds afterwards, followed by 10 points with each 1 second afterwards.
///   "interval": [[10, 5], [10, 1]],
///   //the data for the times as mentioned in the "interval" field, in the order they appear in the "fields" field.
///   "data": [[x, y, z], [x, y, z], [x, y, z]]
/// }
/// ~~~~~~~~~~~~~~~
void Controller::fillTotals(JSON::Value & req, JSON::Value & rep){
  //first, figure out the timestamps wanted
  long long int reqStart = 0;
  long long int reqEnd = 0;
  if (req.isMember("start")){
    reqStart = req["start"].asInt();
  }
  if (req.isMember("end")){
    reqEnd = req["end"].asInt();
  }
  //add the current time, if negative or zero.
  if (reqStart < 0){
    reqStart += Util::epoch();
  }
  if (reqStart == 0){
    reqStart = Util::epoch() - STAT_CUTOFF;
  }
  if (reqEnd <= 0){
    reqEnd += Util::epoch();
  }
  //at this point, reqStart and reqEnd are the absolute timestamp.
  
  unsigned int fields = 0;
  //next, figure out the fields wanted
  if (req.isMember("fields") && req["fields"].size()){
    for (JSON::ArrIter it = req["fields"].ArrBegin(); it != req["fields"].ArrEnd(); it++){
      if ((*it).asStringRef() == "clients"){fields |= STAT_TOT_CLIENTS;}
      if ((*it).asStringRef() == "downbps"){fields |= STAT_TOT_BPS_DOWN;}
      if ((*it).asStringRef() == "upbps"){fields |= STAT_TOT_BPS_UP;}
    }
  }
  //select all, if none selected
  if (!fields){fields = STAT_TOT_ALL;}
  //figure out what streams are wanted
  std::set<std::string> streams;
  if (req.isMember("streams") && req["streams"].size()){
    for (JSON::ArrIter it = req["streams"].ArrBegin(); it != req["streams"].ArrEnd(); it++){
      streams.insert((*it).asStringRef());
    }
  }
  //figure out what protocols are wanted
  std::set<std::string> protos;
  if (req.isMember("protocols") && req["protocols"].size()){
    for (JSON::ArrIter it = req["protocols"].ArrBegin(); it != req["protocols"].ArrEnd(); it++){
      protos.insert((*it).asStringRef());
    }
  }
  //output the selected fields
  rep["fields"].null();
  if (fields & STAT_TOT_CLIENTS){rep["fields"].append("clients");}
  if (fields & STAT_TOT_BPS_DOWN){rep["fields"].append("downbps");}
  if (fields & STAT_TOT_BPS_UP){rep["fields"].append("upbps");}
  //start data collection
  std::map<long long unsigned int, totalsData> totalsCount;
  //start with current connections
  if (curConns.size()){
    for (std::map<unsigned long, statStorage>::iterator it = curConns.begin(); it != curConns.end(); it++){
      //data present and wanted? insert it!
      if (it->second.log.size() > 1 && (it->second.log.rbegin()->first >= (unsigned long long)reqStart || it->second.log.begin()->first <= (unsigned long long)reqEnd) && (!streams.size() || streams.count(it->second.streamName)) && (!protos.size() || protos.count(it->second.connector))){
        //keep track of the previous and current, starting at position 2 so there's always a delta down/up value.
        std::map<unsigned long long, statLog>::iterator pi = it->second.log.begin();
        for (std::map<unsigned long long, statLog>::iterator li = ++(it->second.log.begin()); li != it->second.log.end(); li++){
          if (li->first < (unsigned long long)reqStart || pi->first > (unsigned long long)reqEnd){
            continue;
          }
          unsigned int diff = li->first - pi->first;
          unsigned int ddown = (li->second.down - pi->second.down) / diff;
          unsigned int dup = (li->second.up - pi->second.up) / diff;
          for (long long unsigned int t = pi->first; t < li->first; t++){
            if (t >= (unsigned long long)reqStart && t <= (unsigned long long)reqEnd){
              totalsCount[t].add(ddown, dup);
            }
          }
          pi = li;//set previous iterator to log iterator
        }
      }
    }
  }
  //look at history
  if (oldConns.size()){
    for (std::map<unsigned long long int, statStorage>::iterator it = oldConns.begin(); it != oldConns.end(); it++){
      //data present and wanted? insert it!
      if (it->second.log.size() > 1 && (it->second.log.rbegin()->first >= (unsigned long long)reqStart || it->second.log.begin()->first <= (unsigned long long)reqEnd) && (!streams.size() || streams.count(it->second.streamName)) && (!protos.size() || protos.count(it->second.connector))){
        //keep track of the previous and current, starting at position 2 so there's always a delta down/up value.
        std::map<unsigned long long, statLog>::iterator pi = it->second.log.begin();
        for (std::map<unsigned long long, statLog>::iterator li = ++(it->second.log.begin()); li != it->second.log.end(); li++){
          if (li->first < (unsigned long long)reqStart || pi->first > (unsigned long long)reqEnd){
            continue;
          }
          unsigned int diff = li->first - pi->first;
          unsigned int ddown = (li->second.down - pi->second.down) / diff;
          unsigned int dup = (li->second.up - pi->second.up) / diff;
          for (long long unsigned int t = pi->first; t < li->first; t++){
            if (t >= (unsigned long long)reqStart && t <= (unsigned long long)reqEnd){
              totalsCount[t].add(ddown, dup);
            }
          }
          pi = li;//set previous iterator to log iterator
        }
      }
    }
  }
  //output the data itself
  if (!totalsCount.size()){
    //Oh noes! No data. We'll just reply with a bunch of nulls.
    rep["start"].null();
    rep["end"].null();
    rep["data"].null();
    rep["interval"].null();
    return;
  }
  //yay! We have data!
  rep["start"] = (long long)totalsCount.begin()->first;
  rep["end"] = (long long)totalsCount.rbegin()->first;
  rep["data"].null();
  rep["interval"].null();
  long long prevT = 0;
  JSON::Value i;
  for (std::map<long long unsigned int, totalsData>::iterator it = totalsCount.begin(); it != totalsCount.end(); it++){
    JSON::Value d;
    if (fields & STAT_TOT_CLIENTS){d.append(it->second.clients);}
    if (fields & STAT_TOT_BPS_DOWN){d.append(it->second.downbps);}
    if (fields & STAT_TOT_BPS_UP){d.append(it->second.upbps);}
    rep["data"].append(d);
    if (prevT){
      if (i.size() < 2){
        i.append(1ll);
        i.append((long long)(it->first - prevT));
      }else{
        if (i[1u].asInt() != (long long)(it->first - prevT)){
          rep["interval"].append(i);
          i[0u] = 1ll;
          i[1u] = (long long)(it->first - prevT);
        }else{
          i[0u] = i[0u].asInt() + 1;
        }
      }
    }
    prevT = it->first;
  }
  if (i.size() > 1){
    rep["interval"].append(i);
    i.null();
  }
  //all done! return is by reference, so no need to return anything here.
}
Example #11
0
// VFALCO TODO This function should take a reference to the params, modify it
//             as needed, and then there should be a separate function to
//             submit the transaction.
//
Json::Value
transactionSign (
    Json::Value params,
    bool bSubmit,
    bool bFailHard,
    RPCDetail::LedgerFacade& ledgerFacade,
    Role role)
{
    Json::Value jvResult;

    WriteLog (lsDEBUG, RPCHandler) << "transactionSign: " << params;

    if (! params.isMember ("secret"))
        return RPC::missing_field_error ("secret");

    if (! params.isMember ("tx_json"))
        return RPC::missing_field_error ("tx_json");

    RippleAddress naSeed;

    if (! naSeed.setSeedGeneric (params["secret"].asString ()))
        return RPC::make_error (rpcBAD_SEED,
            RPC::invalid_field_message ("secret"));

    Json::Value& tx_json (params ["tx_json"]);

    if (! tx_json.isObject ())
        return RPC::object_field_error ("tx_json");

    if (! tx_json.isMember ("TransactionType"))
        return RPC::missing_field_error ("tx_json.TransactionType");

    std::string const sType = tx_json ["TransactionType"].asString ();

    if (! tx_json.isMember ("Account"))
        return RPC::make_error (rpcSRC_ACT_MISSING,
            RPC::missing_field_message ("tx_json.Account"));

    RippleAddress raSrcAddressID;

    if (! raSrcAddressID.setAccountID (tx_json["Account"].asString ()))
        return RPC::make_error (rpcSRC_ACT_MALFORMED,
            RPC::invalid_field_message ("tx_json.Account"));

    bool const verify = !(params.isMember ("offline")
                          && params["offline"].asBool ());

    if (!tx_json.isMember ("Sequence") && !verify)
        return RPC::missing_field_error ("tx_json.Sequence");

    // Check for current ledger.
    if (verify && !getConfig ().RUN_STANDALONE &&
        (ledgerFacade.getValidatedLedgerAge () > 120))
        return rpcError (rpcNO_CURRENT);

    // Check for load.
    if (ledgerFacade.isLoadedCluster () && (role != Role::ADMIN))
        return rpcError (rpcTOO_BUSY);

    ledgerFacade.snapshotAccountState (raSrcAddressID);

    if (verify) {
        if (!ledgerFacade.isValidAccount ())
        {
            // If not offline and did not find account, error.
            WriteLog (lsDEBUG, RPCHandler)
                << "transactionSign: Failed to find source account "
                << "in current ledger: "
                << raSrcAddressID.humanAccountID ();

            return rpcError (rpcSRC_ACT_NOT_FOUND);
        }
    }

    autofill_fee (params, ledgerFacade, jvResult, role == Role::ADMIN);
    if (RPC::contains_error (jvResult))
        return jvResult;

    if ("Payment" == sType)
    {
        auto e = signPayment(
            params,
            tx_json,
            raSrcAddressID,
            ledgerFacade,
            role);
        if (contains_error(e))
            return e;
    }

    if (!tx_json.isMember ("Sequence"))
        tx_json["Sequence"] = ledgerFacade.getSeq ();

    if (!tx_json.isMember ("Flags"))
        tx_json["Flags"] = tfFullyCanonicalSig;

    if (verify)
    {
        if (!ledgerFacade.hasAccountRoot ())
            // XXX Ignore transactions for accounts not created.
            return rpcError (rpcSRC_ACT_NOT_FOUND);
    }

    RippleAddress secret = RippleAddress::createSeedGeneric (
        params["secret"].asString ());
    RippleAddress masterGenerator = RippleAddress::createGeneratorPublic (
        secret);
    RippleAddress masterAccountPublic = RippleAddress::createAccountPublic (
        masterGenerator, 0);

    if (verify)
    {
        WriteLog (lsTRACE, RPCHandler) <<
                "verify: " << masterAccountPublic.humanAccountID () <<
                " : " << raSrcAddressID.humanAccountID ();

        auto const secretAccountID = masterAccountPublic.getAccountID();
        if (raSrcAddressID.getAccountID () == secretAccountID)
        {
            if (ledgerFacade.accountMasterDisabled ())
                return rpcError (rpcMASTER_DISABLED);
        }
        else if (!ledgerFacade.accountMatchesRegularKey (secretAccountID))
        {
            return rpcError (rpcBAD_SECRET);
        }
    }

    STParsedJSONObject parsed ("tx_json", tx_json);
    if (!parsed.object.get())
    {
        jvResult ["error"] = parsed.error ["error"];
        jvResult ["error_code"] = parsed.error ["error_code"];
        jvResult ["error_message"] = parsed.error ["error_message"];
        return jvResult;
    }
    std::unique_ptr<STObject> sopTrans = std::move(parsed.object);
    sopTrans->setFieldVL (
        sfSigningPubKey,
        masterAccountPublic.getAccountPublic ());

    STTx::pointer stpTrans;

    try
    {
        stpTrans = std::make_shared<STTx> (*sopTrans);
        //WriteLog(lsINFO, RPCHandler) << "radar: before sign " << stpTrans->getFieldAmount(sfAmount);
    }
    catch (std::exception&)
    {
        return RPC::make_error (rpcINTERNAL,
            "Exception occurred during transaction");
    }

    std::string reason;
    if (!passesLocalChecks (*stpTrans, reason))
        return RPC::make_error (rpcINVALID_PARAMS, reason);

    if (params.isMember ("debug_signing"))
    {
        jvResult["tx_unsigned"] = strHex (
            stpTrans->getSerializer ().peekData ());
        jvResult["tx_signing_hash"] = to_string (stpTrans->getSigningHash ());
    }

    // FIXME: For performance, transactions should not be signed in this code
    // path.
    RippleAddress naAccountPrivate = RippleAddress::createAccountPrivate (
        masterGenerator, secret, 0);

    stpTrans->sign (naAccountPrivate);

    Transaction::pointer tpTrans;

    try
    {
        //WriteLog(lsINFO, RPCHandler) << "radar: after sign " << stpTrans->getFieldAmount(sfAmount);
        tpTrans = std::make_shared<Transaction>(stpTrans, Validate::NO);
        //WriteLog(lsINFO, RPCHandler) << "radar: after copy" << tpTrans->getSTransaction()->getFieldAmount(sfAmount);
    }
    catch (std::exception&)
    {
        return RPC::make_error (rpcINTERNAL,
            "Exception occurred during transaction");
    }

    try
    {
        // FIXME: For performance, should use asynch interface.
        tpTrans = ledgerFacade.submitTransactionSync (tpTrans,
            role == Role::ADMIN, true, bFailHard, bSubmit);

        if (!tpTrans)
        {
            return RPC::make_error (rpcINTERNAL,
                "Unable to sterilize transaction.");
        }
    }
    catch (std::exception&)
    {
        return RPC::make_error (rpcINTERNAL,
            "Exception occurred during transaction submission.");
    }

    try
    {
        jvResult["tx_json"] = tpTrans->getJson (0);
        jvResult["tx_blob"] = strHex (
            tpTrans->getSTransaction ()->getSerializer ().peekData ());

        if (temUNCERTAIN != tpTrans->getResult ())
        {
            std::string sToken;
            std::string sHuman;

            transResultInfo (tpTrans->getResult (), sToken, sHuman);

            jvResult["engine_result"]           = sToken;
            jvResult["engine_result_code"]      = tpTrans->getResult ();
            jvResult["engine_result_message"]   = sHuman;
        }

        return jvResult;
    }
    catch (std::exception&)
    {
        return RPC::make_error (rpcINTERNAL,
            "Exception occurred during JSON handling.");
    }
}
Animation AnimationBuilder::spawnJobs(std::string &err, int maxTime){
	FractalLogger::getSingleton()->write(id, "Fractal Is Animated: Note Detailed progress not reported.\n");
	FractalLogger::getSingleton()->write(id, "Building Animation Data...\n");
	unsigned long genStart = time(NULL);

	Animation anim;
	anim.baseID = id;
	anim.timeStarted = genStart;
	if(maxTime > 0){
		anim.timeMustStop = time(NULL) + maxTime;
	}else{
		anim.timeMustStop = 0;
	}

	if(!p->getJson().isMember("anim") || !p->getJson()["anim"].isObject()){
		err += "No JSON Object Anim\n";
		return anim;
	}
	Json::Value animData = p->getJson()["anim"];
	p->getJson()["anim"] = Json::ValueType::nullValue;
	p->getJson()["basic"]["anim"]["selected"] = "no";
	if(!animData.isMember("frames") || !animData["frames"].isInt()){
		err += "anim.frames does not exist or non-int\n";
		return anim;
	}
	if(animData["frames"].asInt() < 1){
		err += "anim.frames out of bounds\n";
		return anim;
	}
	anim.frames = animData["frames"].asInt();

	if(!animData.isMember("fps") || !animData["fps"].isInt()){
		err += "anim.fps does not exist or non-int\n";
		return anim;
	}
	if(animData["fps"].asInt() < 1){
		err += "anim.fps out of bounds\n";
		return anim;
	}
	anim.fps = animData["fps"].asInt();

	if(!animData.isMember("keyframes") || !animData["keyframes"].isArray()){
		err += "anim.keyframes does not exist or non-array\n";
		return anim;
	}
	if(!SchemaManager::getSingleton()->validateAnimationParam(animData["keyframes"], anim.frames, err)){
		err += "Keyframe Validation Reported Error(s)!\n";
		return anim;
	}

	// first job will render frame one -- we need to render all others
	ParamsFile pnew(p->getJson().toStyledString(), false); // copy json data to interpolate
	buildAnimatedParams(animData, &pnew);

	for(int i=2; i<=anim.frames; i++){
		pnew.getJson()["internal"]["thisframe"] = i;
		std::string savepath = DirectoryManager::getSingleton()->getRootDirectory()+"renders/";
		savepath = concat(savepath, anim.baseID) + concat(".frame.", i) + ".job";

		interpolateFrame(pnew, i);

		pnew.saveToFile(savepath);
		anim.frameQueue.push_back(savepath);
	}

	p->getJson()["internal"]["thisframe"] = 1;
	p->getJson()["anim"] = animData;
	p->getJson()["basic"]["anim"]["selected"] = "yes"; // restore it :D

	// finally revalidate the parameters in case we messed up
	err += SchemaManager::getSingleton()->validateParamaters(p->getJson());

	if(err == ""){
		genStart = time(NULL) - genStart;
		FractalLogger::getSingleton()->write(id,
				concat("Animation Data Built: Took ", (float)genStart/1000)+" seconds!\n");
	}
	return anim;
}
/// This takes a "clients" request, and fills in the response data.
/// 
/// \api
/// `"client"` requests take the form of:
/// ~~~~~~~~~~~~~~~{.js}
/// {
///   //array of streamnames to accumulate. Empty means all.
///   "streams": ["streama", "streamb", "streamc"],
///   //array of protocols to accumulate. Empty means all.
///   "protocols": ["HLS", "HSS"],
///   //list of requested data fields. Empty means all.
///   "fields": ["host", "stream", "protocol", "conntime", "position", "down", "up", "downbps", "upbps"],
///   //unix timestamp of measuring moment. Negative means X seconds ago. Empty means now.
///   "time": 1234567
/// }
/// ~~~~~~~~~~~~~~~
/// and are responded to as:
/// ~~~~~~~~~~~~~~~{.js}
/// {
///   //unix timestamp of data. Always present, always absolute.
///   "time": 1234567,
///   //array of actually represented data fields.
///   "fields": [...]
///   //for all clients, the data in the order they appear in the "fields" field.
///   "data": [[x, y, z], [x, y, z], [x, y, z]]
/// }
/// ~~~~~~~~~~~~~~~
void Controller::fillClients(JSON::Value & req, JSON::Value & rep){
  //first, figure out the timestamp wanted
  long long int reqTime = 0;
  if (req.isMember("time")){
    reqTime = req["time"].asInt();
  }
  //to make sure no nasty timing business takes place, we store the case "now" as a bool.
  bool now = (reqTime == 0);
  //add the current time, if negative or zero.
  if (reqTime <= 0){
    reqTime += Util::epoch();
  }
  //at this point, reqTime is the absolute timestamp.
  rep["time"] = reqTime; //fill the absolute timestamp
  
  unsigned int fields = 0;
  //next, figure out the fields wanted
  if (req.isMember("fields") && req["fields"].size()){
    for (JSON::ArrIter it = req["fields"].ArrBegin(); it != req["fields"].ArrEnd(); it++){
      if ((*it).asStringRef() == "host"){fields |= STAT_CLI_HOST;}
      if ((*it).asStringRef() == "stream"){fields |= STAT_CLI_STREAM;}
      if ((*it).asStringRef() == "protocol"){fields |= STAT_CLI_PROTO;}
      if ((*it).asStringRef() == "conntime"){fields |= STAT_CLI_CONNTIME;}
      if ((*it).asStringRef() == "position"){fields |= STAT_CLI_POSITION;}
      if ((*it).asStringRef() == "down"){fields |= STAT_CLI_DOWN;}
      if ((*it).asStringRef() == "up"){fields |= STAT_CLI_UP;}
      if ((*it).asStringRef() == "downbps"){fields |= STAT_CLI_BPS_DOWN;}
      if ((*it).asStringRef() == "upbps"){fields |= STAT_CLI_BPS_UP;}
    }
  }
  //select all, if none selected
  if (!fields){fields = STAT_CLI_ALL;}
  //figure out what streams are wanted
  std::set<std::string> streams;
  if (req.isMember("streams") && req["streams"].size()){
    for (JSON::ArrIter it = req["streams"].ArrBegin(); it != req["streams"].ArrEnd(); it++){
      streams.insert((*it).asStringRef());
    }
  }
  //figure out what protocols are wanted
  std::set<std::string> protos;
  if (req.isMember("protocols") && req["protocols"].size()){
    for (JSON::ArrIter it = req["protocols"].ArrBegin(); it != req["protocols"].ArrEnd(); it++){
      protos.insert((*it).asStringRef());
    }
  }
  //output the selected fields
  rep["fields"].null();
  if (fields & STAT_CLI_HOST){rep["fields"].append("host");}
  if (fields & STAT_CLI_STREAM){rep["fields"].append("stream");}
  if (fields & STAT_CLI_PROTO){rep["fields"].append("protocol");}
  if (fields & STAT_CLI_CONNTIME){rep["fields"].append("conntime");}
  if (fields & STAT_CLI_POSITION){rep["fields"].append("position");}
  if (fields & STAT_CLI_DOWN){rep["fields"].append("down");}
  if (fields & STAT_CLI_UP){rep["fields"].append("up");}
  if (fields & STAT_CLI_BPS_DOWN){rep["fields"].append("downbps");}
  if (fields & STAT_CLI_BPS_UP){rep["fields"].append("upbps");}
  //output the data itself
  rep["data"].null();
  //start with current connections
  if (curConns.size()){
    for (std::map<unsigned long, statStorage>::iterator it = curConns.begin(); it != curConns.end(); it++){
      unsigned long long time = reqTime;
      if (now){time = it->second.log.rbegin()->first;}
      //data present and wanted? insert it!
      if ((it->second.log.rbegin()->first >= time && it->second.log.begin()->first <= time) && (!streams.size() || streams.count(it->second.streamName)) && (!protos.size() || protos.count(it->second.connector))){
        JSON::Value d;
        std::map<unsigned long long, statLog>::iterator statRef = it->second.log.lower_bound(time);
        std::map<unsigned long long, statLog>::iterator prevRef = --(it->second.log.lower_bound(time));
        if (fields & STAT_CLI_HOST){d.append(it->second.host);}
        if (fields & STAT_CLI_STREAM){d.append(it->second.streamName);}
        if (fields & STAT_CLI_PROTO){d.append(it->second.connector);}
        if (fields & STAT_CLI_CONNTIME){d.append((long long)statRef->second.time);}
        if (fields & STAT_CLI_POSITION){d.append((long long)statRef->second.lastSecond);}
        if (fields & STAT_CLI_DOWN){d.append(statRef->second.down);}
        if (fields & STAT_CLI_UP){d.append(statRef->second.up);}
        if (fields & STAT_CLI_BPS_DOWN){
          if (statRef != it->second.log.begin()){
            unsigned int diff = statRef->first - prevRef->first;
            d.append((statRef->second.down - prevRef->second.down) / diff);
          }else{
            d.append(statRef->second.down);
          }
        }
        if (fields & STAT_CLI_BPS_UP){
          if (statRef != it->second.log.begin()){
            unsigned int diff = statRef->first - prevRef->first;
            d.append((statRef->second.up - prevRef->second.up) / diff);
          }else{
            d.append(statRef->second.up);
          }
        }
        rep["data"].append(d);
      }
    }
  }
  //if we're only interested in current, don't even bother looking at history
  if (now){
    return;
  }
  //look at history
  if (oldConns.size()){
    for (std::map<unsigned long long int, statStorage>::iterator it = oldConns.begin(); it != oldConns.end(); it++){
      //data present and wanted? insert it!
      if ((it->second.log.rbegin()->first >= (unsigned long long)reqTime && it->second.log.begin()->first <= (unsigned long long)reqTime) && (!streams.size() || streams.count(it->second.streamName)) && (!protos.size() || protos.count(it->second.connector))){
        JSON::Value d;
        std::map<unsigned long long, statLog>::iterator statRef = it->second.log.lower_bound(reqTime);
        std::map<unsigned long long, statLog>::iterator prevRef = --(it->second.log.lower_bound(reqTime));
        if (fields & STAT_CLI_HOST){d.append(it->second.host);}
        if (fields & STAT_CLI_STREAM){d.append(it->second.streamName);}
        if (fields & STAT_CLI_PROTO){d.append(it->second.connector);}
        if (fields & STAT_CLI_CONNTIME){d.append((long long)statRef->second.time);}
        if (fields & STAT_CLI_POSITION){d.append((long long)statRef->second.lastSecond);}
        if (fields & STAT_CLI_DOWN){d.append(statRef->second.down);}
        if (fields & STAT_CLI_UP){d.append(statRef->second.up);}
        if (fields & STAT_CLI_BPS_DOWN){
          if (statRef != it->second.log.begin()){
            unsigned int diff = statRef->first - prevRef->first;
            d.append((statRef->second.down - prevRef->second.down) / diff);
          }else{
            d.append(statRef->second.down);
          }
        }
        if (fields & STAT_CLI_BPS_UP){
          if (statRef != it->second.log.begin()){
            unsigned int diff = statRef->first - prevRef->first;
            d.append((statRef->second.up - prevRef->second.up) / diff);
          }else{
            d.append(statRef->second.up);
          }
        }
        rep["data"].append(d);
      }
    }
  }
  //all done! return is by reference, so no need to return anything here.
}
Example #14
0
  int DTSCMerge(int argc, char ** argv){
    Util::Config conf = Util::Config(argv[0], PACKAGE_VERSION);
    conf.addOption("output", JSON::fromString("{\"arg_num\":1, \"arg\":\"string\", \"help\":\"Filename of the output file.\"}"));
    conf.addOption("input", JSON::fromString("{\"arg_num\":2, \"arg\":\"string\", \"help\":\"Filename of the first input file.\"}"));
    conf.addOption("[additional_inputs ...]", JSON::fromString("{\"arg_num\":3, \"default\":\"\", \"arg\":\"string\", \"help\":\"Filenames of any number of aditional inputs.\"}"));
    conf.parseArgs(argc, argv);

    DTSC::File outFile;
    JSON::Value meta;
    DTSC::Meta newMeta;
    std::map<std::string,std::map<int, int> > trackMapping;

    bool fullSort = true;
    std::map<std::string, DTSC::File> inFiles;
    std::map<std::string, DTSC::Meta> metaData;
    std::string outFileName = argv[1];
    std::string tmpFileName;
    for (int i = 2; i < argc; i++){
      tmpFileName = argv[i];
      if (tmpFileName == outFileName){
        fullSort = false;
      }else{
        DTSC::File F(tmpFileName);
        if (!F.getMeta().isFixed()){
          std::cerr << tmpFileName << " has not been run through DTSCFix yet." << std::endl;
          return 1;
        }
        inFiles[tmpFileName] = F;
      }
    }

    if (fullSort){
      outFile = DTSC::File(outFileName, true);
    }else{
      outFile = DTSC::File(outFileName);
      if ( !outFile.getMeta().isFixed()){
        std::cerr << outFileName << " has not been run through DTSCFix yet." << std::endl;
        return 1;
      }
      meta = outFile.getMeta().toJSON();
      newMeta = DTSC::Meta(meta);
      if (meta.isMember("tracks") && meta["tracks"].size() > 0){
        for (JSON::ObjIter trackIt = meta["tracks"].ObjBegin(); trackIt != meta["tracks"].ObjEnd(); trackIt++){
          int nxtMap = getNextFree(trackMapping);
          trackMapping[argv[1]].insert(std::pair<int,int>(trackIt->second["trackid"].asInt(),nxtMap));
          newMeta.tracks[nxtMap].trackID = nxtMap;
        }
      }
    }

    std::multimap<int,keyframeInfo> allSorted;

    for (std::map<std::string,DTSC::File>::iterator it = inFiles.begin(); it != inFiles.end(); it++){
      DTSC::Meta tmpMeta(it->second.getMeta());
      for (std::map<int,DTSC::Track>::iterator trackIt = tmpMeta.tracks.begin(); trackIt != tmpMeta.tracks.end(); trackIt++){
        long long int oldID = trackIt->first;
        long long int mappedID = getNextFree(trackMapping);
        trackMapping[it->first].insert(std::pair<int,int>(oldID,mappedID));
        for (std::deque<DTSC::Key>::iterator keyIt = trackIt->second.keys.begin(); keyIt != trackIt->second.keys.end(); keyIt++){
          keyframeInfo tmpInfo;
          tmpInfo.fileName = it->first;
          tmpInfo.trackID = oldID;
          tmpInfo.keyTime = keyIt->getTime();
          tmpInfo.keyBPos = keyIt->getBpos();
          tmpInfo.keyNum = keyIt->getNumber();
          tmpInfo.keyLen = keyIt->getLength();
          if ((keyIt + 1) != trackIt->second.keys.end()){
            tmpInfo.endBPos = (keyIt + 1)->getBpos();
          }else{
            tmpInfo.endBPos = it->second.getBytePosEOF();
          }
          allSorted.insert(std::pair<int,keyframeInfo>(keyIt->getTime(),tmpInfo));
        }
        newMeta.tracks[mappedID] = trackIt->second;
        newMeta.tracks[mappedID].trackID = mappedID;
        newMeta.tracks[mappedID].reset();
      }
    }

    if (fullSort){
      meta.null();
      meta["moreheader"] = 0ll;
      std::string tmpWrite = meta.toPacked();
      outFile.writeHeader(tmpWrite,true);
    }

    std::set<int> trackSelector;
    for (std::multimap<int,keyframeInfo>::iterator sortIt = allSorted.begin(); sortIt != allSorted.end(); sortIt++){
      trackSelector.clear();
      trackSelector.insert(sortIt->second.trackID);
      inFiles[sortIt->second.fileName].selectTracks(trackSelector);
      inFiles[sortIt->second.fileName].seek_time(sortIt->second.keyTime);
      inFiles[sortIt->second.fileName].seekNext();
      while (inFiles[sortIt->second.fileName].getPacket() && inFiles[sortIt->second.fileName].getBytePos() <= sortIt->second.endBPos && !inFiles[sortIt->second.fileName].reachedEOF()){
        if (inFiles[sortIt->second.fileName].getPacket().getTrackId() == sortIt->second.trackID){
          JSON::Value tmp = inFiles[sortIt->second.fileName].getPacket().toJSON();
          tmp["trackid"] = trackMapping[sortIt->second.fileName][sortIt->second.trackID];
          outFile.writePacket(tmp);
        }
        inFiles[sortIt->second.fileName].seekNext();
      }
    }

    if (fullSort || (meta.isMember("merged") && meta["merged"])){
      newMeta.merged = 1;
    }else{
      newMeta.merged = 0;
    }
    std::string writeMeta = newMeta.toJSON().toPacked();
    meta["moreheader"] = outFile.addHeader(writeMeta);
    writeMeta = meta.toPacked();
    outFile.writeHeader(writeMeta);

    return 0;
  }
Example #15
0
  ///\brief Reads a DTSC file and attempts to fix the metadata in it.
  ///\param conf The current configuration of the program.
  ///\return The return code for the fixed program.
  int DTSCFix(Util::Config & conf){
    DTSC::File F(conf.getString("filename"));
    F.seek_bpos(0);
    F.parseNext();
    JSON::Value oriheader = F.getJSON();
    JSON::Value meta = F.getMeta();
    JSON::Value pack;

    if ( !oriheader.isMember("moreheader")){
      std::cerr << "This file is too old to fix - please reconvert." << std::endl;
      return 1;
    }
    if (DTSC::isFixed(meta) && !conf.getBool("force")){
      std::cerr << "This file was already fixed or doesn't need fixing - cancelling." << std::endl;
      return 0;
    }
    meta.removeMember("isFixed");
    meta.removeMember("keytime");
    meta.removeMember("keybpos");
    meta.removeMember("moreheader");

    std::map<std::string,int> trackIDs;
    std::map<std::string,HeaderEntryDTSC> trackData;


    long long int nowpack = 0;
    
    std::string currentID;
    int nextFreeID = 0;

    for (JSON::ObjIter it = meta["tracks"].ObjBegin(); it != meta["tracks"].ObjEnd(); it++){
      trackIDs.insert(std::pair<std::string,int>(it->first,it->second["trackid"].asInt()));
      trackData[it->first].type = it->second["type"].asString();
      trackData[it->first].trackID = it->second["trackid"].asInt();
      trackData[it->first].type = it->second["type"].asString();
      if (it->second["trackid"].asInt() >= nextFreeID){
        nextFreeID = it->second["trackid"].asInt() + 1;
      }
      it->second.removeMember("keylen");
      it->second.removeMember("keybpos");
      it->second.removeMember("frags");
      it->second.removeMember("keytime");
      it->second.removeMember("keynum");
      it->second.removeMember("keydata");
      it->second.removeMember("keyparts");
      it->second.removeMember("keys");
    }

    F.parseNext();
    while ( !F.getJSON().isNull()){
      currentID = "";
      if (F.getJSON()["trackid"].asInt() == 0){
        if (F.getJSON()["datatype"].asString() == "video"){
          currentID = "video0";
          if (trackData[currentID].trackID == 0){
            trackData[currentID].trackID = nextFreeID++;
          }
          if (meta.isMember("video")){
            meta["tracks"][currentID] = meta["video"];
            meta.removeMember("video");
          }
          trackData[currentID].type = F.getJSON()["datatype"].asString();
        }else{
          if (F.getJSON()["datatype"].asString() == "audio"){
            currentID = "audio0";
            if (trackData[currentID].trackID == 0){
              trackData[currentID].trackID = nextFreeID++;
            }
            if (meta.isMember("audio")){
              meta["tracks"][currentID] = meta["audio"];
              meta.removeMember("audio");
            }
            trackData[currentID].type = F.getJSON()["datatype"].asString();
          }else{
            //fprintf(stderr, "Found an unknown package with packetid 0 and datatype %s\n",F.getJSON()["datatype"].asString().c_str());
            F.parseNext();
            continue;
          }
        }
      }else{
        for( std::map<std::string,int>::iterator it = trackIDs.begin(); it != trackIDs.end(); it++ ) {
          if( it->second == F.getJSON()["trackid"].asInt() ) {
            currentID = it->first;
            break;
          }
        }
        if( currentID == "" ) {
          //fprintf(stderr, "Found an unknown v2 packet with id %d\n", F.getJSON()["trackid"].asInt());
          F.parseNext();
          continue;
          //should create new track but this shouldnt be needed...
        }
      }
      if (F.getJSON()["time"].asInt() < trackData[currentID].firstms){
        trackData[currentID].firstms = F.getJSON()["time"].asInt();
      }
      if (F.getJSON()["time"].asInt() >= nowpack){
        nowpack = F.getJSON()["time"].asInt();
      }
      if (trackData[currentID].type == "video"){
        if (F.getJSON().isMember("keyframe")){
          int newNum = meta["tracks"][currentID]["keys"].size();
          meta["tracks"][currentID]["keys"][newNum]["num"] = ++trackData[currentID].keynum;
          meta["tracks"][currentID]["keys"][newNum]["time"] = F.getJSON()["time"];
          meta["tracks"][currentID]["keys"][newNum]["bpos"] = F.getLastReadPos();
          if (meta["tracks"][currentID]["keys"].size() > 1){
            meta["tracks"][currentID]["keys"][newNum - 1]["len"] = F.getJSON()["time"].asInt() - meta["tracks"][currentID]["keys"][newNum - 1]["time"].asInt();
            meta["tracks"][currentID]["keys"][newNum - 1]["size"] = trackData[currentID].totalSize;
            trackData[currentID].totalSize = 0;
            std::string encodeVec = JSON::encodeVector( trackData[currentID].parts.begin(), trackData[currentID].parts.end() );
            meta["tracks"][currentID]["keys"][newNum - 1]["parts"] = encodeVec;
            meta["tracks"][currentID]["keys"][newNum - 1]["partsize"] = (long long int)trackData[currentID].parts.size();
            trackData[currentID].parts.clear();
          }
        }
      }else{
        if ((F.getJSON()["time"].asInt() - trackData[currentID].lastKeyTime) > 1000){
          trackData[currentID].lastKeyTime = F.getJSON()["time"].asInt();
          int newNum = meta["tracks"][currentID]["keys"].size();
          meta["tracks"][currentID]["keys"][newNum]["num"] = ++trackData[currentID].keynum;
          meta["tracks"][currentID]["keys"][newNum]["time"] = F.getJSON()["time"];
          meta["tracks"][currentID]["keys"][newNum]["bpos"] = F.getLastReadPos();
          if (meta["tracks"][currentID]["keys"].size() > 1){
            meta["tracks"][currentID]["keys"][newNum - 1]["len"] = F.getJSON()["time"].asInt() - meta["tracks"][currentID]["keys"][newNum - 1]["time"].asInt();
            meta["tracks"][currentID]["keys"][newNum - 1]["size"] = trackData[currentID].totalSize;
            trackData[currentID].totalSize = 0;
            std::string encodeVec = JSON::encodeVector( trackData[currentID].parts.begin(), trackData[currentID].parts.end() );
            meta["tracks"][currentID]["keys"][newNum - 1]["parts"] = encodeVec;
            meta["tracks"][currentID]["keys"][newNum - 1]["partsize"] = (long long int)trackData[currentID].parts.size();
            trackData[currentID].parts.clear();
          }
        }
      }
      trackData[currentID].totalSize += F.getJSON()["data"].asString().size();
      trackData[currentID].lastms = nowpack;
      trackData[currentID].parts.push_back(F.getJSON()["data"].asString().size());
      F.parseNext();
    }

    long long int firstms = 0x7fffffff;
    long long int lastms = -1;

    for (std::map<std::string,HeaderEntryDTSC>::iterator it = trackData.begin(); it != trackData.end(); it++){
      if (it->second.firstms < firstms){
        firstms = it->second.firstms;
      }
      if (it->second.lastms > lastms){
        lastms = it->second.lastms;
      }
      meta["tracks"][it->first]["firstms"] = it->second.firstms;
      meta["tracks"][it->first]["lastms"] = it->second.lastms;
      meta["tracks"][it->first]["length"] = (it->second.lastms - it->second.firstms) / 1000;
      if ( !meta["tracks"][it->first].isMember("bps")){
        meta["tracks"][it->first]["bps"] = (long long int)(it->second.lastms / ((it->second.lastms - it->second.firstms) / 1000));
      }
      if (it->second.trackID != 0){
        meta["tracks"][it->first]["trackid"] = trackIDs[it->first];
      }else{
        meta["tracks"][it->first]["trackid"] = nextFreeID ++;
      }
      meta["tracks"][it->first]["type"] = it->second.type;
      int tmp = meta["tracks"][it->first]["keys"].size();
      if (tmp > 0){
        if (tmp > 1){
          meta["tracks"][it->first]["keys"][tmp - 1]["len"] = it->second.lastms - meta["tracks"][it->first]["keys"][tmp - 2]["time"].asInt();
        }else{
          meta["tracks"][it->first]["keys"][tmp - 1]["len"] = it->second.lastms;
        }
        meta["tracks"][it->first]["keys"][tmp - 1]["size"] = it->second.totalSize;
        std::string encodeVec = JSON::encodeVector( trackData[it->first].parts.begin(), trackData[it->first].parts.end() );
        meta["tracks"][it->first]["keys"][tmp - 1]["parts"] = encodeVec;
        meta["tracks"][it->first]["keys"][tmp - 1]["partsize"] = (long long int)trackData[it->first].parts.size();
      }else{
        meta["tracks"][it->first]["keys"][tmp]["len"] = it->second.lastms;
        meta["tracks"][it->first]["keys"][tmp]["size"] = it->second.totalSize;
        std::string encodeVec = JSON::encodeVector( trackData[it->first].parts.begin(), trackData[it->first].parts.end() );
        meta["tracks"][it->first]["keys"][tmp]["parts"] = encodeVec;
        meta["tracks"][it->first]["keys"][tmp]["partsize"] = (long long int)trackData[it->first].parts.size();
        meta["tracks"][it->first]["keys"][tmp]["time"] = it->second.firstms;
      }
      //calculate fragments
      meta["tracks"][it->first]["frags"].null();
      long long int currFrag = -1;
      long long int maxBps = 0;
      for (JSON::ArrIter arrIt = meta["tracks"][it->first]["keys"].ArrBegin(); arrIt != meta["tracks"][it->first]["keys"].ArrEnd(); arrIt++) {
        if ((*arrIt)["time"].asInt() / 10000 > currFrag){
          currFrag = (*arrIt)["time"].asInt() / 10000;
          long long int fragLen = 1;
          long long int fragDur = (*arrIt)["len"].asInt();
          long long int fragSize = (*arrIt)["size"].asInt();
          for (JSON::ArrIter it2 = arrIt + 1; it2 != meta["tracks"][it->first]["keys"].ArrEnd(); it2++){
            if ((*it2)["time"].asInt() / 10000 > currFrag || (it2 + 1) == meta["tracks"][it->first]["keys"].ArrEnd()){
              JSON::Value thisFrag;
              thisFrag["num"] = (*arrIt)["num"].asInt();
              thisFrag["time"] = (*arrIt)["time"].asInt();
              thisFrag["len"] = fragLen;
              thisFrag["dur"] = fragDur;
              thisFrag["size"] = fragSize;
              if (fragDur / 1000){
                thisFrag["bps"] = fragSize / (fragDur / 1000);
                if (maxBps < (fragSize / (fragDur / 1000))){
                  maxBps = (fragSize / (fragDur / 999));
                }
              } else {
                thisFrag["bps"] = 1;
              }
              meta["tracks"][it->first]["frags"].append(thisFrag);
              break;
            }
            fragLen ++;
            fragDur += (*it2)["len"].asInt();
            fragSize += (*it2)["size"].asInt();
          }
        }
      }
      meta["tracks"][it->first]["maxbps"] = maxBps;
    }

    meta["firstms"] = firstms;
    meta["lastms"] = lastms;
    meta["length"] = (lastms - firstms) / 1000;

    //append the revised header
    std::string loader = meta.toPacked();
    long long int newHPos = F.addHeader(loader);
    if ( !newHPos){
      std::cerr << "Failure appending new header." << std::endl;
      return -1;
    }
    //re-write the original header with information about the location of the new one
    oriheader["moreheader"] = newHPos;
    loader = oriheader.toPacked();
    if (F.writeHeader(loader)){
      return 0;
    }else{
      std::cerr << "Failure rewriting header." << std::endl;
      return -1;
    }
  } //DTSCFix
///\brief Starts a single stream
///\param name The name of the stream
///\param data The corresponding configuration values.
void startStream(std::string name, JSON::Value & data) {
    data["online"] = (std::string)"Checking...";
    data.removeMember("error");
    std::string URL;
    if (data.isMember("channel") && data["channel"].isMember("URL")) {
        URL = data["channel"]["URL"].asString();
    }
    if (data.isMember("source")) {
        URL = data["source"].asString();
    }
    std::string cmd1, cmd2, cmd3;
    if (URL == "") {
        Log("STRM", "Error for stream " + name + "! Source parameter missing.");
        data["error"] = "Missing source parameter!";
        return;
    }
    if (URL.substr(0, 4) == "push") {
        std::string pusher = URL.substr(7);
        if (data.isMember("DVR") && data["DVR"].asInt() > 0) {
            data["DVR"] = data["DVR"].asInt();
            cmd2 = "MistBuffer -t " + data["DVR"].asString() + " -s " + name + " " + pusher;
        } else {
            cmd2 = "MistBuffer -s " + name + " " + pusher;
        }
        Util::Procs::Start(name, Util::getMyPath() + cmd2);
        Log("BUFF", "(re)starting stream buffer " + name + " for push data from " + pusher);
    } else {
        if (URL.substr(0, 1) == "/") {
            struct stat fileinfo;
            if (stat(URL.c_str(), &fileinfo) != 0 || S_ISDIR(fileinfo.st_mode)) {
                Log("BUFF", "Warning for VoD stream " + name + "! File not found: " + URL);
                data["error"] = "Not found: " + URL;
                data["online"] = 0;
                return;
            }
            cmd1 = "cat " + URL;
            if (Util::epoch() - lastBuffer[name] > 5) {
                data["error"] = "Available";
                data["online"] = 2;
            } else {
                data["online"] = 1;
                data.removeMember("error");
            }
            return; //MistPlayer handles VoD
        } else {
            cmd1 = "ffmpeg -re -async 2 -i " + URL + " -f flv -";
            cmd2 = "MistFLV2DTSC";
        }
        if (data.isMember("DVR") && data["DVR"].asInt() > 0) {
            data["DVR"] = data["DVR"].asInt();
            cmd3 = "MistBuffer -t " + data["DVR"].asString() + " -s " + name;
        } else {
            cmd3 = "MistBuffer -s " + name;
        }
        if (cmd2 != "") {
            Util::Procs::Start(name, cmd1, Util::getMyPath() + cmd2, Util::getMyPath() + cmd3);
            Log("BUFF", "(re)starting stream buffer " + name + " for ffmpeg data: " + cmd1);
        } else {
            Util::Procs::Start(name, cmd1, Util::getMyPath() + cmd3);
            Log("BUFF", "(re)starting stream buffer " + name + " using input file " + URL);
        }
    }
}
Example #17
0
static Json::Value signPayment(
    Json::Value const& params,
    Json::Value& tx_json,
    RippleAddress const& raSrcAddressID,
    RPCDetail::LedgerFacade& ledgerFacade,
    Role role)
{
    RippleAddress dstAccountID;

    if (!tx_json.isMember ("Amount"))
        return RPC::missing_field_error ("tx_json.Amount");

    STAmount amount;

    if (! amountFromJsonNoThrow (amount, tx_json ["Amount"]))
        return RPC::invalid_field_error ("tx_json.Amount");

    if (!tx_json.isMember ("Destination"))
        return RPC::missing_field_error ("tx_json.Destination");

    if (!dstAccountID.setAccountID (tx_json["Destination"].asString ()))
        return RPC::invalid_field_error ("tx_json.Destination");

    if (tx_json.isMember ("Paths") && params.isMember ("build_path"))
        return RPC::make_error (rpcINVALID_PARAMS,
            "Cannot specify both 'tx_json.Paths' and 'build_path'");

    if (!tx_json.isMember ("Paths")
        && tx_json.isMember ("Amount")
        && params.isMember ("build_path"))
    {
        // Need a ripple path.
        Currency uSrcCurrencyID;
        Account uSrcIssuerID;

        STAmount    saSendMax;

        if (tx_json.isMember ("SendMax"))
        {
            if (! amountFromJsonNoThrow (saSendMax, tx_json ["SendMax"]))
                return RPC::invalid_field_error ("tx_json.SendMax");
        }
        else
        {
            // If no SendMax, default to Amount with sender as issuer.
            saSendMax = amount;
            saSendMax.setIssuer (raSrcAddressID.getAccountID ());
        }

        if (saSendMax.isNative () && amount.isNative ())
            return RPC::make_error (rpcINVALID_PARAMS,
                "Cannot build XRP to XRP paths.");

        {
            LegacyPathFind lpf (role == Role::ADMIN);
            if (!lpf.isOk ())
                return rpcError (rpcTOO_BUSY);

            STPathSet spsPaths;
            STPath fullLiquidityPath;
            bool valid = ledgerFacade.findPathsForOneIssuer (
                dstAccountID,
                saSendMax.issue (),
                amount,
                getConfig ().PATH_SEARCH_OLD,
                4,  // iMaxPaths
                spsPaths,
                fullLiquidityPath);


            if (!valid)
            {
                WriteLog (lsDEBUG, RPCHandler)
                        << "transactionSign: build_path: No paths found.";
                return rpcError (rpcNO_PATH);
            }
            WriteLog (lsDEBUG, RPCHandler)
                    << "transactionSign: build_path: "
                    << spsPaths.getJson (0);

            if (!spsPaths.empty ())
                tx_json["Paths"] = spsPaths.getJson (0);
        }
    }
    return Json::Value();
}
Example #18
0
void ParticleComponent::parsePrefab(json::Value& val)
{
	if(val.isMember("texture"))
	{
		const std::string assetid = val["texture"].asString();
		TextureAsset* asset = Asset::getTexture(assetid);

		if(asset)
		{
			//m_particleTexture.reset(new sf::Texture(*asset->getAsset()));

			m_particleSystem.reset(new thor::ParticleSystem(asset->getAsset()));

			createEmitter();
		}
		else
		{
			szerr << "Prefab particle texture '" << assetid << "' could not be retrieved." << ErrorStream::error;
		}
	}

	if(val.isMember("emissionrate"))
	{
		setEmissionRate(static_cast<float>(val["emissionrate"].asDouble()));
	}
	
	if(val.isMember("lifetime"))
	{
		if(val["lifetime"].isArray() && val["lifetime"].size() == 2)
		{
			setLifetime(
				static_cast<float>(val["lifetime"][0U].asDouble()),
				static_cast<float>(val["lifetime"][1U].asDouble())
			);
		}
		else if(val["lifetime"].isArray() && val["lifetime"].size() == 1)
		{
			setLifetime(
				static_cast<float>(val["lifetime"][0U].asDouble())
			);
		}
		else if(!val["lifetime"].isArray())
		{
			setLifetime(static_cast<float>(val["lifetime"].asDouble()));
		}
		else
		{
			szerr << "Invalid particle lifetime value in prefab." << ErrorStream::error;
		}
	}

	if(val.isMember("velocity"))
	{
		if(val["velocity"].isArray() && val["velocity"].size() == 2)
		{
			setVelocity(sf::Vector2f(
				static_cast<float>(val["velocity"][0U].asDouble()),
				static_cast<float>(val["velocity"][1U].asDouble())
			));
		}
	}

	if(val.isMember("rotation"))
	{
		if(val["rotation"].isArray() && val["rotation"].size() == 2)
		{
			setRotation(
				static_cast<float>(val["rotation"][0U].asDouble()),
				static_cast<float>(val["rotation"][1U].asDouble())
			);
		}
		else if(val["rotation"].isArray() && val["rotation"].size() == 1)
		{
			setRotation(
				static_cast<float>(val["rotation"][0U].asDouble())
			);
		}
		else if(!val["rotation"].isArray())
		{
			setRotation(static_cast<float>(val["rotation"].asDouble()));
		}
		else
		{
			szerr << "Invalid particle rotation value in prefab." << ErrorStream::error;
		}
	}

	if(val.isMember("scale"))
	{
		if(val["scale"].isArray() && val["scale"].size() == 2)
		{
			setScale(
				static_cast<float>(val["scale"][0U].asDouble()),
				static_cast<float>(val["scale"][1U].asDouble())
			);
		}
		else if(val["scale"].isArray() && val["scale"].size() == 1)
		{
			setScale(
				static_cast<float>(val["scale"][0U].asDouble())
			);
		}
		else if(!val["scale"].isArray())
		{
			setScale(static_cast<float>(val["scale"].asDouble()));
		}
		else
		{
			szerr << "Invalid particle scale value in prefab." << ErrorStream::error;
		}
	}

	if(val.isMember("rotationspeed"))
	{
		if(val["rotationspeed"].isArray() && val["rotationspeed"].size() == 2)
		{
			setRotationSpeed(
				static_cast<float>(val["rotationspeed"][0U].asDouble()),
				static_cast<float>(val["rotationspeed"][1U].asDouble())
			);
		}
		else if(val["rotationspeed"].isArray() && val["rotationspeed"].size() == 1)
		{
			setRotationSpeed(
				static_cast<float>(val["rotationspeed"][0U].asDouble())
			);
		}
		else if(!val["rotationspeed"].isArray())
		{
			setRotationSpeed(static_cast<float>(val["rotationspeed"].asDouble()));
		}
		else
		{
			szerr << "Invalid particle rotationspeed value in prefab." << ErrorStream::error;
		}
	}

	if(val.isMember("affectors"))
	{
		json::Value affectors = val["affectors"];

		for(json::Value::iterator it = affectors.begin(); it != affectors.end(); ++it)
		{
			const std::string affector = it.memberName();

			if(affector == "fade")
			{
				addFadeAffector(
					static_cast<float>((*it)[0U].asDouble()),
					static_cast<float>((*it)[1U].asDouble())
				);
			}
			else if(affector == "scale")
			{
				addScaleAffector(
					static_cast<float>((*it)[0U].asDouble()),
					static_cast<float>((*it)[1U].asDouble())
				);
			}
			else if(affector == "force")
			{
				addForceAffector(
					static_cast<float>((*it)[0U].asDouble()),
					static_cast<float>((*it)[1U].asDouble())
				);
			}
		}
	}

	if(val.get("prewarm", 0).asBool())
	{
		prewarm();
	}

	if(val.isMember("shader"))
	{
		json::Value shader = val["shader"];

		if(shader.isConvertibleTo(json::stringValue))
		{
			setShader(shader.asString());
		}
		else if(shader.isObject())
		{
			setShader(shader["asset"].asString());

			if(shader.isMember("param") && !shader["param"].empty())
			{
				json::Value parameters = shader["param"];

				for(json::Value::iterator it = parameters.begin(); it != parameters.end(); ++it)
				{
					const std::string name = it.memberName();

					json::Value v = *it;
					if(v.isArray())
					{
						switch(v.size())
						{
						case 1:
							m_shaderAsset->getAsset()->setParameter(name,
								(float)v[0U].asDouble());
							break;

						case 2:
							m_shaderAsset->getAsset()->setParameter(name,
								(float)v[0U].asDouble(),
								(float)v[1U].asDouble());
							break;

						case 3:
							m_shaderAsset->getAsset()->setParameter(name,
								(float)v[0U].asDouble(),
								(float)v[1U].asDouble(),
								(float)v[2U].asDouble());
							break;

						case 4:
							{
								m_shaderAsset->getAsset()->setParameter(name,
									(float)v[0U].asDouble(),
									(float)v[1U].asDouble(),
									(float)v[2U].asDouble(),
									(float)v[3U].asDouble());
								break;
							}

						default:
							szerr << "Incorrect amount of parameter arguments in prefab." << ErrorStream::error;
							break;
						}
					}
					else if(v.isConvertibleTo(json::realValue))
					{
						m_shaderAsset->getAsset()->setParameter(name,
							(float)v.asDouble());
					}
				}
			}
		}
	}

	if(val.isMember("color"))
	{
		sf::Uint32 size = val["color"].size();
		if(size == 3 || size == 4)
		{
			sf::Color color;

			color.r = static_cast<sf::Uint8>(val["color"][0U].asUInt());
			color.g = static_cast<sf::Uint8>(val["color"][1U].asUInt());
			color.b = static_cast<sf::Uint8>(val["color"][2U].asUInt());

			if(size == 4)
			{
				color.a = static_cast<sf::Uint8>(val["color"][3U].asUInt());
			}

			setColor(color);
		}
	}
	
	const std::string blend = val.get("blendmode", "alpha").asString();

	if(blend == "alpha")
	{
		m_renderStates.blendMode = sf::BlendAlpha;
	}
	else if(blend == "additive")
	{
		m_renderStates.blendMode = sf::BlendAdd;
	}
	else if(blend == "multiply")
	{
		m_renderStates.blendMode = sf::BlendMultiply;
	}
	else if(blend == "none")
	{
		m_renderStates.blendMode = sf::BlendNone;
	}
}
Example #19
0
E131OutputData::E131OutputData(const Json::Value &config)
: UDPOutputData(config), E131sequenceNumber(1), universeCount(1) {
    memset((char *) &e131Address, 0, sizeof(sockaddr_in));
    e131Address.sin_family = AF_INET;
    e131Address.sin_port = htons(E131_DEST_PORT);

    universe = config["id"].asInt();
    priority = config["priority"].asInt();
    if (config.isMember("universeCount")) {
        universeCount = config["universeCount"].asInt();
    }
    if (universeCount < 1) {
        universeCount = 1;
    }
    switch (type) {
        case 0: // Multicast
            ipAddress = "";
            break;
        case 1: //UnicastAddress
            ipAddress = config["address"].asString();
            break;
    }
    
    
    if (type == E131_TYPE_MULTICAST) {
        int UniverseOctet[2];
        char sAddress[32];

        UniverseOctet[0] = universe/256;
        UniverseOctet[1] = universe%256;
        sprintf(sAddress, "239.255.%d.%d", UniverseOctet[0],UniverseOctet[1]);
        e131Address.sin_addr.s_addr = inet_addr(sAddress);
    } else {
        bool isAlpha = false;
        for (int x = 0; x < ipAddress.length(); x++) {
            isAlpha |= isalpha(ipAddress[x]);
        }
        
        if (isAlpha) {
            struct hostent* uhost = gethostbyname(ipAddress.c_str());
            if (!uhost) {
                LogErr(VB_CHANNELOUT,
                       "Error looking up E1.31 hostname: %s\n",
                       ipAddress.c_str());
                valid = false;
            } else {
                e131Address.sin_addr.s_addr = *((unsigned long*)uhost->h_addr);
            }
        } else {
            e131Address.sin_addr.s_addr = inet_addr(ipAddress.c_str());
        }
    }
    
    e131Iovecs.resize(universeCount * 2);
    e131Headers.resize(universeCount);
    for (int x = 0; x < universeCount; x++) {
        unsigned char *e131Buffer = (unsigned char *)malloc(E131_HEADER_LENGTH);
        e131Headers[x] = e131Buffer;
        memcpy(e131Buffer, E131header, E131_HEADER_LENGTH);
        
        int uni = universe + x;
        e131Buffer[E131_PRIORITY_INDEX] = priority;
        e131Buffer[E131_UNIVERSE_INDEX] = (char)(uni/256);
        e131Buffer[E131_UNIVERSE_INDEX+1] = (char)(uni%256);
        
        // Property Value Count
        e131Buffer[E131_COUNT_INDEX] = ((channelCount+1)/256);
        e131Buffer[E131_COUNT_INDEX+1] = ((channelCount+1)%256);
        
        // RLP Protocol flags and length
        int count = 638 - 16 - (512 - (channelCount));
        e131Buffer[E131_RLP_COUNT_INDEX] = (count/256)+0x70;
        e131Buffer[E131_RLP_COUNT_INDEX+1] = count%256;
        
        // Framing Protocol flags and length
        count = 638 - 38 - (512 - (channelCount));
        e131Buffer[E131_FRAMING_COUNT_INDEX] = (count/256)+0x70;
        e131Buffer[E131_FRAMING_COUNT_INDEX+1] = count%256;
        
        // DMP Protocol flags and length
        count = 638 - 115 - (512 - (channelCount));
        e131Buffer[E131_DMP_COUNT_INDEX] = (count/256)+0x70;
        e131Buffer[E131_DMP_COUNT_INDEX+1] = count%256;

        // use scatter/gather for the packet.   One IOV will contain
        // the header, the second will point into the raw channel data
        // and will be set at output time.   This avoids any memcpy.
        e131Iovecs[x * 2].iov_base = e131Buffer;
        e131Iovecs[x * 2].iov_len = E131_HEADER_LENGTH;
        e131Iovecs[x * 2 + 1].iov_base = nullptr;
        e131Iovecs[x * 2 + 1].iov_len = channelCount;
    }
}
Example #20
0
SpriteComponent::SpriteComponent(GameObject* _parent, const Json::Value& json) :
	Component(_parent)
{
	if (json.isMember("texture"))
		setTexture(json["texture"].asString());
}
Example #21
0
ListDisposition
ValidatorList::verify (
    Json::Value& list,
    PublicKey& pubKey,
    std::string const& manifest,
    std::string const& blob,
    std::string const& signature)
{
    auto m = Manifest::make_Manifest (beast::detail::base64_decode(manifest));

    if (! m || ! publisherLists_.count (m->masterKey))
        return ListDisposition::untrusted;

    pubKey = m->masterKey;
    auto const revoked = m->revoked();

    auto const result = publisherManifests_.applyManifest (
        std::move(*m));

    if (revoked && result == ManifestDisposition::accepted)
    {
        removePublisherList (pubKey);
        publisherLists_.erase (pubKey);
    }

    if (revoked || result == ManifestDisposition::invalid)
        return ListDisposition::untrusted;

    auto const sig = strUnHex(signature);
    auto const data = beast::detail::base64_decode (blob);
    if (! sig.second ||
        ! ripple::verify (
            publisherManifests_.getSigningKey(pubKey),
            makeSlice(data),
            makeSlice(sig.first)))
        return ListDisposition::invalid;

    Json::Reader r;
    if (! r.parse (data, list))
        return ListDisposition::invalid;

    if (list.isMember("sequence") && list["sequence"].isInt() &&
        list.isMember("expiration") && list["expiration"].isInt() &&
        list.isMember("validators") && list["validators"].isArray())
    {
        auto const sequence = list["sequence"].asUInt();
        auto const expiration = TimeKeeper::time_point{
            TimeKeeper::duration{list["expiration"].asUInt()}};
        if (sequence < publisherLists_[pubKey].sequence ||
            expiration <= timeKeeper_.now())
            return ListDisposition::stale;
        else if (sequence == publisherLists_[pubKey].sequence)
            return ListDisposition::same_sequence;
    }
    else
    {
        return ListDisposition::invalid;
    }

    return ListDisposition::accepted;
}
Example #22
0
void SpaceStation::LoadFromJson(const Json::Value &jsonObj, Space *space)
{
	ModelBody::LoadFromJson(jsonObj, space);
	GetModel()->SetLabel(GetLabel());

	if (!jsonObj.isMember("space_station")) throw SavedGameCorruptException();
	Json::Value spaceStationObj = jsonObj["space_station"];

	if (!spaceStationObj.isMember("ship_docking")) throw SavedGameCorruptException();
	if (!spaceStationObj.isMember("ports")) throw SavedGameCorruptException();
	if (!spaceStationObj.isMember("index_for_system_body")) throw SavedGameCorruptException();
	if (!spaceStationObj.isMember("door_animation_step")) throw SavedGameCorruptException();
	if (!spaceStationObj.isMember("door_animation_state")) throw SavedGameCorruptException();

	m_oldAngDisplacement = 0.0;

	Json::Value shipDockingArray = spaceStationObj["ship_docking"];
	if (!shipDockingArray.isArray()) throw SavedGameCorruptException();
	m_shipDocking.reserve(shipDockingArray.size());
	for (Uint32 i = 0; i < shipDockingArray.size(); i++)
	{
		m_shipDocking.push_back(shipDocking_t());
		shipDocking_t &sd = m_shipDocking.back();

		Json::Value shipDockingArrayEl = shipDockingArray[i];
		if (!shipDockingArrayEl.isMember("index_for_body")) throw SavedGameCorruptException();
		if (!shipDockingArrayEl.isMember("stage")) throw SavedGameCorruptException();
		if (!shipDockingArrayEl.isMember("stage_pos")) throw SavedGameCorruptException();
		if (!shipDockingArrayEl.isMember("from_pos")) throw SavedGameCorruptException();
		if (!shipDockingArrayEl.isMember("from_rot")) throw SavedGameCorruptException();

		sd.shipIndex = shipDockingArrayEl["index_for_body"].asInt();
		sd.stage = shipDockingArrayEl["stage"].asInt();
		sd.stagePos = StrToDouble(shipDockingArrayEl["stage_pos"].asString()); // For some reason stagePos was saved as a float in pre-JSON system (saved & loaded as double here).
		JsonToVector(&(sd.fromPos), shipDockingArrayEl, "from_pos");
		JsonToQuaternion(&(sd.fromRot), shipDockingArrayEl, "from_rot");
	}

	// retrieve each of the port details and bay IDs
	Json::Value portArray = spaceStationObj["ports"];
	if (!portArray.isArray()) throw SavedGameCorruptException();
	m_ports.reserve(portArray.size());
	for (Uint32 i = 0; i < portArray.size(); i++)
	{
		m_ports.push_back(SpaceStationType::SPort());
		SpaceStationType::SPort &port = m_ports.back();

		Json::Value portArrayEl = portArray[i];
		if (!portArrayEl.isMember("min_ship_size")) throw SavedGameCorruptException();
		if (!portArrayEl.isMember("max_ship_size")) throw SavedGameCorruptException();
		if (!portArrayEl.isMember("in_use")) throw SavedGameCorruptException();
		if (!portArrayEl.isMember("bays")) throw SavedGameCorruptException();

		port.minShipSize = portArrayEl["min_ship_size"].asInt();
		port.maxShipSize = portArrayEl["max_ship_size"].asInt();
		port.inUse = portArrayEl["in_use"].asBool();

		Json::Value bayArray = portArrayEl["bays"];
		if (!bayArray.isArray()) throw SavedGameCorruptException();
		port.bayIDs.reserve(bayArray.size());
		for (Uint32 j = 0; j < bayArray.size(); j++)
		{
			Json::Value bayArrayEl = bayArray[j];
			if (!bayArrayEl.isMember("bay_id")) throw SavedGameCorruptException();
			if (!bayArrayEl.isMember("name")) throw SavedGameCorruptException();

			port.bayIDs.push_back(std::make_pair(bayArrayEl["bay_id"].asInt(), bayArrayEl["name"].asString()));
		}
	}

	m_sbody = space->GetSystemBodyByIndex(spaceStationObj["index_for_system_body"].asUInt());

	m_doorAnimationStep = StrToDouble(spaceStationObj["door_animation_step"].asString());
	m_doorAnimationState = StrToDouble(spaceStationObj["door_animation_state"].asString());

	InitStation();

	m_navLights->LoadFromJson(spaceStationObj);
}
/**
 * Expected input:
 * {
 * 	alg: "aes",
 * 	mode: "cbc",
 * 	key: key data,
 * 	iv: iv data (16 bytes),
 * 	input: data to encrypt or decrypt
 * }
 *
 * Good output:
 * {
 * 	output: data
 * }
 */
Json::Value AES::crypt(const std::string & algorithm, Json::Value & args,
                       bool isEncrypt) {
    if (!args.isMember("key")) {
        throw std::string("key missing");
    }
    if (!args.isMember("input")) {
        throw std::string("input missing");
    }
    if (!args.isMember("iv")) {
        throw std::string("iv missing");
    }
    if (!args.isMember("mode")) {
        throw std::string("mode missing");
    }

    std::string modeString(
        gsecrypto::util::lowerCaseRemoveDashes(args["mode"].asString()));
    if ("cbc" != modeString) {
        throw std::string("Only CBC currently supported");
    }

    DataTracker input;
    getData(args["input"], input);

    DataTracker result(input.dataLen);

    if (input.dataLen == 0) {
        Json::Value toReturn;
        toReturn["output"] = toJson(result);
        return toReturn;
    }

    DataTracker keyBytes;
    getData(args["key"], keyBytes);

    switch( keyBytes.dataLen*8 ) {
    case 128:
    case 192:
    case 256:
        break;
    default:
        std::stringstream stream;
        stream << "Key Size: " << (keyBytes.dataLen*8) << " bits not supported.";
        throw stream.str();
    }

    if( (input.dataLen % 16) != 0 ) {
        throw std::string("Input not multiple of 128 bits. Use padding.");
    }

    DataTracker iv;
    getData(args["iv"], iv);

    if( iv.dataLen != 16 ) {
        throw std::string("IV not 128 bits.");
    }

    int mode = SB_AES_CBC;

    AESParams params(*this, SB_AES_CBC, SB_AES_128_BLOCK_BITS, false);
    AESKey key(params, keyBytes);
    AESContext context(params, key, mode, iv);
    context.crypt(input, result, isEncrypt);

    Json::Value toReturn;
    toReturn["output"] = toJson(result);
    return toReturn;
}
Example #24
0
/* ---------------------------------------------------------------------------
**  main
** -------------------------------------------------------------------------*/
int main(int argc, char* argv[])
{
	const char* turnurl       = "";
	const char* defaultlocalstunurl  = "0.0.0.0:3478";
	const char* localstunurl  = NULL;
	const char* stunurl       = "stun.l.google.com:19302";
	int logLevel              = rtc::LERROR;
	const char* webroot       = "./html";
	std::string sslCertificate;
	webrtc::AudioDeviceModule::AudioLayer audioLayer = webrtc::AudioDeviceModule::kPlatformDefaultAudio;
	std::string streamName;
	std::map<std::string,std::string> urlVideoList;
	std::map<std::string,std::string> urlAudioList;
	std::string nbthreads;
	std::string passwdFile;
	std::string publishFilter(".*");

	std::string httpAddress("0.0.0.0:");
	std::string httpPort = "8000";
	const char * port = getenv("PORT");
	if (port)
	{
		httpPort = port;
	}
	httpAddress.append(httpPort);

	int c = 0;
	while ((c = getopt (argc, argv, "hVv::" "c:H:w:T:A:C:" "t:S::s::" "a::q:" "n:u:U:")) != -1)
	{
		switch (c)
		{
			case 'H': httpAddress = optarg; break;
			case 'c': sslCertificate = optarg; break;
			case 'w': webroot = optarg; break;
			case 'T': nbthreads = optarg; break;
			case 'A': passwdFile = optarg; break;

			case 't': turnurl = optarg; break;
			case 'S': localstunurl = optarg ? optarg : defaultlocalstunurl; stunurl = localstunurl; break;
			case 's': localstunurl = NULL; stunurl = optarg ? optarg : defaultlocalstunurl; break;
			
			case 'a': audioLayer = optarg ? (webrtc::AudioDeviceModule::AudioLayer)atoi(optarg) : webrtc::AudioDeviceModule::kDummyAudio; break;
			case 'q': publishFilter = optarg ; break;
				
			case 'C': {
				Json::Value root;  
				std::ifstream stream(optarg);
				stream >> root;
				if (root.isMember("urls")) {
					Json::Value urls = root["urls"];
					for( auto it = urls.begin() ; it != urls.end() ; it++ ) {
						std::string name = it.key().asString();
						Json::Value value = *it;
						if (value.isMember("video")) {
							urlVideoList[name]=value["video"].asString();
						} 
						if (value.isMember("audio")) {
							urlAudioList[name]=value["audio"].asString();
						} 
					}
				}
				break;
			}

			case 'n': streamName = optarg; break;
			case 'u': {
				if (!streamName.empty()) {
					urlVideoList[streamName]=optarg;
				}
			}
			break;
			case 'U': {
				if (!streamName.empty()) {
					urlAudioList[streamName]=optarg;
				}
			}
			break;
			
			case 'v': 
				logLevel--; 
				if (optarg) {
					logLevel-=strlen(optarg); 
				}
			break;			
			case 'V':
				std::cout << VERSION << std::endl;
				exit(0);
			break;
			case 'h':
			default:
				std::cout << argv[0] << " [-H http port] [-S[embeded stun address]] [-t [username:password@]turn_address] -[v[v]]  [url1]...[urln]" << std::endl;
				std::cout << argv[0] << " [-H http port] [-s[externel stun address]] [-t [username:password@]turn_address] -[v[v]] [url1]...[urln]" << std::endl;
				std::cout << argv[0] << " -V" << std::endl;

				std::cout << "\t -v[v[v]]           : verbosity"                                                                  << std::endl;
				std::cout << "\t -V                 : print version"                                                              << std::endl;

				std::cout << "\t -H hostname:port   : HTTP server binding (default "   << httpAddress    << ")"                   << std::endl;
				std::cout << "\t -w webroot         : path to get files"                                                          << std::endl;
				std::cout << "\t -c sslkeycert      : path to private key and certificate for HTTPS"                              << std::endl;
				std::cout << "\t -T nbthreads       : number of threads for HTTP server"                                          << std::endl;
				std::cout << "\t -A passwd          : password file for HTTP server access"                                          << std::endl;
			
				std::cout << "\t -S[stun_address]                   : start embeded STUN server bind to address (default " << defaultlocalstunurl << ")" << std::endl;
				std::cout << "\t -s[stun_address]                   : use an external STUN server (default " << stunurl << ")"                    << std::endl;
				std::cout << "\t -t[username:password@]turn_address : use an external TURN relay server (default disabled)"       << std::endl;

				std::cout << "\t -a[audio layer]                    : spefify audio capture layer to use (default:" << audioLayer << ")"          << std::endl;

				std::cout << "\t -n name -u videourl -U audiourl    : register a stream with name using url"                         << std::endl;			
				std::cout << "\t [url]                              : url to register in the source list"                                         << std::endl;
				std::cout << "\t -C config.json                     : load urls from JSON config file"                                                 << std::endl;
			
				exit(0);
		}
	}

	while (optind<argc)
	{
		std::string url(argv[optind]);
		urlVideoList[url]=url;
		optind++;
	}

	rtc::LogMessage::LogToDebug((rtc::LoggingSeverity)logLevel);
	rtc::LogMessage::LogTimestamps();
	rtc::LogMessage::LogThreads();
	std::cout << "Logger level:" <<  rtc::LogMessage::GetLogToDebug() << std::endl;

	rtc::Thread* thread = rtc::Thread::Current();
	rtc::InitializeSSL();

	// webrtc server
	std::list<std::string> iceServerList;
	iceServerList.push_back(std::string("stun:")+stunurl);
	if (strlen(turnurl)) {
		iceServerList.push_back(std::string("turn:")+turnurl);
	}
	PeerConnectionManager webRtcServer(iceServerList, urlVideoList, urlAudioList, audioLayer, publishFilter);
	if (!webRtcServer.InitializePeerConnection())
	{
		std::cout << "Cannot Initialize WebRTC server" << std::endl;
	}
	else
	{
		// http server
		std::vector<std::string> options;
		options.push_back("document_root");
		options.push_back(webroot);
		options.push_back("access_control_allow_origin");
		options.push_back("*");
		options.push_back("listening_ports");
		options.push_back(httpAddress);
		if (!sslCertificate.empty()) {
			options.push_back("ssl_certificate");
			options.push_back(sslCertificate);
		}
		if (!nbthreads.empty()) {
			options.push_back("num_threads");
			options.push_back(nbthreads);
		}
		if (!passwdFile.empty()) {
			options.push_back("global_auth_file");
			options.push_back(passwdFile);
		}

		try {
			std::cout << "HTTP Listen at " << httpAddress << std::endl;
			HttpServerRequestHandler httpServer(&webRtcServer, options);

			// start STUN server if needed
			std::unique_ptr<cricket::StunServer> stunserver;
			if (localstunurl != NULL)
			{
				rtc::SocketAddress server_addr;
				server_addr.FromString(localstunurl);
				rtc::AsyncUDPSocket* server_socket = rtc::AsyncUDPSocket::Create(thread->socketserver(), server_addr);
				if (server_socket)
				{
					stunserver.reset(new cricket::StunServer(server_socket));
					std::cout << "STUN Listening at " << server_addr.ToString() << std::endl;
				}
			}
			
			// mainloop
			thread->Run();

		} catch (const CivetException & ex) {
			std::cout << "Cannot Initialize start HTTP server exception:" << ex.what() << std::endl;
		}
	}

	rtc::CleanupSSL();
	return 0;
}
Example #25
0
void Client::onPresenceData(const json::Value& data, bool whiny)
{
    TraceL << "Updating: " << json::stringify(data, true) << endl;

    if (data.isObject() &&
        data.isMember("id") && 
        data.isMember("user") && 
        data.isMember("name") && 
        data.isMember("online") //&& 
        //data.isMember("type") 
        ) {
        std::string id = data["id"].asString();
        bool online = data["online"].asBool();
        Peer* peer = _roster.get(id, false);
        if (online) {
            if (!peer) {
                peer = new Peer(data);
                _roster.add(id, peer);
                InfoL << "Peer connected: " << peer->address().toString() << endl;
                PeerConnected.emit(this, *peer);
            } 
            else
                static_cast<json::Value&>(*peer) = data;
        }
        else {
            if (peer) {
                InfoL << "Peer disconnected: " << peer->address().toString() << endl;
                PeerDisconnected.emit(this, *peer);
                _roster.free(id);
            }
            else {
                WarnL << "Got peer disconnected for unknown peer: " << id << endl;
            }
        }
    }
    else {
        std::string error("Bad presence data: " + json::stringify(data));
        ErrorL << error << endl;    
        if (whiny)
            throw std::runtime_error(error);
    }

#if 0
    if (data.isObject() &&
        data.isMember("id") && 
        data.isMember("user") && 
        data.isMember("name") //&& 
        //data.isMember("type")
        ) {
        TraceL << "Updating: " << json::stringify(data, true) << endl;
        std::string id = data["id"].asString();
        Peer* peer = get(id, false);
        if (!peer) {
            peer = new Peer(data);
            add(id, peer);
        } else
            static_cast<json::Value&>(*peer) = data;
    }
    else if (data.isArray()) {
        for (auto it = data.begin(); it != data.end(); it++) {
            onPresenceData(*it, whiny);    
        }
    }
    else {
        std::string error("Bad presence data: " + json::stringify(data));
        ErrorL << error << endl;    
        if (whiny)
            throw std::runtime_error(error);
    }
#endif
}
Example #26
0
	void collect()
	{
		int ret;

		if (!first_)
		{
			prev_time_ = cur_time_;
			prev_node_info_ = cur_node_info_;
		}

		ret = ::clock_gettime(CLOCK_REALTIME, &cur_time_);
		if (-1 == ret)
		{
			std::ostringstream oss;
			oss << "Failed to get clock time info: " << std::strerror(errno);

			throw std::runtime_error(oss.str());
		}

		// Get the CPU time used (in ns)
		ret = ::virDomainGetInfo(dom_, &cur_node_info_);
		if (-1 == ret)
		{
			std::ostringstream oss;
			oss << "Failed to get domain info: " << dcs::testbed::libvirt::detail::last_error(conn_);

			throw std::runtime_error(oss.str());
		}

		if (first_)
		{
			first_ = false;
			
			prev_time_ = cur_time_;
			prev_node_info_ = cur_node_info_;
			cpu_util_ = 0;
			mem_util_ = 0;
		}
		else
		{
			bool ok = true;

			// Update CPU utilization stats
			const boost::uint64_t ns_elapsed = (cur_time_.tv_sec-prev_time_.tv_sec)*1.0e9+(cur_time_.tv_nsec-prev_time_.tv_nsec);
			const boost::uint64_t ns_used = cur_node_info_.cpuTime-prev_node_info_.cpuTime;
			const int nvcpus = dcs::testbed::libvirt::detail::num_vcpus(conn_, dom_, VIR_DOMAIN_VCPU_MAXIMUM);
			cpu_util_ = static_cast<double>(ns_used/static_cast<long double>(ns_elapsed));
			cpu_util_ /= static_cast<double>(nvcpus);

			// Update RAM utilization stats
			const unsigned long cfg_max_mem = dcs::testbed::libvirt::detail::config_max_memory(conn_, dom_);
			const unsigned long cur_max_mem = dcs::testbed::libvirt::detail::max_memory(conn_, dom_);
			const unsigned long cur_mem = dcs::testbed::libvirt::detail::current_memory(conn_, dom_);
			::virDomainMemoryStatStruct stats[VIR_DOMAIN_MEMORY_STAT_NR];
			int nr_stats = ::virDomainMemoryStats(dom_, stats, VIR_DOMAIN_MEMORY_STAT_NR, VIR_DOMAIN_AFFECT_CURRENT);
			if (0 <= nr_stats)
			{
				// Currently libvirt offers these stats:
				// - ..._SWAP_IN: The total amount of data read from swap space (in kB).
				// - ..._SWAP_OUT: The total amount of memory written out to swap space (in kB).
				// - ..._MAJOR_FAULT: Number of page faults that have occured when a process makes a valid access to virtual memory that is not available, for which disk I/O is required.
				// - ..._MINOR_FAULT: Number of page faults that have occurred when a process makes a valid access to virtual memory that is not available, for which disk I/O is'nt required.
				// - ..._UNUSED: The amount of memory left completely unused by the system (in kB). Memory that is available but used for reclaimable caches should NOT be reported as free.
				// - ..._AVAILABLE: The total amount of usable memory as seen by the domain (in kB). This value may be less than the amount of memory assigned to the domain if a balloon driver is in use or if the guest OS does not initialize all assigned pages.
				// - ..._ACTUAL_BALLOON: Current balloon value (in KB).
				// - ..._RSS: Resident Set Size of the process running the domain (in kB).

				long double mem_avail = 0;
				for (int i = 0; i < nr_stats; ++i)
				{
					if (stats[i].tag == VIR_DOMAIN_MEMORY_STAT_AVAILABLE)
					{
						//std::cerr << "DEBUG> MEM available " << stats[i].val << std::endl;
						mem_avail = stats[i].val;
					}

					mem_util_ = static_cast<double>((cur_max_mem-mem_avail)/static_cast<long double>(cfg_max_mem));
				}
			}
			else
			{
				//std::cerr << "DEBUG> CONFIG MAX MEM: " << cfg_max_mem << std::endl;
				//std::cerr << "DEBUG> CURRENT MAX MEM: " << cur_max_mem << std::endl;
				//std::cerr << "DEBUG> CURRENT MEM: " << cur_mem << std::endl;

#ifdef DCS_TESTBED_SENSOR_HAVE_MEMINFO_SERVER
				try
				{
					namespace asio = boost::asio;

					std::string server_addr = dcs::testbed::libvirt::detail::domain_name(conn_, dom_);
					std::string server_port = DCS_TESTBED_SENSOR_MEMINFO_SERVER_PORT;

					//std::cerr << "Connecting to " << server_addr << " on port " << server_port << std::endl;

					asio::io_service io_service;

					asio::ip::tcp::resolver resolver(io_service);
					asio::ip::tcp::resolver::query query(server_addr, server_port);
					asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);

					asio::ip::tcp::socket socket(io_service);
					boost::asio::connect(socket, endpoint_iterator);

					std::ostringstream oss;
					for (;;)
					{
						boost::array<char, 1024> buf;
						boost::system::error_code error;

						const std::size_t len = socket.read_some(boost::asio::buffer(buf), error);
						if (error == boost::asio::error::eof)
						{
							break; // Connection closed cleanly by peer.
						}
						else if (error)
						{
							throw boost::system::system_error(error); // Some other error.
						}
						oss << std::string(buf.data(), len);
					}
					socket.close();

					if (!oss.str().empty())
					{
						boost::uint32_t sz;
						std::string meminfo;

						boost::tie(sz, meminfo) = detail::meminfo_unpack(oss.str().c_str());

						//std::cerr << "DEBUG> MEMINFO: " << meminfo << std::endl;

						Json::Value root;   // will contains the root value after parsing
						Json::Reader reader;
						bool parse_ok = reader.parse(meminfo, root);
						if (parse_ok)
						{
							long double mem_avail = 0;
							if (root.isMember("MemAvailable"))
							{
								std::istringstream iss;
								iss.str(root.get("MemAvailable", "").asString());
								iss >> mem_avail;
							}
							else if (root.isMember("MemFree"))
							{
								long double mem_free = 0;
								std::istringstream iss;
								iss.str(root.get("MemFree", "").asString());
								iss >> mem_free;
								long double mem_cache = 0;
								iss.str(root.get("Cached", "0").asString());
								iss >> mem_cache;

								mem_avail = mem_free+mem_cache;
							}
							long double mem_tot = 0;
							if (root.isMember("MemTotal"))
							{
								std::istringstream iss;
								iss.str(root.get("MemTotal", "").asString());
								iss >> mem_tot;
							}
							else
							{
///\brief Checks whether two streams are equal.
///\param one The first stream for the comparison.
///\param two The second stream for the comparison.
///\return True if the streams are equal, false otherwise.
bool streamsEqual(JSON::Value & one, JSON::Value & two) {
    if ( !one.isMember("source") || !two.isMember("source") || one["source"] != two["source"]) {
        return false;
    }
    return true;
}
Example #28
0
    void doClean (Json::Value const& params)
    {
        LedgerIndex minRange;
        LedgerIndex maxRange;
        getApp().getLedgerMaster().getFullValidatedRange (minRange, maxRange);

        {
            SharedState::Access state (m_state);

            state->maxRange = maxRange;
            state->minRange = minRange;
            state->checkNodes = false;
            state->fixTxns = false;
            state->failures = 0;

            /*
            JSON Parameters:

                All parameters are optional. By default the cleaner cleans
                things it thinks are necessary. This behavior can be modified
                using the following options supplied via JSON RPC:

                "ledger"
                    A single unsigned integer representing an individual
                    ledger to clean.

                "min_ledger", "max_ledger"
                    Unsigned integers representing the starting and ending
                    ledger numbers to clean. If unspecified, clean all ledgers.

                "full"
                    A boolean. When set to true, means clean everything possible.

                "fix_txns"
                    A boolean value indicating whether or not to fix the
                    transactions in the database as well.

                "check_nodes"
                    A boolean, when set to true means check the nodes.

                "stop"
                    A boolean, when set to true informs the cleaner to gracefully
                    stop its current activities if any cleaning is taking place.
            */

            // Quick way to fix a single ledger
            if (params.isMember(jss::ledger))
            {
                state->maxRange = params[jss::ledger].asUInt();
                state->minRange = params[jss::ledger].asUInt();
                state->fixTxns = true;
                state->checkNodes = true;
            }

            if (params.isMember(jss::max_ledger))
                 state->maxRange = params[jss::max_ledger].asUInt();

            if (params.isMember(jss::min_ledger))
                state->minRange = params[jss::min_ledger].asUInt();

            if (params.isMember(jss::full))
                state->fixTxns = state->checkNodes = params[jss::full].asBool();

            if (params.isMember(jss::fix_txns))
                state->fixTxns = params[jss::fix_txns].asBool();

            if (params.isMember(jss::check_nodes))
                state->checkNodes = params[jss::check_nodes].asBool();

            if (params.isMember(jss::stop) && params[jss::stop].asBool())
                state->minRange = state->maxRange = 0;
        }

        notify();
    }
Example #29
0
  ///\brief Debugging tool for DTSC data.
  ///
  /// Expects DTSC data in a file given on the command line, outputs human-readable information to stderr.
  ///\param conf The configuration parsed from the commandline.
  ///\return The return code of the analyser.
  int analyseDTSC(Util::Config conf){
    DTSC::File F(conf.getString("filename"));
    JSON::Value meta = F.getMeta();
    std::cout << meta.toPrettyString() << std::endl;
    JSON::Value pack;

    long long unsigned int firstpack = 0;
    long long unsigned int nowpack = 0;
    long long unsigned int lastaudio = 0;
    long long unsigned int lastvideo = 0;
    long long unsigned int lastkey = 0;
    long long unsigned int totalvideo = 0;
    long long unsigned int totalaudio = 0;
    long long unsigned int keyframes = 0;
    long long unsigned int key_min = 0xffffffff;
    long long unsigned int key_max = 0;
    long long unsigned int vid_min = 0xffffffff;
    long long unsigned int vid_max = 0;
    long long unsigned int aud_min = 0xffffffff;
    long long unsigned int aud_max = 0;
    long long unsigned int bfrm_min = 0xffffffff;
    long long unsigned int bfrm_max = 0;
    long long unsigned int bps = 0;

    F.seekNext();
    while ( !F.getJSON().isNull()){
      std::cout << F.getJSON().toPrettyString() << std::endl;
      nowpack = F.getJSON()["time"].asInt();
      if (firstpack == 0){
        firstpack = nowpack;
      }
      if (F.getJSON()["datatype"].asString() == "audio"){
        if (lastaudio != 0 && (nowpack - lastaudio) != 0){
          bps = F.getJSON()["data"].asString().size() / (nowpack - lastaudio);
          if (bps < aud_min){
            aud_min = bps;
          }
          if (bps > aud_max){
            aud_max = bps;
          }
        }
        totalaudio += F.getJSON()["data"].asString().size();
        lastaudio = nowpack;
      }
      if (F.getJSON()["datatype"].asString() == "video"){
        if (lastvideo != 0 && (nowpack - lastvideo) != 0){
          bps = F.getJSON()["data"].asString().size() / (nowpack - lastvideo);
          if (bps < vid_min){
            vid_min = bps;
          }
          if (bps > vid_max){
            vid_max = bps;
          }
        }
        if (F.getJSON()["keyframe"].asInt() != 0){
          if (lastkey != 0){
            bps = nowpack - lastkey;
            if (bps < key_min){
              key_min = bps;
            }
            if (bps > key_max){
              key_max = bps;
            }
          }
          keyframes++;
          lastkey = nowpack;
        }
        if (F.getJSON()["offset"].asInt() != 0){
          bps = F.getJSON()["offset"].asInt();
          if (bps < bfrm_min){
            bfrm_min = bps;
          }
          if (bps > bfrm_max){
            bfrm_max = bps;
          }
        }
        totalvideo += F.getJSON()["data"].asString().size();
        lastvideo = nowpack;
      }
      F.seekNext();
    }

    std::cout << std::endl << "Summary:" << std::endl;
    meta["length"] = (long long int)((nowpack - firstpack) / 1000);
    if (meta.isMember("audio")){
      meta["audio"]["bps"] = (long long int)(totalaudio / ((lastaudio - firstpack) / 1000));
      std::cout << "  Audio: " << meta["audio"]["codec"].asString() << std::endl;
      std::cout << "    Bitrate: " << meta["audio"]["bps"].asInt() << std::endl;
    }
    if (meta.isMember("video")){
      meta["video"]["bps"] = (long long int)(totalvideo / ((lastvideo - firstpack) / 1000));
      meta["video"]["keyms"] = (long long int)((lastvideo - firstpack) / keyframes);
      if (meta["video"]["keyms"].asInt() - key_min > key_max - meta["video"]["keyms"].asInt()){
        meta["video"]["keyvar"] = (long long int)(meta["video"]["keyms"].asInt() - key_min);
      }else{
        meta["video"]["keyvar"] = (long long int)(key_max - meta["video"]["keyms"].asInt());
      }
      std::cout << "  Video: " << meta["video"]["codec"].asString() << std::endl;
      std::cout << "    Bitrate: " << meta["video"]["bps"].asInt() << std::endl;
      std::cout << "    Keyframes: " << meta["video"]["keyms"].asInt() << "~" << meta["video"]["keyvar"].asInt() << std::endl;
      std::cout << "    B-frames: " << bfrm_min << " - " << bfrm_max << std::endl;
    }
    return 0;
  }
Example #30
0
/** Fill in the fee on behalf of the client.
    This is called when the client does not explicitly specify the fee.
    The client may also put a ceiling on the amount of the fee. This ceiling
    is expressed as a multiplier based on the current ledger's fee schedule.

    JSON fields

    "Fee"   The fee paid by the transaction. Omitted when the client
            wants the fee filled in.

    "fee_mult_max"  A multiplier applied to the current ledger's transaction
                    fee that caps the maximum the fee server should auto fill.
                    If this optional field is not specified, then a default
                    multiplier is used.

    @param tx       The JSON corresponding to the transaction to fill in
    @param ledger   A ledger for retrieving the current fee schedule
    @param result   A JSON object for injecting error results, if any
    @param admin    `true` if this is called by an administrative endpoint.
*/
static void autofill_fee (
    Json::Value& request,
    RPCDetail::LedgerFacade& ledgerFacade,
    Json::Value& result,
    bool admin)
{
    Json::Value& tx (request["tx_json"]);
    if (tx.isMember ("Fee"))
        return;

    std::uint64_t feeByTrans = 0;
    if (tx.isMember("TransactionType") && tx["TransactionType"].asString() == "Payment")
    {
        if (!tx.isMember("Destination"))
        {
            RPC::inject_error (rpcINVALID_PARAMS, "no destination account", result);
            return;
        }
        Config d;
        std::string dstAccountID = tx["Destination"].asString();
        RippleAddress dstAddress;
        if (!dstAddress.setAccountID(dstAccountID))
        {
            RPC::inject_error (rpcINVALID_PARAMS, "invalid account id", result);
            return;
        }

        //dst account not exist yet, charge a fix amount of fee(0.01) for creating
        if (!ledgerFacade.isAccountExist(dstAddress.getAccountID()))
        {
            feeByTrans = d.FEE_DEFAULT_CREATE;
        }

        //if currency is native(VRP/VBC), charge 1/1000 of transfer amount,
        //otherwise charge a fix amount of fee(0.001)
        if (tx.isMember("Amount"))
        {
            STAmount amount;
            if (!amountFromJsonNoThrow(amount, tx["Amount"]))
            {
                RPC::inject_error (rpcINVALID_PARAMS, "wrong amount format", result);
                return;
            }
            feeByTrans += amount.isNative() ? amount.getNValue() * d.FEE_DEFAULT_RATE_NATIVE : d.FEE_DEFAULT_NONE_NATIVE;
        }
    }
    
    int mult = Tuning::defaultAutoFillFeeMultiplier;
    if (request.isMember ("fee_mult_max"))
    {
        if (request["fee_mult_max"].isNumeric ())
        {
            mult = request["fee_mult_max"].asInt();
        }
        else
        {
            RPC::inject_error (rpcHIGH_FEE, RPC::expected_field_message (
                "fee_mult_max", "a number"), result);
            return;
        }
    }

    // Default fee in fee units.
    std::uint64_t const feeDefault = getConfig().TRANSACTION_FEE_BASE;

    // Administrative endpoints are exempt from local fees.
    std::uint64_t const fee = ledgerFacade.scaleFeeLoad (feeDefault, admin);
    std::uint64_t const limit = mult * ledgerFacade.scaleFeeBase (feeDefault);

    if (fee > limit)
    {
        std::stringstream ss;
        ss <<
            "Fee of " << fee <<
            " exceeds the requested tx limit of " << limit;
        RPC::inject_error (rpcHIGH_FEE, ss.str(), result);
        return;
    }
    
    std::stringstream ss;
    ss << std::max(fee, feeByTrans);
    tx["Fee"] = ss.str();
}