#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <include/main.h>
#include <include/util.h>
#include <iostream>
#include <sstream>
#include <vector>
#include <include/shaiya/include/CWorld.h>
#include <include/shaiya/include/CZone.h>
using namespace shaiya;
namespace command_manager
{
    std::string output;
    int execute(const char* input, int cmd_case) {
        std::istringstream stream(input);
        std::vector<std::string> args;
        std::string temp;
        stream >> temp;
        while (stream >> temp) {
            args.push_back(temp);
        }
        switch (cmd_case) {
        case 69:
        {
            auto map = std::stoi(args.at(0));
            auto mobId = std::stoi(args.at(1));
            auto count = std::stoi(args.at(2));
            auto x = std::stof(args.at(3));
            auto y = std::stof(args.at(4));
            auto z = std::stof(args.at(5));
            SVector position = { x, y, z };
            shaiya::CZone::MobGen(CWorld::GetZone(map), mobId, count, &position);
            std::stringstream output_format;
            output_format << "Mob:" << mobId << " respawned at Map:" << map;
            output = output_format.str();
            return 0;   
          
        }
            return 0;
        default:
            break;
        }
        return 1;
    }
}
LPCSTR cmd_mmake = "/mmake";
unsigned u0x4F5BE0 = 0x4F5BE0;//SConsole::AddCommand
void __declspec(naked) naked_0x409459() {
    __asm {
        push 0x0
        push - 0x1
        push 0x6 // param count
        push cmd_mmake
        push 69 // switch case
        mov ecx, esi
        call u0x4F5BE0
        originalcode :
        pop esi
        retn
    }
}
unsigned u0x409498 = 0x409498; // The address to return to for an unsuccessfully handled command.
unsigned u0x40B3D4 = 0x40B3D4; // The address to return to for a successful command.
void __declspec(naked) naked_0x40948F()
{
    __asm
    {
        pushad
        sub ebx,0x4024
        push eax // switch case
        push ebx // input
        call command_manager::execute
        add esp,8
        test eax, eax
        popad
        je write_output
        originalcode :
        cmp eax, 0x44
        ja default_case
        jmp u0x409498
        write_output:
        push command_manager::output
        push edi
        call sprintf
        add esp, 8
        default_case :     
        jmp u0x40B3D4
    }
}
void hook::command_manager()
{
    //CServerApp::InitConsoleCommand
    util::detour((void*)0x409459, naked_0x409459, 5);
    //CServerApp::OnConsoleCommand
    util::detour((void*)0x40948F, naked_0x40948F, 9);
}