コード例 #1
0
void cb_downloadStart(FileServer_Private& client)
{
    START_REPLY(e_FileToCli_FileDownloadReply);

    // Trans ID
    client.m_buffer.write<uint32_t>(DS::RecvValue<uint32_t>(client.m_sock));

    // Download filename
    char16_t buffer[260];
    DS::RecvBuffer(client.m_sock, buffer, sizeof(buffer));
    buffer[259] = 0;
    DS::String filename = DS::String::FromUtf16(buffer);

    // Build ID
    uint32_t buildId = DS::RecvValue<uint32_t>(client.m_sock);
    if (buildId && buildId != DS::Settings::BuildId()) {
        fprintf(stderr, "[File] Wrong Build ID from %s: %d\n",
                DS::SockIpAddress(client.m_sock).c_str(), buildId);
        DS::CloseSock(client.m_sock);
        return;
    }

    // Ensure filename is jailed to our data path
    if (filename.find("..") != -1) {
        client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound);
        client.m_buffer.write<uint32_t>(0);     // Reader ID
        client.m_buffer.write<uint32_t>(0);     // File size
        client.m_buffer.write<uint32_t>(0);     // Data packet size
        SEND_REPLY();
        return;
    }
    filename.replace("\\", "/");

    filename = DS::Settings::FileRoot() + filename;
    int fd = open(filename.c_str(), O_RDONLY);

    if (fd < 0) {
        fprintf(stderr, "[File] Could not open file %s\n[File] Requested by %s\n",
                filename.c_str(), DS::SockIpAddress(client.m_sock).c_str());
        client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound);
        client.m_buffer.write<uint32_t>(0);     // Reader ID
        client.m_buffer.write<uint32_t>(0);     // File size
        client.m_buffer.write<uint32_t>(0);     // Data packet size
        SEND_REPLY();
        return;
    }

    std::unique_ptr<FileRequest> req(new FileRequest(fd));
    client.m_buffer.write<uint32_t>(DS::e_NetSuccess);
    client.m_buffer.write<uint32_t>(++client.m_readerId);
    client.m_buffer.write<uint32_t>(req->m_size);

    FileRequest::chunk_t c = req->nextChunk();
    client.m_buffer.write<uint32_t>(std::get<1>(c));
    SEND_FD_REPLY(req->m_fd, req->m_pos, std::get<1>(c));
    if (!std::get<0>(c)) {
        client.m_downloads[client.m_readerId] = std::move(req);
    }
}
コード例 #2
0
ファイル: FileServer.cpp プロジェクト: Deledrius/dirtsand
void cb_manifest(FileServer_Private& client)
{
    START_REPLY(e_FileToCli_ManifestReply);

    // Trans ID
    client.m_buffer.write<uint32_t>(DS::RecvValue<uint32_t>(client.m_sock));

    // Manifest name
    chr16_t mfsbuf[260];
    DS::RecvBuffer(client.m_sock, mfsbuf, 260 * sizeof(chr16_t));
    mfsbuf[259] = 0;
    DS::String mfsname = DS::String::FromUtf16(mfsbuf);

    // Build ID
    uint32_t buildId = DS::RecvValue<uint32_t>(client.m_sock);
    if (buildId && buildId != CLIENT_BUILD_ID) {
        fprintf(stderr, "[File] Wrong Build ID from %s: %d\n",
                DS::SockIpAddress(client.m_sock).c_str(), buildId);
        DS::CloseSock(client.m_sock);
        return;
    }

    // Manifest may not have any path characters
    if (mfsname.find(".") != -1 || mfsname.find("/") != -1
        || mfsname.find("\\") != -1 || mfsname.find(":") != -1) {
        fprintf(stderr, "[File] Invalid manifest request from %s: %s\n",
                DS::SockIpAddress(client.m_sock).c_str(), mfsname.c_str());
        client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound);
        client.m_buffer.write<uint32_t>(0);     // Reader ID
        client.m_buffer.write<uint32_t>(0);     // File count
        client.m_buffer.write<uint32_t>(0);     // Data packet size
        SEND_REPLY();
        return;
    }

    DS::FileManifest manifest;
    mfsname = DS::Settings::FileRoot() + mfsname + ".mfs";
    DS::NetResultCode result = manifest.loadManifest(mfsname.c_str());
    client.m_buffer.write<uint32_t>(result);

    if (result != DS::e_NetSuccess) {
        fprintf(stderr, "[File] %s requested invalid manifest %s\n",
                DS::SockIpAddress(client.m_sock).c_str(), mfsname.c_str());
        client.m_buffer.write<uint32_t>(0);     // Reader ID
        client.m_buffer.write<uint32_t>(0);     // File count
        client.m_buffer.write<uint32_t>(0);     // Data packet size
    } else {
        client.m_buffer.write<uint32_t>(++client.m_readerId);
        client.m_buffer.write<uint32_t>(manifest.fileCount());
        uint32_t sizeLocation = client.m_buffer.tell();
        client.m_buffer.write<uint32_t>(0);
        uint32_t dataSize = manifest.encodeToStream(&client.m_buffer);
        client.m_buffer.seek(sizeLocation, SEEK_SET);
        client.m_buffer.write<uint32_t>(dataSize);
    }

    SEND_REPLY();
}
コード例 #3
0
void cb_downloadStart(AuthServer_Private& client)
{
    START_REPLY(e_AuthToCli_FileDownloadChunk);

    // Trans ID
    uint32_t transId = DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt);
    client.m_buffer.write<uint32_t>(transId);

    // Download filename
    DS::String filename = DS::CryptRecvString(client.m_sock, client.m_crypt);

    // Ensure filename is jailed to our data path
    if (filename.find("..") != -1) {
        client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound);
        client.m_buffer.write<uint32_t>(0);     // File size
        client.m_buffer.write<uint32_t>(0);     // Chunk offset
        client.m_buffer.write<uint32_t>(0);     // Data packet size
        SEND_REPLY();
        return;
    }
    filename.replace("\\", "/");

    filename = DS::Settings::AuthRoot() + filename;
    DS::FileStream* stream = new DS::FileStream();
    try {
        stream->open(filename.c_str(), "rb");
    } catch (const DS::FileIOException& ex) {
        fprintf(stderr, "[Auth] Could not open file %s: %s\n[Auth] Requested by %s\n",
                filename.c_str(), ex.what(), DS::SockIpAddress(client.m_sock).c_str());
        client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound);
        client.m_buffer.write<uint32_t>(0);     // File size
        client.m_buffer.write<uint32_t>(0);     // Chunk offset
        client.m_buffer.write<uint32_t>(0);     // Data packet size
        SEND_REPLY();
        delete stream;
        return;
    }

    client.m_buffer.write<uint32_t>(DS::e_NetSuccess);
    client.m_buffer.write<uint32_t>(stream->size());
    client.m_buffer.write<uint32_t>(stream->tell());

    uint8_t data[CHUNK_SIZE];
    if (stream->size() > CHUNK_SIZE) {
        client.m_buffer.write<uint32_t>(CHUNK_SIZE);
        stream->readBytes(data, CHUNK_SIZE);
        client.m_buffer.writeBytes(data, CHUNK_SIZE);
        client.m_downloads[transId] = stream;
    } else {
        client.m_buffer.write<uint32_t>(stream->size());
        stream->readBytes(data, stream->size());
        client.m_buffer.writeBytes(data, stream->size());
        delete stream;
    }

    SEND_REPLY();
}
コード例 #4
0
ファイル: Texture.cpp プロジェクト: Majchrzak/Drops
bool ds::Texture::Load( const ds::String& Filename, DWORD Type )
{
	Release( );

	if( !ds::Render::GetDevice( ) )
	{
		dsPushMessage( ErrD3DeviceNotCreated );
		return false;
	}

	D3DX10_IMAGE_LOAD_INFO l_Info = D3DX10_IMAGE_LOAD_INFO( );
	CreateInfo( Type, l_Info );

	ID3D10Resource* l_Resource = nullptr;

	HRESULT l_Result = D3DX10CreateTextureFromFile( 
		ds::Render::Device,
		Filename.c_str( ),
		&l_Info,
		nullptr,
		&l_Resource,
		nullptr
		);
	
	if( FAILED( l_Result ) )
	{
		dsPushError( ErrTextureLoad, Filename.c_str( ) );
		return false;
	}

	l_Resource->QueryInterface( __uuidof( ID3D10Texture2D ), ( LPVOID* )&Texture2D );
	l_Resource->Release( );

	D3D10_TEXTURE2D_DESC l_Desc;
	Texture2D->GetDesc( &l_Desc );

	Size = ds::Size( l_Desc.Width, l_Desc.Height );

	if( Type & RenderTarget )
	{
		D3D10_RENDER_TARGET_VIEW_DESC l_Target;
		l_Target.Format = l_Info.Format;
		l_Target.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D;
		l_Target.Texture2D.MipSlice = 0;

		ds::Render::Device->CreateRenderTargetView( Texture2D, &l_Target, &TargetView );
	}

	ShaderView[ 0 ] = CreateResourceView( this );
	return true;
}
コード例 #5
0
ファイル: Audio.cpp プロジェクト: Majchrzak/Drops
bool ds::Audio::Create( const ds::String& Filename )
{
	if( Library )
		Release( );

	Library = LoadLibrary( Filename.c_str( ) );

	if( !Library )
		return false;

	BASS_Init = ( BOOL (__stdcall *)( int, DWORD, DWORD, HWND, const GUID* ) )GetProcAddress( Library, "BASS_Init" );
	BASS_Pause = ( BOOL (__stdcall *) ( ) )GetProcAddress( Library, "BASS_Pause" );
	BASS_Stop = ( BOOL (__stdcall *) ( ) )GetProcAddress( Library, "BASS_Stop" );
	BASS_Start = ( BOOL (__stdcall *) ( ) )GetProcAddress( Library, "BASS_Start" );
	BASS_SetVolume = ( BOOL (__stdcall *) ( float ) )GetProcAddress( Library, "BASS_SetVolume" );
	BASS_Free = ( BOOL (__stdcall *) ( ) )GetProcAddress( Library, "BASS_Free" );
	BASS_StreamFree = ( BOOL (__stdcall *) ( DWORD ) )GetProcAddress( Library, "BASS_StreamFree" );
	BASS_SampleFree = ( BOOL (__stdcall *) ( DWORD ) )GetProcAddress( Library, "BASS_SampleFree" );
	BASS_ChannelPause = ( BOOL (__stdcall *)( DWORD ) )GetProcAddress( Library, "BASS_ChannelPause" );
	BASS_ChannelStop = ( BOOL (__stdcall *)( DWORD ) )GetProcAddress( Library, "BASS_ChannelStop" );
	BASS_ChannelPlay = ( BOOL (__stdcall *)( DWORD, BOOL ) )GetProcAddress( Library, "BASS_ChannelPlay" );
	BASS_ChannelSetAttribute = ( BOOL (__stdcall *)( DWORD, DWORD, float ) )GetProcAddress( Library, "BASS_ChannelSetAttribute" );
	BASS_ChannelIsActive = ( DWORD (__stdcall *)( DWORD ) )GetProcAddress( Library, "BASS_ChannelIsActive" );
	BASS_StreamCreateFile = ( DWORD (__stdcall *)( BOOL, const void*, QWORD, QWORD, DWORD ) )GetProcAddress( Library, "BASS_StreamCreateFile" );
	BASS_SampleLoad = ( DWORD (__stdcall *)( BOOL, const void*, QWORD, DWORD, DWORD, DWORD ) )GetProcAddress( Library, "BASS_SampleLoad" );
	BASS_SampleGetChannel = ( DWORD (__stdcall *)( DWORD, BOOL ) )GetProcAddress( Library, "BASS_SampleGetChannel" );

	BASS_Init( -1, 44100, 0, ds::Render::GetHandle( ), nullptr );

	return true;
}
コード例 #6
0
ファイル: AuthVault.cpp プロジェクト: Hoikas/dirtsand
DS::Blob gen_default_sdl(const DS::String& filename)
{
    SDL::StateDescriptor* desc = SDL::DescriptorDb::FindDescriptor(filename, -1);
    if (!desc) {
        fprintf(stderr, "[Vault] Warning: Could not find SDL descriptor for %s\n",
                filename.c_str());
        return DS::Blob();
    }

    SDL::State state(desc);
    return state.toBlob();
}
コード例 #7
0
ファイル: Texture.cpp プロジェクト: Majchrzak/Drops
bool ds::Texture::Save( const ds::String& Filename, ds::Texture::FileFormat Format ) const
{
	if( !Texture2D )
	{
		dsPushMessage( ErrTextureIsEmpty );
		return false;
	}

	HRESULT l_Result = D3DX10SaveTextureToFileA( 
		Texture2D,
		( D3DX10_IMAGE_FILE_FORMAT )Format, 
		Filename.c_str( )
		);
	
	if( FAILED( l_Result ) )
	{
		dsPushError( ErrTextureSave, Filename.c_str( ) );
		return false;
	}

	return true;
}
コード例 #8
0
ファイル: AuthVault.cpp プロジェクト: TheEggman/dirtsand
DS::Blob gen_default_sdl(const DS::String& filename)
{
    SDL::StateDescriptor* desc = SDL::DescriptorDb::FindDescriptor(filename, -1);
    if (!desc) {
        fprintf(stderr, "[Vault] Warning: Could not find SDL descriptor for %s\n",
                filename.c_str());
        return DS::Blob();
    }

    SDL::State state(desc);
    DS::BufferStream stream;
    state.write(&stream);
    return DS::Blob(stream.buffer(), stream.size());
}
コード例 #9
0
ファイル: GameServer.cpp プロジェクト: Deledrius/dirtsand
void DS::GameServer_Init()
{
    dirent** dirls;
    int count = scandir(DS::Settings::AgePath(), &dirls, &sel_age, &alphasort);
    if (count < 0) {
        fprintf(stderr, "[Game] Error reading age descriptors: %s\n", strerror(errno));
    } else if (count == 0) {
        fprintf(stderr, "[Game] Warning: No age descriptors found!\n");
        free(dirls);
    } else {
        for (int i=0; i<count; ++i) {
            DS::String filename = DS::String::Format("%s/%s", DS::Settings::AgePath(), dirls[i]->d_name);
            FILE* ageFile = fopen(filename.c_str(), "r");
            if (ageFile) {
                char magic[12];
                fread(magic, 1, 12, ageFile);
                if (memcmp(magic, "whatdoyousee", 12) == 0 || memcmp(magic, "notthedroids", 12) == 0
                    || memcmp(magic, "BriceIsSmart", 12) == 0) {
                    fprintf(stderr, "[Game] Error: Please decrypt your .age files before using!\n");
                    break;
                }
                fseek(ageFile, 0, SEEK_SET);

                DS::String ageName = dirls[i]->d_name;
                ageName = ageName.left(ageName.find(".age"));
                Game_AgeInfo age = age_parse(ageFile);
                if (age.m_seqPrefix >= 0)
                    s_ages[ageName] = age;
                fclose(ageFile);
            }
            free(dirls[i]);
        }
        free(dirls);
    }

    pthread_mutex_init(&s_gameHostMutex, 0);
}
コード例 #10
0
void cb_fileList(AuthServer_Private& client)
{
    START_REPLY(e_AuthToCli_FileListReply);

    // Trans ID
    client.m_buffer.write<uint32_t>(DS::CryptRecvValue<uint32_t>(client.m_sock, client.m_crypt));

    DS::String directory = DS::CryptRecvString(client.m_sock, client.m_crypt);
    DS::String fileext = DS::CryptRecvString(client.m_sock, client.m_crypt);

    // Manifest may not have any path characters
    if (directory.find(".") != -1 || directory.find("/") != -1
        || directory.find("\\") != -1 || directory.find(":") != -1
        || fileext.find(".") != -1 || fileext.find("/") != -1
        || fileext.find("\\") != -1 || fileext.find(":") != -1) {
        fprintf(stderr, "[Auth] Invalid manifest request from %s: %s\\%s\n",
                DS::SockIpAddress(client.m_sock).c_str(), directory.c_str(),
                fileext.c_str());
        client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound);
        client.m_buffer.write<uint32_t>(0);     // Data packet size
        SEND_REPLY();
        return;
    }
    DS::String mfsname = DS::String::Format("%s%s_%s.list", DS::Settings::AuthRoot().c_str(),
                                            directory.c_str(), fileext.c_str());
    DS::AuthManifest mfs;
    DS::NetResultCode result = mfs.loadManifest(mfsname.c_str());
    client.m_buffer.write<uint32_t>(result);

    if (result != DS::e_NetSuccess) {
        fprintf(stderr, "[Auth] %s requested invalid manifest %s\n",
                DS::SockIpAddress(client.m_sock).c_str(), mfsname.c_str());
        client.m_buffer.write<uint32_t>(0);     // Data packet size
    } else {
        uint32_t sizeLocation = client.m_buffer.tell();
        client.m_buffer.write<uint32_t>(0);
        uint32_t dataSize = mfs.encodeToStream(&client.m_buffer);
        client.m_buffer.seek(sizeLocation, SEEK_SET);
        client.m_buffer.write<uint32_t>(dataSize);
    }

    SEND_REPLY();
}
コード例 #11
0
ファイル: AuthVault.cpp プロジェクト: Hoikas/dirtsand
bool v_update_node(const DS::Vault::Node& node)
{
    /* This should be plenty to store everything we need without a bunch
     * of dynamic reallocations
     */
    PostgresStrings<32> parms;
    char fieldbuf[1024];

    size_t parmcount = 1;
    char* fieldp = fieldbuf;

    #define SET_FIELD(name, value) \
        { \
            parms.set(parmcount++, value); \
            fieldp += sprintf(fieldp, "\"" #name "\"=$%Zu,", parmcount); \
        }
    int now = time(0);
    SET_FIELD(ModifyTime, now);
    if (node.has_CreateAgeName())
        SET_FIELD(CreateAgeName, node.m_CreateAgeName);
    if (node.has_CreateAgeUuid())
        SET_FIELD(CreateAgeUuid, node.m_CreateAgeUuid.toString());
    if (node.has_CreatorUuid())
        SET_FIELD(CreatorUuid, node.m_CreatorUuid.toString());
    if (node.has_CreatorIdx())
        SET_FIELD(CreatorIdx, node.m_CreatorIdx);
    if (node.has_NodeType())
        SET_FIELD(NodeType, node.m_NodeType);
    if (node.has_Int32_1())
        SET_FIELD(Int32_1, node.m_Int32_1);
    if (node.has_Int32_2())
        SET_FIELD(Int32_2, node.m_Int32_2);
    if (node.has_Int32_3())
        SET_FIELD(Int32_3, node.m_Int32_3);
    if (node.has_Int32_4())
        SET_FIELD(Int32_4, node.m_Int32_4);
    if (node.has_Uint32_1())
        SET_FIELD(Uint32_1, node.m_Uint32_1);
    if (node.has_Uint32_2())
        SET_FIELD(Uint32_2, node.m_Uint32_2);
    if (node.has_Uint32_3())
        SET_FIELD(Uint32_3, node.m_Uint32_3);
    if (node.has_Uint32_4())
        SET_FIELD(Uint32_4, node.m_Uint32_4);
    if (node.has_Uuid_1())
        SET_FIELD(Uuid_1, node.m_Uuid_1.toString());
    if (node.has_Uuid_2())
        SET_FIELD(Uuid_2, node.m_Uuid_2.toString());
    if (node.has_Uuid_3())
        SET_FIELD(Uuid_3, node.m_Uuid_3.toString());
    if (node.has_Uuid_4())
        SET_FIELD(Uuid_4, node.m_Uuid_4.toString());
    if (node.has_String64_1())
        SET_FIELD(String64_1, node.m_String64_1);
    if (node.has_String64_2())
        SET_FIELD(String64_2, node.m_String64_2);
    if (node.has_String64_3())
        SET_FIELD(String64_3, node.m_String64_3);
    if (node.has_String64_4())
        SET_FIELD(String64_4, node.m_String64_4);
    if (node.has_String64_5())
        SET_FIELD(String64_5, node.m_String64_5);
    if (node.has_String64_6())
        SET_FIELD(String64_6, node.m_String64_6);
    if (node.has_IString64_1())
        SET_FIELD(IString64_1, node.m_IString64_1);
    if (node.has_IString64_2())
        SET_FIELD(IString64_2, node.m_IString64_2);
    if (node.has_Text_1())
        SET_FIELD(Text_1, node.m_Text_1);
    if (node.has_Text_2())
        SET_FIELD(Text_2, node.m_Text_2);
    if (node.has_Blob_1())
        SET_FIELD(Blob_1, DS::Base64Encode(node.m_Blob_1.buffer(), node.m_Blob_1.size()));
    if (node.has_Blob_2())
        SET_FIELD(Blob_2, DS::Base64Encode(node.m_Blob_2.buffer(), node.m_Blob_2.size()));
    #undef SET_FIELD

    DS_DASSERT(fieldp - fieldbuf < 1024);
    *(fieldp - 1) = 0;  // Get rid of the last comma
    DS::String queryStr = "UPDATE vault.\"Nodes\"\n    SET ";
    queryStr += fieldbuf;
    queryStr += "\n    WHERE idx=$1";
    parms.set(0, node.m_NodeIdx);

    check_postgres();
    PGresult* result = PQexecParams(s_postgres, queryStr.c_str(),
                                    parmcount, 0, parms.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_COMMAND_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres UPDATE error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return false;
    }
    PQclear(result);
    return true;
}
コード例 #12
0
ファイル: AuthVault.cpp プロジェクト: Hoikas/dirtsand
uint32_t v_create_node(const DS::Vault::Node& node)
{
    /* This should be plenty to store everything we need without a bunch
     * of dynamic reallocations
     */
    PostgresStrings<31> parms;
    char fieldbuf[1024];

    size_t parmcount = 0;
    char* fieldp = fieldbuf;

    #define SET_FIELD(name, value) \
        { \
            parms.set(parmcount++, value); \
            fieldp += sprintf(fieldp, "\"" #name "\","); \
        }
    int now = time(0);
    SET_FIELD(CreateTime, now);
    SET_FIELD(ModifyTime, now);
    if (node.has_CreateAgeName())
        SET_FIELD(CreateAgeName, node.m_CreateAgeName);
    if (node.has_CreateAgeUuid())
        SET_FIELD(CreateAgeUuid, node.m_CreateAgeUuid.toString());
    if (node.has_CreatorUuid())
        SET_FIELD(CreatorUuid, node.m_CreatorUuid.toString());
    if (node.has_CreatorIdx())
        SET_FIELD(CreatorIdx, node.m_CreatorIdx);
    if (node.has_NodeType())
        SET_FIELD(NodeType, node.m_NodeType);
    if (node.has_Int32_1())
        SET_FIELD(Int32_1, node.m_Int32_1);
    if (node.has_Int32_2())
        SET_FIELD(Int32_2, node.m_Int32_2);
    if (node.has_Int32_3())
        SET_FIELD(Int32_3, node.m_Int32_3);
    if (node.has_Int32_4())
        SET_FIELD(Int32_4, node.m_Int32_4);
    if (node.has_Uint32_1())
        SET_FIELD(Uint32_1, node.m_Uint32_1);
    if (node.has_Uint32_2())
        SET_FIELD(Uint32_2, node.m_Uint32_2);
    if (node.has_Uint32_3())
        SET_FIELD(Uint32_3, node.m_Uint32_3);
    if (node.has_Uint32_4())
        SET_FIELD(Uint32_4, node.m_Uint32_4);
    if (node.has_Uuid_1())
        SET_FIELD(Uuid_1, node.m_Uuid_1.toString());
    if (node.has_Uuid_2())
        SET_FIELD(Uuid_2, node.m_Uuid_2.toString());
    if (node.has_Uuid_3())
        SET_FIELD(Uuid_3, node.m_Uuid_3.toString());
    if (node.has_Uuid_4())
        SET_FIELD(Uuid_4, node.m_Uuid_4.toString());
    if (node.has_String64_1())
        SET_FIELD(String64_1, node.m_String64_1);
    if (node.has_String64_2())
        SET_FIELD(String64_2, node.m_String64_2);
    if (node.has_String64_3())
        SET_FIELD(String64_3, node.m_String64_3);
    if (node.has_String64_4())
        SET_FIELD(String64_4, node.m_String64_4);
    if (node.has_String64_5())
        SET_FIELD(String64_5, node.m_String64_5);
    if (node.has_String64_6())
        SET_FIELD(String64_6, node.m_String64_6);
    if (node.has_IString64_1())
        SET_FIELD(IString64_1, node.m_IString64_1);
    if (node.has_IString64_2())
        SET_FIELD(IString64_2, node.m_IString64_2);
    if (node.has_Text_1())
        SET_FIELD(Text_1, node.m_Text_1);
    if (node.has_Text_2())
        SET_FIELD(Text_2, node.m_Text_2);
    if (node.has_Blob_1())
        SET_FIELD(Blob_1, DS::Base64Encode(node.m_Blob_1.buffer(), node.m_Blob_1.size()));
    if (node.has_Blob_2())
        SET_FIELD(Blob_2, DS::Base64Encode(node.m_Blob_2.buffer(), node.m_Blob_2.size()));
    #undef SET_FIELD

    DS_DASSERT(fieldp - fieldbuf < 1024);
    *(fieldp - 1) = ')';    // Get rid of the last comma
    DS::String queryStr = "INSERT INTO vault.\"Nodes\" (";
    queryStr += fieldbuf;

    fieldp = fieldbuf;
    for (size_t i=0; i<parmcount; ++i) {
        sprintf(fieldp, "$%Zu,", i+1);
        fieldp += strlen(fieldp);
    }
    DS_DASSERT(fieldp - fieldbuf < 1024);
    *(fieldp - 1) = ')';    // Get rid of the last comma
    queryStr += "\n    VALUES (";
    queryStr += fieldbuf;
    queryStr += "\n    RETURNING idx";

    check_postgres();
    PGresult* result = PQexecParams(s_postgres, queryStr.c_str(),
                                    parmcount, 0, parms.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres INSERT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return 0;
    }
    DS_DASSERT(PQntuples(result) == 1);
    uint32_t idx = strtoul(PQgetvalue(result, 0, 0), 0, 10);
    PQclear(result);
    return idx;
}
コード例 #13
0
ファイル: AuthVault.cpp プロジェクト: Hoikas/dirtsand
std::list<AuthServer_AgeInfo> configure_static_ages()
{
    AuthServer_AgeInfo age;
    std::list<AuthServer_AgeInfo> configs;

    DS::String filename = DS::Settings::SettingsPath() + "/static_ages.ini";
    FILE* cfgfile = fopen(filename.c_str(), "r");
    if (!cfgfile) {
        fprintf(stderr, "Cannot open %s for reading\n", filename.c_str());
        return configs;
    }

    try {
        char buffer[4096];
        bool haveAge = false;
        while (fgets(buffer, 4096, cfgfile)) {
            DS::String line = DS::String(buffer).strip('#');
            if (line.isEmpty())
                continue;

            if (line.strip().c_str()[0] == '[') {
                if (haveAge)
                    configs.push_back(age);
                age.clear();

                DS::String header = line.strip();
                header.replace("[","");
                header.replace("]","");

                if (header == "auto")
                    age.m_ageId = gen_uuid();
                else
                    age.m_ageId = DS::Uuid(header.c_str());

                haveAge = true;
                continue;
            }

            std::vector<DS::String> params = line.split('=', 1);
            if (params.size() != 2) {
                fprintf(stderr, "Warning: Invalid config line: %s\n", line.c_str());
                continue;
            }

            // Clean any whitespace around the '='
            params[0] = params[0].strip();
            params[1] = params[1].strip();

            if (params[0] == "Filename") {
                age.m_filename = params[1];
            } else if (params[0] == "Instance") {
                age.m_instName = params[1];
            } else if (params[0] == "UserName") {
                age.m_userName = params[1];
            } else {
                fprintf(stderr, "Warning: Unknown setting '%s' ignored\n",
                        params[0].c_str());
            }
        }

        if (haveAge)
            configs.push_back(age);
    } catch (DS::AssertException ex) {
        fprintf(stderr, "[Auth] Assertion failed at %s:%ld:  %s\n",
                ex.m_file, ex.m_line, ex.m_cond);
        fclose(cfgfile);
        return configs;
    }

    fclose(cfgfile);
    return configs;
}
コード例 #14
0
ファイル: AuthVault.cpp プロジェクト: Hoikas/dirtsand
bool v_find_nodes(const DS::Vault::Node& nodeTemplate, std::vector<uint32_t>& nodes)
{
    if (nodeTemplate.isNull())
        return false;

    /* This should be plenty to store everything we need without a bunch
     * of dynamic reallocations
     */
    PostgresStrings<31> parms;
    char fieldbuf[1024];

    size_t parmcount = 0;
    char* fieldp = fieldbuf;

    #define SET_FIELD(name, value) \
        { \
            parms.set(parmcount++, value); \
            fieldp += sprintf(fieldp, "\"" #name "\"=$%Zu AND ", parmcount); \
        }
    #define SET_FIELD_I(name, value) \
        { \
            parms.set(parmcount++, value); \
            fieldp += sprintf(fieldp, "LOWER(\"" #name "\")=LOWER($%Zu) AND ", parmcount); \
        }
    if (nodeTemplate.has_CreateTime())
        SET_FIELD(CreateTime, nodeTemplate.m_CreateTime);
    if (nodeTemplate.has_ModifyTime())
        SET_FIELD(ModifyTime, nodeTemplate.m_ModifyTime);
    if (nodeTemplate.has_CreateAgeName())
        SET_FIELD(CreateAgeName, nodeTemplate.m_CreateAgeName);
    if (nodeTemplate.has_CreateAgeUuid())
        SET_FIELD(CreateAgeUuid, nodeTemplate.m_CreateAgeUuid.toString());
    if (nodeTemplate.has_CreatorUuid())
        SET_FIELD(CreatorUuid, nodeTemplate.m_CreatorUuid.toString());
    if (nodeTemplate.has_CreatorIdx())
        SET_FIELD(CreatorIdx, nodeTemplate.m_CreatorIdx);
    if (nodeTemplate.has_NodeType())
        SET_FIELD(NodeType, nodeTemplate.m_NodeType);
    if (nodeTemplate.has_Int32_1())
        SET_FIELD(Int32_1, nodeTemplate.m_Int32_1);
    if (nodeTemplate.has_Int32_2())
        SET_FIELD(Int32_2, nodeTemplate.m_Int32_2);
    if (nodeTemplate.has_Int32_3())
        SET_FIELD(Int32_3, nodeTemplate.m_Int32_3);
    if (nodeTemplate.has_Int32_4())
        SET_FIELD(Int32_4, nodeTemplate.m_Int32_4);
    if (nodeTemplate.has_Uint32_1())
        SET_FIELD(Uint32_1, nodeTemplate.m_Uint32_1);
    if (nodeTemplate.has_Uint32_2())
        SET_FIELD(Uint32_2, nodeTemplate.m_Uint32_2);
    if (nodeTemplate.has_Uint32_3())
        SET_FIELD(Uint32_3, nodeTemplate.m_Uint32_3);
    if (nodeTemplate.has_Uint32_4())
        SET_FIELD(Uint32_4, nodeTemplate.m_Uint32_4);
    if (nodeTemplate.has_Uuid_1())
        SET_FIELD(Uuid_1, nodeTemplate.m_Uuid_1.toString());
    if (nodeTemplate.has_Uuid_2())
        SET_FIELD(Uuid_2, nodeTemplate.m_Uuid_2.toString());
    if (nodeTemplate.has_Uuid_3())
        SET_FIELD(Uuid_3, nodeTemplate.m_Uuid_3.toString());
    if (nodeTemplate.has_Uuid_4())
        SET_FIELD(Uuid_4, nodeTemplate.m_Uuid_4.toString());
    if (nodeTemplate.has_String64_1())
        SET_FIELD(String64_1, nodeTemplate.m_String64_1);
    if (nodeTemplate.has_String64_2())
        SET_FIELD(String64_2, nodeTemplate.m_String64_2);
    if (nodeTemplate.has_String64_3())
        SET_FIELD(String64_3, nodeTemplate.m_String64_3);
    if (nodeTemplate.has_String64_4())
        SET_FIELD(String64_4, nodeTemplate.m_String64_4);
    if (nodeTemplate.has_String64_5())
        SET_FIELD(String64_5, nodeTemplate.m_String64_5);
    if (nodeTemplate.has_String64_6())
        SET_FIELD(String64_6, nodeTemplate.m_String64_6);
    if (nodeTemplate.has_IString64_1())
        SET_FIELD_I(IString64_1, nodeTemplate.m_IString64_1);
    if (nodeTemplate.has_IString64_2())
        SET_FIELD_I(IString64_2, nodeTemplate.m_IString64_2);
    if (nodeTemplate.has_Text_1())
        SET_FIELD(Text_1, nodeTemplate.m_Text_1);
    if (nodeTemplate.has_Text_2())
        SET_FIELD(Text_2, nodeTemplate.m_Text_2);
    if (nodeTemplate.has_Blob_1())
        SET_FIELD(Blob_1, DS::Base64Encode(nodeTemplate.m_Blob_1.buffer(), nodeTemplate.m_Blob_1.size()));
    if (nodeTemplate.has_Blob_2())
        SET_FIELD(Blob_2, DS::Base64Encode(nodeTemplate.m_Blob_2.buffer(), nodeTemplate.m_Blob_2.size()));
    #undef SET_FIELD
    #undef SET_FIELD_I

    DS_DASSERT(parmcount > 0);
    DS_DASSERT(fieldp - fieldbuf < 1024);
    *(fieldp - 5) = 0;  // Get rid of the last ' AND '
    DS::String queryStr = "SELECT idx FROM vault.\"Nodes\"\n    WHERE ";
    queryStr += fieldbuf;

    check_postgres();
    PGresult* result = PQexecParams(s_postgres, queryStr.c_str(),
                                    parmcount, 0, parms.m_values, 0, 0, 0);
    if (PQresultStatus(result) != PGRES_TUPLES_OK) {
        fprintf(stderr, "%s:%d:\n    Postgres SELECT error: %s\n",
                __FILE__, __LINE__, PQerrorMessage(s_postgres));
        PQclear(result);
        return false;
    }

    nodes.resize(PQntuples(result));
    for (size_t i=0; i<nodes.size(); ++i)
        nodes[i] = strtoul(PQgetvalue(result, i, 0), 0, 10);
    PQclear(result);
    return true;
}
コード例 #15
0
ファイル: Status.cpp プロジェクト: The-Mad-Pirate/dirtsand
void dm_htserv()
{
    printf("[Status] Running on %s\n", DS::SockIpAddress(s_listenSock).c_str());
    try {
        for ( ;; ) {
            DS::SocketHandle client;
            try {
                client = DS::AcceptSock(s_listenSock);
            } catch (DS::SockHup) {
                break;
            }

            if (!client)
                continue;

            std::list<DS::String> lines;
            for ( ;; ) {
                std::unique_ptr<char[]> buffer;
                DS::String scratch;
                try {
                    size_t bufSize = DS::PeekSize(client);
                    buffer.reset(new char[scratch.length() + bufSize + 1]);
                    memcpy(buffer.get(), scratch.c_str(), scratch.length());
                    DS::RecvBuffer(client, buffer.get() + scratch.length(), bufSize);
                    buffer[scratch.length() + bufSize] = 0;
                } catch (const DS::SockHup&) {
                    lines.clear();
                    break;
                }

                char* cp = buffer.get();
                char* sp = buffer.get();
                while (*cp) {
                    if (*cp == '\r' || *cp == '\n') {
                        if (*cp == '\r' && *(cp + 1) == '\n') {
                            // Delete both chars of the Windows newline
                            *cp++ = 0;
                        }
                        *cp++ = 0;
                        lines.push_back(DS::String(sp));
                        sp = cp;
                        scratch = "";
                    } else {
                        ++cp;
                    }
                }
                if (cp != sp)
                    scratch += sp;

                if (lines.size() && lines.back().isEmpty()) {
                    // Got the separator line
                    break;
                }
            }

            if (lines.empty()) {
                DS::FreeSock(client);
                continue;
            }

            // First line contains the action
            std::vector<DS::String> action = lines.front().split();
            if (action.size() < 2) {
                fprintf(stderr, "[Status] Incorrectly formatted HTTP request: %s\n",
                        lines.front().c_str());
                DS::FreeSock(client);
                continue;
            }
            if (action[0] != "GET") {
                fprintf(stderr, "[Status] Unsupported method: %s\n", action[0].c_str());
                DS::FreeSock(client);
                continue;
            }
            if (action.size() < 3 || action[2] != "HTTP/1.1") {
                fputs("[Status] Unsupported HTTP Version\n", stderr);
                DS::FreeSock(client);
                continue;
            }
            DS::String path = action[1];
            lines.pop_front();

            for (auto lniter = lines.begin(); lniter != lines.end(); ++lniter) {
                // TODO: See if any of these fields are useful to us...
            }

            if (path == "/status") {
                DS::String json = "{'online':true";
                DS::String welcome = DS::Settings::WelcomeMsg();
                welcome.replace("\"", "\\\"");
                json += DS::String::Format(",'welcome':\"%s\"", welcome.c_str());
                json += "}\r\n";
                // TODO: Add more status fields (players/ages, etc)

                SEND_RAW(client, "HTTP/1.1 200 OK\r\n");
                SEND_RAW(client, "Server: Dirtsand\r\n");
                SEND_RAW(client, "Connection: close\r\n");
                SEND_RAW(client, "Accept-Ranges: bytes\r\n");
                DS::String lengthParam = DS::String::Format("Content-Length: %u\r\n", json.length());
                DS::SendBuffer(client, lengthParam.c_str(), lengthParam.length());
                SEND_RAW(client, "Content-Type: application/json\r\n");
                SEND_RAW(client, "\r\n");
                DS::SendBuffer(client, json.c_str(), json.length());
                DS::FreeSock(client);
            } else if (path == "/welcome") {
                DS::String welcome = DS::Settings::WelcomeMsg();
                welcome.replace("\\n", "\r\n");

                SEND_RAW(client, "HTTP/1.1 200 OK\r\n");
                SEND_RAW(client, "Server: Dirtsand\r\n");
                SEND_RAW(client, "Connection: close\r\n");
                SEND_RAW(client, "Accept-Ranges: bytes\r\n");
                DS::String lengthParam = DS::String::Format("Content-Length: %u\r\n", welcome.length());
                DS::SendBuffer(client, lengthParam.c_str(), lengthParam.length());
                SEND_RAW(client, "Content-Type: text/plain\r\n");
                SEND_RAW(client, "\r\n");
                DS::SendBuffer(client, welcome.c_str(), welcome.length());
                DS::FreeSock(client);
            } else {
                DS::String content = DS::String::Format("No page found at %s\r\n", path.c_str());

                SEND_RAW(client, "HTTP/1.1 404 NOT FOUND\r\n");
                SEND_RAW(client, "Server: Dirtsand\r\n");
                SEND_RAW(client, "Connection: close\r\n");
                SEND_RAW(client, "Accept-Ranges: bytes\r\n");
                DS::String lengthParam = DS::String::Format("Content-Length: %u\r\n", content.length());
                DS::SendBuffer(client, lengthParam.c_str(), lengthParam.length());
                SEND_RAW(client, "Content-Type: text/plain\r\n");
                SEND_RAW(client, "\r\n");
                DS::SendBuffer(client, content.c_str(), content.length());
                DS::FreeSock(client);
            }
        }
    } catch (DS::AssertException ex) {
        fprintf(stderr, "[Status] Assertion failed at %s:%ld:  %s\n",
                ex.m_file, ex.m_line, ex.m_cond);
    }

    DS::FreeSock(s_listenSock);
}
コード例 #16
0
ファイル: FileServer.cpp プロジェクト: Deledrius/dirtsand
void cb_downloadStart(FileServer_Private& client)
{
    START_REPLY(e_FileToCli_FileDownloadReply);

    // Trans ID
    client.m_buffer.write<uint32_t>(DS::RecvValue<uint32_t>(client.m_sock));

    // Download filename
    chr16_t buffer[260];
    DS::RecvBuffer(client.m_sock, buffer, 260 * sizeof(chr16_t));
    buffer[259] = 0;
    DS::String filename = DS::String::FromUtf16(buffer);

    // Build ID
    uint32_t buildId = DS::RecvValue<uint32_t>(client.m_sock);
    if (buildId && buildId != CLIENT_BUILD_ID) {
        fprintf(stderr, "[File] Wrong Build ID from %s: %d\n",
                DS::SockIpAddress(client.m_sock).c_str(), buildId);
        DS::CloseSock(client.m_sock);
        return;
    }

    // Ensure filename is jailed to our data path
    if (filename.find("..") != -1) {
        client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound);
        client.m_buffer.write<uint32_t>(0);     // Reader ID
        client.m_buffer.write<uint32_t>(0);     // File size
        client.m_buffer.write<uint32_t>(0);     // Data packet size
        SEND_REPLY();
        return;
    }
    filename.replace("\\", "/");

    filename = DS::Settings::FileRoot() + filename;
    DS::FileStream* stream = new DS::FileStream();
    try {
        stream->open(filename.c_str(), "rb");
    } catch (DS::FileIOException ex) {
        fprintf(stderr, "[File] Could not open file %s: %s\n[File] Requested by %s\n",
                filename.c_str(), ex.what(), DS::SockIpAddress(client.m_sock).c_str());
        client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound);
        client.m_buffer.write<uint32_t>(0);     // Reader ID
        client.m_buffer.write<uint32_t>(0);     // File size
        client.m_buffer.write<uint32_t>(0);     // Data packet size
        SEND_REPLY();
        delete stream;
        return;
    }

    client.m_buffer.write<uint32_t>(DS::e_NetSuccess);
    client.m_buffer.write<uint32_t>(++client.m_readerId);
    client.m_buffer.write<uint32_t>(stream->size());

    uint8_t data[CHUNK_SIZE];
    if (stream->size() > CHUNK_SIZE) {
        client.m_buffer.write<uint32_t>(CHUNK_SIZE);
        stream->readBytes(data, CHUNK_SIZE);
        client.m_buffer.writeBytes(data, CHUNK_SIZE);
        client.m_downloads[client.m_readerId] = stream;
    } else {
        client.m_buffer.write<uint32_t>(stream->size());
        stream->readBytes(data, stream->size());
        client.m_buffer.writeBytes(data, stream->size());
        delete stream;
    }

    SEND_REPLY();
}