Implementación del Sistema DailyReward en MuOnline

Implementación del Sistema DailyReward en MuOnline

Implementación del Sistema DailyReward en MuOnline: Guía Completa

En esta guía, te mostraré cómo implementar el sistema DailyReward en MuOnline desde cero. A pesar de que ya existen varias guías, muchas carecen de detalles importantes. Aquí, te proporcionaré un enfoque completo y detallado para que puedas agregar este sistema a tu servidor de manera efectiva.

Implementación del Sistema DailyReward en MuOnline Implementación del Sistema DailyReward en MuOnline


Parte 1: Creación de Archivos Necesarios

Primero, debemos crear los archivos necesarios en nuestras fuentes y agregar el código correspondiente.

Abres el Archivo stdafx.h con tu Visual estudio

y Agregas el Siguiente codigo como indica la imagen de arriba

#define DAILY            1

 

En tu Visual estudio Debes crear nuevo Filtro llamado DailyReward Como indica la Imagen

Luego vas a Crear los nuevos elementos para el DailyReward Como indica la Imagen

 

Estos son los Elementos que debes tener en tu Filtro:

NewFont.cpp
NewFont.h
DailyReward.cpp
DailyReward.h
InterfaceBase.cpp
InterfaceBase.h

1. Crear DailyReward.cpp

#include "stdafx.h"
#if(DAILY)
#include "DailyReward.h"
#include "Import.h"
#include "NewFont.h"
#include <ctime>
#include "Interface.h"
#include "Defines.h"
cDailyReward DailyReward;

cDailyReward::cDailyReward()
{
    this->Init();
}

cDailyReward::~cDailyReward()
{
}

void cDailyReward::Init()
{
    this->SetWindow(false);
    this->SetRect(120, 70, 400, 255);
    this->SetTitle("Daily Reward", 0xc1c1c1ff, 0x0, 1);
    this->SelectedDay = 1;
}

unsigned char last_day_of_month(int year, unsigned char month) {
    return month != 2 ? ((month ^ (month >> 3))) | 30 :
        year % 4 ? 29 : 28;
}

void cDailyReward::ClearDayGift()
{
    this->DayInfo = false;
    this->Type = -1;
    this->Level = 0;
    this->Ex = 0;
    this->Zen = 0;
    this->Wcoin = 0;
}
int ImgTag100 = 0;
void cDailyReward::DrawIcon() //focus move box daily
{

    if (gInterface.CheckWindow(CashShop)
        || gInterface.CheckWindow(SkillTree)
        || gInterface.CheckWindow(FullMap)
        || gInterface.CheckWindow(MoveList)
        || gInterface.CheckWindow(Inventory)
        || gInterface.CheckWindow(ExpandInventory)
        || gInterface.CheckWindow(Store)
        || gInterface.CheckWindow(Inventory)
        || gInterface.CheckWindow(Party)
        || gInterface.CheckWindow(Trade)
        || gInterface.CheckWindow(Warehouse)
        || gInterface.CheckWindow(ExpandWarehouse))
    {
        return;
    }
    int j;

    if (!Blink)
    {
        return;
    }

    CustomFont.Draw(CustomFont.FontNormal, 73, 60, 0xffffffff, 0x00000050, 0, 0, 3, "Daily Reward"); //Move Daily Reward - 70 lados - 60 arriba
    int speed = 2, r = 0;
    if (ImgTag100 >= 25 * speed) ImgTag100 = 0;

    r = floor((float)ImgTag100 / (float)speed);

    RenderBitmap(531026, 80, 30, 102.4 / 2, 93.4 / 2, (r % 5) * 102.4 / 512.0, (r - (r % 5)) / 5 * 93.4 / 512.0, 102.4 / 512.0, 93.4 / 512.0, 0, 1, 0.0);
    ImgTag100++; //Move Box Daily -- 80 lados -- 30 Ariba+Abajo


    if (IsWorkZone(80, 30,40, 40, false))
    {
        if (pIsKeyRelease(VK_LBUTTON) && IsOnWindow())
            DailyReward.ToggleWindow(true);

    }


    if (IsWorkZone(80, 30,40, 40, false))
    {
        pSetCursorFocus = true;
    }
    else pSetCursorFocus = false;

}

void cDailyReward::Draw()
{
    if (pPlayerState < GameProcess)
    {
        return;
    }
    if (gInterface.CheckWindow(ObjWindow::CashShop)
        || gInterface.CheckWindow(ObjWindow::FriendList)
        || gInterface.CheckWindow(ObjWindow::MoveList)
        || gInterface.CheckWindow(ObjWindow::Party)
        || gInterface.CheckWindow(ObjWindow::Quest)
        || gInterface.CheckWindow(ObjWindow::NPC_Devin)
        || gInterface.CheckWindow(ObjWindow::Guild)
        || gInterface.CheckWindow(ObjWindow::Trade)
        || gInterface.CheckWindow(ObjWindow::Warehouse)
        || gInterface.CheckWindow(ObjWindow::ChaosBox)
        || gInterface.CheckWindow(ObjWindow::CommandWindow)
        || gInterface.CheckWindow(ObjWindow::PetInfo)
        || gInterface.CheckWindow(ObjWindow::Shop)
        || gInterface.CheckWindow(ObjWindow::Inventory)
        || gInterface.CheckWindow(ObjWindow::Store)
        || gInterface.CheckWindow(ObjWindow::OtherStore)
        || gInterface.CheckWindow(ObjWindow::Character)
        || gInterface.CheckWindow(ObjWindow::DevilSquare)
        || gInterface.CheckWindow(ObjWindow::BloodCastle)
        || gInterface.CheckWindow(ObjWindow::CreateGuild)
        || gInterface.CheckWindow(ObjWindow::GuardNPC)
        || gInterface.CheckWindow(ObjWindow::SeniorNPC)
        || gInterface.CheckWindow(ObjWindow::GuardNPC2)
        || gInterface.CheckWindow(ObjWindow::CastleGateSwitch)
        || gInterface.CheckWindow(ObjWindow::CatapultNPC)
        || gInterface.CheckWindow(ObjWindow::CrywolfGate)
        || gInterface.CheckWindow(ObjWindow::IllusionTemple)
        || gInterface.CheckWindow(ObjWindow::HeroList)
        || gInterface.CheckWindow(ObjWindow::ChatWindow)
        || gInterface.CheckWindow(ObjWindow::FastMenu)
        || gInterface.CheckWindow(ObjWindow::Options)
        || gInterface.CheckWindow(ObjWindow::Help)
        || gInterface.CheckWindow(ObjWindow::FastDial)
        || gInterface.CheckWindow(ObjWindow::SkillTree)
        || gInterface.CheckWindow(ObjWindow::GoldenArcher1)
        || gInterface.CheckWindow(ObjWindow::GoldenArcher2)
        || gInterface.CheckWindow(ObjWindow::LuckyCoin1)
        || gInterface.CheckWindow(ObjWindow::LuckyCoin2)
        || gInterface.CheckWindow(ObjWindow::NPC_Duel)
        || gInterface.CheckWindow(ObjWindow::NPC_Titus)
        || gInterface.CheckWindow(ObjWindow::CashShop)
        || gInterface.CheckWindow(ObjWindow::Lugard)
        || gInterface.CheckWindow(ObjWindow::QuestList1)
        || gInterface.CheckWindow(ObjWindow::QuestList2)
        || gInterface.CheckWindow(ObjWindow::Jerint)
        || gInterface.CheckWindow(ObjWindow::FullMap)
        || gInterface.CheckWindow(ObjWindow::NPC_Dialog)
        || gInterface.CheckWindow(ObjWindow::GensInfo)
        || gInterface.CheckWindow(ObjWindow::NPC_Julia)
        || gInterface.CheckWindow(ObjWindow::NPC_ChaosMix)
        || gInterface.CheckWindow(ObjWindow::ExpandInventory)
        || gInterface.CheckWindow(ObjWindow::ExpandWarehouse)
        || gInterface.CheckWindow(ObjWindow::MuHelper)
        )
    {

        this->CloseWindow(true);
    }

    if (!CheckWindow())
    {
        DrawIcon();
        return;
    }
    this->DrawBase();

    tm today;
    time_t ltime;
    time(&ltime);
    localtime_s(&today, &ltime);

    char* DoW[] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };

    float sW = 35, sH = 38;
    int i, v1, v2, v3, v4, v5;
    v3 = this->FWday;
    v4 = this->MaxDay;
    for (i = 0; i < 7; i++)
    {
        CustomFont.Draw(CustomFont.FontNormal, x + 15 + sW * i, y + 35, 0xffffffff, 0xc1c1c150, sW - 2, 0, 3, DoW[i]);
    }
    if (Loaded)
    {
        for (i = v3; i < (v3 + v4); i++)
        {
            v1 = i % cDR_SPLIT_DAY;
            v2 = (i - v1) / cDR_SPLIT_DAY;
            v5 = i - v3 + 1;
            //
            if (SelectedDay == v5)
            {
                CustomFont.Draw(CustomFont.FontNormal, x + 15 + sW * v1, y + 52 + v2 * sH, 0xffffffff, 0x00000050, sW - 2, sH - 2, 3, " ");
            }
            if (SelectedDay == v5 && State[v5 - 1] == 0) //selecting
            {
                RenderBitmap(531020, x + 8 + sW * v1 + (sW - 16) / 2, y + 50 + v2 * sH, 45, 45, 0.0, 0.0, 1.0, 1.0, 1, 1, 0.0);
            }
            else if (IsWorkZone(x + 15 + sW * v1, y + 52 + v2 * sH, sW - 2, sH - 2, true))
            {
                RenderBitmap(531020, x + 8 + sW * v1 + (sW - 16) / 2, y + 50 + v2 * sH, 45, 45, 0.0, 0.0, 1.0, 1.0, 1, 1, 0.0);
                if (pIsKeyRelease(VK_LBUTTON))
                {
                    SelectedDay = v5;
                    if (State[v5 - 1] == 0)
                    {
                        this->SendRequest(0x01, SelectedDay);
                        this->ClearDayGift();
                    }
                }
            }
            else if (State[v5 - 1] == 0) //
            {
                RenderBitmap(531020, x + 8 + sW * v1 + (sW - 16) / 2, y + 50 + v2 * sH, 45, 45, 0.0, 0.0, 1.0, 1.0, 1, 1, 0.0);
            }
            else
            {
                RenderBitmap(531021, x + 8 + sW * v1 + (sW - 16) / 2, y + 50 + v2 * sH, 45, 45, 0.0, 0.0, 1.0, 1.0, 1, 1, 0.0);
            }
            CustomFont.Draw(CustomFont.FontNormal, x + 15 + sW * v1, y + 52 + v2 * sH + sH - 13, 0xffffffff, (v5) != today.tm_mday ? 0x00000050 : 0x00ff007f, sW - 2, 12, 3, "%d", v5);
        }

        if (SelectedDay != 0)
        {
            if (State[SelectedDay - 1] != 0)
            {
                CustomFont.Draw(CustomFont.FontNormal, x + 260, y + 50, 0xffffffff, 0x00000050, 130, 0, 3, "Complete", Wcoin);
            }
            else if (DayInfo)
            {
                CustomFont.Draw(CustomFont.FontNormal, x + 260, y + 50, 0xffffffff, 0x00000050, 130, 0, 3, "Wcoin : %d", Wcoin);
                CustomFont.Draw(CustomFont.FontNormal, x + 260, y + 65, 0xffffffff, 0x00000050, 130, 0, 3, "Zen : %d", Zen);

                CustomFont.Draw(CustomFont.FontNormal, x + 260, y + 80, 0xffffffff, 0x00000050, 130, 0, 3, Text);

                if (SelectedDay <= today.tm_mday)
                {
                    this->DrawButton(32331, x - 5 + 75 * 4, y + h - 50, 73, 27, 128.0, 128.0, DailyReward.RecvGiftAction);
                    CustomFont.Draw(CustomFont.FontNormal, x - 5 + 75 * 4, y + h - 42.5, 0xffffffff, 0x0, 73, 0, 3, "Rewarded");
                }

                CustomFont.Draw(CustomFont.FontNormal, x + 280, y + 100, 0xffffffff, 0x00000050, 90, 90, 3, " ");

                gInterface.DrawItem2(x + 280, y + 100, 90, 90, this->Type, this->Level, this->Ex, 0, 0);


                if (IsWorkZone(x + 280, y + 100, 90, 90, true))
                {
                    gInterface.DrawItemToolTipText((void*)&Item, *(int*)0x879340C, *(int*)0x8793410 + 25);
                    glColor3f(1, 1, 1);
                    pSetBlend(false);
                }
            }
            else
            {
                CustomFont.Draw(CustomFont.FontNormal, x + 260, y + 50, 0xffffffff, 0x00000050, 130, 0, 3, "No Data...", Wcoin);
            }
        }
    }
    else
    {
        CustomFont.Draw(CustomFont.FontNormal, x + 60, y + 50, 0xffffffff, 0x00000050, 200, 0, 3, "No Data...");
    }
}

bool cDailyReward::AllowedGift()
{
    return Loaded && State[SelectedDay - 1] == 0 && SelectedDay <= CurDay;
}
void cDailyReward::SendRequest(BYTE type, int value)
{
    PMSG_DAILY_REWARD_SEND pRequest;
    pRequest.h.set((LPBYTE)&pRequest, 0xFB, 0x02, sizeof(pRequest));
    pRequest.Type = type;
    pRequest.Value = value;
    DataSend((LPBYTE)&pRequest, pRequest.h.size);
}

void cDailyReward::RecvGiftAction(LPVOID pClass)
{
    cDailyReward* This = (cDailyReward*)pClass;

    if (This->AllowedGift())
    {
        This->SendRequest(0x02, This->SelectedDay);
    }
}

void cDailyReward::OnOpen()
{
    this->Loaded = false;
    this->DayInfo = false;
    this->SendRequest(0x0, 0x0);
}
void cDailyReward::OnClose()
{
}

void cDailyReward::ToggleWindow(bool mode)
{
    SetWindow(!CheckWindow(), mode);
}
void cDailyReward::OpenWindow(bool mode)
{
    SetWindow(true, mode);
}
void cDailyReward::CloseWindow(bool mode)
{
    SetWindow(false, mode);
}
void cDailyReward::SetWindow(bool state, bool mode)
{
    this->Drawing = state;
    if (mode)
        CheckWindow() ? OnOpen() : OnClose();
}

void cDailyReward::GCRecvUserInfo(BYTE* a)
{
    PMSG_DAILY_REWARD_USER_INFO_RECV* Data = (PMSG_DAILY_REWARD_USER_INFO_RECV*)a;
    this->CurDay = Data->CurDay;
    this->MaxDay = Data->MaxDay;
    this->FWday = Data->FWday;
    this->Timer = Data->Timer;

    for (int i = 0; i < 31; i++)
    {
        this->State[i] = Data->State[i];
    }

    if (State[CurDay - 1] == 0)
    {
        Blink = true;
    }
    else
    {
        Blink = false;
    }

    Loaded = true;
}
int cDailyReward::CheckItemInfo(signed int a1)
{
    if (a1 > 3092)
    {
        if (a1 > 4661)
        {
            if (a1 > 5685 || a1 < 5676 && (a1 < 5164 || a1 > 5173))
                return 0;
        }
        else if (a1 < 4652 && (a1 > 4149 || a1 < 4140 && (a1 < 3628 || a1 > 3637)))
        {
            return 0;
        }

        return 1;
    }

    if (a1 >= 3089)
        return 1;

    if (a1 > 2071)
    {
        if (a1 != 2580 && (a1 <= 2589 || a1 > 2592))
            return 0;
        return 1;
    }

    if (a1 == 2071 || a1 <= 1041 && (a1 >= 1040 || a1 >= 26 && a1 <= 28))
        return 1;

    return 0;
}

void cDailyReward::GCRecvDayInfo(BYTE* a)
{
    PMSG_DAILY_REWARD_DAY_INFO_RECV* Data = (PMSG_DAILY_REWARD_DAY_INFO_RECV*)a;

    DayInfo = true;
    if (Data->Type != -1)
    {
        this->Type = Data->Type;

        DWORD dwAddress;
        int a5;
        int a6;
        int a7;
        int a8;
        int a9;
        DWORD a10;

        dwAddress = (DWORD)&this->Item;

        *(WORD *)dwAddress = Data->Type;
        a5 = Data->Dur;
        *(BYTE *)(dwAddress + 22) = a5;
        a6 = Data->Item[3];
        *(BYTE *)(dwAddress + 23) = a6;
        a7 = Data->Item[4];
        *(BYTE *)(dwAddress + 24) = a7;
        a8 = Data->Item[5];
        *(BYTE *)(dwAddress + 97) = (a8 & 2) >> 1 > 0;
        *(BYTE *)(dwAddress + 98) = (a8 & 4) >> 2 > 0;
        *(BYTE *)(dwAddress + 73) = 16 * (a8 & 8) >> 7 > 0;
        a9 = Data->Item[6];
        *(WORD *)(dwAddress + 69) = (a9 & 0xF0) >> 4;
        *(WORD *)(dwAddress + 71) = a9 & 0xF;

        a10 = (DWORD)&Data->Item[7];

        if (a10)
        {
            *(BYTE *)(dwAddress + 79) = 5;

            for (int i = 0; i < 5; ++i)
                *(BYTE *)(i + dwAddress + 74) = *(BYTE *)(i + a10);

            for (int j = 0; j < 5; ++j)
            {
                if (*(BYTE *)(j + a10) == 255)
                {
                    *(BYTE *)(dwAddress + 79) = j;
                    break;
                }

                if (*(BYTE *)(j + a10) == 254)
                {
                    *(BYTE *)(j + dwAddress + 80) = -1;
                }
                else
                {
                    *(BYTE *)(j + dwAddress + 80) = *(BYTE *)(j + a10) % 50;
                    *(BYTE *)(j + dwAddress + 85) = *(BYTE *)(j + a10) / 50 + 1;
                }
            }

            if (this->CheckItemInfo(*(WORD *)dwAddress))
            {
                *(BYTE *)(dwAddress + 90) = a9;
                *(WORD *)(dwAddress + 69) = 0;
                *(WORD *)(dwAddress + 71) = 0;
            }
            else
            {
                *(BYTE *)(dwAddress + 90) = -1;
            }
        }
        else
        {
            *(BYTE *)(dwAddress + 79) = 0;
        }

        *(BYTE *)(dwAddress + 96) = 0;
        *(DWORD *)(dwAddress + 103) = 1;

        if (Data->PeriodTime)
        {
            this->Item.PeriodItem = 1;
            this->Item.ExpireDateConvert = Data->PeriodTime;
        }

        ((void(__cdecl*)(ObjectItem * lpItem, BYTE Option, BYTE Special, BYTE Value)) 0x58B910)(&this->Item, Data->Item[1], Data->Item[3], Data->Item[4]);
    }
    this->Zen = Data->Zen;
    this->Wcoin = Data->Wcoin;
    memcpy_s(Text, 100, Data->Text, 100);
}
#endif

 

2. Crear DailyReward.h

#pragma once
#if (DAILY)
#include "InterfaceBase.h"
#include "Protocol.h"
#include "Object.h"

#define cDR_SPLIT_DAY	7

struct PMSG_DAILY_REWARD_SEND
{
    PBMSG_HEAD2 h;
    BYTE Type;
    int  Value;
};

struct PMSG_DAILY_REWARD_USER_INFO_RECV
{
    PBMSG_HEAD2 h;
    BYTE MaxDay;
    BYTE CurDay;
    BYTE FWday;
    BYTE State[31];
    DWORD Timer;
};

struct PMSG_DAILY_REWARD_DAY_INFO_RECV
{
    PBMSG_HEAD2 h;
    short Type;
    BYTE Dur;
    BYTE Item[12];
    int  PeriodTime;
    int Wcoin;
    int Zen;
    char Text[100];
};

class cDailyReward : public cInterfaceBase
{
public:
    cDailyReward();
    ~cDailyReward();
    void ToggleWindow(bool mode = false);
    void OpenWindow(bool mode = false);
    void CloseWindow(bool mode = false);
    void SetWindow(bool state, bool mode = false);
    void Init();
    void Draw();
    void OnOpen();
    void OnClose();
    bool AllowedGift();
    void OnRequestGift();
    void ClearDayGift();
    void SendRequest(BYTE type, int value);
    void GCRecvUserInfo(BYTE* a);
    void GCRecvDayInfo(BYTE* a);
    int  CheckItemInfo(signed int a1);
    void DrawIcon();
    static void RecvGiftAction(LPVOID pClass);

    BYTE SelectedDay;
    BOOL Blink;
    BOOL Loaded;
    BOOL Checked;
    BOOL DayInfo;
    BYTE MaxDay;
    BYTE CurDay;
    BYTE FWday;
    BYTE State[31];
    DWORD Timer;
    ObjectItem Item;
    short Type;
    BYTE Level;
    BYTE Ex;
    int Wcoin;
    int Zen;
    char Text[100];
    DWORD TickCount;
};

extern cDailyReward DailyReward;
#endif

 

3. Crear NewFont.cpp y NewFont.h

Estos archivos manejarán la fuente personalizada que se usará en la interfaz.

NewFont.cpp

#include "stdafx.h"
#include "NewFont.h"
#include "Interface.h"

eCustomFont CustomFont;

eCustomFont::eCustomFont()
{
}

eCustomFont::~eCustomFont()
{
}

void eCustomFont::load() 
{
    DWORD Width = 0;
    DWORD Italic = 0;
    DWORD UnderLine = 0;
    DWORD StrikeOut = 0;
    DWORD Quality = 3;

    this->FontNormal = CreateFontA(13, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Tahoma");
    this->FontBold   = CreateFontA(13, Width, 0, 0, 700, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Tahoma");
    this->FontSize15 = CreateFontA(15, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Tahoma");
    this->FontSize16 = CreateFontA(15, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize18 = CreateFontA(18, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Tahoma");
    this->FontSize19 = CreateFontA(19, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize20 = CreateFontA(20, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize21 = CreateFontA(21, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize22 = CreateFontA(22, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize23 = CreateFontA(23, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize24 = CreateFontA(24, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize25 = CreateFontA(25, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize26 = CreateFontA(26, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize27 = CreateFontA(27, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize28 = CreateFontA(28, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize29 = CreateFontA(29, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
    this->FontSize30 = CreateFontA(30, Width, 0, 0, 400, Italic, UnderLine, StrikeOut, 0x1, 0, 0, Quality, 0, "Georgia");
}

eColor eCustomFont::SinWaveColor(float frc1, float frc2, float frc3, BYTE phs1, BYTE phs2, BYTE phs3, BYTE center, BYTE width, BYTE step) {
    eColor result;

    result.red = std::sin(frc1*step + phs1) * width + center;
    result.grn = std::sin(frc2*step + phs2) * width + center;
    result.blu = std::sin(frc3*step + phs3) * width + center;
    result.opl = 0xff;

    return result;
}

void eCustomFont::Draw(HFONT font, int PosX, int PosY, DWORD color, DWORD bkcolor, int Width, int Height, BYTE Align, LPCTSTR Text, ...) {
    char Buff[2048];
    int BuffLen = sizeof(Buff)-1;
    ZeroMemory(Buff, BuffLen);

    va_list args;
    va_start(args, Text);
    int Len = vsprintf_s(Buff, BuffLen, Text, args);
    va_end(args);

    int LineCount = 0;

    char * Line = strtok(Buff, "\n");

    while (Line != NULL)
    {
        pSetTextSize(pTextThis(), font);
        pSetTextColor(pTextThis(), (color & 0xff000000) >> 24, (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, color & 0x000000ff);
        pSetBackgroundTextColor(pTextThis(), (bkcolor & 0xff000000) >> 24, (bkcolor & 0x00ff0000) >> 16, (bkcolor & 0x0000ff00) >> 8, bkcolor & 0x000000ff);
        pDrawText(pTextThis(), PosX, PosY, Line, Width, Height, (LPINT)Align, 0);
        PosY += 10;
        Line = strtok(NULL, "\n");
    }
}

void eCustomFont::DrawMultipleColor(HFONT font, int PosX, int PosY, DWORD bkcolor, int Width, int Height, BYTE Align, LPCTSTR Text, ...) {
    char Buff[2048];
    int BuffLen = sizeof(Buff)-1;
    ZeroMemory(Buff, BuffLen);

    va_list args;
    va_start(args, Text);
    int Len = vsprintf_s(Buff, BuffLen, Text, args);
    va_end(args);

    int LineCount = 0;

    char * Line = strtok(Buff, "\n");
    BYTE len = strlen(Line);

    char filter[10];
    char bufer[255];
    while (Line != NULL)
    {
        pSetTextSize(pTextThis(), font);

        pSetBackgroundTextColor(pTextThis(), (bkcolor & 0xff000000) >> 24, (bkcolor & 0x00ff0000) >> 16, (bkcolor & 0x0000ff00) >> 8, bkcolor & 0x000000ff);
        for (BYTE i = 0; i < len; i++) {
            eColor mColor = CustomFont.SinWaveColor(0.1f, 0.1f, 0.1f, 0, 2, 4, 128, 127, i + GetTickCount() / 100 % 255);
            pSetTextColor(pTextThis(), mColor.red, mColor.grn, mColor.blu, mColor.opl);
            sprintf(filter, "%%.%ds", len - i);
            sprintf(bufer, filter, Line);
            pDrawText(pTextThis(), PosX, PosY, bufer, Width, Height, (LPINT)Align, 0);
        }
        PosY += 10;
        Line = strtok(NULL, "\n");
    }
}

 


NewFont.h

#define pTextThis				((LPVOID(*)()) 0x0041FE10)
#define pTextFormat				((int(__cdecl*)(char * Buffer, int Arg2, int LineSize, LPCTSTR Text, int LineWidth, bool Arg6, BYTE Arg7)) 0x540880)
#define pDrawColorText			((int(__cdecl*)(LPCTSTR Text, int PosX, int PosY, int Width, int Arg5, int Color, int Arg7, int Align)) 0x7D0380)
#define pGetTextLine			((LPCSTR(__thiscall*)(LPVOID This, int LineNumber)) 0x00402320)
#define pMakeColor				((DWORD(__cdecl*)(BYTE, BYTE, BYTE, BYTE)) 0x00412D20)
#define pSetTextColor			((void(__thiscall*)(LPVOID This, int r, int g, int b, int h)) 0x00420040)
#define pSetBackgroundTextColor	((void(__thiscall*)(LPVOID This, int r, int g, int b, int h)) 0x004200B0)
#define pSetTextSize			((int(__thiscall*)(LPVOID This, HFONT a2)) 0x00420120)
#define pSetTextFont			((int(__thiscall*)(LPVOID This, HFONT a2)) 0x00420120)
#define pDrawText				((int(__thiscall*)(LPVOID This, int PosX, int PosY, LPCTSTR Text, int Width, int Height, LPINT Align, int unknow)) 0x00420150)
#define pUnknow00420080			((DWORD(__cdecl*)(LPVOID This, char Arg1)) 0x00420080)
#define pUnknow004200F0			((DWORD(__cdecl*)(LPVOID This, char Arg1)) 0x004200F0)
#define pSetBlend				((void(__cdecl*)(BYTE Mode)) 0x635FD0)
#define pGetTextNumber			((int(__cdecl*)(int a1))0x009CFF45)	

struct eColor {
    BYTE red;
    BYTE grn;
    BYTE blu;
    BYTE opl;
};

class eCustomFont
{
public:
    eCustomFont();
    ~eCustomFont();
    void load();
    void Draw(HFONT font, int PosX, int PosY, DWORD color, DWORD bkcolor, int Width, int Height, BYTE Align, LPCTSTR Text, ...);
    void DrawMultipleColor(HFONT font, int PosX, int PosY, DWORD bkcolor, int Width, int Height, BYTE Align, LPCTSTR Text, ...);
    eColor	SinWaveColor(float frc1, float frc2, float frc3, BYTE phs1, BYTE phs2, BYTE phs3, BYTE center, BYTE width, BYTE step);

    HFONT	FontNormal;
    HFONT	FontBold;
    HFONT	FontSize15;
    HFONT	FontSize16;
    HFONT	FontSize18;
    HFONT	FontSize19;
    HFONT	FontSize20;
    HFONT	FontSize21;
    HFONT	FontSize22;
    HFONT	FontSize23;
    HFONT	FontSize24;
    HFONT	FontSize25;
    HFONT	FontSize26;
    HFONT	FontSize27;
    HFONT	FontSize28;
    HFONT	FontSize29;
    HFONT	FontSize30;
};

extern eCustomFont CustomFont;

 

InterfaceBase.cpp

#include "stdafx.h"
#if(DAILY)
#include "Import.h"
#include "InterfaceBase.h"
#include "NewFont.h"

cInterfaceBase::cInterfaceBase()
{
    SetWindow(false);
}

cInterfaceBase::~cInterfaceBase()
{
}

void cInterfaceBase::ToggleWindow(bool mode)
{
    SetWindow(!CheckWindow(), mode);
}
void cInterfaceBase::OpenWindow(bool mode)
{
    SetWindow(true, mode);
}
void cInterfaceBase::CloseWindow(bool mode)
{
    SetWindow(false, mode);
}
void cInterfaceBase::SetWindow(bool state, bool mode)
{
    this->Drawing = state;
    if (mode)
        CheckWindow() ? OnOpen() : OnClose();
}
bool cInterfaceBase::CheckWindow()
{
    return this->Drawing;
}
void cInterfaceBase::SetRect(float a1, float a2, float a3, float a4)
{
    this->x = a1;
    this->y = a2;
    this->w = a3;
    this->h = a4;
}
bool cInterfaceBase::CheckRect(bool mode)
{
    return CheckWindow() && IsWorkZone(x, y, w, h + 30, mode);
}
void cInterfaceBase::OnOpen()
{
    //do smt
    //pDrawMessage("OnOpen", 1);
}
void cInterfaceBase::OnClose()
{
    //do smt
    //pDrawMessage("OnClose", 0);
}
void cInterfaceBase::DrawBase()
{

    //==========
    glAlphaFunc(GL_GREATER, 0.0f);

    CustomFont.Draw(CustomFont.FontBold, x, y, 0x0, 0x373b45ff, w, h + 30, 1, " ");


    RenderBitmap(31355, x, y + 63, 21.0, 189.2f, 0, 0, 21.f / 32.f, 320.f / 512.f, 1, 1, 0.0);
    RenderBitmap(31356, x + w - 21.f, y + 63, 21.0, 189.2f, 0, 0, 21.f / 32.f, 320.f / 512.f, 1, 1, 0.0);

    RenderBitmap(31353, x, y, 60.f, 63.f, 0.0, 0, 60.f / 256.f, 63.f / 64.f, 1, 1, 0.0);
    RenderBitmap(31353, x + 60, y, 70.f, 63.f, 60.f / 256.f, 0, 70.f / 256.f, 63.f / 64.f, 1, 1, 0.0);
    RenderBitmap(31353, x + 130, y, 70.f, 63.f, 60.f / 256.f, 0, 70.f / 256.f, 63.f / 64.f, 1, 1, 0.0);
    RenderBitmap(31353, x + 200, y, 70.f, 63.f, 60.f / 256.f, 0, 70.f / 256.f, 63.f / 64.f, 1, 1, 0.0);
    RenderBitmap(31353, x + 270, y, 70.f, 63.f, 60.f / 256.f, 0, 70.f / 256.f, 63.f / 64.f, 1, 1, 0.0);
    RenderBitmap(31353, x + 340, y, 60.f, 63.f, 130.f / 256.f, 0, 60.f / 256.f, 63.f / 64.f, 1, 1, 0.0);

    pDrawButton(31357, x, y + 242, 60.0, 45.0, 0, 0);
    pDrawButton(31357, x + 60, y + 242, 70.0, 45.0, 60.0, 0);
    pDrawButton(31357, x + 130, y + 242, 70.0, 45.0, 60.0, 0);
    pDrawButton(31357, x + 200, y + 242, 70.0, 45.0, 60.0, 0);
    pDrawButton(31357, x + 270, y + 242, 70.0, 45.0, 60.0, 0);
    pDrawButton(31357, x + 340, y + 242, 60.0, 45.0, 130.0, 0);


    if (IsWorkZone(x + w - 25, y + 5, 20, 18, false))
    {
        if (pIsKeyRelease(VK_LBUTTON) && IsOnWindow())
            this->SetWindow(false, true);
        ((int(__cdecl*)(int X, int Y, LPCSTR Text)) 0x00597220)(x + w - 25, y + 25, "Close");
    }

    glAlphaFunc(GL_GREATER, 0.25f);


    if (_Title->Enable)
        CustomFont.Draw(_Title->Bold ? CustomFont.FontBold : CustomFont.FontNormal, x, y + 12, _Title->Color, _Title->Background, w, 0, 3, _Title->Title);
}
void cInterfaceBase::SetTitle(char* title, DWORD color, DWORD bg, bool bold)
{
    this->_Title = new cIB_Title(title, color, bg, bold);
}

bool cInterfaceBase::IsOnWindow()
{
    return *(HWND*)0x0E8C578 == GetForegroundWindow();
}
bool cInterfaceBase::IsWorkZone(float x, float y, float w, float h, bool mode)
{
    if (mode)
        return IsOnWindow() && * (int*)0x879340C >= x && *(int*)0x879340C <= x + w && *(int*)0x8793410 >= y && *(int*)0x8793410 <= y + h;
    return *(int*)0x879340C >= x && *(int*)0x879340C <= x + w && *(int*)0x8793410 >= y && *(int*)0x8793410 <= y + h;
}
void cInterfaceBase::DrawButton(int IMGcode, float x, float y, float w, float h, float a6, float a7, PUSHEVENT_CALLBACK_LPVOID pCallbackFunc) {
    if (IsWorkZone(x, y, w, h, true)) {
        if (GetKeyState(VK_LBUTTON) & 0x8000) {
            RenderBitmap(IMGcode, x, y, w, h, 0.0, h / a7 * 2.0, w / a6, h / a7, 1, 1, 0.0);
        }
        else {
            RenderBitmap(IMGcode, x, y, w, h, 0.0, h / a7, w / a6, h / a7, 1, 1, 0.0);
        }
        if (pIsKeyRelease(VK_LBUTTON))
        {
            pCallbackFunc(this);
            return;
        }
        return;
    }
    else {
        RenderBitmap(IMGcode, x, y, w, h, 0.0, 0.0, w / a6, h / a7, 1, 1, 0.0);
    }
    return;
}
#endif

 


InterfaceBase.h

#pragma once
#if(DAILY)
#define pIsKeyRelease		((bool(__cdecl*)(int)) 0x791050)
#define RenderBitmap		((void(__cdecl*)(int a1, float a2, float a3, float a4, float a5, float a6, float a7, float a8, float a9, char a10, char a11, float a12)) 0x00637C60)

typedef void(*PUSHEVENT_CALLBACK_LPVOID)(LPVOID);

struct cIB_Title
{
    bool Enable;
    bool Bold;
    char Title[60];
    DWORD Color;
    DWORD Background;
    cIB_Title()
    {
        Enable = false;
        ZeroMemory(Title, sizeof(Title));
    };
    cIB_Title(char* title, DWORD color = 0xffffffff, DWORD bg = 0x0, bool bold = false)
    {
        Enable = true;
        Bold = bold;
        Color = color;
        Background = bg;
        ZeroMemory(Title, sizeof(Title));
        memcpy_s(Title, sizeof(Title), title, sizeof(Title));
    };
};

class cInterfaceBase
{
public:
    cInterfaceBase();
    ~cInterfaceBase();

    void ToggleWindow(bool mode = false);
    void OpenWindow(bool mode = false);
    void CloseWindow(bool mode = false);
    void SetWindow(bool state, bool mode = false);
    bool CheckWindow();
    void SetRect(float a1, float a2, float a3, float a4);
    bool CheckRect(bool mode = true);
    void OnOpen();
    void OnClose();
    void DrawBase();
    void SetTitle(char* title, DWORD color = 0xffffffff, DWORD bg = 0x0, bool bold = false);
    bool IsWorkZone(float, float, float, float, bool mode = false);
    bool IsOnWindow();
    void DrawButton(int IMGcode, float x, float y, float w, float h, float a6, float a7, PUSHEVENT_CALLBACK_LPVOID pCallbackFunc);
protected:
    float x;
    float y;
    float w;
    float h;
    bool Drawing;
    cIB_Title* _Title;
};
#endif

 

Parte 2: Integración en el Código Existente

1. Modificar Interface.cpp

Este Define va en los sguientes .cpp:

Interface.cpp 

#include "DailyReward.h"

 

Luego, busca void Interface::Work() y agrega lo siguiente:

Interface.cpp

#if(DAILY)
if (gProtect.m_MainInfo.DailyReward == 1)
{
DailyReward.Draw();
}
#endif

Luego Buscas if (GetKeyState(‘ y agregas el siguiente codigo:

if (GetKeyState('Y') & 0x4000 && GetTickCount() >= gCustomRanking.OpenTestDelay + 250)
{
    if (GetForegroundWindow() == pGameWindow && !gInterface.CheckWindow(ObjWindow::ChatWindow))
    {
        DailyReward.ToggleWindow(true);
        gCustomRanking.OpenTestDelay = GetTickCount();
    }
}

Agregar el SetCursorFocus este codigo lo agregas al final del codigo de interface.cpp

#if SKIN
void Interface::SetCursorFocus()
{
    bool focus = false;

    bool focus1 = false;
    bool focus2 = false;

    focus = RentSkin.CheckRect();

    focus1 = DailyReward.CheckRect();

    focus2 = ThueFlag.CheckRect();

    if (focus)
    {
        if (!pSetCursorFocus)
        {
            pSetCursorFocus = true;
        }
    }

    if (focus1)
    {
        if (!pSetCursorFocus)
        {
            pSetCursorFocus = true;
        }
    }

    if (focus2)
    {
        if (!pSetCursorFocus)
        {
            pSetCursorFocus = true;
        }
    }
}
#endif

Interface.h

Aqui vas a bucar class Interface y agregas debajo de publico

#if SKIN
    void SetCursorFocus();
#endif

 

2. Modificar Protocol.cpp

#include "DailyReward.h"

 

Luego, busca case 0xFB: y agrega:

#if(DAILY)
case 0x03:
DailyReward.GCRecvUserInfo(lpMsg);
break;
case 0x04:
DailyReward.GCRecvDayInfo(lpMsg);
break;
#endif

3. Protect.h

Agrega debajo de struct MAIN_FILE_INFO:

DWORD DailyReward; //Reward Diario

 

4. Controller.cpp

En Busca VK_ESCAPE: y agregas el siguiente codgo.

asi debes colocar el codigod entro de CloseWindow

 

DailyReward.CloseWindow(true);

 


CODIGOS FALTANTE PARA LAS BASES LIMPIAS

Aqui dejare algunos codgos que le faltan a las bases limpias como Louis 15 p Takumi 15 Aqui unos ejemplos y soluciones

Interface.cpp

  • DrawItem2
void Interface::DrawItem2(float PosX, float PosY, float Width, float Height, int ItemID, int Level, int Excl, int Anc, bool OnMouse){
    glMatrixMode(0x1701);
    glPushMatrix();
    glLoadIdentity();
    sub_6363D0_Addr(0, 0, *(GLsizei*)0x00E61E58, *(GLsizei*)0x00E61E5C);
    float v2 = *(float*)0x00E61E58 / *(float*)0x00E61E5C;
    sub_6358A0_Addr(1.0, v2, *(float*)0xE61E38, *(float*)0xE61E3C);
    glMatrixMode(0x1700);
    glPushMatrix();
    glLoadIdentity();
    sub_635830_Addr((LPVOID)0x87933A0);
    sub_635DE0_Addr();
    sub_635E40_Addr();
    pDrawItemModel(PosX, PosY, Width, Height, ItemID, Level, Excl, Anc, OnMouse);
    glColor3f(1,1,1);
    pSetBlend(false);
}

Interface.h

void	    DrawItem2(float PosX, float PosY, float Width, float Height, int ItemID, int Level, int Excl, int Anc, bool OnMouse);

Interface.cpp

  • DrawItemToolTipText
void Interface::DrawItemToolTipText ( void * item, int x, int y ) {
        static DWORD mem = 0;
        //static DWORD ItemToolTipAdress1 = 0x00861110; //1.04D-> 0x00860FC0
        //static DWORD ItemToolTipAdress2 = 0x00861AA0; //1.04D-> 0x00861950
        //static DWORD ItemToolTipAdress3 = 0x007E3E30; //1.04D-> 0x007E3CE0
        _asm {
            PUSH 0
            PUSH 0
            PUSH 0
            PUSH item
            PUSH y
            PUSH x
            MOV mem,0x00861110
            CALL mem
            MOV ECX, EAX
            MOV mem,0x00861AA0
            CALL mem
            MOV ECX, EAX
            MOV mem,0x007E3E30
            CALL mem
        }

}

Interface.h

static void DrawItemToolTipText ( void * item, int x, int y );

 

 

 

Conclusión

Con estos pasos, tendrás implementado el sistema DailyReward en tu servidor de MuOnline. Este sistema no solo mejorará la experiencia de tus jugadores, sino que también fomentará su participación continua. Si encuentras algún error o tienes dudas, no dudes en comentarlo. Recuerda que cada fuente puede tener sus particularidades, así que adapta la guía según sea necesario.

Créditos

Agradecimientos a Dakosmu por su contribución a esta guía.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *