<commit_before>#include "chronotext/utils/glUtils.h"
#include "chronotext/utils/Utils.h"
#include "chronotext/utils/MathUtils.h"

using namespace std;
using namespace ci;

const Matrix44f getPerspectiveMatrix(float fovy, float aspect, float zNear, float zFar)
{
    float ymax = zNear * math<float>::tan(fovy * PI / 360);
    float ymin = -ymax;

    float xmin = ymin * aspect;
    float xmax = ymax * aspect;

    return getFrustumMatrix(xmin, xmax, ymin, ymax, zNear, zFar);
}

/*
 * SPECIAL VERSION TAKING IN COUNT PAN AND ZOOM
 */
const Matrix44f getPerspectiveMatrix(float fovy, float zNear, float zFar, float width, float height, float panX, float panY, float zoom)
{
    float halfHeight = zNear * math<float>::tan(fovy * PI / 360) / zoom;
    float halfWidth = halfHeight * width / height;

    float offsetX = -panX * (halfWidth * 2 / width);
    float offsetY = -panY * (halfHeight * 2 / height);

    return getFrustumMatrix(-halfWidth + offsetX, halfWidth + offsetX, -halfHeight + offsetY, halfHeight + offsetY, zNear, zFar);
}

/*
 * BASED ON CODE FROM http://www.mesa3d.org
 */
const Matrix44f getFrustumMatrix(float left, float right, float bottom, float top, float znear, float zfar)
{
    float x = (2 * znear) / (right - left);
    float y = (2 * znear) / (top - bottom);
    float a = (right + left) / (right - left);
    float b = (top + bottom) / (top - bottom);
    float c = -(zfar + znear) / ( zfar - znear);
    float d = -(2 * zfar * znear) / (zfar - znear);

    float m[] =
    {
        x, 0, 0,  0,
        0, y, 0,  0,
        a, b, c, -1,
        0, 0, d,  0
    };

    return Matrix44f(m);
}

void drawGrid(const ci::Rectf &bounds, float size, const Vec2f &offset)
{
    drawGrid(bounds, size, size, offset);
}

void drawGrid(const Rectf &bounds, float sx, float sy, const Vec2f &offset)
{
    float x1 = bounds.x1 - boundf(bounds.x1 - offset.x, sx);
    float y1 = bounds.y1 - boundf(bounds.y1 - offset.y, sy);

    int nx = (int) math<float>::ceil(bounds.getWidth() / sx) + 1;
    int ny = (int) math<float>::ceil(bounds.getHeight() / sy) + 1;

    vector<Vec2f> vertices;
    vertices.reserve((nx + ny) * 4);

    for (int iy = 0; iy < ny; iy++)
    {
        float y = y1 + iy * sy;
        vertices.push_back(Vec2f(bounds.x1, y));
        vertices.push_back(Vec2f(bounds.x2, y));
    }

    for (int ix = 0; ix < nx; ix++)
    {
        float x = x1 + ix * sx;
        vertices.push_back(Vec2f(x, bounds.y1));
        vertices.push_back(Vec2f(x, bounds.y2));
    }

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, vertices.data());
    glDrawArrays(GL_LINES, 0, vertices.size());
    glDisableClientState(GL_VERTEX_ARRAY);
}

void drawFullScreenQuad()
{
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();

    const float vertices[] =
    {
        -1, -1,
        +1, -1,
        +1, +1,
        -1, +1
    };

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, vertices);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    glDisableClientState(GL_VERTEX_ARRAY);

    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
}

void dumpCamera(const ci::Camera &cam, const string &name)
{
    Vec3f worldUp = cam.getWorldUp();
    Vec3f eyepoint = cam.getEyePoint();
    Vec3f centerOfInterestPoint = cam.getCenterOfInterestPoint();
    Quatf orientation = cam.getOrientation();
    Vec3f axis = orientation.getAxis();

    LOGI << name << ".setWorldUp(Vec3f(" << worldUp.x << ", " << worldUp.y << ", " << worldUp.z << "));" << endl;
    LOGI << name << ".setEyePoint(Vec3f(" << eyepoint.x << ", " << eyepoint.y << ", " << eyepoint.z << "));" << endl;
    LOGI << name << ".setCenterOfInterestPoint(Vec3f(" << centerOfInterestPoint.x << ", " << centerOfInterestPoint.y << ", " << centerOfInterestPoint.z << "));" << endl;
    LOGI << name << ".setOrientation(Quatf(Vec3f(" << axis.x << ", " << axis.y << ", " << axis.z << "), " << orientation.getAngle() << "));" << endl;
    LOGI << name << ".setPerspective(" << cam.getFov() << ", getWindowAspectRatio(), " << cam.getNearClip() << ", " << cam.getFarClip() << ");" << endl;
}
<commit_msg>COSMETICS<commit_after>#include "chronotext/utils/glUtils.h"
#include "chronotext/utils/Utils.h"
#include "chronotext/utils/MathUtils.h"

using namespace std;
using namespace ci;

const Matrix44f getPerspectiveMatrix(float fovy, float aspect, float zNear, float zFar)
{
    float ymax = zNear * math<float>::tan(fovy * PI / 360);
    float ymin = -ymax;

    float xmin = ymin * aspect;
    float xmax = ymax * aspect;

    return getFrustumMatrix(xmin, xmax, ymin, ymax, zNear, zFar);
}

/*
 * SPECIAL VERSION TAKING IN COUNT PAN AND ZOOM
 */
const Matrix44f getPerspectiveMatrix(float fovy, float zNear, float zFar, float width, float height, float panX, float panY, float zoom)
{
    float halfHeight = zNear * math<float>::tan(fovy * PI / 360) / zoom;
    float halfWidth = halfHeight * width / height;

    float offsetX = -panX * (halfWidth * 2 / width);
    float offsetY = -panY * (halfHeight * 2 / height);

    return getFrustumMatrix(-halfWidth + offsetX, halfWidth + offsetX, -halfHeight + offsetY, halfHeight + offsetY, zNear, zFar);
}

/*
 * BASED ON CODE FROM http://www.mesa3d.org
 */
const Matrix44f getFrustumMatrix(float left, float right, float bottom, float top, float znear, float zfar)
{
    float x = (2 * znear) / (right - left);
    float y = (2 * znear) / (top - bottom);
    float a = (right + left) / (right - left);
    float b = (top + bottom) / (top - bottom);
    float c = -(zfar + znear) / ( zfar - znear);
    float d = -(2 * zfar * znear) / (zfar - znear);

    float m[] =
    {
        x, 0, 0,  0,
        0, y, 0,  0,
        a, b, c, -1,
        0, 0, d,  0
    };

    return Matrix44f(m);
}

void drawGrid(const Rectf &bounds, float size, const Vec2f &offset)
{
    drawGrid(bounds, size, size, offset);
}

void drawGrid(const Rectf &bounds, float sx, float sy, const Vec2f &offset)
{
    float x1 = bounds.x1 - boundf(bounds.x1 - offset.x, sx);
    float y1 = bounds.y1 - boundf(bounds.y1 - offset.y, sy);

    int nx = (int)math<float>::ceil(bounds.getWidth() / sx) + 1;
    int ny = (int)math<float>::ceil(bounds.getHeight() / sy) + 1;

    vector<Vec2f> vertices;
    vertices.reserve((nx + ny) * 4);

    for (int iy = 0; iy < ny; iy++)
    {
        float y = y1 + iy * sy;
        vertices.push_back(Vec2f(bounds.x1, y));
        vertices.push_back(Vec2f(bounds.x2, y));
    }

    for (int ix = 0; ix < nx; ix++)
    {
        float x = x1 + ix * sx;
        vertices.push_back(Vec2f(x, bounds.y1));
        vertices.push_back(Vec2f(x, bounds.y2));
    }

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, vertices.data());
    glDrawArrays(GL_LINES, 0, vertices.size());
    glDisableClientState(GL_VERTEX_ARRAY);
}

void drawFullScreenQuad()
{
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();

    const float vertices[] =
    {
        -1, -1,
        +1, -1,
        +1, +1,
        -1, +1
    };

    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_FLOAT, 0, vertices);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    glDisableClientState(GL_VERTEX_ARRAY);

    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
}

void dumpCamera(const Camera &cam, const string &name)
{
    Vec3f worldUp = cam.getWorldUp();
    Vec3f eyepoint = cam.getEyePoint();
    Vec3f centerOfInterestPoint = cam.getCenterOfInterestPoint();
    Quatf orientation = cam.getOrientation();
    Vec3f axis = orientation.getAxis();

    LOGI << name << ".setWorldUp(Vec3f(" << worldUp.x << ", " << worldUp.y << ", " << worldUp.z << "));" << endl;
    LOGI << name << ".setEyePoint(Vec3f(" << eyepoint.x << ", " << eyepoint.y << ", " << eyepoint.z << "));" << endl;
    LOGI << name << ".setCenterOfInterestPoint(Vec3f(" << centerOfInterestPoint.x << ", " << centerOfInterestPoint.y << ", " << centerOfInterestPoint.z << "));" << endl;
    LOGI << name << ".setOrientation(Quatf(Vec3f(" << axis.x << ", " << axis.y << ", " << axis.z << "), " << orientation.getAngle() << "));" << endl;
    LOGI << name << ".setPerspective(" << cam.getFov() << ", getWindowAspectRatio(), " << cam.getNearClip() << ", " << cam.getFarClip() << ");" << endl;
}
<|endoftext|>


<commit_before>#include <julia.h>
#include "JMain.h"

using namespace std;

shared_ptr<nj::Expr> JMain::eval(const shared_ptr<nj::Expr> &expr)
{
   shared_ptr<nj::Expr> result;

   return result;
}

JMain::JMain()
{
   initialized = false;
   deactivated = false;
}

void JMain::initialize(int argc,const char *argv[]) throw(nj::InitializationException)
{
   unique_lock<mutex> lock(m_state);

   if(argc >= 1) install_directory = argv[0];
   initialized = true;
}

shared_ptr<nj::Expr> JMain::dequeue(list<shared_ptr<nj::Expr>> &queue,mutex &m_queue,condition_variable &c_queue)
{
   bool done = false;
   shared_ptr<nj::Expr> expr;

   while(!done)
   {
      {
         unique_lock<mutex> lock(m_queue);

         if(queue.empty()) c_queue.wait(lock);
         if(!queue.empty())
         {
            expr = queue.back();
            queue.pop_back();
            done = true;
            if(expr.get()) printf("Dequeued Expr text = %s\n",expr->getText().c_str());
            else printf("Dequeued Null text\n");
         }
      }
      {
         unique_lock<mutex> lock(m_state);

         if(deactivated) done = true;
      }
   }
   return expr;
}

void JMain::enqueue(shared_ptr<nj::Expr> &expr,list<shared_ptr<nj::Expr>> &queue,mutex &m_queue,condition_variable &c_queue)
{
   unique_lock<mutex> lock(m_queue);

   queue.push_front(expr);
   c_queue.notify_all();
}

void JMain::operator()()
{
   bool done = false;

   while(!done)
   {
      unique_lock<mutex> lock(m_state);

      if(!initialized) c_state.wait(lock);
      if(initialized || deactivated) done = true;
   }

   if(!deactivated)
   {
      if(install_directory == "") jl_init(0);
      else jl_init((char*)install_directory.c_str());
      JL_SET_STACK_BASE;

      done = false;

      while(!done)
      {
printf("entering de_queue\n");
         shared_ptr<nj::Expr> expr = dequeue(eval_queue,m_evalq,c_evalq);

printf("got an expr\n");

         if(expr.get())
         {
printf("expr text = %s\n",expr->getText().c_str());
            shared_ptr<nj::Expr> result = eval(expr);
printf("Eval expr\n");
            enqueue(result,result_queue,m_resultq,c_resultq);
         }
         else
         {
            printf("Expr to eval is null result will be null\n");
            shared_ptr<nj::Expr> result;

            enqueue(result,result_queue,m_resultq,c_resultq);
         }
         {
            unique_lock<mutex> lock(m_state);

            if(deactivated) done = true;
         }
      }
   }
}

void JMain::evalQueuePut(const string &expressionText)
{
   shared_ptr<nj::Expr> expr(new nj::Expr(expressionText));
printf("Received an expr from Outside%s\n",expressionText.c_str());
   enqueue(expr,eval_queue,m_evalq,c_evalq);
}

string JMain::resultQueueGet()
{
   shared_ptr<nj::Expr> expr = dequeue(result_queue,m_resultq,c_resultq);
printf("Got Result\n");
   if(expr.get())
   {
printf("Result text = %s\n",expr->getText().c_str());
    return expr->getText();
   }
printf("Result text = ""\n");
   return "";
}

void JMain::stop()
{
   unique_lock<mutex> lock(m_state);

   deactivated = true;
   c_state.notify_all();
   c_evalq.notify_all();
   c_resultq.notify_all();
}

JMain::~JMain() {}
<commit_msg>Actually connected to Julia eval first try.<commit_after>#include <julia.h>
#include "JMain.h"

using namespace std;

shared_ptr<nj::Expr> JMain::eval(const shared_ptr<nj::Expr> &expr)
{
   jl_value_t *res = (jl_value_t*)jl_eval_string((char*)expr->getText().c_str());

   if(jl_is_float64(res))
   {
      double res_unboxed = jl_unbox_float64(res);
      return shared_ptr<nj::Expr>(new nj::Expr(to_string(res_unboxed)));
   }
   return shared_ptr<nj::Expr>();
}

JMain::JMain()
{
   initialized = false;
   deactivated = false;
}

void JMain::initialize(int argc,const char *argv[]) throw(nj::InitializationException)
{
   unique_lock<mutex> lock(m_state);

   if(argc >= 1) install_directory = argv[0];
   initialized = true;
}

shared_ptr<nj::Expr> JMain::dequeue(list<shared_ptr<nj::Expr>> &queue,mutex &m_queue,condition_variable &c_queue)
{
   bool done = false;
   shared_ptr<nj::Expr> expr;

   while(!done)
   {
      {
         unique_lock<mutex> lock(m_queue);

         if(queue.empty()) c_queue.wait(lock);
         if(!queue.empty())
         {
            expr = queue.back();
            queue.pop_back();
            done = true;
         }
      }
      {
         unique_lock<mutex> lock(m_state);

         if(deactivated) done = true;
      }
   }
   return expr;
}

void JMain::enqueue(shared_ptr<nj::Expr> &expr,list<shared_ptr<nj::Expr>> &queue,mutex &m_queue,condition_variable &c_queue)
{
   unique_lock<mutex> lock(m_queue);

   queue.push_front(expr);
   c_queue.notify_all();
}

void JMain::operator()()
{
   bool done = false;

   while(!done)
   {
      unique_lock<mutex> lock(m_state);

      if(!initialized) c_state.wait(lock);
      if(initialized || deactivated) done = true;
   }

   if(!deactivated)
   {
      if(install_directory == "") jl_init(0);
      else jl_init((char*)install_directory.c_str());
      JL_SET_STACK_BASE;

      done = false;

      while(!done)
      {
         shared_ptr<nj::Expr> expr = dequeue(eval_queue,m_evalq,c_evalq);

         if(expr.get())
         {
printf("Eval-ing expr; text = %s\n",expr->getText().c_str());
            shared_ptr<nj::Expr> result = eval(expr);
printf("Evaled expr\n");
            enqueue(result,result_queue,m_resultq,c_resultq);
         }
         else
         {
            printf("Evaled null to null\n");
            shared_ptr<nj::Expr> result;

            enqueue(result,result_queue,m_resultq,c_resultq);
         }
         {
            unique_lock<mutex> lock(m_state);

            if(deactivated) done = true;
         }
      }
   }
}

void JMain::evalQueuePut(const string &expressionText)
{
   shared_ptr<nj::Expr> expr(new nj::Expr(expressionText));
printf("Received an expr from Outside; %s\n",expressionText.c_str());
   enqueue(expr,eval_queue,m_evalq,c_evalq);
}

string JMain::resultQueueGet()
{
   shared_ptr<nj::Expr> expr = dequeue(result_queue,m_resultq,c_resultq);
   if(expr.get())
   {
printf("Result text = %s\n",expr->getText().c_str());
    return expr->getText();
   }
printf("Result text = ""\n");
   return "";
}

void JMain::stop()
{
   unique_lock<mutex> lock(m_state);

   deactivated = true;
   c_state.notify_all();
   c_evalq.notify_all();
   c_resultq.notify_all();
}

JMain::~JMain() {}
<|endoftext|>


<commit_before>
//by ZouZhiZhang

#include "tetris_core.h"
#include "ai_zzz.h"

using namespace m_tetris;
namespace ai_zzz
{
    namespace qq
    {
        void Attack::init(m_tetris::TetrisContext const *context)
        {
            check_line_.clear();
            const int full = (1 << 10) - 1;
            for(int x = 0; x <= 10; ++x)
            {
                check_line_.insert(full & ~(1 << x));
            }
        }

        std::string Attack::ai_name() const
        {
            return "ZZZ Attack v0.1";
        }

        double Attack::eval_map_bad() const
        {
            return -99999999;
        }

        double Attack::eval_map(TetrisMap const &map, EvalParam<> const *history, size_t history_length)
        {
            if(history->node->low >= 20)
            {
                return eval_map_bad();
            }
            double value = 0;
            int top = map.roof;

            int new_last_top = history->map.roof;
            for(size_t i = 0; i < history_length; ++i)
            {
                new_last_top -= history[i].clear;
            }
            const int width = 10;
            const int top_m4 = std::max(1, history->map.roof - 4);
            const int danger = std::max(history->map.roof + 4 - 20, 0);
            const int width_mul = 20 * 2560 / (width + 8) / (width + 8);

            int const *tops = map.top;

            for(int x = 0; x < width; ++x)
            {
                for(int y = top - 1; y >= 0; --y)
                {
                    if(map.full(x, y))
                    {
                        for(; y >= 0; --y)
                        {
                            if(!map.full(x, y))
                            {
                                if(x == width - 1 || map.full(x + 1, y))
                                {
                                    value -= (y + 1) * 2;
                                }
                                if(x == 0 || map.full(x - 1, y))
                                {
                                    value -= (y + 1) * 2;
                                }
                                if((y + 1) >= top_m4)
                                {
                                    value -= 512 + (y + 1) * width_mul;
                                }
                                else
                                {
                                    value -= 128 + (y + 1) * width_mul / 4;
                                }
                            }
                        }
                        break;
                    }
                    else
                    {
                        if(x == width - 1 || map.full(x + 1, y))
                        {
                            value -= (y + 1) * 2;
                        }
                        if(x == 0 || map.full(x - 1, y))
                        {
                            value -= (y + 1) * 2;
                        }
                    }
                }
            }
            int low_x = (tops[width - 1] <= tops[0]) ? width - 1 : 0;
            for(int x = width - 3; x > 1; --x)
            {
                if(tops[x] < tops[low_x])
                {
                    low_x = x;
                }
            }
            if(tops[1] < tops[low_x])
            {
                low_x = 1;
            }
            if(tops[width - 2] < tops[low_x])
            {
                low_x = width - 2;
            }
            const int low_y = tops[low_x];
            int deep = 0;
            for(int y = top - 1; y >= low_y; --y)
            {
                if(check_line_.find(map.row[y]) != check_line_.end())
                {
                    deep += 16;
                    for(--y; y >= low_y; --y)
                    {
                        if(check_line_.find(map.row[y]) != check_line_.end())
                        {
                            deep += 3;
                        }
                        else
                        {
                            deep -= 5;
                        }
                    }
                    break;
                }
                else
                {
                    deep -= 1;
                }
            }
            value += deep * width * 16 * history->map.roof / 10 / (danger * danger + 1);
            for(int x = 0; x < width; ++x)
            {
                int dx = std::abs(x - low_x);
                int dy = std::max(0, new_last_top - tops[x] - 4);
                if(dx > 1 && dy > 0)
                {
                    dx += 8;
                    if(danger == 0)
                    {
                        dy += 3;
                        value -= dy * dy * dx * width * 8;
                    }
                    else
                    {
                        value -= dy * dx * width * 16;
                    }
                }
            }
            value -= width_mul * new_last_top / 3;

            for(size_t i = 0; i < history_length; ++i)
            {
                switch(history[i].clear)
                {
                case 0:
                    break;
                case 1:
                case 2:
                    if(danger == 0)
                    {
                        value -= 4 * history->map.roof * width * history[i].clear * 128 / width_mul;
                    }
                    else if(danger >= 2)
                    {
                        value += danger * 16 * history->map.roof * width * history[i].clear * 2;
                    }
                    break;
                default:
                    value += (400 + (history_length - i) * 50) * history->map.roof * width * history[i].clear * 2;
                }
            }

            return value;
        }

        size_t Attack::prune_map(m_tetris::PruneParam<double> *prune, size_t prune_length, TetrisNode const **after_pruning, size_t next_length)
        {
            struct
            {
                bool operator()(m_tetris::PruneParam<double> const &left, m_tetris::PruneParam<double> const &right)
                {
                    return left.eval > right.eval;
                }
            } c;
            std::sort(prune, prune + prune_length, c);
            size_t hold_count = std::min<size_t>(prune_length, 4);
            for(size_t i = 0; i < hold_count; ++i)
            {
                after_pruning[i] = prune[i].land_point;
            }
            return hold_count;
        }

    }

    void Dig::init(m_tetris::TetrisContext const *context, Param const *param)
    {
        param_ = param;
    }

    std::string Dig::ai_name() const
    {
        return "ZZZ Dig v0.2";
    }

    double Dig::eval_map_bad() const
    {
        return -99999999;
    }

    double Dig::eval_map(TetrisMap const &map, EvalParam<> const *history, size_t history_length)
    {
        if(history->node->low >= 20)
        {
            return eval_map_bad();
        }
        double value = 0;

        const int width = 10;

        for(int x = 0; x < width; ++x)
        {
            for(int y = 0; y < map.roof; ++y)
            {
                if(map.full(x, y))
                {
                    continue;
                }
                if(x == width - 1 || map.full(x + 1, y))
                {
                    value -= 3 * (y + 1);
                }
                if(x == 0 || map.full(x - 1, y))
                {
                    value -= 3 * (y + 1);
                }
                if(map.full(x, y + 1))
                {
                    value -= 10 * (y + 1);
                    if(map.full(x, y + 2))
                    {
                        value -= 4;
                        if(map.full(x, y + 3))
                        {
                            value -= 3;
                            if(map.full(x, y + 4))
                            {
                                value -= 2;
                            }
                        }
                    }
                }
            }
        }
        int combo = param_->combo;
        int clear = 0;
        for(size_t i = 0; i < history_length; ++i)
        {
            ++clear;
            if(history[i].clear > 0)
            {
                ++combo;
            }
            else
            {
                for(++i; i < history_length; ++i)
                {
                    ++clear;
                }
                break;
            }
        }
        if(combo >= 5)
        {
            value += combo * 4096;
        }
        else
        {
            value -= clear * 256;
        }
        TetrisNode const *node = history->node;
        if(map.width == 10 && map.height == 40 && node->row + node->height + 2 >= 20 && node->col >= 3 && node->col + width <= 6)
        {
            value -= 50000000;
        }
        return value;
    }

    size_t Dig::prune_map(m_tetris::PruneParam<double> *prune, size_t prune_length, TetrisNode const **after_pruning, size_t next_length)
    {
        struct
        {
            bool operator()(m_tetris::PruneParam<double> const &left, m_tetris::PruneParam<double> const &right)
            {
                return left.eval > right.eval;
            }
        } c;
        std::sort(prune, prune + prune_length, c);
        size_t hold_count = std::min<size_t>(prune_length, 2);
        for(size_t i = 0; i < hold_count; ++i)
        {
            after_pruning[i] = prune[i].land_point;
        }
        return hold_count;
    }
}<commit_msg>调整一下剪枝...大概强了一些?<commit_after>
//by ZouZhiZhang

#include "tetris_core.h"
#include "ai_zzz.h"

using namespace m_tetris;
namespace ai_zzz
{
    namespace qq
    {
        void Attack::init(m_tetris::TetrisContext const *context)
        {
            check_line_.clear();
            const int full = (1 << 10) - 1;
            for(int x = 0; x <= 10; ++x)
            {
                check_line_.insert(full & ~(1 << x));
            }
        }

        std::string Attack::ai_name() const
        {
            return "ZZZ Attack v0.1";
        }

        double Attack::eval_map_bad() const
        {
            return -99999999;
        }

        double Attack::eval_map(TetrisMap const &map, EvalParam<> const *history, size_t history_length)
        {
            if(history->node->low >= 20)
            {
                return eval_map_bad();
            }
            double value = 0;
            int top = map.roof;

            int new_last_top = history->map.roof;
            for(size_t i = 0; i < history_length; ++i)
            {
                new_last_top -= history[i].clear;
            }
            const int width = 10;
            const int top_m4 = std::max(1, history->map.roof - 4);
            const int danger = std::max(history->map.roof + 4 - 20, 0);
            const int width_mul = 20 * 2560 / (width + 8) / (width + 8);

            int const *tops = map.top;

            for(int x = 0; x < width; ++x)
            {
                for(int y = top - 1; y >= 0; --y)
                {
                    if(map.full(x, y))
                    {
                        for(; y >= 0; --y)
                        {
                            if(!map.full(x, y))
                            {
                                if(x == width - 1 || map.full(x + 1, y))
                                {
                                    value -= (y + 1) * 2;
                                }
                                if(x == 0 || map.full(x - 1, y))
                                {
                                    value -= (y + 1) * 2;
                                }
                                if((y + 1) >= top_m4)
                                {
                                    value -= 512 + (y + 1) * width_mul;
                                }
                                else
                                {
                                    value -= 128 + (y + 1) * width_mul / 4;
                                }
                            }
                        }
                        break;
                    }
                    else
                    {
                        if(x == width - 1 || map.full(x + 1, y))
                        {
                            value -= (y + 1) * 2;
                        }
                        if(x == 0 || map.full(x - 1, y))
                        {
                            value -= (y + 1) * 2;
                        }
                    }
                }
            }
            int low_x = (tops[width - 1] <= tops[0]) ? width - 1 : 0;
            for(int x = width - 3; x > 1; --x)
            {
                if(tops[x] < tops[low_x])
                {
                    low_x = x;
                }
            }
            if(tops[1] < tops[low_x])
            {
                low_x = 1;
            }
            if(tops[width - 2] < tops[low_x])
            {
                low_x = width - 2;
            }
            const int low_y = tops[low_x];
            int deep = 0;
            for(int y = top - 1; y >= low_y; --y)
            {
                if(check_line_.find(map.row[y]) != check_line_.end())
                {
                    deep += 16;
                    for(--y; y >= low_y; --y)
                    {
                        if(check_line_.find(map.row[y]) != check_line_.end())
                        {
                            deep += 3;
                        }
                        else
                        {
                            deep -= 5;
                        }
                    }
                    break;
                }
                else
                {
                    deep -= 1;
                }
            }
            value += deep * width * 16 * history->map.roof / 10 / (danger * danger + 1);
            for(int x = 0; x < width; ++x)
            {
                int dx = std::abs(x - low_x);
                int dy = std::max(0, new_last_top - tops[x] - 4);
                if(dx > 1 && dy > 0)
                {
                    dx += 8;
                    if(danger == 0)
                    {
                        dy += 3;
                        value -= dy * dy * dx * width * 8;
                    }
                    else
                    {
                        value -= dy * dx * width * 16;
                    }
                }
            }
            value -= width_mul * new_last_top / 3;

            for(size_t i = 0; i < history_length; ++i)
            {
                switch(history[i].clear)
                {
                case 0:
                    break;
                case 1:
                case 2:
                    if(danger == 0)
                    {
                        value -= 4 * history->map.roof * width * history[i].clear * 128 / width_mul;
                    }
                    else if(danger >= 2)
                    {
                        value += danger * 16 * history->map.roof * width * history[i].clear * 2;
                    }
                    break;
                default:
                    value += (400 + (history_length - i) * 50) * history->map.roof * width * history[i].clear * 2;
                }
            }

            return value;
        }

        size_t Attack::prune_map(m_tetris::PruneParam<double> *prune, size_t prune_length, TetrisNode const **after_pruning, size_t next_length)
        {
            struct
            {
                bool operator()(m_tetris::PruneParam<double> const &left, m_tetris::PruneParam<double> const &right)
                {
                    return left.eval > right.eval;
                }
            } c;
            std::sort(prune, prune + prune_length, c);
            size_t hold_count = std::min<size_t>(prune_length, 4);
            for(size_t i = 0; i < hold_count; ++i)
            {
                after_pruning[i] = prune[i].land_point;
            }
            return hold_count;
        }

    }

    void Dig::init(m_tetris::TetrisContext const *context, Param const *param)
    {
        param_ = param;
    }

    std::string Dig::ai_name() const
    {
        return "ZZZ Dig v0.2";
    }

    double Dig::eval_map_bad() const
    {
        return -99999999;
    }

    double Dig::eval_map(TetrisMap const &map, EvalParam<> const *history, size_t history_length)
    {
        if(history->node->low >= 20)
        {
            return eval_map_bad();
        }
        double value = 0;

        const int width = 10;

        for(int x = 0; x < width; ++x)
        {
            for(int y = 0; y < map.roof; ++y)
            {
                if(map.full(x, y))
                {
                    continue;
                }
                if(x == width - 1 || map.full(x + 1, y))
                {
                    value -= 3 * (y + 1);
                }
                if(x == 0 || map.full(x - 1, y))
                {
                    value -= 3 * (y + 1);
                }
                if(map.full(x, y + 1))
                {
                    value -= 10 * (y + 1);
                    if(map.full(x, y + 2))
                    {
                        value -= 4;
                        if(map.full(x, y + 3))
                        {
                            value -= 3;
                            if(map.full(x, y + 4))
                            {
                                value -= 2;
                            }
                        }
                    }
                }
            }
        }
        int combo = param_->combo;
        int clear = 0;
        for(size_t i = 0; i < history_length; ++i)
        {
            ++clear;
            if(history[i].clear > 0)
            {
                ++combo;
            }
            else
            {
                for(++i; i < history_length; ++i)
                {
                    ++clear;
                }
                break;
            }
        }
        if(combo >= 5)
        {
            value += combo * 4096;
        }
        else
        {
            value -= clear * 256;
        }
        TetrisNode const *node = history->node;
        if(map.width == 10 && map.height == 40 && node->row + node->height + 2 >= 20 && node->col >= 3 && node->col + width <= 6)
        {
            value -= 50000000;
        }
        return value;
    }

    size_t Dig::prune_map(m_tetris::PruneParam<double> *prune, size_t prune_length, TetrisNode const **after_pruning, size_t next_length)
    {
        struct
        {
            bool operator()(m_tetris::PruneParam<double> const &left, m_tetris::PruneParam<double> const &right)
            {
                return left.eval > right.eval;
            }
        } c;
        std::sort(prune, prune + prune_length, c);
        size_t hold_count = std::min<size_t>(prune_length, next_length < 6 ? 1 : 6);
        for(size_t i = 0; i < hold_count; ++i)
        {
            after_pruning[i] = prune[i].land_point;
        }
        return hold_count;
    }
}<|endoftext|>


<commit_before>// Copyright (c) 2014 The Bitcoin developers
// Copyright (c) 2017-2019 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "base58.h"

#include "hash.h"
#include "uint256.h"

#include <assert.h>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
#include <sstream>
#include <stdint.h>
#include <string.h>
#include <string>
#include <vector>

/** All alphanumeric characters except for "0", "I", "O", and "l" */
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
{
    // Skip leading spaces.
    while (*psz && isspace(*psz))
        psz++;
    // Skip and count leading '1's.
    int zeroes = 0;
    int length = 0;
    while (*psz == '1') {
        zeroes++;
        psz++;
    }
    // Allocate enough space in big-endian base256 representation.
    int size = strlen(psz) * 733 /1000 + 1; // log(58) / log(256), rounded up.
    std::vector<unsigned char> b256(size);
    // Process the characters.
    while (*psz && !isspace(*psz)) {
        // Decode base58 character
        const char* ch = strchr(pszBase58, *psz);
        if (ch == NULL)
            return false;
        // Apply "b256 = b256 * 58 + ch".
        int carry = ch - pszBase58;
        int i = 0;
        for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); (carry != 0 || i < length) && (it != b256.rend()); it++, i++) {
            carry += 58 * (*it);
            *it = carry % 256;
            carry /= 256;
        }
        assert(carry == 0);
        length = i;
        psz++;
    }
    // Skip trailing spaces.
    while (isspace(*psz))
        psz++;
    if (*psz != 0)
        return false;
    // Skip leading zeroes in b256.
    std::vector<unsigned char>::iterator it = b256.begin() + (size - length);
    while (it != b256.end() && *it == 0)
        it++;
    // Copy result into output vector.
    vch.reserve(zeroes + (b256.end() - it));
    vch.assign(zeroes, 0x00);
    while (it != b256.end())
        vch.push_back(*(it++));
    return true;
}

std::string DecodeBase58(const char* psz)
{
    std::vector<unsigned char> vch;
    DecodeBase58(psz, vch);
    std::stringstream ss;
    ss << std::hex;

    for (unsigned int i = 0; i < vch.size(); i++) {
        unsigned char* c = &vch[i];
        ss << std::setw(2) << std::setfill('0') << (int)c[0];
    }

    return ss.str();
}

std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
{
    // Skip & count leading zeroes.
    int zeroes = 0;
    int length = 0;
    while (pbegin != pend && *pbegin == 0) {
        pbegin++;
        zeroes++;
    }
    // Allocate enough space in big-endian base58 representation.
    int size = (pend - pbegin) * 138 / 100 + 1; // log(256) / log(58), rounded up.
    std::vector<unsigned char> b58(size);
    // Process the bytes.
    while (pbegin != pend) {
        int carry = *pbegin;
        int i = 0;
        // Apply "b58 = b58 * 256 + ch".
        for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); (carry != 0 || i < length) && (it != b58.rend()); it++, i++) {
            carry += 256 * (*it);
            *it = carry % 58;
            carry /= 58;
        }

        assert(carry == 0);
        length = i;
        pbegin++;
    }
    // Skip leading zeroes in base58 result.
    std::vector<unsigned char>::iterator it = b58.begin() + (size - length);
    while (it != b58.end() && *it == 0)
        it++;
    // Translate the result into a string.
    std::string str;
    str.reserve(zeroes + (b58.end() - it));
    str.assign(zeroes, '1');
    while (it != b58.end())
        str += pszBase58[*(it++)];
    return str;
}

std::string EncodeBase58(const std::vector<unsigned char>& vch)
{
    return EncodeBase58(&vch[0], &vch[0] + vch.size());
}

bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
{
    return DecodeBase58(str.c_str(), vchRet);
}

std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
{
    // add 4-byte hash check to the end
    std::vector<unsigned char> vch(vchIn);
    uint256 hash = Hash(vch.begin(), vch.end());
    vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
    return EncodeBase58(vch);
}

bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
{
    if (!DecodeBase58(psz, vchRet) ||
        (vchRet.size() < 4)) {
        vchRet.clear();
        return false;
    }
    // re-calculate the checksum, insure it matches the included 4-byte checksum
    uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4);
    if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) {
        vchRet.clear();
        return false;
    }
    vchRet.resize(vchRet.size() - 4);
    return true;
}

bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
{
    return DecodeBase58Check(str.c_str(), vchRet);
}

CBase58Data::CBase58Data()
{
    vchVersion.clear();
    vchData.clear();
}

void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const void* pdata, size_t nSize)
{
    vchVersion = vchVersionIn;
    vchData.resize(nSize);
    if (!vchData.empty())
        memcpy(&vchData[0], pdata, nSize);
}

void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend)
{
    SetData(vchVersionIn, (void*)pbegin, pend - pbegin);
}

bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
{
    std::vector<unsigned char> vchTemp;
    bool rc58 = DecodeBase58Check(psz, vchTemp);
    if ((!rc58) || (vchTemp.size() < nVersionBytes)) {
        vchData.clear();
        vchVersion.clear();
        return false;
    }
    vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes);
    vchData.resize(vchTemp.size() - nVersionBytes);
    if (!vchData.empty())
        memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
    memory_cleanse(&vchTemp[0], vchData.size());
    return true;
}

bool CBase58Data::SetString(const std::string& str)
{
    if (str.empty())
        return false;
    return SetString(str.c_str());
}

std::string CBase58Data::ToString() const
{
    std::vector<unsigned char> vch = vchVersion;
    vch.insert(vch.end(), vchData.begin(), vchData.end());
    return EncodeBase58Check(vch);
}

int CBase58Data::CompareTo(const CBase58Data& b58) const
{
    if (vchVersion < b58.vchVersion)
        return -1;
    if (vchVersion > b58.vchVersion)
        return 1;
    if (vchData < b58.vchData)
        return -1;
    if (vchData > b58.vchData)
        return 1;
    return 0;
}

namespace
{
class CBitcoinAddressVisitor : public boost::static_visitor<bool>
{
private:
    CBitcoinAddress* addr;
    CChainParams::Base58Type type;

public:
    CBitcoinAddressVisitor(CBitcoinAddress* addrIn,
            const CChainParams::Base58Type addrType = CChainParams::PUBKEY_ADDRESS) :
        addr(addrIn),
        type(addrType){};

    bool operator()(const CKeyID& id) const { return addr->Set(id, type); }
    bool operator()(const CScriptID& id) const { return addr->Set(id); }
    bool operator()(const CNoDestination& no) const { return false; }
};

} // anon namespace

bool CBitcoinAddress::Set(const CKeyID& id, const CChainParams::Base58Type addrType)
{
    SetData(Params().Base58Prefix(addrType), &id, 20);
    return true;
}

bool CBitcoinAddress::Set(const CScriptID& id)
{
    SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
    return true;
}

bool CBitcoinAddress::Set(const CTxDestination& dest, const CChainParams::Base58Type addrType)
{
    return boost::apply_visitor(CBitcoinAddressVisitor(this, addrType), dest);
}

bool CBitcoinAddress::IsValid() const
{
    return IsValid(Params());
}

bool CBitcoinAddress::IsValid(const CChainParams& params) const
{
    bool fCorrectSize = vchData.size() == 20;
    bool fKnownVersion = vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
                         vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS) ||
                         vchVersion == params.Base58Prefix(CChainParams::STAKING_ADDRESS);
    return fCorrectSize && fKnownVersion;
}

CTxDestination CBitcoinAddress::Get() const
{
    if (!IsValid())
        return CNoDestination();
    uint160 id;
    memcpy(&id, &vchData[0], 20);
    if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
            vchVersion == Params().Base58Prefix(CChainParams::STAKING_ADDRESS))
        return CKeyID(id);
    else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS))
        return CScriptID(id);
    else
        return CNoDestination();
}

bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const
{
    if (!IsValid() ||
            (vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) &&
            vchVersion != Params().Base58Prefix(CChainParams::STAKING_ADDRESS)))
        return false;
    uint160 id;
    memcpy(&id, &vchData[0], 20);
    keyID = CKeyID(id);
    return true;
}

bool CBitcoinAddress::IsScript() const
{
    bool fCorrectSize = vchData.size() == 20;
    return fCorrectSize && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
}

bool CBitcoinAddress::IsStakingAddress() const
{
    bool fCorrectSize = vchData.size() == 20;
    return fCorrectSize && vchVersion == Params().Base58Prefix(CChainParams::STAKING_ADDRESS);
}

void CBitcoinSecret::SetKey(const CKey& vchSecret)
{
    assert(vchSecret.IsValid());
    SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size());
    if (vchSecret.IsCompressed())
        vchData.push_back(1);
}

CKey CBitcoinSecret::GetKey()
{
    CKey ret;
    assert(vchData.size() >= 32);
    ret.Set(vchData.begin(), vchData.begin() + 32, vchData.size() > 32 && vchData[32] == 1);
    return ret;
}

bool CBitcoinSecret::IsValid() const
{
    bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
    bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
    return fExpectedFormat && fCorrectVersion;
}

bool CBitcoinSecret::SetString(const char* pszSecret)
{
    return CBase58Data::SetString(pszSecret) && IsValid();
}

bool CBitcoinSecret::SetString(const std::string& strSecret)
{
    return SetString(strSecret.c_str());
}

CTxDestination DestinationFor(const CKeyID& keyID, const CChainParams::Base58Type addrType)
{
    CBitcoinAddress addr(keyID, addrType);
    if (!addr.IsValid()) throw std::runtime_error("Error, trying to decode an invalid keyID");
    return addr.Get();
}

std::string EncodeDestination(const CTxDestination& dest, const CChainParams::Base58Type addrType)
{
    CBitcoinAddress addr(dest, addrType);
    if (!addr.IsValid()) return "";
    return addr.ToString();
}

CTxDestination DecodeDestination(const std::string& str)
{
    return CBitcoinAddress(str).Get();
}

CTxDestination DecodeDestination(const std::string& str, bool& isStaking)
{
    CBitcoinAddress addr(str);
    isStaking = addr.IsStakingAddress();
    return addr.Get();
}

bool IsValidDestinationString(const std::string& str, bool fStaking, const CChainParams& params)
{
    return IsValidDestinationString(str, fStaking);
}

bool IsValidDestinationString(const std::string& str)
{
    CBitcoinAddress address(str);
    return address.IsValid();
}

bool IsValidDestinationString(const std::string& str, bool isStaking)
{
    CBitcoinAddress address(str);
    return address.IsValid() && (address.IsStakingAddress() == isStaking);
}
<commit_msg>Use prefix operator in for loop of DecodeBase58.<commit_after>// Copyright (c) 2014 The Bitcoin developers
// Copyright (c) 2017-2019 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "base58.h"

#include "hash.h"
#include "uint256.h"

#include <assert.h>
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
#include <sstream>
#include <stdint.h>
#include <string.h>
#include <string>
#include <vector>

/** All alphanumeric characters except for "0", "I", "O", and "l" */
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch)
{
    // Skip leading spaces.
    while (*psz && isspace(*psz))
        psz++;
    // Skip and count leading '1's.
    int zeroes = 0;
    int length = 0;
    while (*psz == '1') {
        zeroes++;
        psz++;
    }
    // Allocate enough space in big-endian base256 representation.
    int size = strlen(psz) * 733 /1000 + 1; // log(58) / log(256), rounded up.
    std::vector<unsigned char> b256(size);
    // Process the characters.
    while (*psz && !isspace(*psz)) {
        // Decode base58 character
        const char* ch = strchr(pszBase58, *psz);
        if (ch == NULL)
            return false;
        // Apply "b256 = b256 * 58 + ch".
        int carry = ch - pszBase58;
        int i = 0;
        for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); (carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) {
            carry += 58 * (*it);
            *it = carry % 256;
            carry /= 256;
        }
        assert(carry == 0);
        length = i;
        psz++;
    }
    // Skip trailing spaces.
    while (isspace(*psz))
        psz++;
    if (*psz != 0)
        return false;
    // Skip leading zeroes in b256.
    std::vector<unsigned char>::iterator it = b256.begin() + (size - length);
    while (it != b256.end() && *it == 0)
        it++;
    // Copy result into output vector.
    vch.reserve(zeroes + (b256.end() - it));
    vch.assign(zeroes, 0x00);
    while (it != b256.end())
        vch.push_back(*(it++));
    return true;
}

std::string DecodeBase58(const char* psz)
{
    std::vector<unsigned char> vch;
    DecodeBase58(psz, vch);
    std::stringstream ss;
    ss << std::hex;

    for (unsigned int i = 0; i < vch.size(); i++) {
        unsigned char* c = &vch[i];
        ss << std::setw(2) << std::setfill('0') << (int)c[0];
    }

    return ss.str();
}

std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
{
    // Skip & count leading zeroes.
    int zeroes = 0;
    int length = 0;
    while (pbegin != pend && *pbegin == 0) {
        pbegin++;
        zeroes++;
    }
    // Allocate enough space in big-endian base58 representation.
    int size = (pend - pbegin) * 138 / 100 + 1; // log(256) / log(58), rounded up.
    std::vector<unsigned char> b58(size);
    // Process the bytes.
    while (pbegin != pend) {
        int carry = *pbegin;
        int i = 0;
        // Apply "b58 = b58 * 256 + ch".
        for (std::vector<unsigned char>::reverse_iterator it = b58.rbegin(); (carry != 0 || i < length) && (it != b58.rend()); it++, i++) {
            carry += 256 * (*it);
            *it = carry % 58;
            carry /= 58;
        }

        assert(carry == 0);
        length = i;
        pbegin++;
    }
    // Skip leading zeroes in base58 result.
    std::vector<unsigned char>::iterator it = b58.begin() + (size - length);
    while (it != b58.end() && *it == 0)
        it++;
    // Translate the result into a string.
    std::string str;
    str.reserve(zeroes + (b58.end() - it));
    str.assign(zeroes, '1');
    while (it != b58.end())
        str += pszBase58[*(it++)];
    return str;
}

std::string EncodeBase58(const std::vector<unsigned char>& vch)
{
    return EncodeBase58(&vch[0], &vch[0] + vch.size());
}

bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
{
    return DecodeBase58(str.c_str(), vchRet);
}

std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
{
    // add 4-byte hash check to the end
    std::vector<unsigned char> vch(vchIn);
    uint256 hash = Hash(vch.begin(), vch.end());
    vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
    return EncodeBase58(vch);
}

bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
{
    if (!DecodeBase58(psz, vchRet) ||
        (vchRet.size() < 4)) {
        vchRet.clear();
        return false;
    }
    // re-calculate the checksum, insure it matches the included 4-byte checksum
    uint256 hash = Hash(vchRet.begin(), vchRet.end() - 4);
    if (memcmp(&hash, &vchRet.end()[-4], 4) != 0) {
        vchRet.clear();
        return false;
    }
    vchRet.resize(vchRet.size() - 4);
    return true;
}

bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
{
    return DecodeBase58Check(str.c_str(), vchRet);
}

CBase58Data::CBase58Data()
{
    vchVersion.clear();
    vchData.clear();
}

void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const void* pdata, size_t nSize)
{
    vchVersion = vchVersionIn;
    vchData.resize(nSize);
    if (!vchData.empty())
        memcpy(&vchData[0], pdata, nSize);
}

void CBase58Data::SetData(const std::vector<unsigned char>& vchVersionIn, const unsigned char* pbegin, const unsigned char* pend)
{
    SetData(vchVersionIn, (void*)pbegin, pend - pbegin);
}

bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
{
    std::vector<unsigned char> vchTemp;
    bool rc58 = DecodeBase58Check(psz, vchTemp);
    if ((!rc58) || (vchTemp.size() < nVersionBytes)) {
        vchData.clear();
        vchVersion.clear();
        return false;
    }
    vchVersion.assign(vchTemp.begin(), vchTemp.begin() + nVersionBytes);
    vchData.resize(vchTemp.size() - nVersionBytes);
    if (!vchData.empty())
        memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
    memory_cleanse(&vchTemp[0], vchData.size());
    return true;
}

bool CBase58Data::SetString(const std::string& str)
{
    if (str.empty())
        return false;
    return SetString(str.c_str());
}

std::string CBase58Data::ToString() const
{
    std::vector<unsigned char> vch = vchVersion;
    vch.insert(vch.end(), vchData.begin(), vchData.end());
    return EncodeBase58Check(vch);
}

int CBase58Data::CompareTo(const CBase58Data& b58) const
{
    if (vchVersion < b58.vchVersion)
        return -1;
    if (vchVersion > b58.vchVersion)
        return 1;
    if (vchData < b58.vchData)
        return -1;
    if (vchData > b58.vchData)
        return 1;
    return 0;
}

namespace
{
class CBitcoinAddressVisitor : public boost::static_visitor<bool>
{
private:
    CBitcoinAddress* addr;
    CChainParams::Base58Type type;

public:
    CBitcoinAddressVisitor(CBitcoinAddress* addrIn,
            const CChainParams::Base58Type addrType = CChainParams::PUBKEY_ADDRESS) :
        addr(addrIn),
        type(addrType){};

    bool operator()(const CKeyID& id) const { return addr->Set(id, type); }
    bool operator()(const CScriptID& id) const { return addr->Set(id); }
    bool operator()(const CNoDestination& no) const { return false; }
};

} // anon namespace

bool CBitcoinAddress::Set(const CKeyID& id, const CChainParams::Base58Type addrType)
{
    SetData(Params().Base58Prefix(addrType), &id, 20);
    return true;
}

bool CBitcoinAddress::Set(const CScriptID& id)
{
    SetData(Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS), &id, 20);
    return true;
}

bool CBitcoinAddress::Set(const CTxDestination& dest, const CChainParams::Base58Type addrType)
{
    return boost::apply_visitor(CBitcoinAddressVisitor(this, addrType), dest);
}

bool CBitcoinAddress::IsValid() const
{
    return IsValid(Params());
}

bool CBitcoinAddress::IsValid(const CChainParams& params) const
{
    bool fCorrectSize = vchData.size() == 20;
    bool fKnownVersion = vchVersion == params.Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
                         vchVersion == params.Base58Prefix(CChainParams::SCRIPT_ADDRESS) ||
                         vchVersion == params.Base58Prefix(CChainParams::STAKING_ADDRESS);
    return fCorrectSize && fKnownVersion;
}

CTxDestination CBitcoinAddress::Get() const
{
    if (!IsValid())
        return CNoDestination();
    uint160 id;
    memcpy(&id, &vchData[0], 20);
    if (vchVersion == Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) ||
            vchVersion == Params().Base58Prefix(CChainParams::STAKING_ADDRESS))
        return CKeyID(id);
    else if (vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS))
        return CScriptID(id);
    else
        return CNoDestination();
}

bool CBitcoinAddress::GetKeyID(CKeyID& keyID) const
{
    if (!IsValid() ||
            (vchVersion != Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS) &&
            vchVersion != Params().Base58Prefix(CChainParams::STAKING_ADDRESS)))
        return false;
    uint160 id;
    memcpy(&id, &vchData[0], 20);
    keyID = CKeyID(id);
    return true;
}

bool CBitcoinAddress::IsScript() const
{
    bool fCorrectSize = vchData.size() == 20;
    return fCorrectSize && vchVersion == Params().Base58Prefix(CChainParams::SCRIPT_ADDRESS);
}

bool CBitcoinAddress::IsStakingAddress() const
{
    bool fCorrectSize = vchData.size() == 20;
    return fCorrectSize && vchVersion == Params().Base58Prefix(CChainParams::STAKING_ADDRESS);
}

void CBitcoinSecret::SetKey(const CKey& vchSecret)
{
    assert(vchSecret.IsValid());
    SetData(Params().Base58Prefix(CChainParams::SECRET_KEY), vchSecret.begin(), vchSecret.size());
    if (vchSecret.IsCompressed())
        vchData.push_back(1);
}

CKey CBitcoinSecret::GetKey()
{
    CKey ret;
    assert(vchData.size() >= 32);
    ret.Set(vchData.begin(), vchData.begin() + 32, vchData.size() > 32 && vchData[32] == 1);
    return ret;
}

bool CBitcoinSecret::IsValid() const
{
    bool fExpectedFormat = vchData.size() == 32 || (vchData.size() == 33 && vchData[32] == 1);
    bool fCorrectVersion = vchVersion == Params().Base58Prefix(CChainParams::SECRET_KEY);
    return fExpectedFormat && fCorrectVersion;
}

bool CBitcoinSecret::SetString(const char* pszSecret)
{
    return CBase58Data::SetString(pszSecret) && IsValid();
}

bool CBitcoinSecret::SetString(const std::string& strSecret)
{
    return SetString(strSecret.c_str());
}

CTxDestination DestinationFor(const CKeyID& keyID, const CChainParams::Base58Type addrType)
{
    CBitcoinAddress addr(keyID, addrType);
    if (!addr.IsValid()) throw std::runtime_error("Error, trying to decode an invalid keyID");
    return addr.Get();
}

std::string EncodeDestination(const CTxDestination& dest, const CChainParams::Base58Type addrType)
{
    CBitcoinAddress addr(dest, addrType);
    if (!addr.IsValid()) return "";
    return addr.ToString();
}

CTxDestination DecodeDestination(const std::string& str)
{
    return CBitcoinAddress(str).Get();
}

CTxDestination DecodeDestination(const std::string& str, bool& isStaking)
{
    CBitcoinAddress addr(str);
    isStaking = addr.IsStakingAddress();
    return addr.Get();
}

bool IsValidDestinationString(const std::string& str, bool fStaking, const CChainParams& params)
{
    return IsValidDestinationString(str, fStaking);
}

bool IsValidDestinationString(const std::string& str)
{
    CBitcoinAddress address(str);
    return address.IsValid();
}

bool IsValidDestinationString(const std::string& str, bool isStaking)
{
    CBitcoinAddress address(str);
    return address.IsValid() && (address.IsStakingAddress() == isStaking);
}
<|endoftext|>


<commit_before>#include "beacon.h"
#include "util.h"
#include "uint256.h"
#include "key.h"
#include "main.h"
#include "init.h"
#include "appcache.h"
#include "contract/contract.h"
#include "key.h"

std::string RetrieveBeaconValueWithMaxAge(const std::string& cpid, int64_t iMaxSeconds);
int64_t GetRSAWeightByCPIDWithRA(std::string cpid);

std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end);

bool GenerateBeaconKeys(const std::string &cpid, CKey &outPrivPubKey)
{
    AssertLockHeld(cs_main);
    AssertLockHeld(pwalletMain->cs_wallet);
    // Try to reuse 5-month-old beacon
    const std::string sBeaconPublicKey = GetBeaconPublicKey(cpid,false);

    if(!sBeaconPublicKey.empty())
    {
        CPubKey oldKey(ParseHex(sBeaconPublicKey));
        if(oldKey.IsValid())
        {
            if (pwalletMain->GetKey(oldKey.GetID(), outPrivPubKey))
            {
                assert(outPrivPubKey.IsValid());//GetKey gives valid key or false
                assert(outPrivPubKey.GetPubKey()==oldKey);//GetKey should return the key we ask for
                LogPrintf("GenerateBeaconKeys: Reusing >5 <6 m old Key");
                return true;
            }
        }
    }

    // Generate a new key that is added to wallet
    CPubKey newKey;
    if (!pwalletMain->GetKeyFromPool(newKey, false))
        return error("GenerateBeaconKeys: Failed to get Key from Wallet");

    CKeyID keyID = newKey.GetID();

    // Assign a description for this address
    std::string strLabel= "DPoR Beacon CPID "+cpid+" "+ToString(nBestHeight);
    pwalletMain->SetAddressBookName(keyID, strLabel);

    // Get the private part of the key from wallet
    if (!pwalletMain->GetKey(keyID, outPrivPubKey))
        return error("GenerateBeaconKeys: Failed to get Private Key from Wallet");

    return true;
}

bool GetStoredBeaconPrivateKey(const std::string& cpid, CKey& outPrivPubKey)
{
    AssertLockHeld(cs_main);
    AssertLockHeld(pwalletMain->cs_wallet);
    CPubKey oldKey(ParseHex(GetBeaconPublicKey(cpid, false)));
    if(oldKey.IsValid())
    {
        if (pwalletMain->GetKey(oldKey.GetID(), outPrivPubKey))
        {
            return outPrivPubKey.IsValid();
        }
    }
    return false;
}

void GetBeaconElements(const std::string& sBeacon, std::string& out_cpid, std::string& out_address, std::string& out_publickey)
{
    if (sBeacon.empty()) return;
    std::string sContract = DecodeBase64(sBeacon);
    std::vector<std::string> vContract = split(sContract.c_str(),";");
    if (vContract.size() < 4) return;
    out_cpid = vContract[0];
    out_address = vContract[2];
    out_publickey = vContract[3];
}

std::string GetBeaconPublicKey(const std::string& cpid, bool bAdvertisingBeacon)
{
    //3-26-2017 - Ensure beacon public key is within 6 months of network age (If advertising, let it be returned as missing after 5 months, to ensure the public key is renewed seamlessly).
    int iMonths = bAdvertisingBeacon ? 5 : 6;
    int64_t iMaxSeconds = 60 * 24 * 30 * iMonths * 60;
    std::string sBeacon = RetrieveBeaconValueWithMaxAge(cpid, iMaxSeconds);
    if (sBeacon.empty()) return "";
    // Beacon data structure: CPID,hashRand,Address,beacon public key: base64 encoded
    std::string sContract = DecodeBase64(sBeacon);
    std::vector<std::string> vContract = split(sContract.c_str(),";");
    if (vContract.size() < 4) return "";
    std::string sBeaconPublicKey = vContract[3];
    return sBeaconPublicKey;
}

int64_t BeaconTimeStamp(const std::string& cpid, bool bZeroOutAfterPOR)
{
    AssertLockHeld(cs_main);
    const AppCacheEntry& entry =  ReadCache("beacon", cpid);
    std::string sBeacon = entry.value;
    int64_t iLocktime = entry.timestamp;
    int64_t iRSAWeight = GetRSAWeightByCPIDWithRA(cpid);
    if (fDebug10)
        LogPrintf("Beacon %s, Weight %" PRId64 ", Locktime %" PRId64, sBeacon, iRSAWeight, iLocktime);
    if (bZeroOutAfterPOR && iRSAWeight==0)
        iLocktime = 0;
    return iLocktime;

}

bool HasActiveBeacon(const std::string& cpid)
{
    return GetBeaconPublicKey(cpid, false).empty() == false;
}

std::string RetrieveBeaconValueWithMaxAge(const std::string& cpid, int64_t iMaxSeconds)
{
    AssertLockHeld(cs_main);
    const AppCacheEntry& entry = ReadCache("beacon", cpid);

    // Compare the age of the beacon to the age of the current block. If we have
    // no current block we assume that the beacon is valid.
    int64_t iAge = pindexBest != NULL
          ? pindexBest->nTime - entry.timestamp
          : 0;

    return (iAge > iMaxSeconds)
          ? ""
          : entry.value;
}

bool VerifyBeaconContractTx(const CTransaction& tx)
{
    AssertLockHeld(cs_main);
    // Check if tx contains beacon advertisement and evaluate for certain conditions
    std::string chkMessageType = ExtractXML(tx.hashBoinc, "<MT>", "</MT>");
    std::string chkMessageAction = ExtractXML(tx.hashBoinc, "<MA>", "</MA>");

    if (chkMessageType != "beacon")
        return true; // Not beacon contract

    if (chkMessageAction != "A")
        return true; // Not an add contract for beacon

    std::string chkMessageContract = ExtractXML(tx.hashBoinc, "<MV>", "</MV>");
    std::string chkMessageContractCPID = ExtractXML(tx.hashBoinc, "<MK>", "</MK>");
    // Here we GetBeaconElements for the contract in the tx
    std::string tx_out_cpid;
    std::string tx_out_address;
    std::string tx_out_publickey;

    GetBeaconElements(chkMessageContract, tx_out_cpid, tx_out_address, tx_out_publickey);

    if (tx_out_cpid.empty() || tx_out_address.empty() || tx_out_publickey.empty() || chkMessageContractCPID.empty())
        return false; // Incomplete contract

    const AppCacheEntry& beaconEntry = ReadCache("beacon", chkMessageContractCPID);
    if (beaconEntry.value.empty())
    {
        if (fDebug10)
            LogPrintf("VBCTX : No Previous beacon found for CPID %s", chkMessageContractCPID);

        return true; // No previous beacon in cache
    }

    int64_t chkiAge = pindexBest != NULL
        ? tx.nLockTime - beaconEntry.timestamp
        : 0;
    int64_t chkSecondsBase = 60 * 24 * 30 * 60;

    // Conditions
    // Condition a) if beacon is younger then 5 months deny tx
    if (chkiAge <= chkSecondsBase * 5 && chkiAge >= 1)
    {
        if (fDebug10)
            LogPrintf("VBCTX : Beacon age violation. Beacon Age %" PRId64 " < Required Age %" PRId64, chkiAge, (chkSecondsBase * 5));

        return false;
    }

    // Condition b) if beacon is younger then 6 months but older then 5 months verify using the same keypair; if not deny tx
    if (chkiAge >= chkSecondsBase * 5 && chkiAge <= chkSecondsBase * 6)
    {
        std::string chk_out_cpid;
        std::string chk_out_address;
        std::string chk_out_publickey;

        // Here we GetBeaconElements for the contract in the current beacon in chain
        GetBeaconElements(beaconEntry.value, chk_out_cpid, chk_out_address, chk_out_publickey);

        if (tx_out_publickey != chk_out_publickey)
        {
            if (fDebug10)
                LogPrintf("VBCTX : Beacon tx publickey != publickey in chain. %s != %s", tx_out_publickey, chk_out_publickey);

            return false;
        }
    }

    // Passed checks
    return true;
}

bool ImportBeaconKeysFromConfig(const std::string& cpid)
{
    AssertLockHeld(cs_main);

    if(cpid.empty())
        return error("Empty CPID");

    std::string sBeaconPublicKey = GetBeaconPublicKey(cpid, false);
    std::string strSecret= GetArgument("privatekey" + cpid + (fTestNet ? "testnet" : ""), "");
    if(strSecret.empty())
        return false;
    auto vecsecret = ParseHex(strSecret);

    CKey key;
    if(!key.SetPrivKey(CPrivKey(vecsecret.begin(),vecsecret.end())))
        return error("ImportBeaconKeysFromConfig: Invalid private key");
    CKeyID vchAddress = key.GetPubKey().GetID();

    LOCK2(cs_main, pwalletMain->cs_wallet);

    // Don't throw error in case a key is already there
    if (!pwalletMain->HaveKey(vchAddress))
    {
        if (pwalletMain->IsLocked())
            return error("ImportBeaconKeysFromConfig: Wallet locked!");

        pwalletMain->MarkDirty();

        pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 0;

        if (!pwalletMain->AddKey(key))
            return error("ImportBeaconKeysFromConfig: failed to add key to wallet");

        pwalletMain->SetAddressBookName(vchAddress, "DPoR Beacon CPID " + cpid + " imported");
    }
    return true;
}
<commit_msg>Remove assertion on cs_main being held.<commit_after>#include "beacon.h"
#include "util.h"
#include "uint256.h"
#include "key.h"
#include "main.h"
#include "init.h"
#include "appcache.h"
#include "contract/contract.h"
#include "key.h"

std::string RetrieveBeaconValueWithMaxAge(const std::string& cpid, int64_t iMaxSeconds);
int64_t GetRSAWeightByCPIDWithRA(std::string cpid);

std::string ExtractXML(std::string XMLdata, std::string key, std::string key_end);

bool GenerateBeaconKeys(const std::string &cpid, CKey &outPrivPubKey)
{
    AssertLockHeld(cs_main);
    AssertLockHeld(pwalletMain->cs_wallet);
    // Try to reuse 5-month-old beacon
    const std::string sBeaconPublicKey = GetBeaconPublicKey(cpid,false);

    if(!sBeaconPublicKey.empty())
    {
        CPubKey oldKey(ParseHex(sBeaconPublicKey));
        if(oldKey.IsValid())
        {
            if (pwalletMain->GetKey(oldKey.GetID(), outPrivPubKey))
            {
                assert(outPrivPubKey.IsValid());//GetKey gives valid key or false
                assert(outPrivPubKey.GetPubKey()==oldKey);//GetKey should return the key we ask for
                LogPrintf("GenerateBeaconKeys: Reusing >5 <6 m old Key");
                return true;
            }
        }
    }

    // Generate a new key that is added to wallet
    CPubKey newKey;
    if (!pwalletMain->GetKeyFromPool(newKey, false))
        return error("GenerateBeaconKeys: Failed to get Key from Wallet");

    CKeyID keyID = newKey.GetID();

    // Assign a description for this address
    std::string strLabel= "DPoR Beacon CPID "+cpid+" "+ToString(nBestHeight);
    pwalletMain->SetAddressBookName(keyID, strLabel);

    // Get the private part of the key from wallet
    if (!pwalletMain->GetKey(keyID, outPrivPubKey))
        return error("GenerateBeaconKeys: Failed to get Private Key from Wallet");

    return true;
}

bool GetStoredBeaconPrivateKey(const std::string& cpid, CKey& outPrivPubKey)
{
    AssertLockHeld(cs_main);
    AssertLockHeld(pwalletMain->cs_wallet);
    CPubKey oldKey(ParseHex(GetBeaconPublicKey(cpid, false)));
    if(oldKey.IsValid())
    {
        if (pwalletMain->GetKey(oldKey.GetID(), outPrivPubKey))
        {
            return outPrivPubKey.IsValid();
        }
    }
    return false;
}

void GetBeaconElements(const std::string& sBeacon, std::string& out_cpid, std::string& out_address, std::string& out_publickey)
{
    if (sBeacon.empty()) return;
    std::string sContract = DecodeBase64(sBeacon);
    std::vector<std::string> vContract = split(sContract.c_str(),";");
    if (vContract.size() < 4) return;
    out_cpid = vContract[0];
    out_address = vContract[2];
    out_publickey = vContract[3];
}

std::string GetBeaconPublicKey(const std::string& cpid, bool bAdvertisingBeacon)
{
    //3-26-2017 - Ensure beacon public key is within 6 months of network age (If advertising, let it be returned as missing after 5 months, to ensure the public key is renewed seamlessly).
    int iMonths = bAdvertisingBeacon ? 5 : 6;
    int64_t iMaxSeconds = 60 * 24 * 30 * iMonths * 60;
    std::string sBeacon = RetrieveBeaconValueWithMaxAge(cpid, iMaxSeconds);
    if (sBeacon.empty()) return "";
    // Beacon data structure: CPID,hashRand,Address,beacon public key: base64 encoded
    std::string sContract = DecodeBase64(sBeacon);
    std::vector<std::string> vContract = split(sContract.c_str(),";");
    if (vContract.size() < 4) return "";
    std::string sBeaconPublicKey = vContract[3];
    return sBeaconPublicKey;
}

int64_t BeaconTimeStamp(const std::string& cpid, bool bZeroOutAfterPOR)
{
    AssertLockHeld(cs_main);
    const AppCacheEntry& entry =  ReadCache("beacon", cpid);
    std::string sBeacon = entry.value;
    int64_t iLocktime = entry.timestamp;
    int64_t iRSAWeight = GetRSAWeightByCPIDWithRA(cpid);
    if (fDebug10)
        LogPrintf("Beacon %s, Weight %" PRId64 ", Locktime %" PRId64, sBeacon, iRSAWeight, iLocktime);
    if (bZeroOutAfterPOR && iRSAWeight==0)
        iLocktime = 0;
    return iLocktime;

}

bool HasActiveBeacon(const std::string& cpid)
{
    return GetBeaconPublicKey(cpid, false).empty() == false;
}

std::string RetrieveBeaconValueWithMaxAge(const std::string& cpid, int64_t iMaxSeconds)
{
    AssertLockHeld(cs_main);
    const AppCacheEntry& entry = ReadCache("beacon", cpid);

    // Compare the age of the beacon to the age of the current block. If we have
    // no current block we assume that the beacon is valid.
    int64_t iAge = pindexBest != NULL
          ? pindexBest->nTime - entry.timestamp
          : 0;

    return (iAge > iMaxSeconds)
          ? ""
          : entry.value;
}

bool VerifyBeaconContractTx(const CTransaction& tx)
{
    AssertLockHeld(cs_main);
    // Check if tx contains beacon advertisement and evaluate for certain conditions
    std::string chkMessageType = ExtractXML(tx.hashBoinc, "<MT>", "</MT>");
    std::string chkMessageAction = ExtractXML(tx.hashBoinc, "<MA>", "</MA>");

    if (chkMessageType != "beacon")
        return true; // Not beacon contract

    if (chkMessageAction != "A")
        return true; // Not an add contract for beacon

    std::string chkMessageContract = ExtractXML(tx.hashBoinc, "<MV>", "</MV>");
    std::string chkMessageContractCPID = ExtractXML(tx.hashBoinc, "<MK>", "</MK>");
    // Here we GetBeaconElements for the contract in the tx
    std::string tx_out_cpid;
    std::string tx_out_address;
    std::string tx_out_publickey;

    GetBeaconElements(chkMessageContract, tx_out_cpid, tx_out_address, tx_out_publickey);

    if (tx_out_cpid.empty() || tx_out_address.empty() || tx_out_publickey.empty() || chkMessageContractCPID.empty())
        return false; // Incomplete contract

    const AppCacheEntry& beaconEntry = ReadCache("beacon", chkMessageContractCPID);
    if (beaconEntry.value.empty())
    {
        if (fDebug10)
            LogPrintf("VBCTX : No Previous beacon found for CPID %s", chkMessageContractCPID);

        return true; // No previous beacon in cache
    }

    int64_t chkiAge = pindexBest != NULL
        ? tx.nLockTime - beaconEntry.timestamp
        : 0;
    int64_t chkSecondsBase = 60 * 24 * 30 * 60;

    // Conditions
    // Condition a) if beacon is younger then 5 months deny tx
    if (chkiAge <= chkSecondsBase * 5 && chkiAge >= 1)
    {
        if (fDebug10)
            LogPrintf("VBCTX : Beacon age violation. Beacon Age %" PRId64 " < Required Age %" PRId64, chkiAge, (chkSecondsBase * 5));

        return false;
    }

    // Condition b) if beacon is younger then 6 months but older then 5 months verify using the same keypair; if not deny tx
    if (chkiAge >= chkSecondsBase * 5 && chkiAge <= chkSecondsBase * 6)
    {
        std::string chk_out_cpid;
        std::string chk_out_address;
        std::string chk_out_publickey;

        // Here we GetBeaconElements for the contract in the current beacon in chain
        GetBeaconElements(beaconEntry.value, chk_out_cpid, chk_out_address, chk_out_publickey);

        if (tx_out_publickey != chk_out_publickey)
        {
            if (fDebug10)
                LogPrintf("VBCTX : Beacon tx publickey != publickey in chain. %s != %s", tx_out_publickey, chk_out_publickey);

            return false;
        }
    }

    // Passed checks
    return true;
}

bool ImportBeaconKeysFromConfig(const std::string& cpid)
{
    if(cpid.empty())
        return error("Empty CPID");

    std::string sBeaconPublicKey = GetBeaconPublicKey(cpid, false);
    std::string strSecret= GetArgument("privatekey" + cpid + (fTestNet ? "testnet" : ""), "");
    if(strSecret.empty())
        return false;
    auto vecsecret = ParseHex(strSecret);

    CKey key;
    if(!key.SetPrivKey(CPrivKey(vecsecret.begin(),vecsecret.end())))
        return error("ImportBeaconKeysFromConfig: Invalid private key");
    CKeyID vchAddress = key.GetPubKey().GetID();

    LOCK2(cs_main, pwalletMain->cs_wallet);

    // Don't throw error in case a key is already there
    if (!pwalletMain->HaveKey(vchAddress))
    {
        if (pwalletMain->IsLocked())
            return error("ImportBeaconKeysFromConfig: Wallet locked!");

        pwalletMain->MarkDirty();

        pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 0;

        if (!pwalletMain->AddKey(key))
            return error("ImportBeaconKeysFromConfig: failed to add key to wallet");

        pwalletMain->SetAddressBookName(vchAddress, "DPoR Beacon CPID " + cpid + " imported");
    }
    return true;
}
<|endoftext|>


<commit_before>#include <Halide.h>

using namespace Halide;

int main(int argc, char **argv) {
    Param<float> time;

    const float pi = 3.1415926536;

    Var x, y, c;
    Func result;

    Expr kx, ky;
    Expr xx, yy;
    kx = x / 150.0f;
    ky = y / 150.0f;

    xx = kx + sin(time/3.0f);
    yy = ky + sin(time/2.0f);

    Expr angle;
    angle = 2 * pi * sin(time/20.0f);
    kx = kx * cos(angle) - ky * sin(angle);
    ky = kx * sin(angle) + ky * cos(angle);

    Expr v = 0.0;
//    v += sin(kx + time);
    v += sin((ky + time) / 2.0f);
    v += sin((kx + ky + time) / 2.0f);
    v += sin(sqrt(xx * xx + yy * yy + 1.0f) + time);

    result(x, y, c) = cast<uint8_t>(
        select(c == 0, 64,
               select(c == 1, cos(pi * v),
                      sin(pi * v)) * 80 + (255 - 80)));

    result.output_buffer().set_stride(0, 4);
    result.bound(c, 0, 4);
    result.glsl(x, y, c);

    std::vector<Argument> args;
    args.push_back(time);
    result.compile_to_file("halide", args);

    return 0;
}
<commit_msg>Remove double constant in Halide code<commit_after>#include <Halide.h>

using namespace Halide;

int main(int argc, char **argv) {
    Param<float> time;

    const float pi = 3.1415926536;

    Var x, y, c;
    Func result;

    Expr kx, ky;
    Expr xx, yy;
    kx = x / 150.0f;
    ky = y / 150.0f;

    xx = kx + sin(time/3.0f);
    yy = ky + sin(time/2.0f);

    Expr angle;
    angle = 2 * pi * sin(time/20.0f);
    kx = kx * cos(angle) - ky * sin(angle);
    ky = kx * sin(angle) + ky * cos(angle);

    Expr v = 0.0f;
    v += sin((ky + time) / 2.0f);
    v += sin((kx + ky + time) / 2.0f);
    v += sin(sqrt(xx * xx + yy * yy + 1.0f) + time);

    result(x, y, c) = cast<uint8_t>(
        select(c == 0, 32,
               select(c == 1, cos(pi * v),
                      sin(pi * v)) * 80 + (255 - 80)));

    result.output_buffer().set_stride(0, 4);
    result.bound(c, 0, 4);
    result.glsl(x, y, c);

    std::vector<Argument> args;
    args.push_back(time);
    result.compile_to_file("halide", args);

    return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/message_box.h"

#include <windows.h>
#include <commctrl.h>

#include "atom/browser/native_window_views.h"
#include "base/callback.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "content/public/browser/browser_thread.h"

namespace atom {

namespace {

// Small command ID values are already taken by Windows, we have to start from
// a large number to avoid conflicts with Windows.
const int kIDStart = 100;

int ShowMessageBoxUTF16(HWND parent,
                        const std::vector<base::string16>& buttons,
                        int cancel_id,
                        const base::string16& title,
                        const base::string16& message,
                        const base::string16& detail) {
  std::vector<TASKDIALOG_BUTTON> dialog_buttons;
  for (size_t i = 0; i < buttons.size(); ++i)
    dialog_buttons.push_back({i + kIDStart, buttons[i].c_str()});

  TASKDIALOG_FLAGS flags = TDF_SIZE_TO_CONTENT;  // show all content.
  if (cancel_id != 0)
    flags |= TDF_ALLOW_DIALOG_CANCELLATION;  // allow dialog to be cancelled.

  TASKDIALOGCONFIG config = { 0 };
  config.cbSize         = sizeof(config);
  config.hwndParent     = parent;
  config.hInstance      = GetModuleHandle(NULL);
  config.dwFlags        = flags;
  config.pszWindowTitle = title.c_str();
  config.pButtons       = &dialog_buttons.front();
  config.cButtons       = dialog_buttons.size();

  // If "detail" is empty then don't make message hilighted.
  if (detail.empty()) {
    config.pszContent = message.c_str();
  } else {
    config.pszMainInstruction = message.c_str();
    config.pszContent = detail.c_str();
  }

  int id = 0;
  TaskDialogIndirect(&config, &id, NULL, NULL);
  if (id == 0 || id == IDCANCEL)
    return cancel_id;
  else
    return id - kIDStart;
}

void RunMessageBoxInNewThread(base::Thread* thread,
                              NativeWindow* parent,
                              MessageBoxType type,
                              const std::vector<std::string>& buttons,
                              int cancel_id,
                              const std::string& title,
                              const std::string& message,
                              const std::string& detail,
                              const gfx::ImageSkia& icon,
                              const MessageBoxCallback& callback) {
  int result = ShowMessageBox(parent, type, buttons, cancel_id, title, message,
                              detail, icon);
  content::BrowserThread::PostTask(
      content::BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
  content::BrowserThread::DeleteSoon(
      content::BrowserThread::UI, FROM_HERE, thread);
}

}  // namespace

int ShowMessageBox(NativeWindow* parent,
                   MessageBoxType type,
                   const std::vector<std::string>& buttons,
                   int cancel_id,
                   const std::string& title,
                   const std::string& message,
                   const std::string& detail,
                   const gfx::ImageSkia& icon) {
  std::vector<base::string16> utf16_buttons;
  for (const auto& button : buttons)
    utf16_buttons.push_back(base::UTF8ToUTF16(button));

  HWND hwnd_parent = parent ?
      static_cast<atom::NativeWindowViews*>(parent)->GetAcceleratedWidget() :
      NULL;

  NativeWindow::DialogScope dialog_scope(parent);
  return ShowMessageBoxUTF16(hwnd_parent,
                             utf16_buttons,
                             cancel_id,
                             base::UTF8ToUTF16(title),
                             base::UTF8ToUTF16(message),
                             base::UTF8ToUTF16(detail));
}

void ShowMessageBox(NativeWindow* parent,
                    MessageBoxType type,
                    const std::vector<std::string>& buttons,
                    int cancel_id,
                    const std::string& title,
                    const std::string& message,
                    const std::string& detail,
                    const gfx::ImageSkia& icon,
                    const MessageBoxCallback& callback) {
  scoped_ptr<base::Thread> thread(
      new base::Thread(ATOM_PRODUCT_NAME "MessageBoxThread"));
  thread->init_com_with_mta(false);
  if (!thread->Start()) {
    callback.Run(cancel_id);
    return;
  }

  base::Thread* unretained = thread.release();
  unretained->message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&RunMessageBoxInNewThread, base::Unretained(unretained),
                 parent, type, buttons, cancel_id, title, message, detail, icon,
                 callback));
}

void ShowErrorBox(const base::string16& title, const base::string16& content) {
}

}  // namespace atom
<commit_msg>Show icon according to dialog's type<commit_after>// Copyright (c) 2013 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include "atom/browser/ui/message_box.h"

#include <windows.h>
#include <commctrl.h>

#include "atom/browser/native_window_views.h"
#include "base/callback.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h"
#include "content/public/browser/browser_thread.h"

namespace atom {

namespace {

// Small command ID values are already taken by Windows, we have to start from
// a large number to avoid conflicts with Windows.
const int kIDStart = 100;

int ShowMessageBoxUTF16(HWND parent,
                        MessageBoxType type,
                        const std::vector<base::string16>& buttons,
                        int cancel_id,
                        const base::string16& title,
                        const base::string16& message,
                        const base::string16& detail) {
  std::vector<TASKDIALOG_BUTTON> dialog_buttons;
  for (size_t i = 0; i < buttons.size(); ++i)
    dialog_buttons.push_back({i + kIDStart, buttons[i].c_str()});

  TASKDIALOG_FLAGS flags = TDF_SIZE_TO_CONTENT;  // show all content.
  if (cancel_id != 0)
    flags |= TDF_ALLOW_DIALOG_CANCELLATION;  // allow dialog to be cancelled.

  TASKDIALOGCONFIG config = { 0 };
  config.cbSize         = sizeof(config);
  config.hwndParent     = parent;
  config.hInstance      = GetModuleHandle(NULL);
  config.dwFlags        = flags;
  config.pszWindowTitle = title.c_str();
  config.pButtons       = &dialog_buttons.front();
  config.cButtons       = dialog_buttons.size();

  // Show icon according to dialog's type.
  switch (type) {
    case MESSAGE_BOX_TYPE_INFORMATION:
      config.pszMainIcon = TD_INFORMATION_ICON;
      break;
    case MESSAGE_BOX_TYPE_WARNING:
      config.pszMainIcon = TD_WARNING_ICON;
      break;
    case MESSAGE_BOX_TYPE_ERROR:
      config.pszMainIcon = TD_ERROR_ICON;
      break;
  }

  // If "detail" is empty then don't make message hilighted.
  if (detail.empty()) {
    config.pszContent = message.c_str();
  } else {
    config.pszMainInstruction = message.c_str();
    config.pszContent = detail.c_str();
  }

  int id = 0;
  TaskDialogIndirect(&config, &id, NULL, NULL);
  if (id == 0 || id == IDCANCEL)
    return cancel_id;
  else
    return id - kIDStart;
}

void RunMessageBoxInNewThread(base::Thread* thread,
                              NativeWindow* parent,
                              MessageBoxType type,
                              const std::vector<std::string>& buttons,
                              int cancel_id,
                              const std::string& title,
                              const std::string& message,
                              const std::string& detail,
                              const gfx::ImageSkia& icon,
                              const MessageBoxCallback& callback) {
  int result = ShowMessageBox(parent, type, buttons, cancel_id, title, message,
                              detail, icon);
  content::BrowserThread::PostTask(
      content::BrowserThread::UI, FROM_HERE, base::Bind(callback, result));
  content::BrowserThread::DeleteSoon(
      content::BrowserThread::UI, FROM_HERE, thread);
}

}  // namespace

int ShowMessageBox(NativeWindow* parent,
                   MessageBoxType type,
                   const std::vector<std::string>& buttons,
                   int cancel_id,
                   const std::string& title,
                   const std::string& message,
                   const std::string& detail,
                   const gfx::ImageSkia& icon) {
  std::vector<base::string16> utf16_buttons;
  for (const auto& button : buttons)
    utf16_buttons.push_back(base::UTF8ToUTF16(button));

  HWND hwnd_parent = parent ?
      static_cast<atom::NativeWindowViews*>(parent)->GetAcceleratedWidget() :
      NULL;

  NativeWindow::DialogScope dialog_scope(parent);
  return ShowMessageBoxUTF16(hwnd_parent,
                             type,
                             utf16_buttons,
                             cancel_id,
                             base::UTF8ToUTF16(title),
                             base::UTF8ToUTF16(message),
                             base::UTF8ToUTF16(detail));
}

void ShowMessageBox(NativeWindow* parent,
                    MessageBoxType type,
                    const std::vector<std::string>& buttons,
                    int cancel_id,
                    const std::string& title,
                    const std::string& message,
                    const std::string& detail,
                    const gfx::ImageSkia& icon,
                    const MessageBoxCallback& callback) {
  scoped_ptr<base::Thread> thread(
      new base::Thread(ATOM_PRODUCT_NAME "MessageBoxThread"));
  thread->init_com_with_mta(false);
  if (!thread->Start()) {
    callback.Run(cancel_id);
    return;
  }

  base::Thread* unretained = thread.release();
  unretained->message_loop()->PostTask(
      FROM_HERE,
      base::Bind(&RunMessageBoxInNewThread, base::Unretained(unretained),
                 parent, type, buttons, cancel_id, title, message, detail, icon,
                 callback));
}

void ShowErrorBox(const base::string16& title, const base::string16& content) {
}

}  // namespace atom
<|endoftext|>


<commit_before>#include "abstractalbumcollectionmodel.h"

#include <map>

#include <QHash>

namespace sp = Spotinetta;

namespace Sonetta {

namespace {

QHash<int, QByteArray> createRoles() {
    QHash<int, QByteArray> r;
    r.insert(AbstractAlbumCollectionModel::AlbumRole, "album" );
    r.insert(AbstractAlbumCollectionModel::ArtistRole, "artist" );
    r.insert(AbstractAlbumCollectionModel::IsValidRole, "isValid" );
    r.insert(AbstractAlbumCollectionModel::IsLoadedRole, "isLoaded" );
    r.insert(AbstractAlbumCollectionModel::IsAvailableRole, "isAvailable" );
    r.insert(AbstractAlbumCollectionModel::NameRole, "name" );
    r.insert(AbstractAlbumCollectionModel::YearRole, "year" );
    r.insert(AbstractAlbumCollectionModel::TypeRole, "type" );
    r.insert(AbstractAlbumCollectionModel::SmallCoverUriRole, "smallCoverUri" );
    r.insert(AbstractAlbumCollectionModel::NormalCoverUriRole, "normalCoverUri" );
    r.insert(AbstractAlbumCollectionModel::LargeCoverUriRole, "largeCoverUri" );
    r.insert(AbstractAlbumCollectionModel::ArtistNameRole, "artistName");
    return r;
}

QHash<int, QByteArray> const g_roleNames = createRoles();

}

AbstractAlbumCollectionModel::AbstractAlbumCollectionModel(QObject *parent) :
    QAbstractListModel(parent)
{
}

QVariant AbstractAlbumCollectionModel::data(const QModelIndex &index, int role) const
{
    int row = index.row();
    sp::Album album = getAlbumAt(row);
    Role r = (Role) role;

    switch (r)
    {
    case AlbumRole:
        return QVariant::fromValue(album);
        break;
    case ArtistRole:
        return QVariant::fromValue(album.artist());
        break;
    case IsValidRole:
        return album.isValid();
        break;
    case IsLoadedRole:
        return album.isLoaded();
        break;
    case IsAvailableRole:
        return album.isAvailable();
        break;
    case NameRole:
        return album.name();
        break;
    case YearRole:
        return album.year();
        break;
    case TypeRole:
        return static_cast<int>(album.type());
        break;
//    case SmallCoverUriRole:
//        return SpLink::fromAlbumCover(album, Spotify::ImageSizeSmall).uri(); // Temporary
//        break;
//    case NormalCoverUriRole:
//        return SpLink::fromAlbumCover(album, Spotify::ImageSizeNormal).uri();
//        break;
//    case LargeCoverUriRole:
//        return SpLink::fromAlbumCover(album, Spotify::ImageSizeLarge).uri();
//        break;
    case ArtistNameRole:
        return album.artist().name();
        break;

    default:
        return QVariant();
    }
}

int AbstractAlbumCollectionModel::rowCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : getAlbumCount();
}

QHash<int, QByteArray> AbstractAlbumCollectionModel::roleNames() const
{
    return g_roleNames;
}

void AbstractAlbumCollectionModel::updateData(int first, int last)
{
    QModelIndex begin = index(first);
    QModelIndex end = last == -1 ? index(first) : index(last);

    emit dataChanged(begin, end);
}

}
<commit_msg>Fixed missing role data for cover links in AbstractAlbumCollectionModel<commit_after>#include "abstractalbumcollectionmodel.h"

#include <map>

#include <QHash>

namespace sp = Spotinetta;

namespace Sonetta {

namespace {

QHash<int, QByteArray> createRoles() {
    QHash<int, QByteArray> r;
    r.insert(AbstractAlbumCollectionModel::AlbumRole, "album" );
    r.insert(AbstractAlbumCollectionModel::ArtistRole, "artist" );
    r.insert(AbstractAlbumCollectionModel::IsValidRole, "isValid" );
    r.insert(AbstractAlbumCollectionModel::IsLoadedRole, "isLoaded" );
    r.insert(AbstractAlbumCollectionModel::IsAvailableRole, "isAvailable" );
    r.insert(AbstractAlbumCollectionModel::NameRole, "name" );
    r.insert(AbstractAlbumCollectionModel::YearRole, "year" );
    r.insert(AbstractAlbumCollectionModel::TypeRole, "type" );
    r.insert(AbstractAlbumCollectionModel::SmallCoverUriRole, "smallCoverUri" );
    r.insert(AbstractAlbumCollectionModel::NormalCoverUriRole, "normalCoverUri" );
    r.insert(AbstractAlbumCollectionModel::LargeCoverUriRole, "largeCoverUri" );
    r.insert(AbstractAlbumCollectionModel::ArtistNameRole, "artistName");
    return r;
}

QHash<int, QByteArray> const g_roleNames = createRoles();

}

AbstractAlbumCollectionModel::AbstractAlbumCollectionModel(QObject *parent) :
    QAbstractListModel(parent)
{
}

QVariant AbstractAlbumCollectionModel::data(const QModelIndex &index, int role) const
{
    int row = index.row();
    sp::Album album = getAlbumAt(row);
    Role r = (Role) role;

    switch (r)
    {
    case AlbumRole:
        return QVariant::fromValue(album);
        break;
    case ArtistRole:
        return QVariant::fromValue(album.artist());
        break;
    case IsValidRole:
        return album.isValid();
        break;
    case IsLoadedRole:
        return album.isLoaded();
        break;
    case IsAvailableRole:
        return album.isAvailable();
        break;
    case NameRole:
        return album.name();
        break;
    case YearRole:
        return album.year();
        break;
    case TypeRole:
        return static_cast<int>(album.type());
        break;
    case SmallCoverUriRole:
        return sp::Link::fromAlbumCover(album, sp::ImageSize::Small).uri();
        break;
    case NormalCoverUriRole:
        return sp::Link::fromAlbumCover(album, sp::ImageSize::Normal).uri();
        break;
    case LargeCoverUriRole:
        return sp::Link::fromAlbumCover(album, sp::ImageSize::Large).uri();
        break;
    case ArtistNameRole:
        return album.artist().name();
        break;

    default:
        return QVariant();
    }
}

int AbstractAlbumCollectionModel::rowCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : getAlbumCount();
}

QHash<int, QByteArray> AbstractAlbumCollectionModel::roleNames() const
{
    return g_roleNames;
}

void AbstractAlbumCollectionModel::updateData(int first, int last)
{
    QModelIndex begin = index(first);
    QModelIndex end = last == -1 ? index(first) : index(last);

    emit dataChanged(begin, end);
}

}
<|endoftext|>