Esempio n. 1
0
void P_SetYellowMessage(player_t* pl, int flags, const char* msg)
{
#define YELLOW_FMT      "{r=1;g=0.7;b=0.3;}"
#define YELLOW_FMT_LEN  18

    size_t len;
    AutoStr* buf;

    if(!msg || !msg[0]) return;
    len = strlen(msg);

    buf = AutoStr_NewStd();
    Str_Reserve(buf, YELLOW_FMT_LEN + len+1);
    Str_Set(buf, YELLOW_FMT);
    Str_Appendf(buf, "%s", msg);

    ST_LogPost(pl - players, flags, Str_Text(buf));

    if(pl == &players[CONSOLEPLAYER] && cfg.echoMsg)
        Con_FPrintf(CPF_CYAN, "%s\n", msg);

    // Servers are responsible for sending these messages to the clients.
    /// @todo We shouldn't need to send the format string along with every
    /// important game message. Instead flag a bit in the packet and then
    /// reconstruct on the other end.
    NetSv_SendMessage(pl - players, Str_Text(buf));

#undef YELLOW_FMT
}
    virtual void invoke(int player, EventSequenceArg* args, int numArgs)
    {
        if(!strchr(Str_Text(&commandTemplate), '%'))
        {
            DD_Execute(true/*silent*/, Str_Text(&commandTemplate));
            return;
        }

        // Compose the command from the template, inserting values for named arguments.
        /// @todo This logic should be extracted and made into an Str method.
        AutoStr* cmd = AutoStr_NewStd();
        // Reserve an estimate of the composed command length.
        Str_Reserve(cmd, Str_Length(&commandTemplate) + numArgs + 1);

        int len = Str_Length(&commandTemplate);
        const char* start = Str_Text(&commandTemplate);
        const char* ch = start, *substart = start;
        while(ch + 1 < start + len)
        {
            if(ch[0] == '%' && ch[1] && ch[1] != '%')
            {
                Str_PartAppend(cmd, substart, 0, ch - substart);

                if(ch[1] == 'p')
                {
                    Str_AppendChar(cmd, '0' + player);
                }
                else
                {
                    int arg = ch[1] - '0' - 1;
                    DENG_ASSERT(arg >= 0 && arg < 9);
                    Str_AppendChar(cmd, char(args[arg]));
                }
                ch += 2;
                substart = ch;
            }
            else
            {
                ch++;
            }
        }
        // Add anything remaining.
        Str_Append(cmd, substart);

        DD_Execute(true/*silent*/, Str_Text(cmd));
    }
Esempio n. 3
0
/// @note Derived from Qt's QByteArray q_toPercentEncoding
ddstring_t *Str_PercentEncode2(ddstring_t *str, char const *excludeChars, char const *includeChars)
{
    dd_bool didEncode = false;
    int i, span, begin, len;
    ddstring_t buf;

    DENG_ASSERT(str);
    if(!str) return 0;

    if(Str_IsEmpty(str)) return str;

    len = Str_Length(str);
    begin = span = 0;
    for(i = 0; i < len; ++i)
    {
        char ch = str->str[i];

        // Are we encoding this?
        if(((ch >= 0x61 && ch <= 0x7A) // ALPHA
            || (ch >= 0x41 && ch <= 0x5A) // ALPHA
            || (ch >= 0x30 && ch <= 0x39) // DIGIT
            || ch == 0x2D // -
            || ch == 0x2E // .
            || ch == 0x5F // _
            || ch == 0x7E // ~
            || (excludeChars && strchr(excludeChars, ch)))
           && !(includeChars && strchr(includeChars, ch)))
        {
            // Not an encodeable. Span grows.
            span++;
        }
        else
        {
            // Found an encodeable.
            if(!didEncode)
            {
                Str_InitStd(&buf);
                Str_Reserve(&buf, len*3); // Worst case.
                didEncode = true;
            }

            Str_PartAppend(&buf, str->str, begin, span);
            Str_Appendf(&buf, "%%%X", (uint)ch);

            // Start a new span.
            begin += span + 1;
            span = 0;
        }
    }

    if(didEncode)
    {
        // Copy anything remaining.
        if(span)
        {
            Str_PartAppend(&buf, str->str, begin, span);
        }

        Str_Set(str, Str_Text(&buf));
        Str_Free(&buf);
    }

    return str;
}
Esempio n. 4
0
de::Action *EventBinding_ActionForEvent(evbinding_t *eb, ddevent_t const *event,
                                        struct bcontext_s *eventClass,
                                        bool respectHigherAssociatedContexts)
{
    int         i;
    inputdev_t* dev = 0;
    ddstring_t  command;

    if(eb->device != event->device || eb->type != event->type)
        return 0;

    if(event->type != E_SYMBOLIC)
    {
        dev = I_GetDevice(eb->device, true);
        if(!dev)
        {
            // The device is not active, there is no way this could get executed.
            return 0;
        }
    }

    switch(event->type)
    {
    case E_TOGGLE:
        if(eb->id != event->toggle.id)
            return 0;

        if(respectHigherAssociatedContexts)
        {
            if(eventClass && dev->keys[eb->id].assoc.bContext != eventClass)
                return 0; // Shadowed by a more important active class.
        }

        // We're checking it, so clear the triggered flag.
        dev->keys[eb->id].assoc.flags &= ~IDAF_TRIGGERED;

        // Is the state as required?
        switch(eb->state)
        {
            case EBTOG_UNDEFINED:
                // Passes no matter what.
                break;

            case EBTOG_DOWN:
                if(event->toggle.state != ETOG_DOWN)
                    return 0;
                break;

            case EBTOG_UP:
                if(event->toggle.state != ETOG_UP)
                    return 0;
                break;

            case EBTOG_REPEAT:
                if(event->toggle.state != ETOG_REPEAT)
                    return 0;
                break;

            case EBTOG_PRESS:
                if(event->toggle.state == ETOG_UP)
                    return 0;
                break;

            default:
                return 0;
        }
        break;

    case E_AXIS:
        if(eb->id != event->axis.id)
            return 0;
        if(eventClass && dev->axes[eb->id].assoc.bContext != eventClass)
            return 0; // Shadowed by a more important active class.

        // Is the position as required?
        if(!B_CheckAxisPos(eb->state, eb->pos,
                           I_TransformAxis(I_GetDevice(event->device, false),
                                           event->axis.id, event->axis.pos)))
            return 0;
        break;

    case E_ANGLE:
        if(eb->id != event->angle.id)
            return 0;
        if(eventClass && dev->hats[eb->id].assoc.bContext != eventClass)
            return 0; // Shadowed by a more important active class.
        // Is the position as required?
        if(event->angle.pos != eb->pos)
            return 0;
        break;

    case E_SYMBOLIC:
        if(strcmp(event->symbolic.name, eb->symbolicName))
            return 0;
        break;

    default:
        return 0;
    }

    // Any conditions on the current state of the input devices?
    for(i = 0; i < eb->numConds; ++i)
    {
        if(!B_CheckCondition(&eb->conds[i], 0, NULL))
            return 0;
    }

    // Substitute parameters in the command.
    Str_Init(&command);
    Str_Reserve(&command, strlen(eb->command));
    B_SubstituteInCommand(eb->command, event, eb, &command);

    de::Action *act = new CommandAction(Str_Text(&command), CMDS_BIND);

    Str_Free(&command);
    return act;
}