Jump to content

daveh

Members
  • Posts

    38
  • Joined

  • Last visited

    Never
  • Donations

    0.00 GBP 

Posts posted by daveh

  1. struct SMSG_AUTH_CHALLENGE // Opcode: 0x8500
    {
            uint32 unk1[2];
            byte connectionIndex;
            uint32 ServerSeed;
            uint32 unk2[5];
    };
    
    

    Thank you, btw SMSG_AUTH_CHALLENGE is:

    struct SMSG_AUTH_CHALLENGE // Opcode: 0x8500
    {
       uint32 ClientKey_part3;
       uint32 ServerKey_part1;
       uint8  unk;
       uint32 Seed;
       uint32 ServerKey_part3;
       uint32 ServerKey_part2;
       uint32 ClientKey_part1;
       uint32 ClientKey_part2;
       uint32 ServerKey_part4;
       uint32 ClientKey_part4;
    }

  2. Hi, I've made a rough patch for tiawps (https://github.com/arrai/tiawps), to decrypt 4.0.x wow sniff data.

    4.0.3 CONNECTION_PTR_OFFSET is 0xCB2F8C, session key offset is still 1288.

    4.0.1 CONNECTION_PTR_OFFSET is 0xCA5C34, session key offset is still 1288.

    Update:

    2010-11-10: Now handling SMSG_REDIRECT_CLIENT

    2010-11-23: Update for 4.0.3

    Patch for 4.0.3 (for git master branch)

    patch for reader 4.0.3:

    diff --git a/src/reader/reader.bat b/src/reader/reader.bat
    index 7f8177e..58b125e
    --- a/src/reader/reader.bat
    +++ b/src/reader/reader.bat
    @@ -1,5 +1,6 @@
    @echo off
    -echo "Tiawps sessionkey reader Build 12340 3.3.5"
    +echo "Tiawps sessionkey reader Build 13287 4.0.3"
    
    SET PATH=%~dp0
    REM Switch to drive
    @@ -7,5 +8,7 @@ REM Switch to drive
    
    cd %PATH%
    
    -tiawps_reader.exe 13081844 1288
    +rem CONNECTION_PTR_OFFSET = 0xCB2F8C
    +tiawps_reader.exe 13315980 1288
    PAUSE
    

    patch for decrypter 4.0.3:

    diff --git a/src/decrypter/main.c b/src/decrypter/main.c
    old mode 100644
    new mode 100755
    index 8bfe4ff..3f92af0
    --- a/src/decrypter/main.c
    +++ b/src/decrypter/main.c
    @@ -4,6 +4,8 @@
    #include <time.h>
    #include <ctype.h>
    #include <sqlite3.h>
    +#include <openssl/bn.h>
    +//#include <openssl/rsa.h>
    
    #include "pcapreader.h"
    #include "structs.h"
    @@ -13,10 +15,14 @@
    #define DEBUG               0
    
                                    // SIZE  SIZE  CMD   CMD
    -const uint8_t MAGIC_WOW_START[] = {0x00, 0x2A, 0xEC, 0x01};
    +//const uint8_t MAGIC_WOW_START[] = {0x00, 0x2A, 0xEC, 0x01}; // 3.3.5
    +//const uint8_t MAGIC_WOW_START[] = {0x00, 0x27, 0x00, 0x85}; // 4.0.1
    +const uint8_t MAGIC_WOW_START[] = {0x00, 0x27, 0x00, 0x34}; // 4.0.3
    
    static uint8_t SESSIONKEY[sESSION_KEY_LENGTH];
    
    +static int merge_files = 0;
    +
    void readSessionkeyFile(const char* file)
    {
        FILE *fp = fopen(file, "r");
    @@ -385,6 +391,258 @@ void removeInvalidConnections()
    
    struct tcp_connection *currentDecryptedConnection;
    
    +static BIGNUM *my_BN_bin2bn(const uint8_t *s, int len, BIGNUM *ret)
    +{
    +    uint8_t tmp[1024] = {0};
    +    for (int i = 0; i < len; i++)
    +        tmp[i] = s[len-1-i];
    +    return BN_bin2bn(tmp, len, ret);
    +}
    +
    +static int my_BN_bn2bin(const BIGNUM *a, unsigned char *to)
    +{
    +    uint8_t tmp[1024] = {0};
    +    int len = BN_bn2bin(a, tmp);
    +    for (int i = 0; i < len; i++)
    +        to[i] = tmp[len-1-i];
    +    return len;
    +}
    +
    +static int parse_SMSG_REDIRECT_CLIENT(const uint8_t *in, uint8_t *out)
    +{
    +    uint8_t b_e[] = { 0x01, 0x00, 0x01, 0x00 }; // public-key exp
    +    uint8_t b_m[] = { // modulus
    +        0x91, 0xD5, 0x9B, 0xB7, 0xD4, 0xE1, 0x83, 0xA5, 0x22, 0x2B, 0x5F, 0x38, 0xF4, 0xB8, 0x86, 0xFF,
    +        0x32, 0x84, 0x38, 0x2D, 0x99, 0x38, 0x8F, 0xBA, 0xF3, 0xC9, 0x22, 0x5D, 0x51, 0x73, 0x1E, 0x28,
    +        0x87, 0x24, 0x8F, 0xB5, 0xC9, 0xB0, 0x7C, 0x95, 0xD0, 0x6B, 0x5B, 0xF4, 0x94, 0xC5, 0x94, 0x9D,
    +        0xFA, 0x6F, 0x47, 0x3A, 0xA3, 0x86, 0xC0, 0xA8, 0x37, 0xF3, 0x9B, 0xEF, 0x2F, 0xC1, 0xFB, 0xB3,
    +        0xF4, 0x1C, 0x2B, 0x0E, 0xD3, 0x6D, 0x88, 0xBB, 0x02, 0xE0, 0x4E, 0x63, 0xFA, 0x76, 0xE3, 0x43,
    +        0xF9, 0x01, 0xFD, 0x23, 0x5E, 0x6A, 0x0B, 0x14, 0xEC, 0x5E, 0x91, 0x34, 0x0D, 0x0B, 0x4F, 0xA3,
    +        0x5A, 0x46, 0xC5, 0x5E, 0xDC, 0xB5, 0xCD, 0xC1, 0x47, 0x6B, 0x59, 0xCA, 0xFA, 0xA9, 0xBE, 0x24,
    +        0x9F, 0xF5, 0x05, 0x6B, 0xBB, 0x67, 0x8B, 0xB7, 0xE4, 0x3A, 0x43, 0x00, 0x5C, 0x1C, 0xB7, 0xCA,
    +        0x98, 0x90, 0x79, 0x77, 0x6D, 0x05, 0x4F, 0x83, 0xCC, 0xAC, 0x06, 0x2E, 0x50, 0x11, 0x87, 0x23,
    +        0xD8, 0xA6, 0xF7, 0x6F, 0x7A, 0x59, 0x87, 0xA6, 0xDE, 0x5D, 0xD8, 0xEC, 0x44, 0xBE, 0x45, 0x31,
    +        0x7F, 0x8A, 0xF0, 0x58, 0x89, 0x53, 0x74, 0xDF, 0xCC, 0xAD, 0x01, 0x24, 0xD8, 0x19, 0x65, 0x1C,
    +        0x25, 0xD3, 0xE1, 0x6B, 0x8B, 0xDA, 0xFE, 0x1D, 0xA4, 0x2C, 0x8B, 0x25, 0xED, 0x7C, 0xFF, 0x6A,
    +        0xE0, 0x63, 0xD0, 0x52, 0x20, 0x7E, 0x62, 0x49, 0xD2, 0xB3, 0x6B, 0xCC, 0x91, 0x69, 0xA5, 0x08,
    +        0x8B, 0x69, 0x65, 0xFF, 0xB9, 0xC9, 0x17, 0x02, 0x5D, 0xD8, 0x8E, 0x1A, 0x63, 0xD9, 0x2A, 0x7F,
    +        0xDB, 0xE3, 0xF8, 0x76, 0x6D, 0xEA, 0x0E, 0x36, 0x98, 0x78, 0x19, 0xC5, 0x87, 0xBA, 0x6C, 0x20,
    +        0xB6, 0x08, 0x44, 0x04, 0x4C, 0xA8, 0xD5, 0xB6, 0x9D, 0x4D, 0x00, 0x20, 0x40, 0x00, 0x90, 0x04
    +    };
    +
    +    // decrypt data (RSA-decrypt)
    +    BIGNUM r, a, e, m;
    +    BN_init(&r);
    +    BN_init(&a);
    +    BN_init(&e);
    +    BN_init(&m);
    +    my_BN_bin2bn(in, 256, &a);
    +    my_BN_bin2bn(b_e, 4, &e);
    +    my_BN_bin2bn(b_m, 256, &m);
    +    BN_CTX *ctx = BN_CTX_new();
    +    BN_mod_exp(&r, &a, &e, &m, ctx); //FIXME: use RSA-decrypt
    +    BN_CTX_free(ctx);
    +
    +    uint8_t d_out[256] = {0};
    +    int len = my_BN_bn2bin(&r, d_out);
    +    printf("len = %d\\n", len);
    +    if (len < 0)
    +        return len;
    +
    +    // make data ordered
    +    uint8_t *p = d_out;
    +    memcpy(out+6, p, 1); p++;
    +    memcpy(out+104, p, 1); p++;
    +    memcpy(out+8, p, 1); p++;
    +    memcpy(out+134, p, 2); p+=2;
    +    memcpy(out+124, p, 1); p++;
    +    memcpy(out+140, p, 2); p+=2;
    +    memcpy(out+19, p, 1); p++;
    +    memcpy(out+142, p, 2); p+=2;
    +    memcpy(out+160, p, 2); p+=2;
    +    memcpy(out+52, p, 1); p++;
    +    memcpy(out, p, 1); p++;
    +    memcpy(out+26, p, 1); p++;
    +    memcpy(out+248, p, 1); p++;
    +    memcpy(out+84, p, 1); p++;
    +    memcpy(out+86, p, 1); p++;
    +    memcpy(out+56, p, 1); p++;
    +    memcpy(out+235, p, 1); p++;
    +    memcpy(out+154, p, 2); p+=2;
    +    memcpy(out+68, p, 1); p++;
    +    memcpy(out+48, p, 1); p++;
    +    memcpy(out+13, p, 1); p++;
    +    memcpy(out+81, p, 1); p++;
    +    memcpy(out+252, p, 2); p+=2;
    +    memcpy(out+110, p, 1); p++;
    +    memcpy(out+128, p, 1); p++;
    +    memcpy(out+32, p, 1); p++;
    +    memcpy(out+62, p, 1); p++;
    +    memcpy(out+256, p, 4); p+=4;
    +    memcpy(out+126, p, 1); p++;
    +    memcpy(out+138, p, 2); p+=2;
    +    memcpy(out+123, p, 1); p++;
    +    memcpy(out+121, p, 1); p++;
    +    memcpy(out+82, p, 1); p++;
    +    memcpy(out+200, p, 4); p+=4;
    +    memcpy(out+245, p, 1); p++;
    +    memcpy(out+50, p, 1); p++;
    +    memcpy(out+9, p, 1); p++;
    +    memcpy(out+232, p, 1); p++;
    +    memcpy(out+148, p, 2); p+=2;
    +    memcpy(out+35, p, 1); p++;
    +    memcpy(out+21, p, 1); p++;
    +    memcpy(out+4, p, 1); p++;
    +    memcpy(out+95, p, 1); p++;
    +    memcpy(out+168, p, 4); p+=4;
    +    memcpy(out+37, p, 1); p++;
    +    memcpy(out+97, p, 1); p++;
    +    memcpy(out+71, p, 1); p++;
    +    memcpy(out+25, p, 1); p++;
    +    memcpy(out+130, p, 2); p+=2;
    +    memcpy(out+224, p, 4); p+=4;
    +    memcpy(out+23, p, 1); p++;
    +    memcpy(out+61, p, 1); p++;
    +    memcpy(out+36, p, 1); p++;
    +    memcpy(out+40, p, 1); p++;
    +    memcpy(out+57, p, 1); p++;
    +    memcpy(out+65, p, 1); p++;
    +    memcpy(out+233, p, 1); p++;
    +    memcpy(out+74, p, 1); p++;
    +    memcpy(out+34, p, 1); p++;
    +    memcpy(out+249, p, 1); p++;
    +    memcpy(out+42, p, 1); p++;
    +    memcpy(out+47, p, 1); p++;
    +    memcpy(out+118, p, 1); p++;
    +    memcpy(out+76, p, 1); p++;
    +    memcpy(out+108, p, 1); p++;
    +    memcpy(out+78, p, 1); p++;
    +    memcpy(out+33, p, 1); p++;
    +    memcpy(out+192, p, 4); p+=4;
    +    memcpy(out+156, p, 2); p+=2;
    +    memcpy(out+132, p, 2); p+=2;
    +    memcpy(out+152, p, 2); p+=2;
    +    memcpy(out+45, p, 1); p++;
    +    memcpy(out+67, p, 1); p++;
    +    memcpy(out+180, p, 4); p+=4;
    +    memcpy(out+92, p, 1); p++;
    +    memcpy(out+91, p, 1); p++;
    +    memcpy(out+75, p, 1); p++;
    +    memcpy(out+101, p, 1); p++;
    +    memcpy(out+216, p, 4); p+=4;
    +    memcpy(out+120, p, 1); p++;
    +    memcpy(out+44, p, 1); p++;
    +    memcpy(out+240, p, 1); p++;
    +    memcpy(out+109, p, 1); p++;
    +    memcpy(out+99, p, 1); p++;
    +    memcpy(out+234, p, 1); p++;
    +    memcpy(out+15, p, 1); p++;
    +    memcpy(out+125, p, 1); p++;
    +    memcpy(out+89, p, 1); p++;
    +    memcpy(out+196, p, 4); p+=4;
    +    memcpy(out+251, p, 1); p++;
    +    memcpy(out+66, p, 1); p++;
    +    memcpy(out+31, p, 1); p++;
    +    memcpy(out+93, p, 1); p++;
    +    memcpy(out+29, p, 1); p++;
    +    memcpy(out+239, p, 1); p++;
    +    memcpy(out+64, p, 1); p++;
    +    memcpy(out+87, p, 1); p++;
    +    memcpy(out+73, p, 1); p++;
    +    memcpy(out+238, p, 1); p++;
    +    memcpy(out+55, p, 1); p++;
    +    memcpy(out+70, p, 1); p++;
    +    memcpy(out+150, p, 2); p+=2;
    +    memcpy(out+63, p, 1); p++;
    +    memcpy(out+246, p, 1); p++;
    +    memcpy(out+243, p, 1); p++;
    +    memcpy(out+49, p, 1); p++;
    +    memcpy(out+241, p, 1); p++;
    +    memcpy(out+172, p, 4); p+=4;
    +    memcpy(out+79, p, 1); p++;
    +    memcpy(out+103, p, 1); p++;
    +    memcpy(out+1, p, 1); p++;
    +    memcpy(out+12, p, 1); p++;
    +    memcpy(out+122, p, 1); p++;
    +    memcpy(out+41, p, 1); p++;
    +    memcpy(out+18, p, 1); p++;
    +    memcpy(out+106, p, 1); p++;
    +    memcpy(out+46, p, 1); p++;
    +    memcpy(out+22, p, 1); p++;
    +    memcpy(out+208, p, 4); p+=4;
    +    memcpy(out+102, p, 1); p++;
    +    memcpy(out+30, p, 1); p++;
    +    memcpy(out+54, p, 1); p++;
    +    memcpy(out+247, p, 1); p++;
    +    memcpy(out+77, p, 1); p++;
    +    memcpy(out+228, p, 4); p+=4;
    +    memcpy(out+85, p, 1); p++;
    +    memcpy(out+100, p, 1); p++;
    +    memcpy(out+146, p, 2); p+=2;
    +    memcpy(out+111, p, 1); p++;
    +    memcpy(out+11, p, 1); p++;
    +    memcpy(out+43, p, 1); p++;
    +    memcpy(out+242, p, 1); p++;
    +    memcpy(out+94, p, 1); p++;
    +    memcpy(out+14, p, 1); p++;
    +    memcpy(out+90, p, 1); p++;
    +    memcpy(out+28, p, 1); p++;
    +    memcpy(out+53, p, 1); p++;
    +    memcpy(out+72, p, 1); p++;
    +    memcpy(out+98, p, 1); p++;
    +    memcpy(out+114, p, 1); p++;
    +    memcpy(out+127, p, 1); p++;
    +    memcpy(out+236, p, 1); p++;
    +    memcpy(out+204, p, 4); p+=4;
    +    memcpy(out+59, p, 1); p++;
    +    memcpy(out+212, p, 4); p+=4;
    +    memcpy(out+184, p, 4); p+=4;
    +    memcpy(out+60, p, 1); p++;
    +    memcpy(out+17, p, 1); p++;
    +    memcpy(out+113, p, 1); p++;
    +    memcpy(out+105, p, 1); p++;
    +    memcpy(out+107, p, 1); p++;
    +    memcpy(out+5, p, 1); p++;
    +    memcpy(out+83, p, 1); p++;
    +    memcpy(out+27, p, 1); p++;
    +    memcpy(out+96, p, 1); p++;
    +    memcpy(out+164, p, 4); p+=4;
    +    memcpy(out+24, p, 1); p++;
    +    memcpy(out+158, p, 2); p+=2;
    +    memcpy(out+119, p, 1); p++;
    +    memcpy(out+250, p, 1); p++;
    +    memcpy(out+58, p, 1); p++;
    +    memcpy(out+88, p, 1); p++;
    +    memcpy(out+10, p, 1); p++;
    +    memcpy(out+7, p, 1); p++;
    +    memcpy(out+20, p, 1); p++;
    +    memcpy(out+51, p, 1); p++;
    +    memcpy(out+3, p, 1); p++;
    +    memcpy(out+144, p, 2); p+=2;
    +    memcpy(out+188, p, 4); p+=4;
    +    memcpy(out+16, p, 1); p++;
    +    memcpy(out+136, p, 2); p+=2;
    +    memcpy(out+116, p, 1); p++;
    +    memcpy(out+39, p, 1); p++;
    +    memcpy(out+38, p, 1); p++;
    +    memcpy(out+237, p, 1); p++;
    +    memcpy(out+2, p, 1); p++;
    +    memcpy(out+69, p, 1); p++;
    +    memcpy(out+220, p, 4); p+=4;
    +    memcpy(out+115, p, 1); p++;
    +    memcpy(out+117, p, 1); p++;
    +    memcpy(out+112, p, 1); p++;
    +    memcpy(out+176, p, 4); p+=4;
    +    memcpy(out+80, p, 1); p++;
    +    memcpy(out+244, p, 1); p++;
    +
    +    // verify data
    +    if (*(uint32_t*)(out+256) != 0x77177AB3)
    +        return -1;
    +
    +    return len;
    +}
    +
    void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, uint32_t data_len, void *db)
    {
        insertPacket(s2c, time, opcode, data, data_len, db);
    @@ -397,16 +655,24 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,
        switch(opcode)
        {
            // forwarding connection
    -        case 1293:
    +        case 0x9000:// 0x8400(4.0.1) //SMSG_REDIRECT_CLIENT //1293:
            {
    -            const uint32_t expected_size = 4+2+4+20;
    +            const uint32_t expected_size = 1+256+4+8; //4+2+4+20;
                if(data_len != expected_size)
                {
    -                printf("WARNING: packet 1293 is %u bytes long, but we expected %u\\n", data_len, expected_size);
    +                printf("WARNING: packet SMSG_REDIRECT_CLIENT is %u bytes long, but we expected %u\\n", data_len, expected_size);
                    return;
                }
    -            uint32_t fwd_addr = *(data)<<24 | *(data+1)<<16 | *(data+2) << 8 | *(data+3);
    -            uint16_t fwd_port = ntohs(*((uint16_t*)(data+4)));
    +            uint8_t ordered_data[256] = {0};
    +            if (parse_SMSG_REDIRECT_CLIENT(data+1, ordered_data) < 0)
    +            {
    +                printf("WARNING: decrypt/parse packet SMSG_REDIRECT_CLIENT fail\\n");
    +                break;
    +            }
    +            //uint32_t fwd_addr = *(data)<<24 | *(data+1)<<16 | *(data+2) << 8 | *(data+3);
    +            //uint16_t fwd_port = ntohs(*((uint16_t*)(data+4)));
    +            uint32_t fwd_addr = ntohl(*((uint32_t*)(ordered_data+164)));
    +            uint16_t fwd_port = ntohs(*((uint16_t*)(ordered_data+252)));
                // find the connection
                for(uint32_t i=0; i<connection_count; ++i)
                {
    @@ -416,6 +682,7 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,
                    {
                        printf("Set connection forwarding bit on %s:%u\\n", addrToStr(fwd_addr), ntohs(fwd_port));
                        connection->forwarded = 1;
    +                    currentDecryptedConnection->forwarded = 2;
                        return;
                    }
                }
    @@ -427,6 +694,7 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,
    
    void decrypt()
    {
    +    sqlite3 *db=NULL;
        for(uint32_t i=0; i<connection_count; ++i)
        {
            struct tcp_connection *connection = connections[i];
    @@ -442,8 +710,8 @@ void decrypt()
            struct tm* timestruct = localtime(&time);
            strftime (filename, sizeof(filename), format, timestruct);
    
    -        sqlite3 *db=NULL;
    -        initDatabase(filename, &db);
    +        if(!merge_files || (merge_files && !connection->forwarded))
    +            initDatabase(filename, &db);
    
            struct decryption_state client_state, server_state;
            uint8_t custom_serverseed[16];
    @@ -451,11 +719,11 @@ void decrypt()
    
            if(connection->forwarded)
            {
    -            const uint32_t expected_size = 2+2*4+2*16;
    +            const uint32_t expected_size = 2+4+1+2*16;//2+2*4+2*16;
                uint8_t* data = connection->to.data.buffer;
                uint32_t size = data[0]<<8 | data[1];
                uint32_t opcode = data[3]<<8 | data[2];
    -            if(opcode != 492)
    +            if(opcode != 0x3400) // 8500(4.0.1) //SMSG_AUTH_CHALLENGE //492)
                {
                    printf("WARNING: first packet in stream is not 492 but %u\\n", opcode);
                    continue;
    @@ -465,12 +733,22 @@ void decrypt()
                    printf("WARNING: packet 492 is %u bytes long, but we expected %u\\n", size, expected_size);
                    continue;
                }
    -            memcpy(custom_serverseed, data+4+2*4, 16);
    -            memcpy(custom_clientseed, data+4+2*4+16, 16);
    +            //memcpy(custom_serverseed, data+4+2*4, 16);
    +            //memcpy(custom_clientseed, data+4+2*4+16, 16);
    +            memcpy(custom_serverseed+0*4, data+4+3*4, 4);
    +            memcpy(custom_serverseed+1*4, data+4+6*4+1, 4);
    +            memcpy(custom_serverseed+2*4, data+4+8*4+1, 4);
    +            memcpy(custom_serverseed+3*4, data+4+5*4+1, 4);
    +            memcpy(custom_clientseed+0*4, data+4+0*4, 4);
    +            memcpy(custom_clientseed+1*4, data+4+7*4+1, 4);
    +            memcpy(custom_clientseed+2*4, data+4+4*4+1, 4);
    +            memcpy(custom_clientseed+3*4, data+4+1*4, 4);
                printf("Using custom seeds for forwarded connection\\n");
    
                init_decryption_state_server(&server_state, SESSIONKEY, custom_serverseed);
                init_decryption_state_client(&client_state, SESSIONKEY, custom_clientseed);
    +
    +            connection->forwarded = 0;
            }
            else
            {
    @@ -514,7 +792,8 @@ void decrypt()
                }
                update_decryption(nextState, participant->timeinfo.info[ti_counter].epoch_micro, data, datalen, db, decryptCallback);
            }
    -        freeDatabase(&db);
    +        if(!merge_files || (merge_files && !connection->forwarded))
    +            freeDatabase(&db);
    
            free_decryption_state(&server_state);
            free_decryption_state(&client_state);
    @@ -524,20 +803,28 @@ void decrypt()
    
    int main(int argc, char *argv[])
    {
    -    if(argc != 3)
    +    if(argc < 3)
        {
    -        printf("Usage: %s $dumpfile.cap $keyfile.txt\\n", argv[0]);
    +        printf("Usage: %s [-m] $dumpfile.cap $keyfile.txt\\n", argv[0]);
    +        printf("                [-m] merge output files\\n");
            return 1;
        }
        char* pcapFile = argv[1];
        char* keyFile = argv[2];
    +    if (!strcmp(argv[1], "-m"))
    +    {
    +        merge_files = 1;
    +        pcapFile = argv[2];
    +        keyFile = argv[3];
    +    }
    
        // maybe switched arguments?
        char* magicKeyfileEnd = "txt";
        if(strlen(keyFile) >= 3 && memcmp(keyFile+strlen(keyFile)-3, magicKeyfileEnd, 3))
        {
    -        pcapFile = argv[2];
    -        keyFile = argv[1];
    +        char *temp = pcapFile;
    +        pcapFile = keyFile;
    +        keyFile = temp;
        }
    
        readSessionkeyFile(keyFile);
    diff --git a/src/decrypter/sqliteout.c b/src/decrypter/sqliteout.c
    old mode 100644
    new mode 100755
    index cc75c05..2fcd4f4
    --- a/src/decrypter/sqliteout.c
    +++ b/src/decrypter/sqliteout.c
    @@ -47,7 +47,8 @@ void insertClientBuild(uint8_t *data, uint32_t data_len, sqlite3 *db)
            printf("FATAL: got a packet with opcode = 493 = CMSG_AUTH_SESSION but payload len=%u < 4\\n", data_len);
            exit(1);
        }
    -    uint32_t *clientBuild = (uint32_t*)data;
    +    //uint32_t *clientBuild = (uint32_t*)data;
    +    uint16_t *clientBuild = (uint16_t*)(data+2*1);
    
        const char* insertFormat = "insert into header values ('clientBuild', %u)";
        uint32_t allocSize = strlen(insertFormat)+10 /*uint32*/;
    @@ -60,6 +61,19 @@ void insertClientBuild(uint8_t *data, uint32_t data_len, sqlite3 *db)
        sprintf(buffer, insertFormat, *clientBuild);
        executeSql(db, buffer);
        free(buffer);
    +
    +    // make sniffitzt happy
    +    char sql[512];
    +    sprintf(sql, "insert into header values ('clientLang', '%s')", "");
    +    executeSql(db, sql);
    +    sprintf(sql, "insert into header values ('accountName', '%s')", (char*)(data+22*1+1*2+1*8+5*4));
    +    executeSql(db, sql);
    +    sprintf(sql, "insert into header values ('realmName', '%s')", "");
    +    executeSql(db, sql);
    +    sprintf(sql, "insert into header values ('realmServer', '%s')", "");
    +    executeSql(db, sql);
    +    sprintf(sql, "insert into header values ('snifferVersion', '%s')", "");
    +    executeSql(db, sql);    
    }
    
    void insertPacket(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, uint32_t data_len, void* arg)
    @@ -83,7 +97,7 @@ void insertPacket(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, ui
    
        free(queryBuffer);
    
    -    if(opcode == 493)
    +    if(opcode == 0x880a) // 0x3000(4.0.1) //CMSG_AUTH_SESSION //493(3.3.5))
            insertClientBuild(data, data_len, db);
    }
    
    

    Patch for 4.0.1 (already in git cata branch)

    BTW:

    SMSG_AUTH_CHALLENGE = 0x8500 (4.0.1)
    {
       uint32 ClientKey_part3;
       uint32 ServerKey_part1;
       uint8  unk;
       uint32 Seed;
       uint32 ServerKey_part3;
       uint32 ServerKey_part2;
       uint32 ClientKey_part1;
       uint32 ClientKey_part2;
       uint32 ServerKey_part4;
       uint32 ClientKey_part4;
    }
    

    patch for reader 4.0.1:

    diff --git a/src/reader/reader.bat b/src/reader/reader.bat
    index 7f8177e..58b125e
    --- a/src/reader/reader.bat
    +++ b/src/reader/reader.bat
    @@ -1,5 +1,6 @@
    @echo off
    -echo "Tiawps sessionkey reader Build 12340 3.3.5"
    +rem echo "Tiawps sessionkey reader Build 12340 3.3.5"
    +echo "Tiawps sessionkey reader Build 13205 4.0.1"
    
    SET PATH=%~dp0
    REM Switch to drive
    @@ -7,5 +8,7 @@ REM Switch to drive
    
    cd %PATH%
    
    -tiawps_reader.exe 13081844 1288
    +rem tiawps_reader.exe 13081844 1288
    +rem CONNECTION_PTR_OFFSET = 0xCA5C34
    +tiawps_reader.exe 13261876 1288
    PAUSE
    

    patch for decrypter 4.0.1:

    diff --git a/src/decrypter/main.c b/src/decrypter/main.c
    old mode 100644
    new mode 100755
    index 228a7bc..b59e0e7
    --- a/src/decrypter/main.c
    +++ b/src/decrypter/main.c
    @@ -4,6 +4,8 @@
    #include <time.h>
    #include <ctype.h>
    #include <sqlite3.h>
    +#include <openssl/bn.h>
    +//#include <openssl/rsa.h>
    
    #include "pcapreader.h"
    #include "structs.h"
    @@ -13,10 +15,13 @@
    #define DEBUG               0
    
                                    // SIZE  SIZE  CMD   CMD
    -const uint8_t MAGIC_WOW_START[] = {0x00, 0x2A, 0xEC, 0x01};
    +//const uint8_t MAGIC_WOW_START[] = {0x00, 0x2A, 0xEC, 0x01};
    +const uint8_t MAGIC_WOW_START[] = {0x00, 0x27, 0x00, 0x85};
    
    static uint8_t SESSIONKEY[sESSION_KEY_LENGTH];
    
    +static int merge_files = 0;
    +
    void readSessionkeyFile(const char* file)
    {
        FILE *fp = fopen(file, "r");
    @@ -385,6 +390,257 @@ void removeInvalidConnections()
    
    struct tcp_connection *currentDecryptedConnection;
    
    +static BIGNUM *my_BN_bin2bn(const uint8_t *s, int len, BIGNUM *ret)
    +{
    +    uint8_t tmp[1024] = {0};
    +    for (int i = 0; i < len; i++)
    +        tmp[i] = s[len-1-i];
    +    return BN_bin2bn(tmp, len, ret);
    +}
    +
    +static int my_BN_bn2bin(const BIGNUM *a, unsigned char *to)
    +{
    +    uint8_t tmp[1024] = {0};
    +    int len = BN_bn2bin(a, tmp);
    +    for (int i = 0; i < len; i++)
    +        to[i] = tmp[len-1-i];
    +    return len;
    +}
    +
    +static int parse_SMSG_REDIRECT_CLIENT(const uint8_t *in, uint8_t *out)
    +{
    +    uint8_t b_e[] = { 0x01, 0x00, 0x01, 0x00 }; // private-key exp
    +    uint8_t b_m[] = { // modulus
    +        0x91, 0xD5, 0x9B, 0xB7, 0xD4, 0xE1, 0x83, 0xA5, 0x22, 0x2B, 0x5F, 0x38, 0xF4, 0xB8, 0x86, 0xFF,
    +        0x32, 0x84, 0x38, 0x2D, 0x99, 0x38, 0x8F, 0xBA, 0xF3, 0xC9, 0x22, 0x5D, 0x51, 0x73, 0x1E, 0x28,
    +        0x87, 0x24, 0x8F, 0xB5, 0xC9, 0xB0, 0x7C, 0x95, 0xD0, 0x6B, 0x5B, 0xF4, 0x94, 0xC5, 0x94, 0x9D,
    +        0xFA, 0x6F, 0x47, 0x3A, 0xA3, 0x86, 0xC0, 0xA8, 0x37, 0xF3, 0x9B, 0xEF, 0x2F, 0xC1, 0xFB, 0xB3,
    +        0xF4, 0x1C, 0x2B, 0x0E, 0xD3, 0x6D, 0x88, 0xBB, 0x02, 0xE0, 0x4E, 0x63, 0xFA, 0x76, 0xE3, 0x43,
    +        0xF9, 0x01, 0xFD, 0x23, 0x5E, 0x6A, 0x0B, 0x14, 0xEC, 0x5E, 0x91, 0x34, 0x0D, 0x0B, 0x4F, 0xA3,
    +        0x5A, 0x46, 0xC5, 0x5E, 0xDC, 0xB5, 0xCD, 0xC1, 0x47, 0x6B, 0x59, 0xCA, 0xFA, 0xA9, 0xBE, 0x24,
    +        0x9F, 0xF5, 0x05, 0x6B, 0xBB, 0x67, 0x8B, 0xB7, 0xE4, 0x3A, 0x43, 0x00, 0x5C, 0x1C, 0xB7, 0xCA,
    +        0x98, 0x90, 0x79, 0x77, 0x6D, 0x05, 0x4F, 0x83, 0xCC, 0xAC, 0x06, 0x2E, 0x50, 0x11, 0x87, 0x23,
    +        0xD8, 0xA6, 0xF7, 0x6F, 0x7A, 0x59, 0x87, 0xA6, 0xDE, 0x5D, 0xD8, 0xEC, 0x44, 0xBE, 0x45, 0x31,
    +        0x7F, 0x8A, 0xF0, 0x58, 0x89, 0x53, 0x74, 0xDF, 0xCC, 0xAD, 0x01, 0x24, 0xD8, 0x19, 0x65, 0x1C,
    +        0x25, 0xD3, 0xE1, 0x6B, 0x8B, 0xDA, 0xFE, 0x1D, 0xA4, 0x2C, 0x8B, 0x25, 0xED, 0x7C, 0xFF, 0x6A,
    +        0xE0, 0x63, 0xD0, 0x52, 0x20, 0x7E, 0x62, 0x49, 0xD2, 0xB3, 0x6B, 0xCC, 0x91, 0x69, 0xA5, 0x08,
    +        0x8B, 0x69, 0x65, 0xFF, 0xB9, 0xC9, 0x17, 0x02, 0x5D, 0xD8, 0x8E, 0x1A, 0x63, 0xD9, 0x2A, 0x7F,
    +        0xDB, 0xE3, 0xF8, 0x76, 0x6D, 0xEA, 0x0E, 0x36, 0x98, 0x78, 0x19, 0xC5, 0x87, 0xBA, 0x6C, 0x20,
    +        0xB6, 0x08, 0x44, 0x04, 0x4C, 0xA8, 0xD5, 0xB6, 0x9D, 0x4D, 0x00, 0x20, 0x40, 0x00, 0x90, 0x04
    +    };
    +
    +    // decrypt data (RSA-decrypt)
    +    BIGNUM r, a, e, m;
    +    BN_init(&r);
    +    BN_init(&a);
    +    BN_init(&e);
    +    BN_init(&m);
    +    my_BN_bin2bn(in, 256, &a);
    +    my_BN_bin2bn(b_e, 4, &e);
    +    my_BN_bin2bn(b_m, 256, &m);
    +    BN_CTX *ctx = BN_CTX_new();
    +    BN_mod_exp(&r, &a, &e, &m, ctx); //FIXME: use RSA-decrypt
    +    BN_CTX_free(ctx);
    +
    +    uint8_t d_out[256] = {0};
    +    int len = my_BN_bn2bin(&r, d_out);
    +    if (len < 0)
    +        return len;
    +
    +    // make data ordered
    +    uint8_t *p = d_out;
    +    memcpy(out+89, p, 1); p++;
    +    memcpy(out+94, p, 1); p++;
    +    memcpy(out+151, p, 1); p++;
    +    memcpy(out+159, p, 1); p++;
    +    memcpy(out+155, p, 1); p++;
    +    memcpy(out+118, p, 1); p++;
    +    memcpy(out+46, p, 2); p+=2;
    +    memcpy(out+129, p, 1); p++;
    +    memcpy(out+127, p, 1); p++;
    +    memcpy(out+44, p, 2); p+=2;
    +    memcpy(out+32, p, 2); p+=2;
    +    memcpy(out+157, p, 1); p++;
    +    memcpy(out+164, p, 1); p++;
    +    memcpy(out+134, p, 1); p++;
    +    memcpy(out+124, p, 1); p++;
    +    memcpy(out+83, p, 1); p++;
    +    memcpy(out+122, p, 1); p++;
    +    memcpy(out+96, p, 1); p++;
    +    memcpy(out+71, p, 1); p++;
    +    memcpy(out+50, p, 2); p+=2;
    +    memcpy(out+17, p, 1); p++;
    +    memcpy(out+4, p, 1); p++;
    +    memcpy(out+132, p, 1); p++;
    +    memcpy(out+112, p, 1); p++;
    +    memcpy(out+156, p, 1); p++;
    +    memcpy(out+220, p, 4); p+=4;
    +    memcpy(out+59, p, 1); p++;
    +    memcpy(out+72, p, 1); p++;
    +    memcpy(out+130, p, 1); p++;
    +    memcpy(out+182, p, 1); p++;
    +    memcpy(out+154, p, 1); p++;
    +    memcpy(out+138, p, 1); p++;
    +    memcpy(out+61, p, 1); p++;
    +    memcpy(out+166, p, 1); p++;
    +    memcpy(out+139, p, 1); p++;
    +    memcpy(out+186, p, 1); p++;
    +    memcpy(out+10, p, 1); p++;
    +    memcpy(out+137, p, 1); p++;
    +    memcpy(out+68, p, 1); p++;
    +    memcpy(out+36, p, 2); p+=2;
    +    memcpy(out+115, p, 1); p++;
    +    memcpy(out+87, p, 1); p++;
    +    memcpy(out+175, p, 1); p++;
    +    memcpy(out+172, p, 1); p++;
    +    memcpy(out+252, p, 4); p+=4;
    +    memcpy(out+16, p, 1); p++;
    +    memcpy(out+88, p, 1); p++;
    +    memcpy(out+248, p, 4); p+=4;
    +    memcpy(out+180, p, 1); p++;
    +    memcpy(out+18, p, 1); p++;
    +    memcpy(out+78, p, 1); p++;
    +    memcpy(out+11, p, 1); p++;
    +    memcpy(out+24, p, 2); p+=2;
    +    memcpy(out+162, p, 1); p++;
    +    memcpy(out+204, p, 4); p+=4;
    +    memcpy(out+54, p, 2); p+=2;
    +    memcpy(out+125, p, 1); p++;
    +    memcpy(out+98, p, 1); p++;
    +    memcpy(out+102, p, 1); p++;
    +    memcpy(out+114, p, 1); p++;
    +    memcpy(out+216, p, 4); p+=4;
    +    memcpy(out+20, p, 1); p++;
    +    memcpy(out+136, p, 1); p++;
    +    memcpy(out+116, p, 1); p++;
    +    memcpy(out+185, p, 1); p++;
    +    memcpy(out+224, p, 4); p+=4;
    +    memcpy(out+146, p, 1); p++;
    +    memcpy(out+109, p, 1); p++;
    +    memcpy(out+106, p, 1); p++;
    +    memcpy(out+244, p, 4); p+=4;
    +    memcpy(out+135, p, 1); p++;
    +    memcpy(out+62, p, 1); p++;
    +    memcpy(out+60, p, 1); p++;
    +    memcpy(out+84, p, 1); p++;
    +    memcpy(out+91, p, 1); p++;
    +    memcpy(out+48, p, 2); p+=2;
    +    memcpy(out+144, p, 1); p++;
    +    memcpy(out+108, p, 1); p++;
    +    memcpy(out+63, p, 1); p++;
    +    memcpy(out+121, p, 1); p++;
    +    memcpy(out+145, p, 1); p++;
    +    memcpy(out+19, p, 1); p++;
    +    memcpy(out+13, p, 1); p++;
    +    memcpy(out+12, p, 1); p++;
    +    memcpy(out+52, p, 2); p+=2;
    +    memcpy(out+6, p, 1); p++;
    +    memcpy(out+74, p, 1); p++;
    +    memcpy(out+176, p, 1); p++;
    +    memcpy(out+69, p, 1); p++;
    +    memcpy(out+5, p, 1); p++;
    +    memcpy(out+99, p, 1); p++;
    +    memcpy(out+97, p, 1); p++;
    +    memcpy(out+14, p, 1); p++;
    +    memcpy(out+140, p, 1); p++;
    +    memcpy(out+177, p, 1); p++;
    +    memcpy(out+149, p, 1); p++;
    +    memcpy(out+101, p, 1); p++;
    +    memcpy(out+107, p, 1); p++;
    +    memcpy(out+228, p, 4); p+=4;
    +    memcpy(out+82, p, 1); p++;
    +    memcpy(out+184, p, 1); p++;
    +    memcpy(out+119, p, 1); p++;
    +    memcpy(out+158, p, 1); p++;
    +    memcpy(out+143, p, 1); p++;
    +    memcpy(out+196, p, 4); p+=4;
    +    memcpy(out+86, p, 1); p++;
    +    memcpy(out+38, p, 2); p+=2;
    +    memcpy(out+142, p, 1); p++;
    +    memcpy(out+240, p, 4); p+=4;
    +    memcpy(out+104, p, 1); p++;
    +    memcpy(out+77, p, 1); p++;
    +    memcpy(out+168, p, 1); p++;
    +    memcpy(out+150, p, 1); p++;
    +    memcpy(out+9, p, 1); p++;
    +    memcpy(out+22, p, 1); p++;
    +    memcpy(out+7, p, 1); p++;
    +    memcpy(out+95, p, 1); p++;
    +    memcpy(out+110, p, 1); p++;
    +    memcpy(out+34, p, 2); p+=2;
    +    memcpy(out+161, p, 1); p++;
    +    memcpy(out+117, p, 1); p++;
    +    memcpy(out+141, p, 1); p++;
    +    memcpy(out+111, p, 1); p++;
    +    memcpy(out+212, p, 4); p+=4;
    +    memcpy(out+179, p, 1); p++;
    +    memcpy(out+200, p, 4); p+=4;
    +    memcpy(out+147, p, 1); p++;
    +    memcpy(out+66, p, 1); p++;
    +    memcpy(out+70, p, 1); p++;
    +    memcpy(out+67, p, 1); p++;
    +    memcpy(out+100, p, 1); p++;
    +    memcpy(out+128, p, 1); p++;
    +    memcpy(out+133, p, 1); p++;
    +    memcpy(out+28, p, 2); p+=2;
    +    memcpy(out+15, p, 1); p++;
    +    memcpy(out+188, p, 4); p+=4;
    +    memcpy(out, p, 4); p+=4;
    +    memcpy(out+165, p, 1); p++;
    +    memcpy(out+169, p, 1); p++;
    +    memcpy(out+76, p, 1); p++;
    +    memcpy(out+65, p, 1); p++;
    +    memcpy(out+163, p, 1); p++;
    +    memcpy(out+85, p, 1); p++;
    +    memcpy(out+148, p, 1); p++;
    +    memcpy(out+23, p, 1); p++;
    +    memcpy(out+208, p, 4); p+=4;
    +    memcpy(out+183, p, 1); p++;
    +    memcpy(out+56, p, 2); p+=2;
    +    memcpy(out+73, p, 1); p++;
    +    memcpy(out+21, p, 1); p++;
    +    memcpy(out+120, p, 1); p++;
    +    memcpy(out+152, p, 1); p++;
    +    memcpy(out+113, p, 1); p++;
    +    memcpy(out+232, p, 4); p+=4;
    +    memcpy(out+170, p, 1); p++;
    +    memcpy(out+64, p, 1); p++;
    +    memcpy(out+81, p, 1); p++;
    +    memcpy(out+80, p, 1); p++;
    +    memcpy(out+123, p, 1); p++;
    +    memcpy(out+8, p, 1); p++;
    +    memcpy(out+79, p, 1); p++;
    +    memcpy(out+26, p, 2); p+=2;
    +    memcpy(out+236, p, 4); p+=4;
    +    memcpy(out+92, p, 1); p++;
    +    memcpy(out+30, p, 2); p+=2;
    +    memcpy(out+42, p, 2); p+=2;
    +    memcpy(out+174, p, 1); p++;
    +    memcpy(out+131, p, 1); p++;
    +    memcpy(out+75, p, 1); p++;
    +    memcpy(out+93, p, 1); p++;
    +    memcpy(out+40, p, 2); p+=2;
    +    memcpy(out+167, p, 1); p++;
    +    memcpy(out+171, p, 1); p++;
    +    memcpy(out+173, p, 1); p++;
    +    memcpy(out+160, p, 1); p++;
    +    memcpy(out+105, p, 1); p++;
    +    memcpy(out+178, p, 1); p++;
    +    memcpy(out+103, p, 1); p++;
    +    memcpy(out+192, p, 4); p+=4;
    +    memcpy(out+58, p, 1); p++;
    +    memcpy(out+90, p, 1); p++;
    +    memcpy(out+126, p, 1); p++;
    +    memcpy(out+181, p, 1); p++;
    +    memcpy(out+153, p, 1); p++;
    +
    +    // verify data
    +    if (*(uint32_t*)out != 0x77177AB3)
    +        return -1;
    +
    +    return len;
    +}
    +
    void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, uint32_t data_len, void *db)
    {
        insertPacket(s2c, time, opcode, data, data_len, db);
    @@ -397,16 +653,24 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,
        switch(opcode)
        {
            // forwarding connection
    -        case 1293:
    +        case 0x8400: //SMSG_REDIRECT_CLIENT //1293:
            {
    -            const uint32_t expected_size = 4+2+4+20;
    +            const uint32_t expected_size = 4+256+1; //4+2+4+20;
                if(data_len != expected_size)
                {
                    printf("WARNING: packet 1293 is %u bytes long, but we expected %u\\n", data_len, expected_size);
                    return;
                }
    -            uint32_t fwd_addr = *(data)<<24 | *(data+1)<<16 | *(data+2) << 8 | *(data+3);
    -            uint16_t fwd_port = ntohs(*((uint16_t*)(data+4)));
    +            uint8_t ordered_data[256] = {0};
    +            if (parse_SMSG_REDIRECT_CLIENT(data+4, ordered_data) < 0)
    +            {
    +                printf("WARNING: decrypt/parse packet SMSG_REDIRECT_CLIENT fail\\n");
    +                break;
    +            }
    +            //uint32_t fwd_addr = *(data)<<24 | *(data+1)<<16 | *(data+2) << 8 | *(data+3);
    +            //uint16_t fwd_port = ntohs(*((uint16_t*)(data+4)));
    +            uint32_t fwd_addr = ntohl(*((uint32_t*)(ordered_data+252)));
    +            uint16_t fwd_port = ntohs(*((uint16_t*)(ordered_data+24)));
                // find the connection
                for(uint32_t i=0; i<connection_count; ++i)
                {
    @@ -416,6 +680,7 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,
                    {
                        printf("Set connection forwarding bit on %s:%u\\n", addrToStr(fwd_addr), ntohs(fwd_port));
                        connection->forwarded = 1;
    +                    currentDecryptedConnection->forwarded = 2;
                        return;
                    }
                }
    @@ -427,6 +692,7 @@ void decryptCallback(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data,
    
    void decrypt()
    {
    +    sqlite3 *db=NULL;
        for(uint32_t i=0; i<connection_count; ++i)
        {
            struct tcp_connection *connection = connections[i];
    @@ -442,8 +708,8 @@ void decrypt()
            struct tm* timestruct = localtime(&time);
            strftime (filename, sizeof(filename), format, timestruct);
    
    -        sqlite3 *db=NULL;
    -        initDatabase(filename, &db);
    +        if(!merge_files || (merge_files && !connection->forwarded))
    +            initDatabase(filename, &db);
    
            struct decryption_state client_state, server_state;
            uint8_t custom_serverseed[16];
    @@ -451,11 +717,11 @@ void decrypt()
    
            if(connection->forwarded)
            {
    -            const uint32_t expected_size = 2+2*4+2*16;
    +            const uint32_t expected_size = 2+4+1+2*16;//2+2*4+2*16;
                uint8_t* data = connection->to.data.buffer;
                uint32_t size = data[0]<<8 | data[1];
                uint32_t opcode = data[3]<<8 | data[2];
    -            if(opcode != 492)
    +            if(opcode != 0x8500) //SMSG_AUTH_CHALLENGE //492)
                {
                    printf("WARNING: first packet in stream is not 492 but %u\\n", opcode);
                    continue;
    @@ -465,12 +731,22 @@ void decrypt()
                    printf("WARNING: packet 492 is %u bytes long, but we expected %u\\n", size, expected_size);
                    continue;
                }
    -            memcpy(custom_serverseed, data+4+2*4, 16);
    -            memcpy(custom_clientseed, data+4+2*4+16, 16);
    +            //memcpy(custom_serverseed, data+4+2*4, 16);
    +            //memcpy(custom_clientseed, data+4+2*4+16, 16);
    +            memcpy(custom_serverseed+0*4, data+4+1*4, 4);
    +            memcpy(custom_serverseed+1*4, data+4+4*4+1, 4);
    +            memcpy(custom_serverseed+2*4, data+4+3*4+1, 4);
    +            memcpy(custom_serverseed+3*4, data+4+7*4+1, 4);
    +            memcpy(custom_clientseed+0*4, data+4+5*4+1, 4);
    +            memcpy(custom_clientseed+1*4, data+4+6*4+1, 4);
    +            memcpy(custom_clientseed+2*4, data+4+0*4, 4);
    +            memcpy(custom_clientseed+3*4, data+4+8*4+1, 4);
                printf("Using custom seeds for forwarded connection\\n");
    
                init_decryption_state_server(&server_state, SESSIONKEY, custom_serverseed);
                init_decryption_state_client(&client_state, SESSIONKEY, custom_clientseed);
    +
    +            connection->forwarded = 0;
            }
            else
            {
    @@ -514,7 +790,8 @@ void decrypt()
                }
                update_decryption(nextState, participant->timeinfo.info[ti_counter].epoch_micro, data, datalen, db, decryptCallback);
            }
    -        freeDatabase(&db);
    +        if(!merge_files || (merge_files && !connection->forwarded))
    +            freeDatabase(&db);
    
            free_decryption_state(&server_state);
            free_decryption_state(&client_state);
    @@ -524,20 +801,28 @@ void decrypt()
    
    int main(int argc, char *argv[])
    {
    -    if(argc != 3)
    +    if(argc < 3)
        {
    -        printf("Usage: %s $dumpfile.cap $keyfile.txt\\n", argv[0]);
    +        printf("Usage: %s [-m] $dumpfile.cap $keyfile.txt\\n", argv[0]);
    +        printf("                [-m] merge output files\\n");
            return 1;
        }
        char* pcapFile = argv[1];
        char* keyFile = argv[2];
    +    if (!strcmp(argv[1], "-m"))
    +    {
    +        merge_files = 1;
    +        pcapFile = argv[2];
    +        keyFile = argv[3];
    +    }
    
        // maybe switched arguments?
        char* magicKeyfileEnd = "txt";
        if(strlen(keyFile) >= 3 && memcmp(keyFile+strlen(keyFile)-3, magicKeyfileEnd, 3))
        {
    -        pcapFile = argv[2];
    -        keyFile = argv[1];
    +        char *temp = pcapFile;
    +        pcapFile = keyFile;
    +        keyFile = temp;
        }
    
        readSessionkeyFile(keyFile);
    diff --git a/src/decrypter/sqliteout.c b/src/decrypter/sqliteout.c
    index cc75c05..3a67983 100644
    --- a/src/decrypter/sqliteout.c
    +++ b/src/decrypter/sqliteout.c
    @@ -60,6 +60,19 @@ void insertClientBuild(uint8_t *data, uint32_t data_len, sqlite3 *db)
        sprintf(buffer, insertFormat, *clientBuild);
        executeSql(db, buffer);
        free(buffer);
    +
    +    //FIXME make sniffitzt happy
    +    char sql[512];
    +    sprintf(sql, "insert into header values ('clientLang', '%s')", "");
    +    executeSql(db, sql);
    +    sprintf(sql, "insert into header values ('accountName', '%s')", (char*)(data+8));//FIXME
    +    executeSql(db, sql);
    +    sprintf(sql, "insert into header values ('realmName', '%s')", "");
    +    executeSql(db, sql);
    +    sprintf(sql, "insert into header values ('realmServer', '%s')", "");
    +    executeSql(db, sql);
    +    sprintf(sql, "insert into header values ('snifferVersion', '%s')", "");
    +    executeSql(db, sql);    
    }
    
    void insertPacket(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, uint32_t data_len, void* arg)
    @@ -83,7 +96,7 @@ void insertPacket(uint8_t s2c, uint64_t time, uint16_t opcode, uint8_t *data, ui
    
        free(queryBuffer);
    
    -    if(opcode == 493)
    +    if(opcode == 0x3000) //CMSG_AUTH_SESSION //493)
            insertClientBuild(data, data_len, db);
    }
    
    

  3. * What bug does the patch fix? What features does the patch add?

    Server crashes on Linux at startup since 9170

    * For which repository revision was the patch created?

    [9174]

    * Is there a thread in the bug report section or at lighthouse? If yes, please add a link to the thread.

    no.

    * Who has been writing this patch? Please include either forum user names or email addresses.

    daveh

    Patch:

    diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp
    index ce4d88c..8923d99 100644
    --- a/src/game/DBCStores.cpp
    +++ b/src/game/DBCStores.cpp
    @@ -186,7 +186,6 @@ static bool ReadDBCBuildFileText(const std::string& dbc_path, char const* locale
        {
            char buf[100];
            fread(buf,1,100-1,file);
    -        fclose(file);
    
            text = &buf[0];
            fclose(file);
    

  4. * What bug does the patch fix? What features does the patch add?

    Hunter/Warlock summon a hunter/summon pet first, then can't summon a mini pet.

    * For which repository revision was the patch created?

    [9162]

    * Is there a thread in the bug report section or at lighthouse? If yes, please add a link to the thread.

    No

    * Who has been writing this patch? Please include either forum user names or email addresses.

    daveh

    Patch:

    diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
    index b082a09..318c4ee 100644
    --- a/src/game/Spell.cpp
    +++ b/src/game/Spell.cpp
    @@ -4759,6 +4759,8 @@ SpellCastResult Spell::CheckCast(bool strict)
                                return SPELL_FAILED_ALREADY_HAVE_CHARM;
                        }
                    }
    +
    +                break;
                }
                // Not used for summon?
                case SPELL_EFFECT_SUMMON_PHANTASM:
    

  5. Just found SMSG_SPELL_START and SMSG_SPELL_GO send unknown spell ID (not in Spell.dbc) in a offi server, while doing quest As the Crow Flies by using item Stormcrow Amulet:

    1. When using item Stormcrow Amulet, it casts spell Stormcrow Amulet:

    SMSG_SPELL_START:

    xx xx xx xx xx xx xx item guid

    xx xx xx xx xx player pack guid

    02

    76 7B 00 00 spell ID Stormcrow Amulet

    12 00 00 00 00 00 00 00 00 00 00 00

    SMSG_SPELL_GO

    xx xx xx xx xx xx xx item guid

    xx xx xx xx xx player pack guid

    02

    76 7B 00 00 spellID Stormcrow Amulet

    10 01 00 00 flags

    72 F6 E5 DE timestamp

    01

    xx xx xx xx xx xx xx player guid

    00 02 00 00 00 00

    2. After sending spell Stormcrow Amulet, offi server sends some unknown spell IDs:

    (1).

    SMSG_SPELL_START

    xx xx xx xx xx player pack guid

    xx xx xx xx xx player pack guid

    00

    02 7C 00 00 it's supposed to be spell ID 0x7C02=31746, but it doesn't exist in DBC

    0B 00 00 00 00 00 00 00 00 00 00 00

    SMSG_SPELL_GO

    xx xx xx xx xx player pack guid

    xx xx xx xx xx player pack guid

    00

    02 7C 00 00 it's supposed to be spell ID 0x7C02=31746, but it doesn't exist in DBC

    09 01 00 00 flags

    6F F7 E5 DE timestamp

    01

    xx xx xx xx xx xx xx player guid

    00 02 00 00 00 00

    SMSG_AURA_UPDATE

    xx xx xx xx xx player pack guid

    05

    02 7C 00 00 it's supposed to be spell ID 0x7C02=31746, but it doesn't exist in DBC

    39 40 00 78 5D 02 00 78 5D 02 00 0C 00 00 00 00

    (2)

    SMSG_SPELL_START

    xx xx xx xx xx player pack guid

    xx xx xx xx xx player pack guid

    00

    1D 7C 00 00 it's supposed to be spell ID 0x7C1D=31773, but it doesn't exist in DBC

    0B 00 00 00 00 00 00 00 00 00 00 00

    SMSG_SPELL_GO

    xx xx xx xx xx player pack guid

    xx xx xx xx xx player pack guid

    00

    1D 7C 00 00 it's supposed to be spell ID 0x7C1D=31773, but it doesn't exist in DBC

    09 01 00 00

    E3 02 E6 DE

    01

    xx xx xx xx xx xx xx player guid

    00 02 00 00 00 00

    How does this mean?

  6. Same has been discussed from DB devs for a while, and it looks like there is indeed a int32 value. However, you will still find value==0 in cache. That means you must also handle 0 as a valid value and not change all currently having 0 to -1.

    You sure the cache data is from offi server? And it's clean?

    I don't see level 0 in my clean WDB cache, they all are -1.

    And a quick search in wowhead.com show no level 0 quests:

    http://www.wowhead.com/?quests&filter=minle=0;maxle=0

  7. Yes, last 2 lines heal 0, overheal 698. The screenshot was taken ~30 minutes ago, 3.2.2a version.

    Didn't see "heal 0, overheal 698" in 3.1.3.

    3.1.3 didn't send full overheal log to client, but 3.2.2a does.

    Sending full overheal log every 5s is really noisily, consider as a new 3.2.x blizz bug.

    So this problem is clear: mangos doesn't send overheal log to client for SPELL_AURA_OBS_MOD_HEALTH/SPELL_AURA_PERIODIC_HEAL.

    Anyway, the updated blizzlike patch:

    diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
    index 2cf57a8..18179ea 100644
    --- a/src/game/SpellAuras.cpp
    +++ b/src/game/SpellAuras.cpp
    @@ -6499,11 +6571,11 @@ void Aura::PeriodicTick()
                sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
                    GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
    
    -            SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, 0, 0, 0.0f, isCrit);
    -            m_target->SendPeriodicAuraLog(&pInfo);
    -
                int32 gain = m_target->ModifyHealth(pdamage);
    
    +            SpellPeriodicAuraLogInfo pInfo(this, pdamage, pdamage-gain, 0, 0, 0.0f, isCrit);
    +            m_target->SendPeriodicAuraLog(&pInfo);
    +
                // add HoTs to amount healed in bgs
                if( pCaster->GetTypeId() == TYPEID_PLAYER )
                    if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() )

  8. Exactly this one.

    Here is a screenie: http://filebeam.com/b8865dfd0a33886b2f73e28a59ec27ae.jpg (a big one)

    At the picture you can see Fel Armor buff, and multiple entries in combat log, with full heal, partial heal, and full overheal. All 3 of them are present.

    Sorry for Russian :/

    I see, the last 2 lines mean heal 0 point?

    And which version? But I don't see these logs in a 3.1.3 offi server, I'll confirm that again.

    Thank you:)

  9. Just found HIGHGUID_PLAYER is 0x0A00 in an offi server.

    It happens in all server? Does the HIGHGUID_PLAYER value changed?

    enum HighGuid
    {
       HIGHGUID_ITEM           = 0x4000,                       // blizz 4000
       HIGHGUID_CONTAINER      = 0x4000,                       // blizz 4000
    [b]    HIGHGUID_PLAYER         = 0x0000,                       // blizz 0000[/b]
       HIGHGUID_GAMEOBJECT     = 0xF110,                       // blizz F110
       HIGHGUID_TRANSPORT      = 0xF120,                       // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT)
       HIGHGUID_UNIT           = 0xF130,                       // blizz F130
       HIGHGUID_PET            = 0xF140,                       // blizz F140
       HIGHGUID_VEHICLE        = 0xF150,                       // blizz F550
       HIGHGUID_DYNAMICOBJECT  = 0xF100,                       // blizz F100
       HIGHGUID_CORPSE         = 0xF101,                       // blizz F100
       HIGHGUID_MO_TRANSPORT   = 0x1FC0,                       // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT)
    };
    

  10. Well, when I was writing my previous post on this topic I meant that overheal effect from HOTs is displayed in client on offy, but the health (actual or max) is not affected at all.

    That was implemented in some of early WotLK builds, after being removed in TBC.

    Oh, which spell btw?

    I'm trying fix the problem got too much noise from spell 28176

    http://www.wowhead.com/?spell=28176

  11. The reason why HoTs and some spells are allowed to still tick is because of items with spells like 64415 and 67356, which do trigger with overheals.

    ~Seline~

    This patch doesn't stop the tick, it just does nothing when triggered.

    My goal is to fix the bug that client still receive aura log when player has max health.

    How about this alt fix:

    diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
    index 2cf57a8..a08d0ae 100644
    --- a/src/game/SpellAuras.cpp
    +++ b/src/game/SpellAuras.cpp
    @@ -6499,11 +6571,14 @@ void Aura::PeriodicTick()
                sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
                    GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
    
    -            SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, 0, 0, 0.0f, isCrit);
    -            m_target->SendPeriodicAuraLog(&pInfo);
    -
                int32 gain = m_target->ModifyHealth(pdamage);
    
    +            if (gain)
    +            {
    +                SpellPeriodicAuraLogInfo pInfo(this, gain, 0, 0, 0, 0.0f, isCrit);
    +                m_target->SendPeriodicAuraLog(&pInfo);
    +            }
    +
                // add HoTs to amount healed in bgs
                if( pCaster->GetTypeId() == TYPEID_PLAYER )
                    if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() )

  12. What bug does the patch fix? What features does the patch add?

    When caster has aura SPELL_AURA_PERIODIC_HEAL or SPELL_AURA_OBS_MOD_HEALTH, he's healed again and again even he has reached max health.

    mangos doesn't send overheal log to client for SPELL_AURA_OBS_MOD_HEALTH/SPELL_AURA_PERIODIC_HEAL.

    For which repository revision was the patch created?

    8713

    Is there a thread in the bug report section or at lighthouse? If yes, please add a link to the thread.

    No.

    Who has been writing this patch? Please include either forum user names or email addresses.

    me

    [color="Silver"]diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
    index 75a166e..73a68d3 100644
    --- a/src/game/SpellAuras.cpp
    +++ b/src/game/SpellAuras.cpp
    @@ -6512,6 +6584,9 @@ void Aura::PeriodicTick()
                // This method can modify pdamage
                bool isCrit = IsCritFromAbilityAura(pCaster, pdamage);
    
    +            if (pdamage == 0 || (pdamage > 0 && (m_target->GetHealth() >= m_target->GetMaxHealth())))
    +                return;
    +
                sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
                    GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());[/color]
    

    Updated patch:

    diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
    index 2cf57a8..18179ea 100644
    --- a/src/game/SpellAuras.cpp
    +++ b/src/game/SpellAuras.cpp
    @@ -6499,11 +6571,11 @@ void Aura::PeriodicTick()
                sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
                    GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
    
    -            SpellPeriodicAuraLogInfo pInfo(this, pdamage, 0, 0, 0, 0.0f, isCrit);
    -            m_target->SendPeriodicAuraLog(&pInfo);
    -
                int32 gain = m_target->ModifyHealth(pdamage);
    
    +            SpellPeriodicAuraLogInfo pInfo(this, pdamage, pdamage-gain, 0, 0, 0.0f, isCrit);
    +            m_target->SendPeriodicAuraLog(&pInfo);
    +
                // add HoTs to amount healed in bgs
                if( pCaster->GetTypeId() == TYPEID_PLAYER )
                    if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() )
    

  13. What bug does the patch fix? What features does the patch add?

    Just find quest dynamic level also uses value -1, client also uses -1 to display quest color.

    This should fix dynamic level quest shows in gray in client quest log window.

    For which repository revision was the patch created?

    8734

    Is there a thread in the bug report section or at lighthouse? If yes, please add a link to the thread.

    No.

    Who has been writing this patch? Please include either forum user names or email addresses.

    me

    PS: Pls clean client cache first, then update DB.

    code:

    http://paste2.org/p/483939

    diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp
    index 422ad6f..6ecfe2c 100644
    --- a/src/game/GossipDef.cpp
    +++ b/src/game/GossipDef.cpp
    @@ -151,7 +172,7 @@ void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )
    
            data << uint32(questID);
            data << uint32(qItem.m_qIcon);
    -        data << uint32(pSession->GetPlayer()->GetQuestLevel(pQuest));
    +        data << int32(pQuest->GetQuestLevel());
            std::string Title = pQuest->GetTitle();
    
            int loc_idx = pSession->GetSessionDbLocaleIndex();
    @@ -400,7 +421,7 @@ void PlayerMenu::SendQuestGiverQuestList( QEmote eEmote, const std::string& Titl
    
            data << uint32(questID);
            data << uint32(qmi.m_qIcon);
    -        data << uint32(pSession->GetPlayer()->GetQuestLevel(pQuest));
    +        data << int32(pQuest->GetQuestLevel());
            data << title;
        }
        pSession->SendPacket( &data );
    @@ -547,7 +568,7 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )
    
        data << uint32(pQuest->GetQuestId());                   // quest id
        data << uint32(pQuest->GetQuestMethod());               // Accepted values: 0, 1 or 2. 0==IsAutoComplete() (skip objectives/details)
    -    data << uint32(pQuest->GetQuestLevel());                // may be 0, static data, in other cases must be used dynamic level: Player::GetQuestLevel
    +    data << int32(pQuest->GetQuestLevel());                 // may be 0, -1, static data, in other cases must be used dynamic level: Player::GetQuestOrPlayerLevel
        data << uint32(pQuest->GetZoneOrSort());                // zone or sort to display in quest log
    
        data << uint32(pQuest->GetType());                      // quest type
    diff --git a/src/game/Player.cpp b/src/game/Player.cpp
    index c8e9ca2..2445d0f 100644
    --- a/src/game/Player.cpp
    +++ b/src/game/Player.cpp
    @@ -5952,7 +5945,7 @@ void Player::RewardReputation(Quest const *pQuest)
        {
            if(pQuest->RewRepFaction[i] && pQuest->RewRepValue[i] )
            {
    -            int32 rep = CalculateReputationGain(GetQuestLevel(pQuest), pQuest->RewRepValue[i], pQuest->RewRepFaction[i], true);
    +            int32 rep = CalculateReputationGain(GetQuestOrPlayerLevel(pQuest), pQuest->RewRepValue[i], pQuest->RewRepFaction[i], true);
                FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i]);
                if(factionEntry)
                    GetReputationMgr().ModifyReputation(factionEntry, rep);
    diff --git a/src/game/Player.h b/src/game/Player.h
    index 4c9325d..d571ea9 100644
    --- a/src/game/Player.h
    +++ b/src/game/Player.h
    @@ -1280,7 +1280,7 @@ class MANGOS_DLL_SPEC Player : public Unit
            /***                    QUEST SYSTEM                   ***/
            /*********************************************************/
    
    -        uint32 GetQuestLevel( Quest const* pQuest ) const { return pQuest && pQuest->GetQuestLevel() ? pQuest->GetQuestLevel() : getLevel(); }
    +        uint32 GetQuestOrPlayerLevel( Quest const* pQuest ) const { return pQuest && (pQuest->GetQuestLevel()>0) ? pQuest->GetQuestLevel() : getLevel(); }
    
            void PrepareQuestMenu( uint64 guid );
            void SendPreparedQuest( uint64 guid );
    diff --git a/src/game/QuestDef.cpp b/src/game/QuestDef.cpp
    index 5a53e52..c469537 100644
    --- a/src/game/QuestDef.cpp
    +++ b/src/game/QuestDef.cpp
    @@ -27,7 +27,7 @@ Quest::Quest(Field * questRecord)
        ZoneOrSort = questRecord[2].GetInt32();
        SkillOrClass = questRecord[3].GetInt32();
        MinLevel = questRecord[4].GetUInt32();
    -    QuestLevel = questRecord[5].GetUInt32();
    +    QuestLevel = questRecord[5].GetInt32();
        Type = questRecord[6].GetUInt32();
        RequiredRaces = questRecord[7].GetUInt32();
        RequiredSkillValue = questRecord[8].GetUInt32();
    @@ -169,7 +169,7 @@ uint32 Quest::XPValue( Player *pPlayer ) const
            if( RewMoneyMaxLevel > 0 )
            {
                uint32 pLevel = pPlayer->getLevel();
    -            uint32 qLevel = QuestLevel;
    +            uint32 qLevel = QuestLevel > 0 ? QuestLevel : 0;
                float fullxp = 0;
                if (qLevel >= 15)
                    fullxp = RewMoneyMaxLevel / 6.0f;
    diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h
    index 546a5dc..54e95a4 100644
    --- a/src/game/QuestDef.h
    +++ b/src/game/QuestDef.h
    @@ -181,7 +181,7 @@ class Quest
            int32  GetZoneOrSort() const { return ZoneOrSort; }
            int32  GetSkillOrClass() const { return SkillOrClass; }
            uint32 GetMinLevel() const { return MinLevel; }
    -        uint32 GetQuestLevel() const { return QuestLevel; }
    +        int32  GetQuestLevel() const { return QuestLevel; }
            uint32 GetType() const { return Type; }
            uint32 GetRequiredRaces() const { return RequiredRaces; }
            uint32 GetRequiredSkillValue() const { return RequiredSkillValue; }
    @@ -274,7 +274,7 @@ class Quest
            int32  ZoneOrSort;
            int32  SkillOrClass;
            uint32 MinLevel;
    -        uint32 QuestLevel;
    +        int32  QuestLevel;
            uint32 Type;
            uint32 RequiredRaces;
            uint32 RequiredSkillValue;
    diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp
    index a93b658..1ecda8a 100644
    --- a/src/game/QuestHandler.cpp
    +++ b/src/game/QuestHandler.cpp
    @@ -606,7 +606,7 @@ uint32 WorldSession::getDialogStatus(Player *pPlayer, Object* questgiver, uint32
                    {
                        if ( pQuest->IsAutoComplete() || (pQuest->IsRepeatable() && pPlayer->getQuestStatusMap()[quest_id].m_rewarded))
                            result2 = DIALOG_STATUS_REWARD_REP;
    -                    else if (pPlayer->getLevel() <= pPlayer->GetQuestLevel(pQuest) + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF) )
    +                    else if (pPlayer->getLevel() <= pPlayer->GetQuestOrPlayerLevel(pQuest) + sWorld.getConfig(CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF) )
                        {
                            if (pQuest->HasFlag(QUEST_FLAGS_DAILY))
                                result2 = DIALOG_STATUS_AVAILABLE_REP;

    SQL:

    ALTER TABLE quest_template
     CHANGE COLUMN QuestLevel QuestLevel smallint(6) NOT NULL DEFAULT 0;
    

  14. For some reason, I need clone mangos over http, but get errors:

    $ git clone http://github.com/mangos/mangos.git mangos

    Initialized empty Git repository in /home/projects/mangos/.git/

    got f0b906b591377f912202e4d21fb02313877d19a0

    walk f0b906b591377f912202e4d21fb02313877d19a0

    got 264d515922b5a630271afb0cfb3d2556d3073995

    walk 264d515922b5a630271afb0cfb3d2556d3073995

    got 75437a37a958a8a93c904206d66c22c0d38ae965

    walk 75437a37a958a8a93c904206d66c22c0d38ae965

    Getting alternates list for http://github.com/mangos/mangos.git

    Getting pack list for http://github.com/mangos/mangos.git

    Getting index for pack 432f484bded1042e3c71bdce136de34f68335a9e

    Getting index for pack ecd20e82c12a18bee7bd2eb2777bc08351a48be8

    Getting index for pack 2c4d52023faeb0c597dde9f384ba0f5ac960c3b4

    Getting index for pack 6ec7f1c92892eff58575170fd412ed7a391b0e4c

    Getting index for pack 5800e6322fedff6b2d2acf0e8f2aa1f661c98248

    Getting pack 432f484bded1042e3c71bdce136de34f68335a9e

    which contains 7367b1e2d9179b9969979c10f8fa739bc126669a

    error: Unable to get pack file http://github.com/mangos/mangos.git/objects/pack/pack-432f484bded1042e3c71bdce136de34f68335a9e.pack

    The requested URL returned error: 502

    error: Unable to find 7367b1e2d9179b9969979c10f8fa739bc126669a under http://github.com/mangos/mangos.git

    Cannot obtain needed object 7367b1e2d9179b9969979c10f8fa739bc126669a

    while processing commit 75437a37a958a8a93c904206d66c22c0d38ae965.

    fatal: Fetch failed.

    $ wget -c http://github.com/mangos/mangos.git/objects/pack/pack-432f484bded1042e3c71bdce136de34f68335a9e.pack

    --02:44:00-- http://github.com/mangos/mangos.git/objects/pack/pack-432f484bded1042e3c71bdce136de34f68335a9e.pack

    Resolving github.com... 207.97.227.239

    Connecting to github.com|207.97.227.239|:80... connected.

    HTTP request sent, awaiting response... 502 Bad Gateway

    02:44:05 ERROR 502: Bad Gateway.

    Is it gitbub.com's problem?

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use