M2BobFixed

Members
  • Content count

    277
  • Joined

  • Last visited

M2BobFixed last won the day on May 6 2016

M2BobFixed had the most liked content!

Community Reputation

1,375 Godlike

3 Followers

About M2BobFixed

  • Rank
    Noble

Contact Methods

  • Website URL
    http://www.gamesecurity.eu
  • Skype
    realotus

Profile Information

  • Gender
    Male
  • Location
    Roma

Recent Profile Visitors

2,287 profile views
  1. Open input.cpp Make your Analyze function like mine: int CInputHandshake::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) { if (bHeader == 10) return 0; if (bHeader == HEADER_CG_TEXT)// HEADER_CG_TEXT = 64 -> 64 IN HEXADECIMAL = 0x40 { ++c_pData; const char * c_pSep; if (!(c_pSep = strchr(c_pData, '\n'))) return -1; if (*(c_pSep - 1) == '\r') --c_pSep; std::string stResult; std::string stBuf; stBuf.assign(c_pData, 0, c_pSep - c_pData); sys_log(0, "SOCKET_CMD: FROM(%s) CMD(%s)", d->GetHostName(), stBuf.c_str()); if (!stBuf.compare("PLAYER_ONLINE")) { std::string risultato=""; if (!IsInList(inet_ntoa(d->GetAddr().sin_addr))) { risultato += "[Web Panel] Access Denied."; sys_err("[Web Panel] %s has tried to connect in the web panel.", inet_ntoa(d->GetAddr().sin_addr)); }else{ int iTotal; int *paiEmpireUserCount; int iLocal; DESC_MANAGER::instance().GetUserCount(iTotal, &paiEmpireUserCount, iLocal); risultato += format("Player Online: %d\nShinsoo: %d\nChunjo: %d\nJinno: %d", iTotal, paiEmpireUserCount[1], paiEmpireUserCount[2], paiEmpireUserCount[3]); } stResult += risultato; } else if (!stBuf.compare("PLAYER_RANKLIST")) { std::string risultato=""; if (!IsInList(inet_ntoa(d->GetAddr().sin_addr))) { risultato += "[Web Panel] Access Denied."; sys_err("[Web Panel] %s has tried to connect in the web panel.", inet_ntoa(d->GetAddr().sin_addr)); }else{ std::string Ranklist=""; char classifica[1024]={0}; snprintf(classifica, sizeof(classifica), "SELECT name, level FROM player.player%s WHERE account_id=(SELECT id FROM account.account%s WHERE status='OK' AND id=account_id) ORDER BY level DESC LIMIT 10;", get_table_postfix(), get_table_postfix()); SQLMsg * res = DBManager::instance().DirectQuery(classifica); if (res->Get()->uiNumRows == 0) { M2_DELETE(res); risultato += "Players not found."; } Ranklist+="<Top 10 Player>\n\n"; int pos=0; for (uint i=0; i<res->Get()->uiNumRows; i++) { MYSQL_ROW rows=mysql_fetch_row(res->Get()->pSQLResult); std::string name=std::string(rows[0]); if (name[0] != '[') { pos=i+1; std::string space=""; for (unsigned s=0; s<=(25 - (int)name.length()); s++) space+=" "; Ranklist+=format("%d | %s%s | Lv.%s\n", pos, name.c_str(), space.c_str(), rows[1]); }else{ pos=i-1; } } M2_DELETE(res); risultato += Ranklist; } stResult += risultato; } else if (stBuf.find("ACCOUNT_REGISTER") != std::string::npos) { std::string risultato=""; if (!IsInList(inet_ntoa(d->GetAddr().sin_addr))) { risultato += "[Web Panel] Access Denied."; sys_err("[Web Panel] %s has tried to connect in the web panel.", inet_ntoa(d->GetAddr().sin_addr)); }else{ std::vector<std::string> args; std::string status; boost::split(args, stBuf, boost::is_any_of(",")); if (args.size() > 0 && args[0].compare("ACCOUNT_REGISTER") == 0) { status=RegisterAccount(args[1], args[2], args[3], args[4]); }else{ status="[RegisterAccount] Syntax Error."; } risultato += status; } stResult += risultato; } stResult += "\n"; d->Packet(stResult.c_str(), stResult.length()); return (c_pSep - c_pData) + 1; } else if (bHeader == HEADER_CG_MARK_LOGIN) { if (!guild_mark_server) { sys_err("Guild Mark login requested but i'm not a mark server!"); d->SetPhase(PHASE_CLOSE); return 0; } sys_log(0, "MARK_SERVER: Login"); d->SetPhase(PHASE_LOGIN); return 0; } else if (bHeader == HEADER_CG_STATE_CHECKER) { if (d->isChannelStatusRequested()) { return 0; } d->SetChannelStatusRequested(true); db_clientdesc->DBPacket(HEADER_GD_REQUEST_CHANNELSTATUS, d->GetHandle(), NULL, 0); } else if (bHeader == HEADER_CG_PONG) Pong(d); else if (bHeader == HEADER_CG_HANDSHAKE) Handshake(d, c_pData); #ifdef _IMPROVED_PACKET_ENCRYPTION_ else if (bHeader == HEADER_CG_KEY_AGREEMENT) { d->SendKeyAgreementCompleted(); d->ProcessOutput(); TPacketKeyAgreement* p = (TPacketKeyAgreement*)c_pData; if (!d->IsCipherPrepared()) { sys_err ("Cipher isn't prepared. %s maybe a Hacker.", inet_ntoa(d->GetAddr().sin_addr)); d->DelayedDisconnect(5); return 0; } if (d->FinishHandshake(p->wAgreedLength, p->data, p->wDataLength)) { if (g_bAuthServer) { d->SetPhase(PHASE_AUTH); } else { d->SetPhase(PHASE_LOGIN); } } else { sys_log(0, "[CInputHandshake] Key agreement failed: al=%u dl=%u", p->wAgreedLength, p->wDataLength); d->SetPhase(PHASE_CLOSE); } } #endif else sys_err("Handshake phase does not handle packet %d (fd %d)", bHeader, d->GetSocket()); return 0; } NOW, THE FUNCTIONS: //REMEMBER AT THE TOP OF FILE: //#include <fstream> //#include <boost/algorithm/string.hpp> inline std::string format(const char* fmt, ...) { int size = 512; char* buffer = 0; buffer = new char[size]; va_list vl; va_start(vl, fmt); int nsize = vsnprintf(buffer, size, fmt, vl); if(size<=nsize){ delete[] buffer; buffer = 0; buffer = new char[nsize+1]; nsize = vsnprintf(buffer, size, fmt, vl); } std::string ret(buffer); va_end(vl); delete[] buffer; return ret; } inline bool IsInList(const char *ip) { bool ritorno=false; std::ifstream ifs("locale/pannello_web_ip.txt", std::ifstream::in); if (ifs.fail()) { sys_err("[Web Panel] The file [locale/pannello_web_ip.txt] was not found."); return ritorno; } char c=ifs.get(); std::string read; while (ifs.good()) { read += c; c=ifs.get(); } ifs.close(); if (strstr(read.c_str(), std::string(std::string(ip)+std::string("\n")).c_str()) != NULL) ritorno=true; return ritorno; } bool is_email(std::string const& address) { size_t at_index = address.find_first_of('@', 0); return at_index != std::string::npos && address.find_first_of('.', at_index) != std::string::npos; } std::string RegisterAccount(std::string login, std::string password, std::string email, std::string social_id) { char EscapedLogin[255]={0}; char EscapedPassword[255]={0}; char EscapedSocialID[255]={0}; char EscapedEmail[255]={0}; DBManager::instance().EscapeString(EscapedLogin, sizeof(EscapedLogin), login.c_str(), strlen(login.c_str())); DBManager::instance().EscapeString(EscapedPassword, sizeof(EscapedPassword), password.c_str(), strlen(password.c_str())); DBManager::instance().EscapeString(EscapedSocialID, sizeof(EscapedSocialID), social_id.c_str(), strlen(social_id.c_str())); DBManager::instance().EscapeString(EscapedEmail, sizeof(EscapedEmail), email.c_str(), strlen(email.c_str())); if (strlen(EscapedLogin)<2) return "[RegisterAccount] Login can't be < 2 chars."; if (strlen(EscapedPassword)<3) return "[RegisterAccount] Password can't be < 3 chars."; if (strlen(EscapedEmail)<5) return "[RegisterAccount] Email can't be < 5 chars."; if (strlen(EscapedLogin)>20) return "[RegisterAccount] Login can't be > 20 chars."; if (strlen(EscapedPassword)>30) return "[RegisterAccount] Password can't be > 30 chars."; if (strlen(EscapedEmail)>50) return "[RegisterAccount] Email can't be > 50 chars."; if (strlen(EscapedSocialID)<3) return "[RegisterAccount] Social id can't be < 3 chars."; if (strlen(EscapedSocialID)>7) return "[RegisterAccount] Social id can't be > 7 chars."; if (!is_email(std::string(EscapedEmail))) return "[RegisterAccount] Email is not valid."; char iscrizione[1024]={0}; snprintf(iscrizione, sizeof(iscrizione), "INSERT INTO account.account%s (login, password, social_id, email, create_time, status, gold_expire, silver_expire, safebox_expire, autoloot_expire, fish_mind_expire, marriage_fast_expire, money_drop_rate_expire) " "VALUES ('%s', password('%s'), '%s', '%s', NOW(), 'OK', '2025-01-01 00:00:00', '2025-01-01 00:00:00', '2025-01-01 00:00:00', '2025-01-01 00:00:00', '2025-01-01 00:00:00', '2025-01-01 00:00:00', '2025-01-01 00:00:00')", get_table_postfix(), EscapedLogin, EscapedPassword, EscapedSocialID, EscapedEmail); std::auto_ptr<SQLMsg> res(DBManager::instance().DirectQuery(iscrizione)); if (res->Get()->uiAffectedRows == 0 || res->Get()->uiAffectedRows == (uint32_t)-1) return "[RegisterAccount] The account name already exists, try with another account name."; return "[RegisterAccount] Registration done!"; } PYTHON EXAMPLE: def __Try(ip, port): try: import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, port)) s.send("\x40PLAYER_ONLINE\n") s.recv(100) s.send("\x40PLAYER_ONLINE\n") print s.recv(1024) s.send("\x40PLAYER_RANKLIST\n") print s.recv(1024) s.send("\x40ACCOUNT_REGISTER,Raffa123,pass123,hello@gmail.com,1234567\n") print s.recv(1024) s.close() except (socket.gaierror, socket.error, socket.herror, socket.timeout): print "[Server] Server is not online. [%s:%d]" % (ip, port) __Try("IP_CH1", PORT_CH1) import os os.system("pause") BE SAFE YOUR PANEL: Open packet.h find HEADER_CG_TEXT = 64, and change the 64 with another number of packet, but remember that the number must be unused by other packet. And replace in your scripts the \x40 with the other number in HEXADECIMAL, because 64 in hexadecimal is 0x40, use google to find the hexadecimal of a number and put the escape char, final RESULT: \0x40MYCOMMAND REMEMBER TO create the pannello_web_ip.txt into your locale folder. IN THAT FILE PUT THE IP ADDRESS OF YOUR HOST OF THE WEBSITE, for any errors or log, just check the syserr.txt. You can use your SOCKET API in PHP or Other languages With this you can insert your registration or ranklist or status or others and others without PUT THE "CREDENTIAL of Database".
  2. int _get_ranklist(lua_State* L) { std::string Ranklist=""; char classifica[1024]={0}; snprintf(classifica, sizeof(classifica), "SELECT name, level FROM player.player%s WHERE account_id=(SELECT id FROM account.account%s WHERE status='OK' AND id=account_id) ORDER BY level DESC LIMIT 10;", get_table_postfix(), get_table_postfix()); SQLMsg * res = DBManager::instance().DirectQuery(classifica); if (res->Get()->uiNumRows == 0) { M2_DELETE(res); lua_pushstring(L, "There aren't players now."); sys_err("Query: %s", classifica); return 1; } Ranklist+="<Top 10 Player>[ENTER][ENTER]"; int pos=0; for (uint i=0; i<res->Get()->uiNumRows; i++) { MYSQL_ROW rows=mysql_fetch_row(res->Get()->pSQLResult); std::string name=std::string(rows[0]); if (name[0] != '[') { pos=i+1; std::string space=""; for (unsigned s=0; s<=(25 - (int)name.length()); s++) space+=" "; Ranklist+=format("%d | %s%s | Lv.%s[ENTER]", pos, name.c_str(), space.c_str(), rows[1]); }else{ pos=i-1; } } M2_DELETE(res); lua_pushstring(L, Ranklist.c_str()); return 1; }
  3. Today i get this problem, when i enter in a party dungeon and someone of the party goes offline or warp in another map, the core crashed. I want give all my idea to fix that, i know that is not the best method to fix that but i think for someone can be useful. I tried to fix the problem with the tutorial on metin2dev with SetDungeon(NULL) in SetParty but without any results, the bug continue... This is my fix/idea: When someone goes offline all the members of the group will go to the own village and the core doesn't crash. Open party.cpp and replace your UpdateOfflineState function with this: void CParty::UpdateOfflineState(DWORD dwPID) { TPacketGCPartyAdd p; p.header = HEADER_GC_PARTY_ADD; p.pid = dwPID; memset(p.name, 0, CHARACTER_NAME_MAX_LEN+1); for (TMemberMap::iterator it = m_memberMap.begin(); it != m_memberMap.end(); ++it) { if (it->second.pCharacter && it->second.pCharacter->GetDesc()) { if (it->second.pCharacter->GetDungeon()) { LPDUNGEON dung=it->second.pCharacter->GetDungeon(); dung->ExitAllToStartPosition(); }else{ it->second.pCharacter->GetDesc()->Packet(&p, sizeof(p)); } } } }
  4. The koray shop is in free download and it's easy to find it on the web: http://www50.zippyshare.com/v/sJd3CEhV/file.html Here is the offline shop by koray, my advice is check your files with these files (Folder: ready made files) with WinMerge.
  5. FIXED. WHEN PLAYER ARE OFFLINE, ITEMS GOING IN ITEM SHOP MALL!
  6. Exactly but a lot of server haven't got the SAFEBOX OFFLINE SHOP!
  7. In the koray offline shop (a good offline shop), there is a big problem, when you close the shop, items not sold disappear! I'm there to give you the fix for this problem: Open the shop.cpp and search the function CShop::Remove(), change your function with this: void CShop::Remove() { if (!HasOwner()) return; m_bIsLocked = true; TOfflineShopTable p; memset(&p, 0, sizeof(p)); p.dwAID = m_dwOwnerAID; p.dwPID = m_dwOwnerPID; LPCHARACTER ch=CHARACTER_MANAGER::instance().FindByPID(m_dwOwnerPID); p.dwX = m_pkPC->GetX(); p.dwY = m_pkPC->GetY(); p.dwMapIndex = m_pkPC->GetMapIndex(); p.dwChannel = g_bChannel; p.ullMoney = m_Money; p.dwSize = m_bSize; p.dwColor = m_bColor; strlcpy(p.szSign, m_pkPC->GetShopSign().c_str(), sizeof(p.szSign)); for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i) { SHOP_ITEM& item = m_itemVector[i]; if (item.pkItem == NULL) continue; p.items2[i] = item.itemid; p.price[i] = item.price; LPITEM item2=item.pkItem; if (item.isSold != 1) { if (ch == NULL) { sys_err("[OfflineShop] Shop owner was offline, i'm sending the items into the mall...\n"); char query_pos[1025]; snprintf(query_pos, sizeof(query_pos), "SELECT pos FROM player.item%s WHERE window='MALL' AND owner_id=%d;", get_table_postfix(), m_dwOwnerAID); SQLMsg * pMsg = DBManager::instance().DirectQuery(query_pos); if (pMsg != NULL) { int pos=0; if (pMsg->Get()->uiNumRows > 0) { MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult); str_to_number(pos, row[0]); pos+=1; } int random_id=number(1,999999999)+m_dwOwnerPID+number(1,50); int socket1=(int)item2->GetSocket(0); int socket2=(int)item2->GetSocket(1); int socket3=(int)item2->GetSocket(2); int applytype0=(int)item2->GetAttributeType(0); int applyvalue0=(int)item2->GetAttributeValue(0); int applytype1=(int)item2->GetAttributeType(1); int applyvalue1=(int)item2->GetAttributeValue(1); int applytype2=(int)item2->GetAttributeType(2); int applyvalue2=(int)item2->GetAttributeValue(2); int applytype3=(int)item2->GetAttributeType(3); int applyvalue3=(int)item2->GetAttributeValue(3); int applytype4=(int)item2->GetAttributeType(4); int applyvalue4=(int)item2->GetAttributeValue(4); int applytype5=(int)item2->GetAttributeType(5); int applyvalue5=(int)item2->GetAttributeValue(5); int applytype6=(int)item2->GetAttributeType(6); int applyvalue6=(int)item2->GetAttributeValue(6); char query[1025]; sprintf( query, // TABLE POSTFIX RANDOM-ID - AID - WINDOW - POS - COUNT - VNUM - S1 - S2 - S3 - B1 B1 B2 B2 B3 B3 B4 B4 B5 B5 B6 B6 B7 B7 "INSERT INTO player.item%s VALUES ('%d', '%d', 'MALL', '%d', '%d', '%d', '%d', '%d', '%d', '0', '0', '0', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d');", get_table_postfix(), random_id, (int)m_dwOwnerAID, pos, (int)item.count, (int)item.vnum, socket1, socket2, socket3, applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2, applytype3, applyvalue3, applytype4, applyvalue4, applytype5, applyvalue5, applytype6, applyvalue6 ); std::auto_ptr<SQLMsg> ripristina(DBManager::instance().DirectQuery(query)); if (ripristina->Get()->uiAffectedRows > 0) sys_err("[OfflineShop] Done, Now items of the ID: %d are in the mall!\nQUERY: %s\n", m_dwOwnerAID, query); }else{ sys_err("[OfflineShop] Error while trying to get position.\n"); } }else{ LPITEM item3 = ITEM_MANAGER::instance().CreateItem(item2->GetVnum(), 1, 0, false); ITEM_MANAGER::CopyAllAttrTo(item2, item3); int Slot=ch->GetEmptyInventory(item2->GetSize()); item3->AddToCharacter(ch, TItemPos(INVENTORY, Slot)); ITEM_MANAGER::instance().FlushDelayedSave(item3); item3->AttrLog(); } }else{ item.pkItem->SetSkipSave(true); M2_DESTROY_ITEM(item.pkItem); memset(&item, 0, sizeof(item)); } } db_clientdesc->DBPacket(HEADER_GD_OFFLINE_SHOP_REMOVE, 0, &p, sizeof(p)); }
  8. HI GUYS I NEED HELP, I HAVE A BIG PROBLEM WITH THE KORAY OFFLINE SHOP, AFTER THE INSTALLATION THE OFFLINE SHOP WORKS WELL BUT THE "TYPE 0" (THE PRIVATE SHOP) NOT WORK! THE STANDARD SHOP WHEN I CLICK TO THE SHOP DOESN'T SHOW ME THE WINDOW OF ITEM! WHY? I CHECK A LOT OF TIMES THE FUNCTIONS IN THE SOURCE BUT WITHOUT ANY RESULTS. CAN U HELP ME? And if i try to "disconnect" or "change character" not work!
  9. Open char.cpp and find this function void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast) Search the case POINT_EXP and replace with this: case POINT_EXP: { quest::PC* Check = quest::CQuestManager::Instance().GetCurrentPC(); int flag=Check->GetFlag("exp_block"); if (flag == 0) { DWORD exp = GetExp(); DWORD next_exp = GetNextExp(); if (amount < 0 && exp < -amount) { sys_log(1, "%s AMOUNT < 0 %d, CUR EXP: %d", GetName(), -amount, exp); amount = -exp; SetExp(exp + amount); val = GetExp(); } else { if (gPlayerMaxLevel <= GetLevel()) return; if (test_server) ChatPacket(CHAT_TYPE_INFO, "You have gained %d exp.", amount); DWORD iExpBalance = 0; if (exp + amount >= next_exp) { iExpBalance = (exp + amount) - next_exp; amount = next_exp - exp; SetExp(0); exp = next_exp; } else { SetExp(exp + amount); exp = GetExp(); } DWORD q = DWORD(next_exp / 4.0f); int iLevStep = GetRealPoint(POINT_LEVEL_STEP); if (iLevStep >= 4) { sys_err("%s LEVEL_STEP bigger than 4! (%d)", GetName(), iLevStep); iLevStep = 4; } if (exp >= next_exp && iLevStep < 4) { for (int i = 0; i < 4 - iLevStep; ++i) PointChange(POINT_LEVEL_STEP, 1, false, true); } else if (exp >= q * 3 && iLevStep < 3) { for (int i = 0; i < 3 - iLevStep; ++i) PointChange(POINT_LEVEL_STEP, 1, false, true); } else if (exp >= q * 2 && iLevStep < 2) { for (int i = 0; i < 2 - iLevStep; ++i) PointChange(POINT_LEVEL_STEP, 1, false, true); } else if (exp >= q && iLevStep < 1) PointChange(POINT_LEVEL_STEP, 1); if (iExpBalance) { PointChange(POINT_EXP, iExpBalance); } val = GetExp(); } }else{ val = GetExp(); } } break; Now open Questlua_pc.cpp and add this in the namespace quest: int pc_block_exp(lua_State* L) { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); if (!lua_isnumber(L, 1)) { return 0; } int type=lua_tonumber(L,1); PC* Check = CQuestManager::Instance().GetCurrentPC(); Check->SetFlag("exp_block", type); if (type == 0) { ch->ChatPacket(CHAT_TYPE_INFO, "<ExpBlockSystem> [%d] You unlock your experience.", Check->GetFlag("exp_block")); }else{ ch->ChatPacket(CHAT_TYPE_INFO, "<ExpBlockSystem> [%d] You lock your experience.", Check->GetFlag("exp_block")); } return 0; } And this in the RegisterPCFunctionTable: { "block_exp", pc_block_exp }, Now compile your source, and try this quest: quest ExpBlockQuest begin state start begin when 72501.use begin say_title("Block EXP Ring:") say("") local s = select("Lock EXP", "Unlock EXP", "Reset EXP", "Close") if s == 1 then pc.block_exp(1) setskin(NOWINDOW) elseif s == 2 then pc.block_exp(0) setskin(NOWINDOW) elseif s == 3 then say_title("Block EXP Ring:") say("") say("Are you sure to reset[ENTER]your EXP points: "..pc.get_exp().."?") local s2=select("Yes", "No") if s2 == 1 then pc.block_exp(0) pc.give_exp2(-pc.get_exp()) syschat("<ExpBlockSystem> You reset your experience.") setskin(NOWINDOW) end end end end end
  10. Here: cmd_gm.cpp FUNCTIONS: #include <iostream> #include <vector> #include <string> void split(const std::string& s, char delim, std::vector<std::string>& v) { int i = 0; int pos = s.find(delim); while (pos != std::string::npos) { v.push_back(s.substr(i, pos-i)); i = ++pos; pos = s.find(delim, pos); if (pos == std::string::npos) v.push_back(s.substr(i, s.length())); } } int countChars(char* s, char c) { return *s == '\0' ? 0 : countChars( s + 1, c ) + (*s == c); } COMMAND: ACMD(do_create_item) { char item[256]; char bonus[1024]; two_arguments(argument, item, sizeof(item), bonus, sizeof(bonus)); if (!*item || !*bonus) { ch->ChatPacket(CHAT_TYPE_INFO, "Usage: /create_item <value_item> <b1:v1,b2:v2,b3:v3,b4:v4,b5:v5,b6:v6,b7:v7>"); ch->ChatPacket(CHAT_TYPE_INFO, ""); ch->ChatPacket(CHAT_TYPE_INFO, "[b] = Bonus vnum"); ch->ChatPacket(CHAT_TYPE_INFO, "[v] = Bonus value"); ch->ChatPacket(CHAT_TYPE_INFO, ""); ch->ChatPacket(CHAT_TYPE_INFO, "Created by RaFFa."); return; } if (bonus[(strlen(bonus)-1)] == ',') { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> [Err1] Syntax Error."); return; } if (bonus[(strlen(bonus)-1)] == ':') { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> [Err2] Syntax Error."); return; } if (strstr(bonus, ":") == NULL) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> [Err3] Syntax Error."); return; } if (strstr(bonus, ",") == NULL) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> Adding 1 bonus..."); int vnum=0; str_to_number(vnum, item); LPITEM i = ITEM_MANAGER::instance().CreateItem(vnum); if (!i) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> This item-vnum not exists."); return; } int bonus_vnum=0; int bonus_value=0; std::vector<std::string> bonus2; split(std::string(bonus), ':', bonus2); str_to_number(bonus_vnum, std::string(bonus2[0]).c_str()); str_to_number(bonus_value, std::string(bonus2[1]).c_str()); i->SetForceAttribute(0, bonus_vnum, bonus_value); i->SetSocket(0, 1); int inventario = ch->GetEmptyInventory(i->GetSize()); if (inventario != -1) { i->AddToCharacter(ch, TItemPos(INVENTORY, inventario)); ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> Item created successfully."); }else{ M2_DESTROY_ITEM(i); ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> You haven't enough space in inventory."); } }else{ std::vector<std::string> bonus1; split(std::string(bonus), ',', bonus1); if (bonus1.size()>0) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> Adding %d bonus...", (int)bonus1.size()); if (countChars(bonus, ':') != (int)bonus1.size()) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> [Err4] Syntax Error."); return; } int vnum=0; str_to_number(vnum, item); LPITEM i = ITEM_MANAGER::instance().CreateItem(vnum); if (!i) { ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> This item-vnum not exists."); return; } int b_size=bonus1.size(); if (bonus1.size()>6) b_size=7; int bonus_vnum=0; int bonus_value=0; for (int n=0; n<b_size; n++) { std::vector<std::string> bonus2; split(std::string(bonus1[n]), ':', bonus2); str_to_number(bonus_vnum, std::string(bonus2[0]).c_str()); str_to_number(bonus_value, std::string(bonus2[1]).c_str()); i->SetForceAttribute(n, bonus_vnum, bonus_value); } i->SetSocket(0, 1); int inventario = ch->GetEmptyInventory(i->GetSize()); if (inventario != -1) { i->AddToCharacter(ch, TItemPos(INVENTORY, inventario)); ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> Item created successfully!"); }else{ M2_DESTROY_ITEM(i); ch->ChatPacket(CHAT_TYPE_INFO, "<CreateItem> You haven't enough space in inventory."); } } } } cmd.cpp ACMD(do_create_item); and: (into the struct command_info cmd_info[]) {"create_item", do_create_item, 0, POS_DEAD, GM_IMPLEMENTOR},
  11. Searching videomaker service...
  12. edit
  13. Next days... Gamesecurity re open for sell only a M2BOB FIX Just wait guys..