shepher

Trade 15 Shepher

Nov 20th, 2012
721
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.78 KB | None | 0 0
  1. // Struct trade
  2.  
  3. typedef struct
  4. {
  5.     bool isTrading;
  6.     bool WaitingData;
  7.     bool Confirm;
  8.  
  9.     DWORD Gold;
  10.     clock_t Timer;
  11.        
  12.     WORD ClientID;
  13.  
  14.     st_Item Itens[15];
  15.     char TradeItemSlot[15];
  16. } st_Trade;
  17.  
  18. // Declaração em .h
  19. #define MAX_PLAYER 100
  20. extern st_Trade Trade[MAX_PLAYER+1];
  21.  
  22. // Declare num .cpp
  23. st_Trade Trade[MAX_PLAYER+1];
  24.  
  25. // Em um .cpp com Hooks
  26. void __declspec(naked) NKD_NewTrade()
  27. {
  28.     static const int dwContinue = 0x00438D57;
  29.     __asm
  30.     {
  31.     PUSH [EBP + 08h]
  32.         PUSH [EBP + 0Ch]
  33.         CALL NKD_SystemTrade
  34.         JMP dwContinue
  35.     }
  36. }
  37.  
  38. // Chame a função usando:
  39. JMP_NEAR(0x4323F4, &NKD_NewTrade, 2);
  40.  
  41. // Um novo .cpp contendo o código:
  42. /*
  43. -------------
  44. by Shepher
  45. -------------
  46. */
  47.  
  48. void OpenTrade(short ClientID, short MobID)
  49. {
  50.     // Usado após o Request, onde é enviado o trade totalmente vazio
  51.     SendTrade p;
  52.     memset(&p, 0, sizeof p);
  53.     p.Header.ClientId = MobID;
  54.     p.OtherClientid = ClientID;
  55.     p.Header.Size = 156;
  56.     p.Header.PacketId = 0x383;
  57.     for(UINT8 i=0;i<15;i++)
  58.         p.TradeItemSlot[i] = 255;
  59.     SendPacket((BYTE*)&p, MobID, 156);
  60. }
  61.  
  62. void SendAllTrade(short ClientID, short MobID)
  63. {
  64.     // Envia o trade completo para o MobID
  65.     SendTrade p;   
  66.     memset(&p, 0, sizeof p);
  67.     p.Header.ClientId = MobID;
  68.     p.OtherClientid = ClientID;
  69.     p.Header.Size = 156;
  70.     p.Header.PacketId = 0x383;
  71.     p.Confirma = Trade[ClientID].Confirm;
  72.     for(UINT8 i=0;i<15;i++)
  73.     {
  74.         p.TradeItem[i] = Trade[ClientID].Itens[i];
  75.         p.TradeItemSlot[i] = Trade[ClientID].TradeItemSlot[i];
  76.     }
  77.     p.Gold = Trade[ClientID].Gold;
  78.     SendPacket((BYTE*)&p, MobID, 156);
  79. }
  80.  
  81. void CloseTrade(short ClientID)
  82. {
  83.     // Fecha o trade dos dois usuários
  84.     memset(Trade[ClientID].TradeItemSlot, 255, sizeof(char) * 15);
  85.     memset(Trade[ClientID].Itens, 0, sizeof st_Item * 15);
  86.     Trade[ClientID].isTrading = false;
  87.     Trade[ClientID].Timer = 0;
  88.     Trade[ClientID].Confirm = false;
  89.     Trade[ClientID].WaitingData = false;
  90.     PacketHeader Header;
  91.     Header.ClientId = ClientID;
  92.     Header.Size = 12;
  93.     Header.PacketId = 0x384;
  94.     SendPacket((BYTE*)&Header, ClientID, 12);
  95.     if(Trade[Trade[ClientID].ClientID].isTrading && Trade[Trade[ClientID].ClientID].ClientID != 0 && StatusPlayer(Trade[Trade[ClientID].ClientID].ClientID) == 22)
  96.     {
  97.         // Checa se o outro jogador está em modo troca e se ele é um jogador válido
  98.         // Evita bugs com o outro char ficar em modo troca ainda
  99.         Trade[Trade[ClientID].ClientID].isTrading = false;
  100.         Trade[Trade[ClientID].ClientID].Timer = 0;
  101.         Trade[Trade[ClientID].ClientID].Confirm = false;
  102.         Trade[Trade[ClientID].ClientID].WaitingData = false;
  103.         memset(Trade[Trade[ClientID].ClientID].Itens, 0, sizeof st_Item * 15);
  104.         memset(Trade[Trade[ClientID].ClientID].TradeItemSlot, 0, sizeof(char) * 15);
  105.         Header.ClientId = Trade[ClientID].ClientID;
  106.         SendPacket((BYTE*)&Header, Trade[ClientID].ClientID, 12);
  107.         Trade[Trade[ClientID].ClientID].ClientID = 0;
  108.     }
  109.     Trade[ClientID].ClientID = 0;
  110. }
  111.  
  112.  
  113. void CheckItensOnTrade(short ClientID, short MobID)
  114. {
  115.     // Sua função é checar se os itens colocados no trade realmente existem no inventário do usuário
  116.     // Se não existirem, provavelmente é uma tentativa de hack pois o client não se enganará com isso
  117.     st_Mob *player = (st_Mob*)GetMobFromIndex(ClientID);
  118.     st_Mob *mob = (st_Mob*)GetMobFromIndex(MobID);
  119.     for(UINT8 i=0;i<15;i++)
  120.     {
  121.         if(Trade[ClientID].Itens[i].Index == 255)
  122.             continue;
  123.         if(!memcmp(&Trade[ClientID].Itens[i], &player->Inventory[Trade[ClientID].TradeItemSlot[i]], 8))
  124.         {
  125.             CloseTrade(ClientID);
  126.             break;
  127.         }
  128.         if(!memcmp(&Trade[MobID].Itens[i], &mob->Inventory[Trade[MobID].TradeItemSlot[i]], 8))
  129.         {
  130.             CloseTrade(MobID);
  131.             break;
  132.         }
  133.     }
  134. }
  135.  
  136. bool CanTrade(UINT16 Index)
  137. {
  138.     // Função que serve para adicionar Itens imóveis
  139.     switch(Index)
  140.     {
  141.     case 5338:
  142.     case 4138:
  143.     case 413:
  144.         return false;
  145.     default:
  146.         return true;
  147.     }
  148.     return true;
  149. }
  150.  
  151. bool AddItensOnTrade(SendTrade *p)
  152. {
  153.     // Serve para a verificação de um item imóvel e para adicionar os itens do trade a struct trade do usuário
  154.     for(UINT8 i=0;i<15;i++)
  155.     {
  156.         if(!CanTrade(p->TradeItem[i].Index))
  157.         {
  158.             SendClientMsg(p->Header.ClientId, "Item imóvel!");
  159.             return false;
  160.         }
  161.         Trade[p->Header.ClientId].TradeItemSlot[i] = p->TradeItemSlot[i];
  162.         memcpy(&Trade[p->Header.ClientId].Itens[i], &p->TradeItem[i], 8);      
  163.     }  
  164.     st_Mob *player = (st_Mob*)GetMobFromIndex(p->Header.ClientId);
  165.     st_Mob *mob = (st_Mob*)GetMobFromIndex(p->OtherClientid);
  166.     if(p->Gold > player->Gold)
  167.         return false;
  168.     if(player->Gold + Trade[p->OtherClientid].Gold > 2000000000)
  169.     {
  170.         SendClientMsg(p->Header.ClientId, "Limite de 2bilhões de gold");
  171.         SendClientMsg(p->OtherClientid, "Limite de 2bilhões de gold");
  172.         return false;
  173.     }
  174.     if(mob->Gold + Trade[p->Header.ClientId].Gold > 2000000000)
  175.     {
  176.         SendClientMsg(p->Header.ClientId, "Limite de 2bilhões de gold");
  177.         SendClientMsg(p->OtherClientid, "Limite de 2bilhões de gold");
  178.         return false;
  179.     }
  180.     return true;
  181. }
  182.  
  183. BYTE GetAmountItemOnTrade(short ClientID)
  184. {
  185.     // Retorna quantos itens foram colocados no trade do usuário
  186.     BYTE val = 0;
  187.     for(UINT8 i=0;i<15;i++)
  188.         if(Trade[ClientID].Itens[i].Index != 0)
  189.             val++;
  190.     return val;
  191. }
  192.  
  193. void NKD_SystemTrade(BYTE *m_PacketBuffer, int ClientID)
  194. {
  195.     SendTrade *p = (SendTrade*)m_PacketBuffer;
  196.  
  197.     if(StatusPlayer(p->OtherClientid) != 22)
  198.     {
  199.         // Checa se o usuário está realmente online
  200.         SendClientMsg(ClientID, "O usuário não está conectado!");
  201.         return;
  202.     }
  203.     SendClientMsg(ClientID, "O sistema de troca está em fase de testes.");
  204.     SendClientMsg(ClientID, "Caso encontre algum bug, por favor, reporte.");
  205.     SendClientMsg(p->OtherClientid, "O sistema de troca está em fase de testes.");
  206.     SendClientMsg(p->OtherClientid, "Caso encontre algum bug, por favor, reporte.");
  207.     if(!Trade[p->OtherClientid].isTrading && !Trade[ClientID].isTrading)
  208.     {
  209.         // Verifica se nenhum dos dois jogadores está com trade
  210.         // Se os dois não estiverem, quer dizer que foi enviado um pedido para Trade
  211.         Sleep(2000);
  212.         OpenTrade(ClientID, p->OtherClientid);
  213.         Trade[ClientID].WaitingData = true;
  214.         Trade[ClientID].Timer = clock();
  215.         Trade[ClientID].isTrading = true;
  216.         Trade[ClientID].ClientID = p->OtherClientid;
  217.         Trade[ClientID].Confirm = false;
  218.         Trade[p->OtherClientid].Timer = clock();
  219.         Trade[p->OtherClientid].isTrading = true;
  220.         Trade[p->OtherClientid].ClientID = ClientID;
  221.         Trade[p->OtherClientid].Confirm = false;
  222.     }
  223.     else if(Trade[p->OtherClientid].isTrading && Trade[p->OtherClientid].ClientID != ClientID)
  224.     {
  225.         // Se você está sem o modo trade e o usuário que foi pedido estiver em negociação
  226.         // a mensagem abaixo é mostrada
  227.         SendClientMsg(ClientID, "O outro jogador já está em negociação!");
  228.     }
  229.     else { // Caso não seja um request, será feito as verificações para envio de item/confirm etc.
  230.         if(Trade[ClientID].isTrading && Trade[ClientID].ClientID != p->OtherClientid)
  231.         {
  232.             // Para evitar qualquer tipo de bug se o jogador já está em troca
  233.             // o trade do mesmo é fechado
  234.             SendClientMsg(ClientID, "Você já está em modo troca!");
  235.             CloseTrade(ClientID);
  236.         }
  237.         else if(Trade[p->OtherClientid].isTrading && !Trade[ClientID].isTrading && Trade[p->OtherClientid].WaitingData)
  238.         {
  239.             // Checa se o usuário que foi pedido o trade está sem trade novamente e se
  240.             // o usuário que enviou o trade está realmente esperando o trade
  241.             Trade[ClientID].isTrading = true;
  242.             Trade[ClientID].WaitingData = true;
  243.             Trade[ClientID].Confirm = false;
  244.             Trade[ClientID].Timer = clock();
  245.             Trade[ClientID].ClientID = p->OtherClientid;
  246.             OpenTrade(ClientID, p->OtherClientid);
  247.         }
  248.         else if(p->Confirma)
  249.         {
  250.             if(clock() - Trade[ClientID].Timer < 2 *CLOCKS_PER_SEC)
  251.             {
  252.                 // O próprio cliente existe proteção, mas como o packet pode ser manipulado e/ou enviado
  253.                 // pelo próprio usuário como forma de hack, é feito a proteção no servidor também
  254.                 // Caso queira, coloque um CloseTrade ao final dessa condição porque o client provavelmente não se enganará
  255.                 SendClientMsg(ClientID, "Aguarde 2 segundos e confirme");
  256.                 Trade[ClientID].Timer = clock();
  257.             }
  258.             else {
  259.                 Trade[ClientID].Confirm = p->Confirma;
  260.                 if(Trade[p->OtherClientid].Confirm)
  261.                 {
  262.                     int amount_TradeOID = GetAmountItemOnTrade(p->OtherClientid);
  263.                     int amount_TradeCID = GetAmountItemOnTrade(ClientID);
  264.                     if(GetAmountItem(ClientID, 0) < amount_TradeOID)
  265.                     {
  266.                         // Checa se a quantidade de itens nulos no inventário do usuário é igual ou maior
  267.                         // que a quantidade de itens colocadas no trade
  268.                         SendClientMsg(ClientID, "Você não possui espaço no inventário");
  269.                         SendClientMsg(p->OtherClientid, "O outro jogador não possui espaço no inventário");
  270.                         CloseTrade(ClientID);
  271.                     }
  272.                     else if(GetAmountItem(p->OtherClientid, 0) < amount_TradeCID)
  273.                     {
  274.                         // Checa se a quantidade de itens nulos no inventário do usuário é igual ou maior
  275.                         // que a quantidade de itens colocadas no trade
  276.                         SendClientMsg(p->OtherClientid, "Você não possui espaço no inventário");
  277.                         SendClientMsg(ClientID, "O outro jogador não possui espaço no inventário");
  278.                         CloseTrade(ClientID);
  279.                     } else {
  280.                         st_Mob *player = (st_Mob*)GetMobFromIndex(ClientID);
  281.                         st_Mob *mob = (st_Mob*)GetMobFromIndex(p->OtherClientid);
  282.                         int SlotID = 0;
  283.                         int SlotOID = 0;
  284.                         for(UINT8 i=0;i<15;i++)
  285.                         {
  286.                             // Faz o loop para todos os itens do trade
  287.                             // Slot livre do inventário
  288.                             if(Trade[ClientID].Itens[i].Index != 0)
  289.                                 SlotID = GetFirstSlotSADD(p->OtherClientid, 0, 64);
  290.                             // Slot livre do inventário
  291.                             if(Trade[p->OtherClientid].Itens[i].Index != 0)
  292.                                 SlotOID = GetFirstSlotSADD(ClientID, 0, 64);
  293.                             // Checa se os valores retornados são válidos
  294.                             // Se retornar -1 quer dizer que a funçaõ anterior (GetAmountItem) aconteceu algum erro
  295.                             if(SlotID == -1 || SlotOID == -1) {
  296.                                 // O erro aconteceu então a mensagem é enviada aos dois players e o trade dos mesmos é fechado
  297.                                 SendClientMsg(ClientID, "Ocorreu um erro!");
  298.                                 SendClientMsg(p->OtherClientid, "Ocorreu um erro!");
  299.                                 CloseTrade(ClientID);
  300.                             }
  301.                             // Checa se existe algum item no slot correspondente do trade
  302.                             if(Trade[ClientID].Itens[i].Index != 0) {
  303.                                 // Copia o item que está no trade do outro usuário
  304.                                 memcpy(&mob->Inventory[SlotID], &Trade[ClientID].Itens[i], sizeof st_Item);
  305.                                 // Apaga o item do inventário do outro usuário
  306.                                 memset(&player->Inventory[Trade[ClientID].TradeItemSlot[i]], 0, sizeof st_Item);
  307.                                 // Atualiza o slot do personagem em que o item foi apagado
  308.                                 SendSlot(ClientID, Trade[ClientID].TradeItemSlot[i]);
  309.                                 SendSlot(p->OtherClientid, SlotID);
  310.                             }
  311.                             // Checa se existe algum item no slot correspondente do trade
  312.                             if(Trade[p->OtherClientid].Itens[i].Index != 0) {                          
  313.                                 // Copia o item que está no trade do outro usuário
  314.                                 memcpy(&player->Inventory[SlotOID], &Trade[p->OtherClientid].Itens[i], sizeof st_Item);
  315.                                 // Apaga o item do inventário do outro usuário
  316.                                 memset(&mob->Inventory[Trade[p->OtherClientid].TradeItemSlot[i]], 0, sizeof st_Item);
  317.                                 // Atualiza o slot do personagem em que o item foi apagado
  318.                                 SendSlot(p->OtherClientid, Trade[p->OtherClientid].TradeItemSlot[i]);
  319.                                 SendSlot(ClientID, SlotOID);
  320.                             }
  321.                         }
  322.                         // Adiciona o gold colocado no trade
  323.                         player->Gold += Trade[p->OtherClientid].Gold;
  324.                         // Adiciona o gold colocado no trade do outro player
  325.                         mob->Gold += Trade[ClientID].Gold;
  326.                         // Retira o gold colocado no trade
  327.                         player->Gold -= Trade[ClientID].Gold;
  328.                         // Retira o gold colocado no trade
  329.                         mob->Gold -= Trade[p->OtherClientid].Gold;
  330.                         // Atualiza o gold do inventário dos dois players
  331.                         SendStats(ClientID);
  332.                         SendStats(p->OtherClientid);
  333.                         CloseTrade(ClientID);
  334.                     }
  335.                 } else
  336.                     // Se o outro usuário não confirmou ainda o trade, apenas é enviado para o outro usuário
  337.                     // o botão de confirmação juntamente com os itens/gold do trade
  338.                     SendAllTrade(ClientID, p->OtherClientid);
  339.             }
  340.         }
  341.         else {
  342.             // Aqui o usuário apenas colocou os itens no slot
  343.             if(!AddItensOnTrade(p))  // Aconteceu algum erro ao adicionar os itens ao trade
  344.                 CloseTrade(ClientID);
  345.              else {
  346.                  // Não aconteceu erro, então é setado tudo normalmente
  347.                 Trade[ClientID].Gold = p->Gold;
  348.                 Trade[ClientID].Confirm = false;
  349.                 Trade[Trade[ClientID].ClientID].Confirm = false;
  350.                 Trade[ClientID].Timer = clock();
  351.                 Trade[ClientID].Confirm = false;
  352.                 SendAllTrade(ClientID, p->OtherClientid);
  353.             }
  354.         }
  355.     }
  356.     ZeroMemory(m_PacketBuffer, 156);
  357. }
  358.  
  359. // Ideia para usuários não leigos:
  360. // ItemList com EF_NOTRADE para itens que não podem ser trocados. Aí você adapta conforme quiser
  361.  
  362. // Shepher & fabiosam
Advertisement
Add Comment
Please, Sign In to add comment