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;
}