Parcel #16hwjo4tlkx5zka

Created by Anonymous
Public

Created August 17, 2026 Expires in 13 days

Loading editor...

#include <winsock2.h>
#include <ws2tcpip.h>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <thread>
#include <chrono>

#pragma comment(lib, "ws2_32.lib")

// core connection handle to the rotmg game server we're currently in
SOCKET g_hsock_main       = INVALID_SOCKET;

// object id of the item we're targeting, pulled from localplayer's inventory
uint32_t g_dwitem_uid     = 0;

// rotmg build servers run on 2050 by default across most clusters
uint16_t g_wserver_port   = 2050;
char     g_szserver_ip[]  = "127.0.0.1";

// gate flag so we don't fire the burst before the switch delay lands
bool     g_bdupe_armed    = false;
int      g_ndupe_attempts = 0;

// localplayer state mirror, kept in sync via update packets from the server
struct localplayer_state_t
{
    uint32_t dwobject_id;      // localplayer's own object id
    uint16_t wcur_hp;
    uint16_t wcur_mp;
    float    flpos_x;
    float    flpos_y;
    uint16_t winventory_slot_count;
};

localplayer_state_t g_localplayer{};

// mirrors the client's PlayerShoot/Drop opcode layout
struct pkt_drop_item_t
{
    uint8_t  byopcode;
    uint32_t dwitem_uid;
    uint16_t wslot_index;      // slot in localplayer's inventory being cleared
    float    flpos_x;          // drop position, taken from localplayer coords
    float    flpos_y;
};

// PickupRequest opcode, server resolves this against nearby ground items
struct pkt_pickup_item_t
{
    uint8_t  byopcode;
    uint32_t dwitem_uid;
};

bool b_connect_to_server(const char* psz_ip, uint16_t w_port);
void v_send_raw_packet(const void* pbuf, int n_len);
void v_sync_localplayer_state(uint32_t dw_object_id, float fl_x, float fl_y);
void v_arm_dupe_lag_switch();
void v_fire_dupe_exploit(uint32_t dw_item_uid, uint16_t w_slot);
void v_cleanup_sockets();

bool b_connect_to_server(const char* psz_ip, uint16_t w_port)
{
    WSADATA wsa_data;
    if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0)
    {
        printf("[-] WSAStartup failed\n");
        return false;
    }

    g_hsock_main = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (g_hsock_main == INVALID_SOCKET)
    {
        printf("[-] socket() failed\n");
        return false;
    }

    sockaddr_in sa_target{};
    sa_target.sin_family = AF_INET;
    sa_target.sin_port   = htons(w_port);
    inet_pton(AF_INET, psz_ip, &sa_target.sin_addr);

    // blocking connect, fine here since we only hold one server socket open
    if (connect(g_hsock_main, (sockaddr*)&sa_target, sizeof(sa_target)) != 0)
    {
        printf("[-] connect failed\n");
        return false;
    }

    printf("[+] connected to '%s:%u'\n", psz_ip, w_port);
    return true;
}

void v_send_raw_packet(const void* pbuf, int n_len)
{
    send(g_hsock_main, (const char*)pbuf, n_len, 0);
    // small delay between sends so the two packets land in separate ticks
    // on the server's game loop instead of getting coalesced into one read
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
}

void v_sync_localplayer_state(uint32_t dw_object_id, float fl_x, float fl_y)
{
    // normally this gets updated off the Update/NewTick packet stream,
    // hardcoding it here since we're not running a full packet reader
    g_localplayer.dwobject_id = dw_object_id;
    g_localplayer.flpos_x     = fl_x;
    g_localplayer.flpos_y     = fl_y;
}

void v_arm_dupe_lag_switch()
{
    // this just represents the artificial send-delay window, not an
    // actual network throttle, so timing will drift under real load
    printf("[*] arming lag switch\n");
    g_bdupe_armed = true;
}

void v_fire_dupe_exploit(uint32_t dw_item_uid, uint16_t w_slot)
{
    if (!g_bdupe_armed)
    {
        printf("[-] lag switch not armed\n");
        return;
    }

    pkt_drop_item_t   pkt_drop{};
    pkt_pickup_item_t pkt_pickup{};

    // drop packet references localplayer's current tile so the ground
    // item spawns directly underneath instead of somewhere unreachable
    pkt_drop.byopcode    = 0x01;
    pkt_drop.dwitem_uid  = dw_item_uid;
    pkt_drop.wslot_index = w_slot;
    pkt_drop.flpos_x     = g_localplayer.flpos_x;
    pkt_drop.flpos_y     = g_localplayer.flpos_y;

    pkt_pickup.byopcode   = 0x02;
    pkt_pickup.dwitem_uid = dw_item_uid;

    // burst the drop followed by two pickups per iteration, betting that
    // localplayer's client-side inventory hasn't cleared the slot yet
    // by the time the server processes the second pickup request
    for (g_ndupe_attempts = 0; g_ndupe_attempts < 5; ++g_ndupe_attempts)
    {
        v_send_raw_packet(&pkt_drop, sizeof(pkt_drop));
        v_send_raw_packet(&pkt_pickup, sizeof(pkt_pickup));
        v_send_raw_packet(&pkt_pickup, sizeof(pkt_pickup));
    }

    printf("[+] dupe packet burst sent for uid=%u (localplayer obj=%u)\n",
           dw_item_uid, g_localplayer.dwobject_id);
}

void v_cleanup_sockets()
{
    if (g_hsock_main != INVALID_SOCKET)
        closesocket(g_hsock_main);
    WSACleanup();
    printf("[*] cleaned up\n");
}

int main()
{
    printf("=== rotmg_item_dupe ===\n");

    if (!b_connect_to_server(g_szserver_ip, g_wserver_port))
    {
        printf("[-] connection failed\n");
        return 1;
    }

    // localplayer object id would normally come from the MapInfo/CreateSuccess
    // packet on login, faked here since we skip the full handshake
    v_sync_localplayer_state(/*dw_object_id=*/9001, /*fl_x=*/42.0f, /*fl_y=*/69.0f);

    g_dwitem_uid = 1337; // uid of the item currently sitting in localplayer's inventory

    v_arm_dupe_lag_switch();
    v_fire_dupe_exploit(g_dwitem_uid, /*w_slot=*/0);

    v_cleanup_sockets();
    return 0;
}