Slice Source

From libopenmetaverse - libomv - Developer Wiki

Jump to: navigation, search

NOTE: The Information on this page may be out of date.


Slice will dump the Second Life cache contents to your hard drive. Useful for seeing how data looks after going through SL's filters, and how similar the locally stored information is to what is transferred over the wire.

Note: Viewing images extracted by Slice requires that a JPEG2000-capable image viewer is installed, like ACDSee or IrfranView.

Compiling with VS2005

Edit your project settings to use ANSI characters instead of UNICODE characters. UNICODE characters are the default in a new project in VS2005, but it's quite easy to change that.


// slice.c : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <windows.h>
#include <time.h>
#include <process.h>
#include <stdlib.h>
 
#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)),SWAPWORD(LOWORD(x)))
 
#define UUID_NULL "00000000-0000-0000-0000-000000000000"
 
#pragma pack(1)
 
char szTargetUUID[] = UUID_NULL;
 
typedef struct
{
    DWORD dwOffset;
    WORD wMagic;
    WORD wFlags;
    time_t ltTime;
    BYTE bUUID[16];
    WORD wType;
    DWORD dwSize;
} CACHE_INDEX;
 
typedef struct
{
    WORD wSize;
    LPBYTE lpData;
} J2C_BLOCK;
 
int slice(char *lpszPathIndex, char *lpszPathData);
 
int main(int argc, char* argv[])
{
    char szPathAppData[MAX_PATH];
    char szPathSearch[MAX_PATH];
    char szPathIndex[MAX_PATH];
    char szPathData[MAX_PATH];
    HANDLE hSearch;
    WIN32_FIND_DATA wfdSearch;
 
    if (argc > 1)
    {
        printf("Searching for UUID %s\n", argv[1]);
        strncpy(szTargetUUID, argv[1], sizeof(szTargetUUID));
    }
 
    sprintf(szPathIndex, "c:\\program files\\secondlife\\app_settings\\static_index.db2");
    sprintf(szPathData, "c:\\program files\\secondlife\\app_settings\\static_data.db2");
 
    printf("Found index at %s\n", szPathIndex);
 
    slice(szPathIndex, szPathData);
 
    if (!GetEnvironmentVariable("APPDATA", szPathAppData, sizeof(szPathAppData)))
    {
        printf("Couldn't find application data folder path\n");
        return -1;
    }
 
    sprintf(szPathSearch, "%s\\secondlife\\cache\\index.db2.x.*", szPathAppData);
 
    hSearch = FindFirstFile(szPathSearch, &wfdSearch);
 
    if (hSearch != INVALID_HANDLE_VALUE)
    {
        do
        {
            char *lpszSalt = NULL;
 
            lpszSalt = strrchr(wfdSearch.cFileName, '.');
 
            if (lpszSalt)
            {
                sprintf(szPathIndex, "%s\\secondlife\\cache\\index.db2.x%s", szPathAppData, lpszSalt);
                sprintf(szPathData, "%s\\secondlife\\cache\\data.db2.x%s", szPathAppData, lpszSalt);
 
                printf("Found index at %s\n", szPathIndex);
 
                slice(szPathIndex, szPathData);
            }
 
        }
        while (FindNextFile(hSearch, &wfdSearch));
 
        FindClose(hSearch);
    }
 
    return 0;
}
 
int slice(char *lpszPathIndex, char *lpszPathData)
{
    CACHE_INDEX index;
    int nMode = 0;
    int nImage = 0;
    int nRead = 0;
    FILE *fpIndex = NULL;
    FILE *fpData = NULL;
    FILE *fpWrite = NULL;
 
    fpIndex = fopen(lpszPathIndex, "rb");
    fpData = fopen(lpszPathData, "rb");
 
    if (fpIndex && fpData)
    {
        while (nRead = fread(&index, 1, sizeof(CACHE_INDEX), fpIndex))
        {
            char szUUID[37];
           
            _snprintf(szUUID, sizeof(szUUID),
                "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
                index.bUUID[0], index.bUUID[1], index.bUUID[2], index.bUUID[3],
                index.bUUID[4], index.bUUID[5], index.bUUID[6], index.bUUID[7],
                index.bUUID[8], index.bUUID[9], index.bUUID[10], index.bUUID[11],
                index.bUUID[12], index.bUUID[13], index.bUUID[14], index.bUUID[15]);
 
            if (!strncmp(szTargetUUID, UUID_NULL, sizeof(szTargetUUID)) || !strncmp(szTargetUUID, szUUID, sizeof(szTargetUUID)))
            {
                if (index.dwOffset && index.dwSize)
                {
                    void* vpBuffer = malloc(index.dwSize);
                    LPBYTE lpBuffer = (LPBYTE) vpBuffer;
                    fseek(fpData, index.dwOffset, SEEK_SET);
 
                    if (fread(lpBuffer, 1, index.dwSize, fpData))
                    {
                        char szFileName[MAX_PATH];
       
                        if (index.wType == 0x0000)
                            _snprintf(szFileName, sizeof(szFileName), "%s.j2c", szUUID);
                        else if (index.wType == 0x0001)
                            _snprintf(szFileName, sizeof(szFileName), "%s.ogg", szUUID);
                        else if (index.wType == 0x0002)
                            _snprintf(szFileName, sizeof(szFileName), "%s.callcard", szUUID);
                        else if (index.wType == 0x0003)
                            _snprintf(szFileName, sizeof(szFileName), "%s.landmark", szUUID);
                        else if (index.wType == 0x0004)
                            _snprintf(szFileName, sizeof(szFileName), "%s.lsl", szUUID);
                        else if (index.wType == 0x0005)
                            _snprintf(szFileName, sizeof(szFileName), "%s.clothing", szUUID);
                        else if (index.wType == 0x0006)
                            _snprintf(szFileName, sizeof(szFileName), "%s.object", szUUID);
                        else if (index.wType == 0x0007)
                            _snprintf(szFileName, sizeof(szFileName), "%s.notecard", szUUID);
                        else if (index.wType == 0x0008)
                            _snprintf(szFileName, sizeof(szFileName), "%s.category", szUUID);
                        else if (index.wType == 0x0009)
                            _snprintf(szFileName, sizeof(szFileName), "%s.category", szUUID);
                        else if (index.wType == 0x000a)
                            _snprintf(szFileName, sizeof(szFileName), "%s.lsl", szUUID);
                        else if (index.wType == 0x000b)
                            _snprintf(szFileName, sizeof(szFileName), "%s.lso", szUUID);
                        else if (index.wType == 0x000c)
                            _snprintf(szFileName, sizeof(szFileName), "%s.tga", szUUID);
                        else if (index.wType == 0x000d)
                            _snprintf(szFileName, sizeof(szFileName), "%s.bodypart", szUUID);
                        else if (index.wType == 0x000e)
                            _snprintf(szFileName, sizeof(szFileName), "%s.trash", szUUID);
                        else if (index.wType == 0x000f)
                            _snprintf(szFileName, sizeof(szFileName), "%s.snapshot", szUUID);
                        else if (index.wType == 0x0010)
                            _snprintf(szFileName, sizeof(szFileName), "%s.lstndfnd", szUUID);
                        else if (index.wType == 0x0011)
                            _snprintf(szFileName, sizeof(szFileName), "%s.wav", szUUID);
                        else if (index.wType == 0x0012)
                            _snprintf(szFileName, sizeof(szFileName), "%s.tga", szUUID);
                        else if (index.wType == 0x0013)
                            _snprintf(szFileName, sizeof(szFileName), "%s.jpg", szUUID);
                        else if (index.wType == 0x0014)
                            _snprintf(szFileName, sizeof(szFileName), "%s.animatn", szUUID);
                        else if (index.wType == 0x0015)
                            _snprintf(szFileName, sizeof(szFileName), "%s.gesture", szUUID);
                        else if (index.wType == 0x0016)
                            _snprintf(szFileName, sizeof(szFileName), "%s.simstate", szUUID);
                        else
                            _snprintf(szFileName, sizeof(szFileName), "%s.tmp", szUUID);
 
                        printf("Exporting %s\n", szFileName);
                        DWORD dwWrite = index.dwSize;
 
                        if (index.wType == 0x0000)
                        {
                            BYTE bOwnerUUID[16];
                            char szOwnerUUID[37];
                            WORD wBlockCount = 0;
                            WORD wBlocksRead = 0;
                            DWORD dwFileSize = 0;
 
                            lpBuffer += 5;
                            dwWrite -= 5;
 
                            memcpy(&bOwnerUUID, lpBuffer, sizeof(bOwnerUUID));
                            lpBuffer += sizeof(bOwnerUUID);
                            dwWrite -= sizeof(bOwnerUUID);
 
                            _snprintf(szOwnerUUID, sizeof(szOwnerUUID),
                                "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
                                bOwnerUUID[0], bOwnerUUID[1], bOwnerUUID[2], bOwnerUUID[3],
                                bOwnerUUID[4], bOwnerUUID[5], bOwnerUUID[6], bOwnerUUID[7],
                                bOwnerUUID[8], bOwnerUUID[9], bOwnerUUID[10], bOwnerUUID[11],
                                bOwnerUUID[12], bOwnerUUID[13], bOwnerUUID[14], bOwnerUUID[15]);
 
                            memcpy(&wBlockCount, lpBuffer, sizeof(wBlockCount));
                            lpBuffer += sizeof(wBlockCount);
                            dwWrite -= sizeof(wBlockCount);
 
                            memcpy(&dwFileSize, lpBuffer, sizeof(dwFileSize));
                            lpBuffer += sizeof(dwFileSize);
                            dwWrite -= sizeof(dwFileSize);
 
                            if (wBlockCount)
                            {
                                J2C_BLOCK *lpj2cbData = calloc( sizeof(J2C_BLOCK), wBlockCount);
                                if (lpj2cbData)
                                {
                                    while (dwWrite > 0)
                                    {
                                        WORD wBlock = 0;
                                        WORD wBlockSize = 0;
                                       
                                        memcpy(&wBlock, lpBuffer, sizeof(wBlock));
                                        lpBuffer += sizeof(wBlock);
                                        dwWrite -= sizeof(wBlock);
 
                                        memcpy(&wBlockSize, lpBuffer, sizeof(wBlockSize));
                                        lpBuffer += sizeof(wBlockSize);
                                        dwWrite -= sizeof(wBlockSize);
 
                                        //printf("Block: %hu, %hu\n", wBlock, wBlockSize);
                                       
                                        lpj2cbData[wBlock].wSize = wBlockSize;
                                        lpj2cbData[wBlock].lpData = malloc(wBlockSize);
 
                                        if (lpj2cbData[wBlock].lpData)
                                        {
                                            memcpy(lpj2cbData[wBlock].lpData, lpBuffer, wBlockSize);
                                        }
 
                                        lpBuffer += wBlockSize;
                                        dwWrite -= wBlockSize;
 
                                        wBlocksRead++;
                                    }
 
                                    if (wBlocksRead == wBlockCount)
                                    {
                                        fpWrite = fopen(szFileName, "wb");
 
                                        if (fpWrite)
                                        {
                                            for (WORD i = 0; i < wBlockCount; i++)
                                            {
                                                if (lpj2cbData[i].lpData)
                                                {
                                                    fwrite(lpj2cbData[i].lpData, 1, lpj2cbData[i].wSize, fpWrite);
                                                }
                                            }
       
                                            fclose(fpWrite);
 
                                            char szCmd[MAX_PATH];
                                               
                                            sprintf(szCmd, "c:\\progra~1\\irfanview\\i_view32.exe %s    /convert=%s.jpg /silent", szFileName, szUUID);
                                            system(szCmd);
                                           
                                            //unlink(szFileName);
                                        }
                                    }
 
                                    for (WORD i = 0; i < wBlockCount; i++)
                                    {
                                        if (lpj2cbData[i].lpData)
                                        {
                                            free(lpj2cbData[i].lpData);
                                            lpj2cbData[i].lpData = NULL;
                                        }
                                    }
 
                                    free(lpj2cbData);
                                }
                            }
                        }
                        else
                        {
                            fpWrite = fopen(szFileName, "wb");
 
                            if (fpWrite)
                            {
                                fwrite(lpBuffer, 1, dwWrite, fpWrite);
                                fclose(fpWrite);
 
                                char szCmd[MAX_PATH];
 
                                sprintf(szCmd, "c:\\progra~1\\irfanview\\i_view32.exe %s    /convert=%s.jpg /silent", szFileName, szUUID);
                                system(szCmd);
 
                                //unlink(szFileName);
                            }
                        }
                       
                        fpWrite = NULL;
                    }
                    free(vpBuffer);
                }
            }
 
            nImage++;
        }
 
        fclose(fpIndex);
        fclose(fpData);
    }
 
    return 0;
}