<commit_before>//
//  Created by Derek van Vliet on 2015-03-25.
//  Copyright (c) 2015 Get Set Games Inc. All rights reserved.
//

#include "FacebookParsePrivatePCH.h"
#include "CallbackDevice.h"

#if PLATFORM_IOS
NSArray* GetNSStringArray(TArray<FString> FStringArray)
{
	NSMutableArray* NewArray = [NSMutableArray array];

	for (auto Itr(FStringArray.CreateIterator()); Itr; Itr++)
	{
		FString String = (*Itr);
		[NewArray addObject:String.GetNSString()];
	}

	return NewArray;
}
#endif

void UFacebookLoginComponent::OnRegister()
{
	Super::OnRegister();

	// init here
	FCoreDelegates::ApplicationOpenURLDelegate.AddUObject(this, &UFacebookLoginComponent::ApplicationOpenURL_Handler);
	UFacebookLoginComponent::FacebookLoginCancelledDelegate.AddUObject(this, &UFacebookLoginComponent::FacebookLoginCancelled_Handler);
	UFacebookLoginComponent::FacebookLoginErrorDelegate.AddUObject(this, &UFacebookLoginComponent::FacebookLoginError_Handler);
	UFacebookLoginComponent::FacebookLoginSucceededDelegate.AddUObject(this, &UFacebookLoginComponent::FacebookLoginSucceeded_Handler);
}

void UFacebookLoginComponent::OnUnregister()
{
	Super::OnUnregister();

	// clean up here

	FCoreDelegates::ApplicationOpenURLDelegate.RemoveAll(this);
	UFacebookLoginComponent::FacebookLoginCancelledDelegate.RemoveAll(this);
	UFacebookLoginComponent::FacebookLoginErrorDelegate.RemoveAll(this);
	UFacebookLoginComponent::FacebookLoginSucceededDelegate.RemoveAll(this);
}

void UFacebookLoginComponent::FacebookLoginWithReadPermissions(TArray<FString> Permissions)
{
#if PLATFORM_IOS
	dispatch_async(dispatch_get_main_queue(), ^{
		FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
		[login logInWithReadPermissions:GetNSStringArray(Permissions) handler:^(FBSDKLoginManagerLoginResult *result, NSError *error)
		 {
			if (error)
			{
				UFacebookLoginComponent::FacebookLoginErrorDelegate.Broadcast(FString([error description]));
			}
			else if (result.isCancelled)
			{
				UFacebookLoginComponent::FacebookLoginCancelledDelegate.Broadcast();
			}
			else
			{
				UFacebookLoginComponent::FacebookLoginSucceededDelegate.Broadcast(UFacebookFunctions::FacebookGetUserId(), UFacebookFunctions::FacebookGetAccessToken(), UFacebookFunctions::FacebookGetAccessTokenExpirationDate());
			}
		 }];
	});
#endif
}

void UFacebookLoginComponent::ApplicationOpenURL_Handler(FString URL, FString SourceApplication)
{
#if PLATFORM_IOS
	IOSAppDelegate* appDelegate = (IOSAppDelegate*)[[UIApplication sharedApplication] delegate];

	[[FBSDKApplicationDelegate sharedInstance] application:[UIApplication sharedApplication]
												   openURL:[NSURL URLWithString:URL.GetNSString()]
										 sourceApplication:SourceApplication.GetNSString()
												annotation:appDelegate.launchAnnotation];
#endif
}

UFacebookLoginComponent::FFacebookLoginSucceededDelegate UFacebookLoginComponent::FacebookLoginSucceededDelegate;
UFacebookLoginComponent::FFacebookLoginCancelledDelegate UFacebookLoginComponent::FacebookLoginCancelledDelegate;
UFacebookLoginComponent::FFacebookLoginErrorDelegate UFacebookLoginComponent::FacebookLoginErrorDelegate;
<commit_msg>[change] call the Android/Java login method passing along specified permissions from blue print<commit_after>//
//  Created by Derek van Vliet on 2015-03-25.
//  Copyright (c) 2015 Get Set Games Inc. All rights reserved.
//

#include "FacebookParsePrivatePCH.h"
#include "CallbackDevice.h"

#if PLATFORM_IOS
NSArray* GetNSStringArray(TArray<FString> FStringArray)
{
	NSMutableArray* NewArray = [NSMutableArray array];

	for (auto Itr(FStringArray.CreateIterator()); Itr; Itr++)
	{
		FString String = (*Itr);
		[NewArray addObject:String.GetNSString()];
	}

	return NewArray;
}
#endif

void UFacebookLoginComponent::OnRegister()
{
	Super::OnRegister();

	// init here
	FCoreDelegates::ApplicationOpenURLDelegate.AddUObject(this, &UFacebookLoginComponent::ApplicationOpenURL_Handler);
	UFacebookLoginComponent::FacebookLoginCancelledDelegate.AddUObject(this, &UFacebookLoginComponent::FacebookLoginCancelled_Handler);
	UFacebookLoginComponent::FacebookLoginErrorDelegate.AddUObject(this, &UFacebookLoginComponent::FacebookLoginError_Handler);
	UFacebookLoginComponent::FacebookLoginSucceededDelegate.AddUObject(this, &UFacebookLoginComponent::FacebookLoginSucceeded_Handler);
}

void UFacebookLoginComponent::OnUnregister()
{
	Super::OnUnregister();

	// clean up here

	FCoreDelegates::ApplicationOpenURLDelegate.RemoveAll(this);
	UFacebookLoginComponent::FacebookLoginCancelledDelegate.RemoveAll(this);
	UFacebookLoginComponent::FacebookLoginErrorDelegate.RemoveAll(this);
	UFacebookLoginComponent::FacebookLoginSucceededDelegate.RemoveAll(this);
}

void UFacebookLoginComponent::FacebookLoginWithReadPermissions(TArray<FString> Permissions)
{
#if PLATFORM_IOS
	dispatch_async(dispatch_get_main_queue(), ^{
		FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
		[login logInWithReadPermissions:GetNSStringArray(Permissions) handler:^(FBSDKLoginManagerLoginResult *result, NSError *error)
		 {
			if (error)
			{
				UFacebookLoginComponent::FacebookLoginErrorDelegate.Broadcast(FString([error description]));
			}
			else if (result.isCancelled)
			{
				UFacebookLoginComponent::FacebookLoginCancelledDelegate.Broadcast();
			}
			else
			{
				UFacebookLoginComponent::FacebookLoginSucceededDelegate.Broadcast(UFacebookFunctions::FacebookGetUserId(), UFacebookFunctions::FacebookGetAccessToken(), UFacebookFunctions::FacebookGetAccessTokenExpirationDate());
			}
		 }];
	});
#elif PLATFORM_ANDROID
    bool bResult = false;

    if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
    {
        jstring AchievementIdJava = Env->NewStringUTF(TCHAR_TO_UTF8(*AchievementId));
        static jmethodID Method = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunk_Java_FacebookLoginWithReadPermissions",  "(Ljava/lang/String;)V", false);
        bResult = FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, Method, Permissions);
        Env->DeleteLocalRef(AchievementIdJava);
    }

    return bResult;

#endif
}

void UFacebookLoginComponent::ApplicationOpenURL_Handler(FString URL, FString SourceApplication)
{
#if PLATFORM_IOS
	IOSAppDelegate* appDelegate = (IOSAppDelegate*)[[UIApplication sharedApplication] delegate];

	[[FBSDKApplicationDelegate sharedInstance] application:[UIApplication sharedApplication]
												   openURL:[NSURL URLWithString:URL.GetNSString()]
										 sourceApplication:SourceApplication.GetNSString()
												annotation:appDelegate.launchAnnotation];
#endif
}

UFacebookLoginComponent::FFacebookLoginSucceededDelegate UFacebookLoginComponent::FacebookLoginSucceededDelegate;
UFacebookLoginComponent::FFacebookLoginCancelledDelegate UFacebookLoginComponent::FacebookLoginCancelledDelegate;
UFacebookLoginComponent::FFacebookLoginErrorDelegate UFacebookLoginComponent::FacebookLoginErrorDelegate;
<|endoftext|>


<commit_before>#include "nano_signal_slot.hpp"

#include <iostream>

struct Foo : public Nano::Observer
{
    void action() const
    {
        std::cout << "Hello, World!" << std::endl;
    }
    long action(std::size_t a) const
    {
        return __LINE__ ^ a;
    }
};

long action(std::size_t a)
{
    return __LINE__ ^ a;
}

int main()
{
    Foo foo;

    // Declare Nano::Signals using function signature syntax
    Nano::Signal<void()> signal_one;
    Nano::Signal<long(std::size_t)> signal_two;

    // Connect member functions to Nano::Signals
    signal_one.connect<Foo, &Foo::action>(&foo);
    signal_two.connect<Foo, &Foo::action>(&foo);

    // Connect a free function to a Nano::Signal
    signal_two.connect<action>();

    // Emit Signals
    signal_one();

    // Emit Signals and accumulate SRVs
    signal_two.accumulate(__LINE__, [](long srv)
    {
        std::cout << srv << ", " << __LINE__ << std::endl;
    });

    // Disconnect a member function from a Nano::Signal
    signal_two.disconnect<Foo, &Foo::action>(foo);

    // Disconnect a free function from a Nano::Signal
    signal_two.disconnect<action>();

    std::cout << "\n\tAfter Disconnect\n" << std::endl;

    // Emit again to test disconnects
    signal_one();
    signal_two(__LINE__);

    // Pause the screen
    std::cin.get();
}
<commit_msg>added additional var<commit_after>#include "nano_signal_slot.hpp"

#include <iostream>
#include <random>

struct Foo : public Nano::Observer
{
    void action() const
    {
        std::cout << "Hello, World!" << std::endl;
    }
    long action(std::size_t a) const
    {
        return __LINE__ ^ a;
    }
};

long action(std::size_t a)
{
    return __LINE__ ^ a;
}

int main()
{
    Foo foo;

    std::size_t sig_arg = 9001;

    // Declare Nano::Signals using function signature syntax
    Nano::Signal<void()> signal_one;
    Nano::Signal<long(std::size_t)> signal_two;

    // Connect member functions to Nano::Signals
    signal_one.connect<Foo, &Foo::action>(&foo);
    signal_two.connect<Foo, &Foo::action>(&foo);

    // Connect a free function to a Nano::Signal
    signal_two.connect<action>();

    // Emit Signals
    signal_one();
    signal_two(sig_arg);

    // Emit Signals and accumulate SRVs (signal return values)
    signal_two.accumulate(__LINE__, [](long srv)
    {
        std::cout << srv << ", " << __LINE__ << std::endl;
    });

    // Disconnect a member function from a Nano::Signal
    signal_two.disconnect<Foo, &Foo::action>(foo);

    // Disconnect a free function from a Nano::Signal
    signal_two.disconnect<action>();

    std::cout << "\n\tAfter Disconnect\n" << std::endl;

    // Emit again to test disconnects
    signal_one();
    signal_two(__LINE__);

    // Pause the screen
    std::cin.get();
}
<|endoftext|>


<commit_before>#include "GMSAssetResourceManagementSystem.hpp"

#include "../AssetResources/TextureInfoResource.hpp"
#include "../AssetResources/GMSRoomResource.hpp"
#include "../AssetResources/GMSObjectResource.hpp"
#include "../AssetResources/OtherGMSResources.hpp"

#include "../CommandLineOptions.hpp"

#include <KEngine/Events/OtherGraphicsEvents.hpp>
#include <KEngine/App.hpp>
#include <KEngine/Utility/FileSystemHelper.hpp>
#include <KEngine/Log/Log.hpp>

#include <SFML/Graphics/Image.hpp>

#include <algorithm>
#include <execution>
#include <filesystem>
#include <fstream>
#include <limits>
#include <mutex>
#include <utility>

namespace fs = std::filesystem;

namespace
{
    ke::Colour gmsColourStrToColour(const ke::String & p_colourStr)
    {
        assert(p_colourStr.length() == 9);
        assert(p_colourStr[0] == '#');
        ke::Colour roomColour = {
            // assume colour is in hex RGBA starting with the '#' symbol.
            static_cast<uint8_t>(std::stol(p_colourStr.substr(1, 2), nullptr, 16)),
            static_cast<uint8_t>(std::stol(p_colourStr.substr(3, 2), nullptr, 16)),
            static_cast<uint8_t>(std::stol(p_colourStr.substr(5, 2), nullptr, 16)),
            static_cast<uint8_t>(std::stol(p_colourStr.substr(7, 2), nullptr, 16)) };
        return roomColour;
    }
}

namespace pf
{

    bool GMSAssetResourceManagementSystem::initialise()
    {
        ke::Log::instance()->info("Scanning assets...");
        this->loadTextureAssets();
        this->loadSpriteAssets();
        this->loadObjectAssets();
        this->loadRoomAssets();
        ke::Log::instance()->info("Scanning assets... DONE");
        return true;
    }

    void GMSAssetResourceManagementSystem::shutdown()
    {
    }

    void GMSAssetResourceManagementSystem::update(ke::Time elapsedTime)
    {
        KE_UNUSED(elapsedTime);
    }

    void GMSAssetResourceManagementSystem::loadTextureAssets(void)
    {
        ke::Log::instance()->info("Scanning texture assets...");
        const auto assetDirPath = ke::App::getCommandLineArgValue(pf::cli::ExecAssetsPath).as<ke::String>();
        const auto texturesRootDirPath = fs::path{ assetDirPath } / "textures";
        sf::Image tempImage;
        std::hash<ke::String> hasher;
        for (const auto & path : ke::FileSystemHelper::getChildPaths(texturesRootDirPath))
        {
            if (fs::is_directory(path)) // is a texture directory.
            {
                ke::Log::instance()->info("Discovered texture asset: {}", path.string());

                auto textureFilePaths = ke::FileSystemHelper::getFilePaths(path);
                if (textureFilePaths.size() == 1)
                {
                    auto texPath = textureFilePaths[0];
                    auto textureResource = std::make_shared<TextureInfoResource>();
                    textureResource->setName(texPath.stem().string());
                    textureResource->setTextureId(hasher(textureResource->getName()));
                    textureResource->setSourcePath(texPath.string());

                    // retrieve size
                    bool ret = tempImage.loadFromFile(texPath.string());
                    assert(ret);
                    TextureInfoResource::DimensionType dimension;
                    dimension.width = tempImage.getSize().x;
                    dimension.height = tempImage.getSize().y;
                    textureResource->setTextureSize(dimension);

                    ke::App::instance()->getResourceManager()->registerResource(textureResource);
                }
                else
                {
                    // ignore when there're multiple texture files in a single dir for now.
                }
            }
            else if (fs::is_regular_file(path) && path.extension() == "png") // is a png texture.
            {
                ke::Log::instance()->info("Discovered texture asset: {}", path.string());

                auto textureResource = std::make_shared<TextureInfoResource>();
                textureResource->setName("texture_" + path.stem().string());
                textureResource->setTextureId(std::stoi(textureResource->getName()));
                textureResource->setSourcePath(path.string());

                // retrieve size
                bool ret = tempImage.loadFromFile(path.string());
                assert(ret);
                TextureInfoResource::DimensionType dimension;
                dimension.width = tempImage.getSize().x;
                dimension.height = tempImage.getSize().y;
                textureResource->setTextureSize(dimension);

                ke::App::instance()->getResourceManager()->registerResource(textureResource);
            }
        }
    }

    void GMSAssetResourceManagementSystem::loadSpriteAssets(void)
    {
        ke::Log::instance()->info("Scanning texpage assets...");
        const auto assetDirPath = ke::App::getCommandLineArgValue(pf::cli::ExecAssetsPath).as<ke::String>();
        const auto texpageRootDirPath = fs::path{ assetDirPath } / "texpage";
        std::mutex texpagesMutex;
        std::unordered_map<unsigned, std::shared_ptr<pf::GMSTexpageResource>> texpages; // <texpage_id, texpage>
        const auto texpagePaths = ke::FileSystemHelper::getChildPaths(texpageRootDirPath);
        std::for_each(std::execution::par_unseq, std::begin(texpagePaths), std::end(texpagePaths), [&](const auto & path)
        {
            if (!path.has_extension() || path.extension() != ".json") return;

            ke::Log::instance()->info("Discovered GM:S texpage asset: {}", path.string());

            std::ifstream texpageFileStream{ path };
            ke::json texpageJson;
            texpageFileStream >> texpageJson;

            auto texpage = std::make_shared<pf::GMSTexpageResource>("texpage_" + path.stem().string(), path.string());

            texpage->id = std::stoi(path.stem().string());
            texpage->sourcePosition.x            = texpageJson["src"]["x"].get<unsigned>();
            texpage->sourcePosition.y            = texpageJson["src"]["y"].get<unsigned>();
            texpage->sourceDimension.width       = texpageJson["src"]["width"].get<unsigned>();
            texpage->sourceDimension.height      = texpageJson["src"]["height"].get<unsigned>();
            texpage->destinationPosition.x       = texpageJson["dest"]["x"].get<unsigned>();
            texpage->destinationPosition.y       = texpageJson["dest"]["y"].get<unsigned>();
            texpage->destinationDimension.width  = texpageJson["dest"]["width"].get<unsigned>();
            texpage->destinationDimension.height = texpageJson["dest"]["height"].get<unsigned>();
            texpage->dimension.width             = texpageJson["size"]["width"].get<unsigned>();
            texpage->dimension.height            = texpageJson["size"]["height"].get<unsigned>();
            texpage->textureId                   = texpageJson["sheetid"].get<unsigned>();

            std::scoped_lock lock(texpagesMutex);
            texpages[texpage->id] = texpage;
        });

        ke::Log::instance()->info("Scanning sprite assets...");
        const auto spriteRootDirPath = fs::path{ assetDirPath } / "sprite";
        const auto spritePaths = ke::FileSystemHelper::getChildPaths(spriteRootDirPath);
        std::for_each(std::execution::par_unseq, std::begin(spritePaths), std::end(spritePaths), [&](const auto & path)
        {
            if (!path.has_extension() || path.extension() != ".json") return;

            ke::Log::instance()->info("Discovered GM:S sprite asset: {}", path.string());
            std::ifstream spriteFileStream{ path };
            ke::json spriteJson;
            spriteFileStream >> spriteJson;

            auto sprite = std::make_shared<pf::GMSSpriteResource>(path.stem().string(), path.string());

            sprite->dimension.width     = spriteJson["size"]["width"].get<unsigned>();
            sprite->dimension.height    = spriteJson["size"]["height"].get<unsigned>();
            sprite->boundingBox.top     = spriteJson["bounding"]["top"].get<unsigned>();
            sprite->boundingBox.left    = spriteJson["bounding"]["left"].get<unsigned>();
            sprite->boundingBox.bottom  = spriteJson["bounding"]["bottom"].get<unsigned>();
            sprite->boundingBox.right   = spriteJson["bounding"]["right"].get<unsigned>();
            sprite->boundingBoxMode     = spriteJson["bboxmode"].get<unsigned>();
            sprite->separateMasks       = spriteJson["sepmasks"].get<bool>();
            sprite->origin.x            = spriteJson["origin"]["x"].get<unsigned>();
            sprite->origin.y            = spriteJson["origin"]["y"].get<unsigned>();
            for (const auto & textureJson : spriteJson["textures"])
            {
                sprite->texpageIds.push_back(textureJson.get<unsigned>());
            }
        });
        // TODO: load and register sprite resources
    }

    void GMSAssetResourceManagementSystem::loadRoomAssets(void)
    {
        ke::Log::instance()->info("Scanning GM:S room assets...");
        const auto assetDirPath = ke::App::getCommandLineArgValue(pf::cli::ExecAssetsPath).as<ke::String>();
        const auto gmsRoomsRootDirPath = fs::path{ assetDirPath } / "rooms";
        const auto gmsRoomPaths = ke::FileSystemHelper::getFilePaths(gmsRoomsRootDirPath);
        std::hash<ke::String> hasher;
        std::for_each(std::execution::par_unseq, std::begin(gmsRoomPaths), std::end(gmsRoomPaths), [&](const auto & gmsRoomPath)
        {
            if (!gmsRoomPath.has_extension() || gmsRoomPath.extension() != ".json") return;

            ke::Log::instance()->info("Discovered GM:S room asset: {}", gmsRoomPath.string());

            auto roomResource = std::make_shared<GMSRoomResource>();
            roomResource->setName(gmsRoomPath.stem().string());
            roomResource->setSourcePath(gmsRoomPath.string());

            std::ifstream roomFileStream{ gmsRoomPath };
            ke::json roomJson;
            roomFileStream >> roomJson;

            //
            // Load general room info.
            //
            GMSRoomResource::SizeType roomSize;
            roomSize.width  = roomJson["size"]["width"].get<unsigned>();
            roomSize.height = roomJson["size"]["height"].get<unsigned>();
            roomResource->setSize(roomSize);
            roomResource->setSpeed(roomJson["speed"].get<int>());
            auto roomColourStr = roomJson["colour"].get<ke::String>();
            roomResource->setColour(::gmsColourStrToColour(roomColourStr));

            //
            // load background info
            //
            const auto & roomBackgroundsJson = roomJson["bgs"];
            for (const auto & backgroundJson : roomBackgroundsJson)
            {
                GMSRoomBackgroundInfo backgroundInfo;
                backgroundInfo.enabled    = backgroundJson["enabled"].get<bool>();
                backgroundInfo.foreground = backgroundJson["foreground"].get<bool>();
                backgroundInfo.pos        = { backgroundJson["pos"]["x"].get<int>(), -backgroundJson["pos"]["y"].get<int>() };
                backgroundInfo.tilex      = backgroundJson["tilex"].get<bool>();
                backgroundInfo.tiley      = backgroundJson["tiley"].get<bool>();
                backgroundInfo.speed      = { backgroundJson["speed"]["x"].get<int>(), -backgroundJson["speed"]["y"].get<int>() };
                backgroundInfo.stretch    = backgroundJson["stretch"].get<bool>();
                backgroundInfo.bg         = backgroundJson.value("bg", "");
                backgroundInfo.bg_hash    = hasher(backgroundInfo.bg);
                roomResource->addBackgroundInfo(backgroundInfo);
            }

            //
            // load tile instances
            //
            const auto & roomTilesJson = roomJson["tiles"];
            roomResource->tiles.reserve(roomTilesJson.size());
            for (const auto & tileJson : roomTilesJson)
            {
                pf::GMSRoomTileInstance newTile;
                newTile.instanceid = tileJson["instanceid"].get<unsigned>();

                // Here we make sure to convert the GM:S room coordinates to KEngine's world coordinates.
                // I.e. y-down to y-up.
                // Texture coordinates are the same at the moment at y-down. I.e. (0,0) at top left.
                newTile.pos       = { tileJson["pos"]["x"].get<int>(), -tileJson["pos"]["y"].get<int>() };
                newTile.bg        = tileJson["bg"].get<ke::String>();
                newTile.bg_hash   = hasher(newTile.bg);
                newTile.sourcepos = { tileJson["sourcepos"]["x"].get<int>(), tileJson["sourcepos"]["y"].get<int>() }; // sourcepos is y-down local image coordinates.
                newTile.size      = { tileJson["size"]["width"].get<int>(), tileJson["size"]["height"].get<int>() };
                newTile.scale     = { tileJson["scale"]["x"].get<float>(), tileJson["scale"]["y"].get<float>() };
                newTile.colour    = ::gmsColourStrToColour(tileJson["colour"].get<ke::String>());

                // Here convert GM:S' depth system to KEngine's depth system.
                // GM:S depth value: larger == further back.
                // KEngine depth value: larger == further in front.
                newTile.tiledepth = -tileJson["tiledepth"].get<ke::graphics::DepthType>();

                roomResource->addTile(newTile);
            }

            //
            // load object instances
            //
            const auto & roomObjsJson = roomJson["objs"];
            roomResource->objects.reserve(roomObjsJson.size());
            for (const auto & objJson : roomObjsJson)
            {
                pf::GMSRoomObjectInstance obj;
                obj.instanceid = objJson["instanceid"].get<ke::EntityId>();
                obj.obj        = objJson["obj"].get<ke::String>();
                obj.pos        = { objJson["pos"]["x"].get<int>(), -objJson["pos"]["y"].get<int>() };
                obj.scale      = { objJson["scale"]["x"].get<float>(), objJson["scale"]["y"].get<float>() };
                obj.rotation   = objJson["rotation"].get<float>();
                obj.colour     = ::gmsColourStrToColour(objJson["colour"].get<ke::String>());

                roomResource->addObject(obj);
            }

            ke::App::instance()->getResourceManager()->registerResource(roomResource);
        });
    }

    void GMSAssetResourceManagementSystem::loadObjectAssets(void)
    {
        ke::Log::instance()->info("Scanning GM:S object assets...");
        const auto assetDirPath = ke::App::getCommandLineArgValue(pf::cli::ExecAssetsPath).as<ke::String>();
        const auto gmsObjectRootDirPath = fs::path{ assetDirPath } / "object";
        const auto gmsObjectPaths = ke::FileSystemHelper::getFilePaths(gmsObjectRootDirPath);
        std::for_each(std::execution::par_unseq, std::begin(gmsObjectPaths), std::end(gmsObjectPaths), [&](const auto & gmsObjectPath)
        {
            if (!gmsObjectPath.has_extension() || gmsObjectPath.extension() != "json") return;

            ke::Log::instance()->info("Discovered GM:S object asset: {}", gmsObjectPath.string());

            std::ifstream objectFileStream{ gmsObjectPath };
            ke::json objectJson;
            objectFileStream >> objectJson;

            auto objectResource = std::make_shared<pf::GMSObjectResource>(fs::path(gmsObjectPath).stem().string(), gmsObjectPath.string());
            objectResource->sprite   = objectJson["sprite"].get<ke::String>();
            objectResource->visible  = objectJson["visible"].get<bool>();
            objectResource->solid    = objectJson["solid"].get<bool>();
            objectResource->depth    = objectJson["depth"].get<decltype(objectResource->depth)>();
            objectResource->persist  = objectJson["persist"].get<bool>();
            objectResource->sensor   = objectJson["sensor"].get<bool>();
            objectResource->colshape = objectJson["colshape"].get<ke::String>();

            ke::App::instance()->getResourceManager()->registerResource(objectResource);
        });
    }
}<commit_msg>rephrase GM:S asset loading messages<commit_after>#include "GMSAssetResourceManagementSystem.hpp"

#include "../AssetResources/TextureInfoResource.hpp"
#include "../AssetResources/GMSRoomResource.hpp"
#include "../AssetResources/GMSObjectResource.hpp"
#include "../AssetResources/OtherGMSResources.hpp"

#include "../CommandLineOptions.hpp"

#include <KEngine/Events/OtherGraphicsEvents.hpp>
#include <KEngine/App.hpp>
#include <KEngine/Utility/FileSystemHelper.hpp>
#include <KEngine/Log/Log.hpp>

#include <SFML/Graphics/Image.hpp>

#include <algorithm>
#include <execution>
#include <filesystem>
#include <fstream>
#include <limits>
#include <mutex>
#include <utility>

namespace fs = std::filesystem;

namespace
{
    ke::Colour gmsColourStrToColour(const ke::String & p_colourStr)
    {
        assert(p_colourStr.length() == 9);
        assert(p_colourStr[0] == '#');
        ke::Colour roomColour = {
            // assume colour is in hex RGBA starting with the '#' symbol.
            static_cast<uint8_t>(std::stol(p_colourStr.substr(1, 2), nullptr, 16)),
            static_cast<uint8_t>(std::stol(p_colourStr.substr(3, 2), nullptr, 16)),
            static_cast<uint8_t>(std::stol(p_colourStr.substr(5, 2), nullptr, 16)),
            static_cast<uint8_t>(std::stol(p_colourStr.substr(7, 2), nullptr, 16)) };
        return roomColour;
    }
}

namespace pf
{

    bool GMSAssetResourceManagementSystem::initialise()
    {
        ke::Log::instance()->info("Scanning assets...");
        this->loadTextureAssets();
        this->loadSpriteAssets();
        this->loadObjectAssets();
        this->loadRoomAssets();
        ke::Log::instance()->info("Scanning assets... DONE");
        return true;
    }

    void GMSAssetResourceManagementSystem::shutdown()
    {
    }

    void GMSAssetResourceManagementSystem::update(ke::Time elapsedTime)
    {
        KE_UNUSED(elapsedTime);
    }

    void GMSAssetResourceManagementSystem::loadTextureAssets(void)
    {
        ke::Log::instance()->info("Scanning texture assets...");
        const auto assetDirPath = ke::App::getCommandLineArgValue(pf::cli::ExecAssetsPath).as<ke::String>();
        const auto texturesRootDirPath = fs::path{ assetDirPath } / "textures";
        sf::Image tempImage;
        std::hash<ke::String> hasher;
        for (const auto & path : ke::FileSystemHelper::getChildPaths(texturesRootDirPath))
        {
            if (fs::is_directory(path)) // is a texture directory.
            {
                auto textureFilePaths = ke::FileSystemHelper::getFilePaths(path);
                if (textureFilePaths.size() == 1)
                {
                    const auto & texPath = textureFilePaths[0];
                    ke::Log::instance()->info("Loading texture asset: {}", texPath.string());

                    auto textureResource = std::make_shared<TextureInfoResource>();
                    textureResource->setName(texPath.stem().string());
                    textureResource->setTextureId(hasher(textureResource->getName()));
                    textureResource->setSourcePath(texPath.string());

                    // retrieve size
                    bool ret = tempImage.loadFromFile(texPath.string());
                    assert(ret);
                    TextureInfoResource::DimensionType dimension;
                    dimension.width = tempImage.getSize().x;
                    dimension.height = tempImage.getSize().y;
                    textureResource->setTextureSize(dimension);

                    ke::App::instance()->getResourceManager()->registerResource(textureResource);
                }
                else
                {
                    // ignore when there're multiple texture files in a single dir for now.
                }
            }
            else if (fs::is_regular_file(path) && path.extension() == "png") // is a png texture.
            {
                ke::Log::instance()->info("Loading texture asset: {}", path.string());

                auto textureResource = std::make_shared<TextureInfoResource>();
                textureResource->setName("texture_" + path.stem().string());
                textureResource->setTextureId(std::stoi(textureResource->getName()));
                textureResource->setSourcePath(path.string());

                // retrieve size
                bool ret = tempImage.loadFromFile(path.string());
                assert(ret);
                TextureInfoResource::DimensionType dimension;
                dimension.width = tempImage.getSize().x;
                dimension.height = tempImage.getSize().y;
                textureResource->setTextureSize(dimension);

                ke::App::instance()->getResourceManager()->registerResource(textureResource);
            }
        }
    }

    void GMSAssetResourceManagementSystem::loadSpriteAssets(void)
    {
        ke::Log::instance()->info("Scanning texpage assets...");
        const auto assetDirPath = ke::App::getCommandLineArgValue(pf::cli::ExecAssetsPath).as<ke::String>();
        const auto texpageRootDirPath = fs::path{ assetDirPath } / "texpage";
        std::mutex texpagesMutex;
        std::unordered_map<unsigned, std::shared_ptr<pf::GMSTexpageResource>> texpages; // <texpage_id, texpage>
        const auto texpagePaths = ke::FileSystemHelper::getChildPaths(texpageRootDirPath);
        std::for_each(std::execution::par_unseq, std::begin(texpagePaths), std::end(texpagePaths), [&](const auto & path)
        {
            if (!path.has_extension() || path.extension() != ".json") return;

            ke::Log::instance()->info("Loading GM:S texpage asset: {}", path.string());

            std::ifstream texpageFileStream{ path };
            ke::json texpageJson;
            texpageFileStream >> texpageJson;

            auto texpage = std::make_shared<pf::GMSTexpageResource>("texpage_" + path.stem().string(), path.string());

            texpage->id = std::stoi(path.stem().string());
            texpage->sourcePosition.x            = texpageJson["src"]["x"].get<unsigned>();
            texpage->sourcePosition.y            = texpageJson["src"]["y"].get<unsigned>();
            texpage->sourceDimension.width       = texpageJson["src"]["width"].get<unsigned>();
            texpage->sourceDimension.height      = texpageJson["src"]["height"].get<unsigned>();
            texpage->destinationPosition.x       = texpageJson["dest"]["x"].get<unsigned>();
            texpage->destinationPosition.y       = texpageJson["dest"]["y"].get<unsigned>();
            texpage->destinationDimension.width  = texpageJson["dest"]["width"].get<unsigned>();
            texpage->destinationDimension.height = texpageJson["dest"]["height"].get<unsigned>();
            texpage->dimension.width             = texpageJson["size"]["width"].get<unsigned>();
            texpage->dimension.height            = texpageJson["size"]["height"].get<unsigned>();
            texpage->textureId                   = texpageJson["sheetid"].get<unsigned>();

            std::scoped_lock lock(texpagesMutex);
            texpages[texpage->id] = texpage;
        });

        ke::Log::instance()->info("Scanning sprite assets...");
        const auto spriteRootDirPath = fs::path{ assetDirPath } / "sprite";
        const auto spritePaths = ke::FileSystemHelper::getChildPaths(spriteRootDirPath);
        std::for_each(std::execution::par_unseq, std::begin(spritePaths), std::end(spritePaths), [&](const auto & path)
        {
            if (!path.has_extension() || path.extension() != ".json") return;

            ke::Log::instance()->info("Loading GM:S sprite asset: {}", path.string());
            std::ifstream spriteFileStream{ path };
            ke::json spriteJson;
            spriteFileStream >> spriteJson;

            auto sprite = std::make_shared<pf::GMSSpriteResource>(path.stem().string(), path.string());

            sprite->dimension.width     = spriteJson["size"]["width"].get<unsigned>();
            sprite->dimension.height    = spriteJson["size"]["height"].get<unsigned>();
            sprite->boundingBox.top     = spriteJson["bounding"]["top"].get<unsigned>();
            sprite->boundingBox.left    = spriteJson["bounding"]["left"].get<unsigned>();
            sprite->boundingBox.bottom  = spriteJson["bounding"]["bottom"].get<unsigned>();
            sprite->boundingBox.right   = spriteJson["bounding"]["right"].get<unsigned>();
            sprite->boundingBoxMode     = spriteJson["bboxmode"].get<unsigned>();
            sprite->separateMasks       = spriteJson["sepmasks"].get<bool>();
            sprite->origin.x            = spriteJson["origin"]["x"].get<unsigned>();
            sprite->origin.y            = spriteJson["origin"]["y"].get<unsigned>();
            for (const auto & textureJson : spriteJson["textures"])
            {
                sprite->texpageIds.push_back(textureJson.get<unsigned>());
            }
        });
        // TODO: load and register sprite resources
    }

    void GMSAssetResourceManagementSystem::loadRoomAssets(void)
    {
        ke::Log::instance()->info("Scanning GM:S room assets...");
        const auto assetDirPath = ke::App::getCommandLineArgValue(pf::cli::ExecAssetsPath).as<ke::String>();
        const auto gmsRoomsRootDirPath = fs::path{ assetDirPath } / "rooms";
        const auto gmsRoomPaths = ke::FileSystemHelper::getFilePaths(gmsRoomsRootDirPath);
        std::hash<ke::String> hasher;
        std::for_each(std::execution::par_unseq, std::begin(gmsRoomPaths), std::end(gmsRoomPaths), [&](const auto & gmsRoomPath)
        {
            if (!gmsRoomPath.has_extension() || gmsRoomPath.extension() != ".json") return;

            ke::Log::instance()->info("Loading GM:S room asset: {}", gmsRoomPath.string());

            auto roomResource = std::make_shared<GMSRoomResource>();
            roomResource->setName(gmsRoomPath.stem().string());
            roomResource->setSourcePath(gmsRoomPath.string());

            std::ifstream roomFileStream{ gmsRoomPath };
            ke::json roomJson;
            roomFileStream >> roomJson;

            //
            // Load general room info.
            //
            GMSRoomResource::SizeType roomSize;
            roomSize.width  = roomJson["size"]["width"].get<unsigned>();
            roomSize.height = roomJson["size"]["height"].get<unsigned>();
            roomResource->setSize(roomSize);
            roomResource->setSpeed(roomJson["speed"].get<int>());
            auto roomColourStr = roomJson["colour"].get<ke::String>();
            roomResource->setColour(::gmsColourStrToColour(roomColourStr));

            //
            // load background info
            //
            const auto & roomBackgroundsJson = roomJson["bgs"];
            for (const auto & backgroundJson : roomBackgroundsJson)
            {
                GMSRoomBackgroundInfo backgroundInfo;
                backgroundInfo.enabled    = backgroundJson["enabled"].get<bool>();
                backgroundInfo.foreground = backgroundJson["foreground"].get<bool>();
                backgroundInfo.pos        = { backgroundJson["pos"]["x"].get<int>(), -backgroundJson["pos"]["y"].get<int>() };
                backgroundInfo.tilex      = backgroundJson["tilex"].get<bool>();
                backgroundInfo.tiley      = backgroundJson["tiley"].get<bool>();
                backgroundInfo.speed      = { backgroundJson["speed"]["x"].get<int>(), -backgroundJson["speed"]["y"].get<int>() };
                backgroundInfo.stretch    = backgroundJson["stretch"].get<bool>();
                backgroundInfo.bg         = backgroundJson.value("bg", "");
                backgroundInfo.bg_hash    = hasher(backgroundInfo.bg);
                roomResource->addBackgroundInfo(backgroundInfo);
            }

            //
            // load tile instances
            //
            const auto & roomTilesJson = roomJson["tiles"];
            roomResource->tiles.reserve(roomTilesJson.size());
            for (const auto & tileJson : roomTilesJson)
            {
                pf::GMSRoomTileInstance newTile;
                newTile.instanceid = tileJson["instanceid"].get<unsigned>();

                // Here we make sure to convert the GM:S room coordinates to KEngine's world coordinates.
                // I.e. y-down to y-up.
                // Texture coordinates are the same at the moment at y-down. I.e. (0,0) at top left.
                newTile.pos       = { tileJson["pos"]["x"].get<int>(), -tileJson["pos"]["y"].get<int>() };
                newTile.bg        = tileJson["bg"].get<ke::String>();
                newTile.bg_hash   = hasher(newTile.bg);
                newTile.sourcepos = { tileJson["sourcepos"]["x"].get<int>(), tileJson["sourcepos"]["y"].get<int>() }; // sourcepos is y-down local image coordinates.
                newTile.size      = { tileJson["size"]["width"].get<int>(), tileJson["size"]["height"].get<int>() };
                newTile.scale     = { tileJson["scale"]["x"].get<float>(), tileJson["scale"]["y"].get<float>() };
                newTile.colour    = ::gmsColourStrToColour(tileJson["colour"].get<ke::String>());

                // Here convert GM:S' depth system to KEngine's depth system.
                // GM:S depth value: larger == further back.
                // KEngine depth value: larger == further in front.
                newTile.tiledepth = -tileJson["tiledepth"].get<ke::graphics::DepthType>();

                roomResource->addTile(newTile);
            }

            //
            // load object instances
            //
            const auto & roomObjsJson = roomJson["objs"];
            roomResource->objects.reserve(roomObjsJson.size());
            for (const auto & objJson : roomObjsJson)
            {
                pf::GMSRoomObjectInstance obj;
                obj.instanceid = objJson["instanceid"].get<ke::EntityId>();
                obj.obj        = objJson["obj"].get<ke::String>();
                obj.pos        = { objJson["pos"]["x"].get<int>(), -objJson["pos"]["y"].get<int>() };
                obj.scale      = { objJson["scale"]["x"].get<float>(), objJson["scale"]["y"].get<float>() };
                obj.rotation   = objJson["rotation"].get<float>();
                obj.colour     = ::gmsColourStrToColour(objJson["colour"].get<ke::String>());

                roomResource->addObject(obj);
            }

            ke::App::instance()->getResourceManager()->registerResource(roomResource);
        });
    }

    void GMSAssetResourceManagementSystem::loadObjectAssets(void)
    {
        ke::Log::instance()->info("Scanning GM:S object assets...");
        const auto assetDirPath = ke::App::getCommandLineArgValue(pf::cli::ExecAssetsPath).as<ke::String>();
        const auto gmsObjectRootDirPath = fs::path{ assetDirPath } / "object";
        const auto gmsObjectPaths = ke::FileSystemHelper::getFilePaths(gmsObjectRootDirPath);
        std::for_each(std::execution::par_unseq, std::begin(gmsObjectPaths), std::end(gmsObjectPaths), [&](const auto & gmsObjectPath)
        {
            if (!gmsObjectPath.has_extension() || gmsObjectPath.extension() != "json") return;

            ke::Log::instance()->info("Loading GM:S object asset: {}", gmsObjectPath.string());

            std::ifstream objectFileStream{ gmsObjectPath };
            ke::json objectJson;
            objectFileStream >> objectJson;

            auto objectResource = std::make_shared<pf::GMSObjectResource>(fs::path(gmsObjectPath).stem().string(), gmsObjectPath.string());
            objectResource->sprite   = objectJson["sprite"].get<ke::String>();
            objectResource->visible  = objectJson["visible"].get<bool>();
            objectResource->solid    = objectJson["solid"].get<bool>();
            objectResource->depth    = objectJson["depth"].get<decltype(objectResource->depth)>();
            objectResource->persist  = objectJson["persist"].get<bool>();
            objectResource->sensor   = objectJson["sensor"].get<bool>();
            objectResource->colshape = objectJson["colshape"].get<ke::String>();

            ke::App::instance()->getResourceManager()->registerResource(objectResource);
        });
    }
}<|endoftext|>


<commit_before>
// Includes.
#include "UI/mainwindow.h"
#include "App/App.h"

#include "App/Factories/AdditionNodeFactoryDelegate.h"
#include "App/Factories/ConstantNodeFactoryDelegate.h"
#include "App/Factories/PrinterNodeFactoryDelegate.h"

// Qt.
#include <QApplication>

QString titleString()
{
    QString name = QString::fromStdString(App::appName());
    QString version = QString::fromStdString(App::appVersion());
    return QString("%1 - v%2").arg(name).arg(version);
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    App app;
    app.addNodeFactory(new AdditionNodeFactoryDelegate);
    app.addNodeFactory(new ConstantNodeFactoryDelegate);
    app.addNodeFactory(new PrinterNodeFactoryDelegate);

    MainWindow w(&app);
    w.setWindowTitle(titleString());
    w.setMinimumSize(640, 480);
    w.show();

    app.setUI(&w);
    app.setDelegate(&w);

    return a.exec();
}
<commit_msg>Enlarge the minimum size of the main window, so that the scene view has enough space again.<commit_after>
// Includes.
#include "UI/mainwindow.h"
#include "App/App.h"

#include "App/Factories/AdditionNodeFactoryDelegate.h"
#include "App/Factories/ConstantNodeFactoryDelegate.h"
#include "App/Factories/PrinterNodeFactoryDelegate.h"

// Qt.
#include <QApplication>

QString titleString()
{
    QString name = QString::fromStdString(App::appName());
    QString version = QString::fromStdString(App::appVersion());
    return QString("%1 - v%2").arg(name).arg(version);
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    App app;
    app.addNodeFactory(new AdditionNodeFactoryDelegate);
    app.addNodeFactory(new ConstantNodeFactoryDelegate);
    app.addNodeFactory(new PrinterNodeFactoryDelegate);

    MainWindow w(&app);
    w.setWindowTitle(titleString());
    w.setMinimumSize(800, 600);
    w.show();

    app.setUI(&w);
    app.setDelegate(&w);

    return a.exec();
}
<|endoftext|>


<commit_before>#include "mqtt_tcp_server.hpp"
#include <stdexcept>
#include <iostream>

using namespace std;

int main(int argc, char*[]) {
    cout << "C++ MQTT server" << endl;
    try {
        constexpr int port = 1883;
        const auto useCache = argc < 2;
        if(!useCache) {
            cout << "Disabling the cache" << endl;
        }
        MqttTcpServer server(port, useCache);
        server.run();
    } catch(const std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}
<commit_msg>Using the cache no longer default<commit_after>#include "mqtt_tcp_server.hpp"
#include <stdexcept>
#include <iostream>

using namespace std;

int main(int argc, char*[]) {
    cout << "C++ MQTT server" << endl;
    try {
        constexpr int port = 1883;
        const auto useCache = argc > 1;
        if(useCache) {
            cout << "Enabling the cache" << endl;
        }
        MqttTcpServer server(port, useCache);
        server.run();
    } catch(const std::exception& e) {
        std::cerr << "Exception: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}
<|endoftext|>


<commit_before>99f03347-ad5b-11e7-a3c1-ac87a332f658<commit_msg>For bobby to integrate at some point<commit_after>9a652be3-ad5b-11e7-9c20-ac87a332f658<|endoftext|>


<commit_before>586a0be3-2748-11e6-a0b9-e0f84713e7b8<commit_msg>Put the thingie in the thingie<commit_after>58769c57-2748-11e6-b9fe-e0f84713e7b8<|endoftext|>


<commit_before>10a6c2ca-2748-11e6-9c7b-e0f84713e7b8<commit_msg>NO CHANGES<commit_after>10b3cba1-2748-11e6-b57b-e0f84713e7b8<|endoftext|>


<commit_before>#include "SmartPointers.hpp"
#include "Exception.hpp"
#include "ImageImporter2D.hpp"
#include "ImageExporter2D.hpp"
#include "VTKImageExporter.hpp"
#include "VTKImageImporter.hpp"
#include "ITKImageExporter.hpp"
#include "ImageStreamer2D.hpp"
#include "DeviceManager.hpp"
#include "GaussianSmoothingFilter2D.hpp"
#include "SimpleWindow.hpp"
#include "ImageRenderer.hpp"

#include <vtkVersion.h>
#include <vtkImageData.h>
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkImageMapper.h>
#include <vtkActor2D.h>

#include <QApplication>

using namespace fast;

Image2D::pointer create() {
    // Example of importing one 2D image
    ImageImporter2D::pointer importer = ImageImporter2D::New();
    importer->setFilename("lena.jpg");
    return importer->getOutput();
}

int main(int argc, char ** argv) {

    // Get a GPU device and set it as the default device
    DeviceManager& deviceManager = DeviceManager::getInstance();
    deviceManager.setDefaultDevice(deviceManager.getOneGPUDevice(true));

    // Example of importing, processing and exporting a 2D image
    ImageImporter2D::pointer importer = ImageImporter2D::New();
    importer->setFilename("lena.jpg");
    GaussianSmoothingFilter2D::pointer filter = GaussianSmoothingFilter2D::New();
    filter->setInput(importer->getOutput());
    filter->setMaskSize(7);
    filter->setStandardDeviation(10);
    Image2D::pointer filteredImage = filter->getOutput();
    ImageExporter2D::pointer exporter = ImageExporter2D::New();
    exporter->setFilename("test.jpg");
    exporter->setInput(filteredImage);
    exporter->update();

    // Example of displaying an image on screen using ImageRenderer (2D) and SimpleWindow
    // TODO The QApplication part should ideally be hid away
    QApplication app(argc,argv);
    ImageRenderer::pointer renderer = ImageRenderer::New();
    renderer->setInput(filteredImage);
    SimpleWindow::pointer window = SimpleWindow::New();
    window->addRenderer(renderer);
    window->resize(512,512);
    window->runMainLoop();

    // Example of creating a pipeline in another scope and updating afterwards
    Image2D::pointer image2 = create();
    std::cout << "after create" << std::endl;
    image2->update();

    // Example of streaming 2D images
    ImageStreamer2D::pointer streamer = ImageStreamer2D::New();
    streamer->setFilenameFormat("test_#.jpg");
    GaussianSmoothingFilter2D::pointer filter2 = GaussianSmoothingFilter2D::New();
    filter2->setInput(streamer->getOutput());
    filter2->setMaskSize(7);
    filter2->setStandardDeviation(10);
    Image2Dt::pointer dynamicImage = filter2->getOutput();
    // Call update 4 times
    int i = 4;
    while(--i) {
        dynamicImage->update();
    }

    // ITK Export example
    typedef itk::Image<float, 2> ImageType;
    ITKImageExporter<ImageType>::Pointer itkExporter = ITKImageExporter<ImageType>::New();
    itkExporter->SetInput(filteredImage);
    ImageType::Pointer itkImage = itkExporter->GetOutput();
    itkExporter->Update();

    // VTK Import example
    VTKImageImporter::pointer vtkImporter = VTKImageImporter::New();
    vtkImporter->setInput(vtkImage);
    Image2D::pointer importedImage = vtkImporter->getOutput();
    vtkImporter->update();
}
<commit_msg>added missing code<commit_after>#include "SmartPointers.hpp"
#include "Exception.hpp"
#include "ImageImporter2D.hpp"
#include "ImageExporter2D.hpp"
#include "VTKImageExporter.hpp"
#include "VTKImageImporter.hpp"
#include "ITKImageExporter.hpp"
#include "ImageStreamer2D.hpp"
#include "DeviceManager.hpp"
#include "GaussianSmoothingFilter2D.hpp"
#include "SimpleWindow.hpp"
#include "ImageRenderer.hpp"

#include <vtkVersion.h>
#include <vtkImageData.h>
#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkImageMapper.h>
#include <vtkActor2D.h>

#include <QApplication>

using namespace fast;

Image2D::pointer create() {
    // Example of importing one 2D image
    ImageImporter2D::pointer importer = ImageImporter2D::New();
    importer->setFilename("lena.jpg");
    return importer->getOutput();
}

int main(int argc, char ** argv) {

    // Get a GPU device and set it as the default device
    DeviceManager& deviceManager = DeviceManager::getInstance();
    deviceManager.setDefaultDevice(deviceManager.getOneGPUDevice(true));

    // Example of importing, processing and exporting a 2D image
    ImageImporter2D::pointer importer = ImageImporter2D::New();
    importer->setFilename("lena.jpg");
    GaussianSmoothingFilter2D::pointer filter = GaussianSmoothingFilter2D::New();
    filter->setInput(importer->getOutput());
    filter->setMaskSize(7);
    filter->setStandardDeviation(10);
    Image2D::pointer filteredImage = filter->getOutput();
    ImageExporter2D::pointer exporter = ImageExporter2D::New();
    exporter->setFilename("test.jpg");
    exporter->setInput(filteredImage);
    exporter->update();

    // Example of displaying an image on screen using ImageRenderer (2D) and SimpleWindow
    // TODO The QApplication part should ideally be hid away
    QApplication app(argc,argv);
    ImageRenderer::pointer renderer = ImageRenderer::New();
    renderer->setInput(filteredImage);
    SimpleWindow::pointer window = SimpleWindow::New();
    window->addRenderer(renderer);
    window->resize(512,512);
    window->runMainLoop();

    // Example of creating a pipeline in another scope and updating afterwards
    Image2D::pointer image2 = create();
    std::cout << "after create" << std::endl;
    image2->update();

    // Example of streaming 2D images
    ImageStreamer2D::pointer streamer = ImageStreamer2D::New();
    streamer->setFilenameFormat("test_#.jpg");
    GaussianSmoothingFilter2D::pointer filter2 = GaussianSmoothingFilter2D::New();
    filter2->setInput(streamer->getOutput());
    filter2->setMaskSize(7);
    filter2->setStandardDeviation(10);
    Image2Dt::pointer dynamicImage = filter2->getOutput();
    // Call update 4 times
    int i = 4;
    while(--i) {
        dynamicImage->update();
    }

    // VTK Export and render example
    vtkSmartPointer<VTKImageExporter> vtkExporter = VTKImageExporter::New();
    vtkExporter->SetInput(filteredImage);
    vtkSmartPointer<vtkImageData> vtkImage = vtkExporter->GetOutput();
    vtkExporter->Update();

    // VTK mess for getting the image on screen
    vtkSmartPointer<vtkImageMapper> imageMapper = vtkSmartPointer<vtkImageMapper>::New();
#if VTK_MAJOR_VERSION <= 5
    imageMapper->SetInputConnection(vtkImage->GetProducerPort());
#else
    imageMapper->SetInputData(vtkImage);
#endif
    imageMapper->SetColorWindow(1);
    imageMapper->SetColorLevel(0.5);

    vtkSmartPointer<vtkActor2D> imageActor = vtkSmartPointer<vtkActor2D>::New();
    imageActor->SetMapper(imageMapper);

    // Setup renderers and render window
    vtkSmartPointer<vtkRenderer> renderer2 = vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer2);
    renderWindow->SetSize(filteredImage->getWidth(), filteredImage->getHeight());

    // Setup render window interactor
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();

    vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
    renderWindowInteractor->SetInteractorStyle(style);
    renderWindowInteractor->SetRenderWindow(renderWindow);
    renderer2->AddActor2D(imageActor);
    renderWindow->Render();
    renderWindowInteractor->Start();

    // ITK Export example
    typedef itk::Image<float, 2> ImageType;
    ITKImageExporter<ImageType>::Pointer itkExporter = ITKImageExporter<ImageType>::New();
    itkExporter->SetInput(filteredImage);
    ImageType::Pointer itkImage = itkExporter->GetOutput();
    itkExporter->Update();

    // VTK Import example
    VTKImageImporter::pointer vtkImporter = VTKImageImporter::New();
    vtkImporter->setInput(vtkImage);
    Image2D::pointer importedImage = vtkImporter->getOutput();
    vtkImporter->update();
}
<|endoftext|>


<commit_before>#include <boost/python.hpp>
#include <boost/multi_array.hpp>
#include <boost/foreach.hpp>
#include <vector>
#include <iostream>
#include <array>
#include <iostream>
#include <string>
#include "shared/path_creator.hpp"
#include "shared/tdmap.hpp"
#include "gui.cpp"
#include "shared/sizes.h"
#include "shared/sprite.hpp"
#include <stdlib.h>     /* srand, rand */
#include <time.h>
#include "shared/spritesheet.hpp"

class TDGamecore
{
    private:
        std::vector<Player> players;
        TDMap * map;
        GUI * gui;

  	public:
        TDGamecore(int number_of_players)
        {
            TDGamecore(number_of_players, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        }
        TDGamecore(int number_of_players, int width, int height)
        {
            srand(time(NULL));
            Path * path = new Path(NUM_ROWS, NUM_COLS);
            std::vector<Path *> paths {path} ;
            map = new TDMap(width, height, paths);
            Tower * tower = new Tower(Coordinate(2,4));
            tower->set_image_string("tower.png");
            tower->set_attack_image_string("arrow.png");
            map->add_tower(tower);
            Spritesheet zombie ("zombie.png", Coordinate(128, 128));
            std::vector<Coordinate> cycles;
            for(int i = 5; i < 13; i++)
                cycles.push_back(Coordinate(i, 5));
            Sprite * sprite = new Sprite(path, &zombie, cycles);
            map->add_sprite(sprite);
            gui = new GUI(NUM_ROWS, NUM_COLS, paths, map);
           	gui->Update();
           	sprite->move_to_next_position();
           	gui->Update();
           	sprite->move_to_next_position();
            sprite->set_attacked();
           	tower->set_attacking(Coordinate(1, 5));
            gui->Update();
            tower->remove_attack_tile(Coordinate(1, 5));
            sprite->move_to_next_position();
            tower->set_attacking(Coordinate(2, 5));
            gui->Update();
            tower->remove_attack_tile(Coordinate(2, 5));
            sprite->move_to_next_position();
            tower->set_attacking(Coordinate(3, 5));
            gui->Update();
            tower->remove_attack_tile(Coordinate(3, 5));
            sprite->die();
            std::vector<Coordinate> v;
            for(int i = 10; i < 30; i++)
                v.push_back(Coordinate(i, 5));
            sprite->set_new_cycles(v);
            gui->Update();
            map->remove_sprite(sprite);
            gui->Update();
        }

        void generate_new_player()
        {
            players.push_back(*(new Player()));
        }
};

using namespace boost::python;

BOOST_PYTHON_MODULE(libtd)
{
    class_<TDGamecore>("TDGamecore", init<int>());
}
<commit_msg>merging<commit_after>#include <boost/python.hpp>
#include <boost/multi_array.hpp>
#include <boost/foreach.hpp>
#include <vector>
#include <iostream>
#include <array>
#include <iostream>
#include <string>
#include "shared/path_creator.hpp"
#include "shared/tdmap.hpp"
#include "gui.cpp"
#include "shared/sizes.h"
#include "shared/sprite.hpp"
#include <stdlib.h>     /* srand, rand */
#include <time.h>
#include "shared/spritesheet.hpp"

class TDGamecore
{
    private:
        std::vector<Player> players;
        TDMap * map;
        GUI * gui;

  	public:
        TDGamecore(int number_of_players)
        {
            TDGamecore(number_of_players, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        }
        TDGamecore(int number_of_players, int width, int height)
        {
            srand(time(NULL));
            Path * path = new Path(NUM_ROWS, NUM_COLS);
            std::vector<Path *> paths {path} ;
            map = new TDMap(width, height, paths);
            Spritesheet projectile ("projectile2.png", Coordinate(64, 64), 2);
            std::vector<Coordinate> tower_cycles = {Coordinate(1, 1), Coordinate(0, 1), Coordinate(2, 0)};
            Tower * tower = new Tower(Coordinate(2,4), "tower.png", &projectile, tower_cycles);
            map->add_tower(tower);
            Spritesheet zombie ("zombie.png", Coordinate(128, 128), 8);
            std::vector<Coordinate> cycles;
            for(int i = 5; i < 13; i++)
                cycles.push_back(Coordinate(i, 5));
            Sprite * sprite = new Sprite(path, &zombie, cycles);
            map->add_sprite(sprite);
            gui = new GUI(NUM_ROWS, NUM_COLS, paths, map);
           	gui->Update();
           	sprite->move_to_next_position();
           	gui->Update();
           	sprite->move_to_next_position();
            sprite->set_attacked();
           	tower->set_attacking(Coordinate(1, 5));
            gui->Update();
            tower->remove_attack_tile(Coordinate(1, 5));
            sprite->move_to_next_position();
            tower->set_attacking(Coordinate(2, 5));
            gui->Update();
            tower->remove_attack_tile(Coordinate(2, 5));
            sprite->move_to_next_position();
            tower->set_attacking(Coordinate(3, 5));
            gui->Update();
            tower->remove_attack_tile(Coordinate(3, 5));
            sprite->die();
            std::vector<Coordinate> v;
            for(int i = 10; i < 30; i++)
                v.push_back(Coordinate(i, 5));
            sprite->set_new_cycles(v);
            gui->Update();
            Sprite * sprite2 = new Sprite(path, &zombie, cycles);
            map->add_sprite(sprite2);
            map->remove_sprite(sprite);
            gui->Update();
            sprite2->move_to_next_position();
            gui->Update();
            sprite2->move_to_next_position();
            gui->Update();
            sprite2->move_to_next_position();
            gui->Update();
            sprite2->move_to_next_position();
            gui->Update();
            sprite2->move_to_next_position();
            gui->Update();
            sprite2->move_to_next_position();
            gui->Update();
            sprite2->move_to_next_position();
            gui->Update();
            sprite2->move_to_next_position();
            gui->Update();

        }

        void generate_new_player()
        {
            players.push_back(*(new Player()));
        }
};

using namespace boost::python;

BOOST_PYTHON_MODULE(libtd)
{
    class_<TDGamecore>("TDGamecore", init<int>());
}
<|endoftext|>


<commit_before>f267c2ab-ad59-11e7-aa9e-ac87a332f658<commit_msg>Nope, didn't work, now it does<commit_after>f2e53cf0-ad59-11e7-a38c-ac87a332f658<|endoftext|>


<commit_before>#include "SIO/LCIORecords.h"

#include "SIO_functions.h"
#include "SIO_stream.h"

#include <SIO/SIORunHeaderHandler.h>
#include <SIO/SIOEventHandler.h>
#include <SIO/SIOCollectionHandler.h>
#include <SIO/SIORandomAccessHandler.h>
#include <EVENT/LCEvent.h>
#include <Exceptions.h>

namespace SIO {

  sio::record_ptr LCIORecords::createEventHeaderRecord( const EVENT::LCEvent *event ) const {
    auto eventHeaderRecord = std::make_shared<SIO_record>( LCSIO_HEADERRECORDNAME );
    eventHeaderRecord->add_block<SIOEventHandler>( LCSIO_HEADERBLOCKNAME );
    auto block = eventHeaderRecord->get_block_as<SIOEventHandler>( LCSIO_HEADERBLOCKNAME );
    block->setEvent( event );
    return eventHeaderRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createEventHeaderRecord( IOIMPL::LCEventIOImpl **event, const std::vector<std::string> &readCol ) const {
    auto eventHeaderRecord = std::make_shared<SIO_record>( LCSIO_HEADERRECORDNAME );
    eventHeaderRecord->add_block<SIOEventHandler>( LCSIO_HEADERBLOCKNAME );
    auto block = eventHeaderRecord->get_block_as<SIOEventHandler>( LCSIO_HEADERBLOCKNAME );
    block->setEventPtr( event );
    block->setReadCollectionNames( readCol );
    return eventHeaderRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createEventRecord( const EVENT::LCEvent *event ) const {
    // create the event record
    auto eventRecord = std::make_shared<SIO_record>( LCSIO_EVENTRECORDNAME );
    // loop over collections and setup the blocks for writing
    auto collectionNames = event->getCollectionNames();
    for( auto collectionName : *collectionNames ) {
      auto collection = event->getCollection( collectionName );
      if( collection->isTransient() ) {
        continue;
      }
      try {
        eventRecord->add_block<SIOCollectionHandler>( collectionName, collection->getTypeName(), nullptr );
      }
      catch(EVENT::Exception& ex) {
        continue;
      }
      auto block = eventRecord->get_block_as<SIOCollectionHandler>( collectionName );
      auto handler = _handlerMgr.getHandler( collection->getTypeName() );
      block->setHandler( handler );
    }
    return eventRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createEventRecord(IOIMPL::LCEventIOImpl **event) const {
    // create the event record
    auto eventRecord = std::make_shared<SIO_record>( LCSIO_EVENTRECORDNAME );
    // loop over collections and setup the blocks for reading/writing an event
    auto collectionNames = (*event)->getCollectionNames();
    for( auto collectionName : *collectionNames ) {
      auto collection = (*event)->getCollection( collectionName );
      try {
        eventRecord->add_block<SIOCollectionHandler>( collectionName, collection->getTypeName(), event );
      }
      catch(EVENT::Exception& ex) {
        continue;
      }
      auto block = eventRecord->get_block_as<SIOCollectionHandler>( collectionName );
      auto handler = _handlerMgr.getHandler( collection->getTypeName() );
      block->setHandler( handler );
      block->setEvent( event );
    }
    return eventRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createRunRecord( const EVENT::LCRunHeader *runHeader ) const {
    auto runRecord = std::make_shared<SIO_record>( LCSIO_RUNRECORDNAME );
    runRecord->add_block<SIORunHeaderHandler>( LCSIO_RUNBLOCKNAME );
    runRecord->get_block_as<SIORunHeaderHandler>( LCSIO_RUNBLOCKNAME )->setRunHeader( runHeader );
    return runRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createRunRecord( IOIMPL::LCRunHeaderIOImpl **runHeader ) const {
    auto runRecord = std::make_shared<SIO_record>( LCSIO_RUNRECORDNAME );
    runRecord->add_block<SIORunHeaderHandler>( LCSIO_RUNBLOCKNAME );
    runRecord->get_block_as<SIORunHeaderHandler>( LCSIO_RUNBLOCKNAME )->setRunHeaderPtr( runHeader );
    return runRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createRandomAccessRecord( LCIORandomAccessMgr *raMgr ) const {
    auto raRecord = std::make_shared<SIO_record>( LCSIO_ACCESSRECORDNAME );
    raRecord->add_block<SIORandomAccessHandler>( LCSIO_ACCESSBLOCKNAME, raMgr );
    return raRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createIndexRecord( LCIORandomAccessMgr *raMgr ) const {
    auto indexRecord = std::make_shared<SIO_record>( LCSIO_INDEXRECORDNAME );
    indexRecord->add_block<SIORandomAccessHandler>( LCSIO_INDEXBLOCKNAME, raMgr );
    return indexRecord;
  }

} // namespace

<commit_msg>Fixed wrong handler type for index record<commit_after>#include "SIO/LCIORecords.h"

#include "SIO_functions.h"
#include "SIO_stream.h"

#include <SIO/SIORunHeaderHandler.h>
#include <SIO/SIOEventHandler.h>
#include <SIO/SIOCollectionHandler.h>
#include <SIO/SIORandomAccessHandler.h>
#include <SIO/SIOIndexHandler.h>
#include <EVENT/LCEvent.h>
#include <Exceptions.h>

namespace SIO {

  sio::record_ptr LCIORecords::createEventHeaderRecord( const EVENT::LCEvent *event ) const {
    auto eventHeaderRecord = std::make_shared<SIO_record>( LCSIO_HEADERRECORDNAME );
    eventHeaderRecord->add_block<SIOEventHandler>( LCSIO_HEADERBLOCKNAME );
    auto block = eventHeaderRecord->get_block_as<SIOEventHandler>( LCSIO_HEADERBLOCKNAME );
    block->setEvent( event );
    return eventHeaderRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createEventHeaderRecord( IOIMPL::LCEventIOImpl **event, const std::vector<std::string> &readCol ) const {
    auto eventHeaderRecord = std::make_shared<SIO_record>( LCSIO_HEADERRECORDNAME );
    eventHeaderRecord->add_block<SIOEventHandler>( LCSIO_HEADERBLOCKNAME );
    auto block = eventHeaderRecord->get_block_as<SIOEventHandler>( LCSIO_HEADERBLOCKNAME );
    block->setEventPtr( event );
    block->setReadCollectionNames( readCol );
    return eventHeaderRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createEventRecord( const EVENT::LCEvent *event ) const {
    // create the event record
    auto eventRecord = std::make_shared<SIO_record>( LCSIO_EVENTRECORDNAME );
    // loop over collections and setup the blocks for writing
    auto collectionNames = event->getCollectionNames();
    for( auto collectionName : *collectionNames ) {
      auto collection = event->getCollection( collectionName );
      if( collection->isTransient() ) {
        continue;
      }
      try {
        eventRecord->add_block<SIOCollectionHandler>( collectionName, collection->getTypeName(), nullptr );
      }
      catch(EVENT::Exception& ex) {
        continue;
      }
      auto block = eventRecord->get_block_as<SIOCollectionHandler>( collectionName );
      auto handler = _handlerMgr.getHandler( collection->getTypeName() );
      block->setHandler( handler );
    }
    return eventRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createEventRecord(IOIMPL::LCEventIOImpl **event) const {
    // create the event record
    auto eventRecord = std::make_shared<SIO_record>( LCSIO_EVENTRECORDNAME );
    // loop over collections and setup the blocks for reading/writing an event
    auto collectionNames = (*event)->getCollectionNames();
    for( auto collectionName : *collectionNames ) {
      auto collection = (*event)->getCollection( collectionName );
      try {
        eventRecord->add_block<SIOCollectionHandler>( collectionName, collection->getTypeName(), event );
      }
      catch(EVENT::Exception& ex) {
        continue;
      }
      auto block = eventRecord->get_block_as<SIOCollectionHandler>( collectionName );
      auto handler = _handlerMgr.getHandler( collection->getTypeName() );
      block->setHandler( handler );
      block->setEvent( event );
    }
    return eventRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createRunRecord( const EVENT::LCRunHeader *runHeader ) const {
    auto runRecord = std::make_shared<SIO_record>( LCSIO_RUNRECORDNAME );
    runRecord->add_block<SIORunHeaderHandler>( LCSIO_RUNBLOCKNAME );
    runRecord->get_block_as<SIORunHeaderHandler>( LCSIO_RUNBLOCKNAME )->setRunHeader( runHeader );
    return runRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createRunRecord( IOIMPL::LCRunHeaderIOImpl **runHeader ) const {
    auto runRecord = std::make_shared<SIO_record>( LCSIO_RUNRECORDNAME );
    runRecord->add_block<SIORunHeaderHandler>( LCSIO_RUNBLOCKNAME );
    runRecord->get_block_as<SIORunHeaderHandler>( LCSIO_RUNBLOCKNAME )->setRunHeaderPtr( runHeader );
    return runRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createRandomAccessRecord( LCIORandomAccessMgr *raMgr ) const {
    auto raRecord = std::make_shared<SIO_record>( LCSIO_ACCESSRECORDNAME );
    raRecord->add_block<SIORandomAccessHandler>( LCSIO_ACCESSBLOCKNAME, raMgr );
    return raRecord;
  }

  //----------------------------------------------------------------------------

  sio::record_ptr LCIORecords::createIndexRecord( LCIORandomAccessMgr *raMgr ) const {
    auto indexRecord = std::make_shared<SIO_record>( LCSIO_INDEXRECORDNAME );
    indexRecord->add_block<SIOIndexHandler>( LCSIO_INDEXBLOCKNAME, raMgr );
    return indexRecord;
  }

} // namespace

<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <string>
#include <iterator>
#include <functional>
#include <algorithm>
#include <deque>
#include <sstream>

std::string trim_begin(const std::string& str) {
    auto alpha = std::find_if_not(str.begin(), str.end(), ::isspace);
    return str.substr(std::distance(str.begin(), alpha));
}

std::string trim_end(const std::string& str) {
    auto alpha = std::find_if_not(str.rbegin(), str.rend(), ::isspace).base();
    return str.substr(0, std::distance(str.begin(), alpha));
}

std::string str_to_lower(const std::string& str) {
    std::string lowercase;
    std::transform(std::begin(str), std::end(str), std::back_inserter(lowercase), ::tolower);
    return lowercase;
}

std::vector<std::string> str_split_whitespace(const std::string& str) {
    std::vector<std::string> words;
    std::istringstream is(str);
    std::copy(
        std::istream_iterator<std::string>(is),
        std::istream_iterator<std::string>(),
        std::back_inserter(words));
    return words;
}

std::vector<std::string> str_split(const std::string& str, const char *delims) {
    size_t found = std::string::npos, prev = 0;
    std::vector<std::string> out;
    out.reserve(log(str.size()));

    found = str.find_first_of(delims);
    while (found != std::string::npos) {
        if (prev < found) {
            out.push_back(str.substr(prev, found - prev));
        }
        prev = found + 1;
        found = str.find_first_of(delims, prev);
    }
    out.push_back(str.substr(prev, std::string::npos));

    return out;
}

std::vector<std::string> extract_sentences(const std::string& str) {
    return str_split(str, ".?!");
}

std::vector<std::string> extract_words(const std::string& str) {
    return str_split(str, " .,;\"?!");
}

class sentence_file_reader {
    std::ifstream ifs;
    std::deque<std::string> sentence_buffer;
    static const size_t BUFFER_SIZE = 16 * 1024;
    char char_buffer[BUFFER_SIZE];

public:
    sentence_file_reader(const char *filename) :
        ifs(filename, std::ios::in)
    {}

    ~sentence_file_reader() {
        ifs.close();
    }

    std::string get_next_sentence() {
        std::string sn;
        if (!sentence_buffer.empty()) {
            sn = sentence_buffer.front();
            sentence_buffer.pop_front();
        }
        else {
            ifs.getline(char_buffer, BUFFER_SIZE);
            auto sentences = extract_sentences(char_buffer);
            sentence_buffer = std::deque<std::string>(std::begin(sentences), std::end(sentences));
            sn = get_next_sentence();
        }
        return trim_begin(trim_end(sn));
    }
    bool has_more() {
        return ifs.good() || !sentence_buffer.empty();
    }
};

struct word_node {
    word_node(const std::string& name) :
    normalized_name(str_to_lower(name))
    {}

    void add_original_name(const std::string& original) {
        auto found = std::find(
            std::begin(original_names),
            std::end(original_names),
            original);

        if (found == original_names.end()) {
            original_names.push_back(original);
        }
    }

    std::vector<std::string> original_names;
    std::string normalized_name;
    std::map<word_node*, size_t> lefts;
    std::map<word_node*, size_t> rights;
};

struct word_graph {
    std::map<std::string, word_node*> word_nodes;
    word_node *head;

    word_node *get_or_create(std::string name) {
        auto word = str_to_lower(name);
        auto name_exists = word_nodes.equal_range(word);
        auto found_node = name_exists.first;
        if (name_exists.first == name_exists.second) {
            word_node *name_node = new word_node(name);
            found_node = word_nodes.insert(name_exists.second, std::make_pair(word, name_node));
        }
        found_node->second->add_original_name(name);
        return found_node->second;
    }

    void make_link(const std::string& a, const std::string& b) {
        word_node *a_node = get_or_create(a);
        word_node *b_node = get_or_create(b);
        a_node->rights[b_node]++;
        b_node->lefts[a_node]++;
    }
};

int main(int argc, char *argv[]) {
    std::ios::ios_base::sync_with_stdio(false);
    const char *in_filename = "test.txt";

    if (argc > 1) {
        in_filename = argv[1];
    }
    sentence_file_reader cfr(in_filename);

    word_graph graph;
    std::string str;
    while (cfr.has_more()) {
        std::string sentence = cfr.get_next_sentence();
        std::vector<std::string> words = extract_words(sentence);

        if (words.size() > 1) {
            graph.make_link(words[0], words[1]);
            for (size_t i = 1, j = 2; j < words.size(); ++i, ++j) {
                graph.make_link(words[i], words[j]);
            }
        }
        else if (words.size() == 1 && !words[0].empty()) {
            graph.get_or_create(words[0]);
        }
    }

    for (auto &kv : graph.word_nodes) {
        std::cout << kv.first << "\n- left: ";
        for (auto &w_node_cnt : kv.second->lefts) {
            std::cout << w_node_cnt.first->normalized_name << ":" << w_node_cnt.second << " ";
        }
        std::cout << "\n- right: ";
        for (auto &w_node_cnt : kv.second->rights) {
            std::cout << w_node_cnt.first->normalized_name << ":" << w_node_cnt.second << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}
<commit_msg>Split better suited for our needs<commit_after>#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <string>
#include <iterator>
#include <functional>
#include <algorithm>
#include <deque>
#include <sstream>

std::string trim_begin(const std::string& str) {
    auto alpha = std::find_if_not(str.begin(), str.end(), ::isspace);
    return str.substr(std::distance(str.begin(), alpha));
}

std::string trim_end(const std::string& str) {
    auto alpha = std::find_if_not(str.rbegin(), str.rend(), ::isspace).base();
    return str.substr(0, std::distance(str.begin(), alpha));
}

std::string str_to_lower(const std::string& str) {
    std::string lowercase;
    std::transform(std::begin(str), std::end(str), std::back_inserter(lowercase), ::tolower);
    return lowercase;
}

std::vector<std::string> str_split_whitespace(const std::string& str) {
    std::vector<std::string> words;
    std::istringstream is(str);
    std::copy(
        std::istream_iterator<std::string>(is),
        std::istream_iterator<std::string>(),
        std::back_inserter(words));
    return words;
}

std::vector<std::string> str_split(const std::string& str, const char *delims) {
    size_t found = std::string::npos, prev = 0;
    std::vector<std::string> out;
    out.reserve(log(str.size()));

    found = str.find_first_of(delims);
    while (found != std::string::npos) {
        if (prev < found) {
            auto sub = str.substr(prev, found - prev);
            if (!sub.empty())
                out.push_back(sub);
        }
        prev = found + 1;
        found = str.find_first_of(delims, prev);
    }
    auto sub = str.substr(prev, std::string::npos);
    if (!sub.empty())
        out.push_back(sub);

    return out;
}

std::vector<std::string> extract_sentences(const std::string& str) {
    return str_split(str, ".?!");
}

std::vector<std::string> extract_words(const std::string& str) {
    return str_split(str, " .,;\"?!\n");
}

class sentence_file_reader {
    std::ifstream ifs;
    std::deque<std::string> sentence_buffer;
    static const size_t BUFFER_SIZE = 16 * 1024;
    char char_buffer[BUFFER_SIZE];

public:
    sentence_file_reader(const char *filename) :
        ifs(filename, std::ios::in)
    {}

    ~sentence_file_reader() {
        ifs.close();
    }

    std::string get_next_sentence() {
        std::string sn;
        if (!sentence_buffer.empty()) {
            sn = sentence_buffer.front();
            sentence_buffer.pop_front();
        }
        else {
            ifs.getline(char_buffer, BUFFER_SIZE);
            auto sentences = extract_sentences(char_buffer);
            sentence_buffer = std::deque<std::string>(std::begin(sentences), std::end(sentences));
            sn = get_next_sentence();
        }
        return trim_begin(trim_end(sn));
    }
    bool has_more() {
        return ifs.good() || !sentence_buffer.empty();
    }
};

struct word_node {
    word_node(const std::string& name) :
    normalized_name(str_to_lower(name))
    {}

    void add_original_name(const std::string& original) {
        auto found = std::find(
            std::begin(original_names),
            std::end(original_names),
            original);

        if (found == original_names.end()) {
            original_names.push_back(original);
        }
    }

    std::vector<std::string> original_names;
    std::string normalized_name;
    std::map<word_node*, size_t> lefts;
    std::map<word_node*, size_t> rights;
};

struct word_graph {
    std::map<std::string, word_node*> word_nodes;
    word_node *head;

    word_node *get_or_create(std::string name) {
        auto word = str_to_lower(name);
        auto name_exists = word_nodes.equal_range(word);
        auto found_node = name_exists.first;
        if (name_exists.first == name_exists.second) {
            word_node *name_node = new word_node(name);
            found_node = word_nodes.insert(name_exists.second, std::make_pair(word, name_node));
        }
        found_node->second->add_original_name(name);
        return found_node->second;
    }

    void make_link(const std::string& a, const std::string& b) {
        word_node *a_node = get_or_create(a);
        word_node *b_node = get_or_create(b);
        a_node->rights[b_node]++;
        b_node->lefts[a_node]++;
    }
};

int main(int argc, char *argv[]) {
    std::ios::ios_base::sync_with_stdio(false);
    const char *in_filename = "test.txt";

    if (argc > 1) {
        in_filename = argv[1];
    }
    sentence_file_reader cfr(in_filename);

    word_graph graph;
    std::string str;
    while (cfr.has_more()) {
        std::string sentence = cfr.get_next_sentence();
        std::vector<std::string> words = extract_words(sentence);

        if (words.size() > 1) {
            graph.make_link(words[0], words[1]);
            for (size_t i = 1, j = 2; j < words.size(); ++i, ++j) {
                graph.make_link(words[i], words[j]);
            }
        }
        else if (words.size() == 1 && !words[0].empty()) {
            graph.get_or_create(words[0]);
        }
    }

    for (auto &kv : graph.word_nodes) {
        std::cout << kv.first << "\n- left: ";
        for (auto &w_node_cnt : kv.second->lefts) {
            std::cout << "'" << w_node_cnt.first->normalized_name << "'" << ":" << w_node_cnt.second << " ";
        }
        std::cout << "\n- right: ";
        for (auto &w_node_cnt : kv.second->rights) {
            std::cout << "'" << w_node_cnt.first->normalized_name << "'" << ":" << w_node_cnt.second << " ";
        }
        std::cout << std::endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>#include <iostream>

int main() {
  std::cout << "Hello, World!" << std::endl;
}
<commit_msg>Delete main.cpp<commit_after><|endoftext|>


<commit_before>#include <vector>
#include <tuple>
#include <fstream>
#include "Windows.h"
#include <psapi.h>
#include <vector>

using namespace std;

namespace {
  typedef void(*callable)(void*);
  typedef tuple<void*, size_t> MyTuple;
  constexpr DWORD invocation_interval_ms = 15 * 1000;
  constexpr size_t stack_size = 0x10000;

  struct VersionToOffset {
    WORD file_version[4];
    uint32_t relative_offset;
  };

  /*
   * See https://changewindows.org/ for a detailed Windows 10 release history,
   * including updates to milestone releases.  A new build of the "mshtml.dll"
   * file has not been included with every update.
   */

  vector<VersionToOffset> mshtml_gadget_offset_map = {
    // Windows 10 Creators Update (Build v10.0.15063.0 as of Mar 20, 2017)
    {    11,     0, 15063,     0, 0x00585098 },
    // Windows 10 Anniversary Update (Build v10.0.14393.953 as of Mar 14, 2017)
    {    11,     0, 14393,   953, 0x003CBD4D },
    // The default ROP gadget offset (for Windows v8.1?)
    {     0,     0,     0,     0, 0x006D55DD }
  };

  struct SetupConfiguration {
    uint32_t initialized;
    void* setup_address;
    uint32_t setup_length;
    void* VirtualProtectEx;
    void* WaitForSingleObjectEx;
    void* CreateWaitableTimer;
    void* SetWaitableTimer;
    void* MessageBox;
    void* tramp_addr;
    void* sleep_handle;
    uint32_t interval;
    void* target;
    uint8_t shadow[8];
  };

  struct StackTrampoline {
    void* VirtualProtectEx;
    void* return_address;
    void* current_process;
    void* address;
    uint32_t size;
    uint32_t protections;
    void* old_protections_ptr;
    uint32_t old_protections;
    void* setup_config;
  };

  struct Workspace {
    SetupConfiguration config;
    uint8_t stack[stack_size];
    StackTrampoline tramp;
  };
}

Workspace& allocate_workspace() {
  auto result = VirtualAllocEx(GetCurrentProcess(), nullptr, sizeof(Workspace), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
  if (!result) throw runtime_error("[-] Couldn't VirtualAllocEx: " + GetLastError());
  RtlSecureZeroMemory(result, sizeof(Workspace));
  return *static_cast<Workspace*>(result);
}

MyTuple allocate_pic(const string& filename) {

  fstream file_stream{ filename, fstream::in | fstream::ate | fstream::binary };
  if (!file_stream) throw runtime_error("[-] Couldn't open " + filename);
  auto pic_size = static_cast<size_t>(file_stream.tellg());
  file_stream.seekg(0, fstream::beg);
  auto pic = VirtualAllocEx(GetCurrentProcess(), nullptr, pic_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  if (!pic) throw runtime_error("[-] Couldn't VirtualAllocEx: " + GetLastError());
  file_stream.read(static_cast<char*>(pic), pic_size);
  file_stream.close();
  DWORD old_protection;
  auto prot_result = VirtualProtectEx(GetCurrentProcess(), pic, pic_size, PAGE_EXECUTE_READ, &old_protection);
  if (!prot_result) throw runtime_error("[-] Couldn't VirtualProtectEx: " + GetLastError());
  return MyTuple(pic, pic_size);
}

uint32_t get_mshtml_gadget_relative_offset(const char *mshtml_filename) {
  DWORD version_handle;
  auto version_info_size = GetFileVersionInfoSizeA(mshtml_filename, &version_handle);
  if (version_info_size == 0) throw runtime_error("[-] Couldn't GetFileVersionInfoSize: " + GetLastError());

  vector<char> version_data(version_info_size);
  auto result = GetFileVersionInfoA(mshtml_filename, version_handle, version_info_size, &version_data[0]);
  if (!result) {
      throw runtime_error("[-] Couldn't GetFileVersionInfo: " + GetLastError());
  }

  LPBYTE version_info_buffer;
  UINT version_info_buffer_size;
  result = VerQueryValueA(&version_data[0], "\\", reinterpret_cast<VOID FAR* FAR*>(&version_info_buffer), &version_info_buffer_size);
  if (!result) {
      throw runtime_error("[-] Couldn't VerQueryValue: " + GetLastError());
  }

  auto *version_info = reinterpret_cast<VS_FIXEDFILEINFO *>(version_info_buffer);
  WORD unpacked_file_version_words[4] = {
    (version_info->dwFileVersionMS >> 16) & 0xffff,
    (version_info->dwFileVersionMS >> 0) & 0xffff,
    (version_info->dwFileVersionLS >> 16) & 0xffff,
    (version_info->dwFileVersionLS >> 0) & 0xffff };
  auto unpacked_file_version = *reinterpret_cast<DWORDLONG *>(unpacked_file_version_words);

  printf("[ ] Found %s version %d.%d.%d.%d.\n",
    mshtml_filename,
    unpacked_file_version_words[0],
    unpacked_file_version_words[1],
    unpacked_file_version_words[2],
    unpacked_file_version_words[3]);

  uint32_t relative_offset = 0;
  auto using_default = false;
  auto entry_num = 0;
  while (relative_offset == 0) {
    auto* version_entry = &mshtml_gadget_offset_map[entry_num];
    if (*reinterpret_cast<DWORDLONG *>(version_entry->file_version) == unpacked_file_version
      || *reinterpret_cast<DWORDLONG *>(version_entry->file_version) == 0)
      relative_offset = version_entry->relative_offset;
      using_default = *reinterpret_cast<DWORDLONG *>(version_entry->file_version) == 0;
    ++entry_num;
  }

  if (using_default) {
    printf("[*] WARNING: Unrecognized version, so using default relative offset.\n");
  }
  printf("[ ] %s ROP gadget is at relative offset 0x%p.\n", mshtml_filename, reinterpret_cast<void *>(relative_offset));

  return relative_offset;
}

void* get_mshtml_gadget() {
  auto mshtml_filename = "mshtml.dll";
  printf("[ ] Loading %s.\n", mshtml_filename);
  auto mshtml_gadget_offset = get_mshtml_gadget_relative_offset(mshtml_filename);
  auto mshtml_base = reinterpret_cast<uint8_t*>(LoadLibraryA(mshtml_filename));
  if (!mshtml_base) throw runtime_error("[-] Couldn't LoadLibrary: " + GetLastError());

  printf("[+] Loaded %s into memory at 0x%p.\n", mshtml_filename, mshtml_base);
  return mshtml_base + mshtml_gadget_offset;
}

void* get_gadget(bool use_mshtml, const string& gadget_pic_path) {
  void* memory;
  if (use_mshtml) {
    memory = get_mshtml_gadget();
  } else {
    printf("[ ] Allocating memory for %s.\n", gadget_pic_path.c_str());
    size_t size;
    tie(memory, size) = allocate_pic(gadget_pic_path);
    printf("[ ] Allocated %u bytes for gadget PIC.\n", size);
  }
  return memory;
}

void launch(const string& setup_pic_path, const string& gadget_pic_path) {
  printf("[ ] Allocating executable memory for %s.\n", setup_pic_path.c_str());
  void* setup_memory; size_t setup_size;
  tie(setup_memory, setup_size) = allocate_pic(setup_pic_path);
  printf("[+] Allocated %d bytes for PIC.\n", setup_size);

  auto use_mshtml{ true };
  printf("[ ] Configuring ROP gadget.\n");
  auto gadget_memory = get_gadget(use_mshtml, gadget_pic_path);
  printf("[+] ROP gadget configured.\n");

  printf("[ ] Allocating read/write memory for config, stack, and trampoline.\n");
  auto& scratch_memory = allocate_workspace();
  auto& config = scratch_memory.config;
  auto& tramp = scratch_memory.tramp;
  printf("[+] Allocated %u bytes for scratch memory.\n", sizeof(scratch_memory));

  printf("[ ] Building stack trampoline.\n");
  tramp.old_protections_ptr = &tramp.old_protections;
  tramp.protections = PAGE_EXECUTE_READ;
  tramp.current_process = GetCurrentProcess();
  tramp.VirtualProtectEx = VirtualProtectEx;
  tramp.size = static_cast<uint32_t>(setup_size);
  tramp.address = setup_memory;
  tramp.return_address = setup_memory;
  tramp.setup_config = &config;
  printf("[+] Stack trampoline built.\n");

  printf("[ ] Building configuration.\n");
  config.setup_address = setup_memory;
  config.setup_length = static_cast<uint32_t>(setup_size);
  config.VirtualProtectEx = VirtualProtectEx;
  config.WaitForSingleObjectEx = WaitForSingleObjectEx;
  config.CreateWaitableTimer = CreateWaitableTimerW;
  config.SetWaitableTimer = SetWaitableTimer;
  config.MessageBox = MessageBoxA;
  config.tramp_addr = &tramp;
  config.interval = invocation_interval_ms;
  config.target = gadget_memory;
  printf("[+] Configuration built.\n");

  printf("[+] Success!\n");
  printf("    ================================\n");
  printf("    Gargoyle PIC @ -----> 0x%p\n", setup_memory);
  printf("    ROP gadget @ -------> 0x%p\n", gadget_memory);
  printf("    Configuration @ ----> 0x%p\n", &scratch_memory.config);
  printf("    Top of stack @ -----> 0x%p\n", &scratch_memory.stack);
  printf("    Bottom of stack @ --> 0x%p\n", &scratch_memory.stack[stack_size-1]);
  printf("    Stack trampoline @ -> 0x%p\n", &scratch_memory.tramp);

  reinterpret_cast<callable>(setup_memory)(&config);
}

int main() {
  try {
    launch("setup.pic", "gadget.pic");
  } catch (exception& e) {
    printf("%s\n", e.what());
  }
}
<commit_msg>Added the ROP gadget offset for the "mshtml.dll" file included with Windows 10 build v10.0.15063.138.<commit_after>#include <vector>
#include <tuple>
#include <fstream>
#include "Windows.h"
#include <psapi.h>
#include <vector>

using namespace std;

namespace {
  typedef void(*callable)(void*);
  typedef tuple<void*, size_t> MyTuple;
  constexpr DWORD invocation_interval_ms = 15 * 1000;
  constexpr size_t stack_size = 0x10000;

  struct VersionToOffset {
    WORD file_version[4];
    uint32_t relative_offset;
  };

  /*
   * See https://changewindows.org/ for a detailed Windows 10 release history,
   * including updates to milestone releases.  A new build of the "mshtml.dll"
   * file has not been included with every update.
   */

  vector<VersionToOffset> mshtml_gadget_offset_map = {
    // Windows 10 Creators Update (Build v10.0.15063.138 as of Apr 11, 2017)
    {    11,     0, 15063,   138, 0x00585068 },
    // Windows 10 Creators Update (Build v10.0.15063.0 as of Mar 20, 2017)
    {    11,     0, 15063,     0, 0x00585098 },
    // Windows 10 Anniversary Update (Build v10.0.14393.953 as of Mar 14, 2017)
    {    11,     0, 14393,   953, 0x003CBD4D },
    // The default ROP gadget offset (for Windows v8.1?)
    {     0,     0,     0,     0, 0x006D55DD }
  };

  struct SetupConfiguration {
    uint32_t initialized;
    void* setup_address;
    uint32_t setup_length;
    void* VirtualProtectEx;
    void* WaitForSingleObjectEx;
    void* CreateWaitableTimer;
    void* SetWaitableTimer;
    void* MessageBox;
    void* tramp_addr;
    void* sleep_handle;
    uint32_t interval;
    void* target;
    uint8_t shadow[8];
  };

  struct StackTrampoline {
    void* VirtualProtectEx;
    void* return_address;
    void* current_process;
    void* address;
    uint32_t size;
    uint32_t protections;
    void* old_protections_ptr;
    uint32_t old_protections;
    void* setup_config;
  };

  struct Workspace {
    SetupConfiguration config;
    uint8_t stack[stack_size];
    StackTrampoline tramp;
  };
}

Workspace& allocate_workspace() {
  auto result = VirtualAllocEx(GetCurrentProcess(), nullptr, sizeof(Workspace), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
  if (!result) throw runtime_error("[-] Couldn't VirtualAllocEx: " + GetLastError());
  RtlSecureZeroMemory(result, sizeof(Workspace));
  return *static_cast<Workspace*>(result);
}

MyTuple allocate_pic(const string& filename) {

  fstream file_stream{ filename, fstream::in | fstream::ate | fstream::binary };
  if (!file_stream) throw runtime_error("[-] Couldn't open " + filename);
  auto pic_size = static_cast<size_t>(file_stream.tellg());
  file_stream.seekg(0, fstream::beg);
  auto pic = VirtualAllocEx(GetCurrentProcess(), nullptr, pic_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  if (!pic) throw runtime_error("[-] Couldn't VirtualAllocEx: " + GetLastError());
  file_stream.read(static_cast<char*>(pic), pic_size);
  file_stream.close();
  DWORD old_protection;
  auto prot_result = VirtualProtectEx(GetCurrentProcess(), pic, pic_size, PAGE_EXECUTE_READ, &old_protection);
  if (!prot_result) throw runtime_error("[-] Couldn't VirtualProtectEx: " + GetLastError());
  return MyTuple(pic, pic_size);
}

uint32_t get_mshtml_gadget_relative_offset(const char *mshtml_filename) {
  DWORD version_handle;
  auto version_info_size = GetFileVersionInfoSizeA(mshtml_filename, &version_handle);
  if (version_info_size == 0) throw runtime_error("[-] Couldn't GetFileVersionInfoSize: " + GetLastError());

  vector<char> version_data(version_info_size);
  auto result = GetFileVersionInfoA(mshtml_filename, version_handle, version_info_size, &version_data[0]);
  if (!result) {
      throw runtime_error("[-] Couldn't GetFileVersionInfo: " + GetLastError());
  }

  LPBYTE version_info_buffer;
  UINT version_info_buffer_size;
  result = VerQueryValueA(&version_data[0], "\\", reinterpret_cast<VOID FAR* FAR*>(&version_info_buffer), &version_info_buffer_size);
  if (!result) {
      throw runtime_error("[-] Couldn't VerQueryValue: " + GetLastError());
  }

  auto *version_info = reinterpret_cast<VS_FIXEDFILEINFO *>(version_info_buffer);
  WORD unpacked_file_version_words[4] = {
    (version_info->dwFileVersionMS >> 16) & 0xffff,
    (version_info->dwFileVersionMS >> 0) & 0xffff,
    (version_info->dwFileVersionLS >> 16) & 0xffff,
    (version_info->dwFileVersionLS >> 0) & 0xffff };
  auto unpacked_file_version = *reinterpret_cast<DWORDLONG *>(unpacked_file_version_words);

  printf("[ ] Found %s version %d.%d.%d.%d.\n",
    mshtml_filename,
    unpacked_file_version_words[0],
    unpacked_file_version_words[1],
    unpacked_file_version_words[2],
    unpacked_file_version_words[3]);

  uint32_t relative_offset = 0;
  auto using_default = false;
  auto entry_num = 0;
  while (relative_offset == 0) {
    auto* version_entry = &mshtml_gadget_offset_map[entry_num];
    if (*reinterpret_cast<DWORDLONG *>(version_entry->file_version) == unpacked_file_version
      || *reinterpret_cast<DWORDLONG *>(version_entry->file_version) == 0)
      relative_offset = version_entry->relative_offset;
      using_default = *reinterpret_cast<DWORDLONG *>(version_entry->file_version) == 0;
    ++entry_num;
  }

  if (using_default) {
    printf("[*] WARNING: Unrecognized version, so using default relative offset.\n");
  }
  printf("[ ] %s ROP gadget is at relative offset 0x%p.\n", mshtml_filename, reinterpret_cast<void *>(relative_offset));

  return relative_offset;
}

void* get_mshtml_gadget() {
  auto mshtml_filename = "mshtml.dll";
  printf("[ ] Loading %s.\n", mshtml_filename);
  auto mshtml_gadget_offset = get_mshtml_gadget_relative_offset(mshtml_filename);
  auto mshtml_base = reinterpret_cast<uint8_t*>(LoadLibraryA(mshtml_filename));
  if (!mshtml_base) throw runtime_error("[-] Couldn't LoadLibrary: " + GetLastError());

  printf("[+] Loaded %s into memory at 0x%p.\n", mshtml_filename, mshtml_base);
  return mshtml_base + mshtml_gadget_offset;
}

void* get_gadget(bool use_mshtml, const string& gadget_pic_path) {
  void* memory;
  if (use_mshtml) {
    memory = get_mshtml_gadget();
  } else {
    printf("[ ] Allocating memory for %s.\n", gadget_pic_path.c_str());
    size_t size;
    tie(memory, size) = allocate_pic(gadget_pic_path);
    printf("[ ] Allocated %u bytes for gadget PIC.\n", size);
  }
  return memory;
}

void launch(const string& setup_pic_path, const string& gadget_pic_path) {
  printf("[ ] Allocating executable memory for %s.\n", setup_pic_path.c_str());
  void* setup_memory; size_t setup_size;
  tie(setup_memory, setup_size) = allocate_pic(setup_pic_path);
  printf("[+] Allocated %d bytes for PIC.\n", setup_size);

  auto use_mshtml{ true };
  printf("[ ] Configuring ROP gadget.\n");
  auto gadget_memory = get_gadget(use_mshtml, gadget_pic_path);
  printf("[+] ROP gadget configured.\n");

  printf("[ ] Allocating read/write memory for config, stack, and trampoline.\n");
  auto& scratch_memory = allocate_workspace();
  auto& config = scratch_memory.config;
  auto& tramp = scratch_memory.tramp;
  printf("[+] Allocated %u bytes for scratch memory.\n", sizeof(scratch_memory));

  printf("[ ] Building stack trampoline.\n");
  tramp.old_protections_ptr = &tramp.old_protections;
  tramp.protections = PAGE_EXECUTE_READ;
  tramp.current_process = GetCurrentProcess();
  tramp.VirtualProtectEx = VirtualProtectEx;
  tramp.size = static_cast<uint32_t>(setup_size);
  tramp.address = setup_memory;
  tramp.return_address = setup_memory;
  tramp.setup_config = &config;
  printf("[+] Stack trampoline built.\n");

  printf("[ ] Building configuration.\n");
  config.setup_address = setup_memory;
  config.setup_length = static_cast<uint32_t>(setup_size);
  config.VirtualProtectEx = VirtualProtectEx;
  config.WaitForSingleObjectEx = WaitForSingleObjectEx;
  config.CreateWaitableTimer = CreateWaitableTimerW;
  config.SetWaitableTimer = SetWaitableTimer;
  config.MessageBox = MessageBoxA;
  config.tramp_addr = &tramp;
  config.interval = invocation_interval_ms;
  config.target = gadget_memory;
  printf("[+] Configuration built.\n");

  printf("[+] Success!\n");
  printf("    ================================\n");
  printf("    Gargoyle PIC @ -----> 0x%p\n", setup_memory);
  printf("    ROP gadget @ -------> 0x%p\n", gadget_memory);
  printf("    Configuration @ ----> 0x%p\n", &scratch_memory.config);
  printf("    Top of stack @ -----> 0x%p\n", &scratch_memory.stack);
  printf("    Bottom of stack @ --> 0x%p\n", &scratch_memory.stack[stack_size-1]);
  printf("    Stack trampoline @ -> 0x%p\n", &scratch_memory.tramp);

  reinterpret_cast<callable>(setup_memory)(&config);
}

int main() {
  try {
    launch("setup.pic", "gadget.pic");
  } catch (exception& e) {
    printf("%s\n", e.what());
  }
}
<|endoftext|>