04-13-2021, 06:16 AM
Hello, could someone help me how to create a cash ticket? If you click on it that you get the entered cash value? best regards.
Ep4 Juni
|
Cash ticket
|
|
04-13-2021, 06:16 AM
Hello, could someone help me how to create a cash ticket? If you click on it that you get the entered cash value? best regards. Ep4 Juni
04-13-2021, 02:22 PM
Simple but working: DoFuncItem.cpp First declare a new function which should look like this: bool do_ItemUse_CashTicket(CPC* ch, const CItemProto* itemproto); You can just paste it around line ~40 you will see some other functions, just add it under them. Now we are doing the function (what should happen if the function is called in the code) For me, it looks like this: bool do_ItemUse_CashTicket(CPC* ch, const CItemProto* itemproto) { mysqldb::connectInfo auth_db_info; auth_db_info.host_ = gserver->m_config.Find("Auth DB", "IP"); auth_db_info.port_ = 0; auth_db_info.user_ = gserver->m_config.Find("Auth DB", "User"); auth_db_info.pw_ = gserver->m_config.Find("Auth DB", "Password"); auth_db_info.dbname_ = gserver->m_config.Find("Auth DB", "DBName"); auth_db_info.charsetname_ = ""; mysqldb auth_db_; auth_db_.connect(auth_db_info); CLCString TicketQuery(1024); CDBCmd DBTicket; DBTicket.Init(auth_db_.getMYSQL()); int userIndex = ch->m_desc->m_index; TicketQuery.Format("UPDATE bg_user SET cash = cash + 100 WHERE user_code = %d", userIndex); DBTicket.SetQuery(TicketQuery); if (!DBTicket.Update()) { LOG_INFO("CashTicket[100] Failed at USER_INDEX[%d]", userIndex); return false; } LOG_INFO("CashTicket[100] Success at USER_INDEX[%d]", userIndex); return true; } Its simple, but it works fine. You can change the Cash value by changing the TicketQuery "UPDATE bg_user SET cash = cash + 100 WHERE user_code = %d" +100 is the Cash Amount which gets added to the Player and don't forget to add the needed Database information to the newstobm file from GameServer. It requires access to the Auth Database. If you have done this steps we just need to add the function call which should be an Item after using. We will go around line 7667 which is inside this function for me bool do_ItemUse_IONCE_ETC(CPC* ch, const CItemProto* itemproto, int nExtar1, CItem* item) Just add another case like this case 11111: // Cash Ticket return do_ItemUse_CashTicket(ch, itemproto); break; case 11111 is the ID from the Item which should be your Cash Ticket you can just change it to any Item ID you want (the item need to be type 2 and subtype 9) you can just copy the "Medal of the Mercenary" ID: 10266 and it should work.
04-13-2021, 03:42 PM
Hello. Many Thanks. I don't know exactly what to do with the second part. if I insert it at line 7667 I get an error " doFuncItem.cpp:7771: error: expected initializer before ‘bool’ make[1]: *** [doFuncItem.o] Error 1 make[1]: Leaving directory `/root/Desktop/Server/GameServer' make: *** [usa] Error 2 " the first part works but the second part doesn't. I hope you understand what i mean bool do_ItemUse_IONCE_ETC(CPC* ch, const CItemProto* itemproto, int nExtar1, CItem* item) case 11111: // Cash Ticket return do_ItemUse_CashTicket(ch, itemproto); break;
04-13-2021, 06:55 PM
Okay, so instead of doing this, I just sat down for 20 minutes and wrote myself a better version of this. So please remove whatever you added and do all the things below. GameServer\doFuncItem.cpp: find the following function: "do_ItemUse" you could theoretically put it after all the checks are done, but to make it easier for you just search for the upcoming line: switch(item->m_itemProto->getItemIndex()) to the bottom of the switch statement (after it says "break;") add the following line // instead of case 11371 use YOUR id for the cash ticket. case 11371: do_ItemUse_CashTicket(ch, msg); break; now just go to the bottom of the doFuncItem.cpp and add the following lines void do_ItemUse_CashTicket(CPC* ch, CNetMsg::SP& rmsg) { RequestClient::doItemUse* packet = reinterpret_cast<RequestClient::doItemUse*>(rmsg->m_buf); if (ch->m_inventory.isValidNormalInventory(packet->tab, packet->invenIndex) == false) { LOG_ERROR("HACKING? : invalid packet. char_index[%d] tab[%d] invenIndex[%d]", ch->m_index, packet->tab, packet->invenIndex); ch->m_desc->Close("invalid packet"); return; } // ¾ÆÀÌÅÛ Ã£±â CItem* item = ch->m_inventory.getItem(packet->tab, packet->invenIndex); if (item == NULL) { LOG_ERROR("HACKING? : not found item. char_index[%d] tab[%d] invenIndex[%d]", ch->m_index, packet->tab, packet->invenIndex); ch->m_desc->Close("not found item"); return; } if (item->getVIndex() != packet->virtualIndex) { LOG_ERROR("HACKING? : invalid virtual index. char_index[%d] tab[%d] invenIndex[%d]", ch->m_index, packet->tab, packet->invenIndex); ch->m_desc->Close("invalid virtual index"); return; } if (item->getWearPos() != WEARING_NONE) { LOG_ERROR("HACKING? : item is wearing. char_index[%d] tab[%d] invenIndex[%d]", ch->m_index, packet->tab, packet->invenIndex); ch->m_desc->Close("invalid virtual index"); return; } if (item->Count() < 1) { ch->m_inventory.deleteItemByItem(item); return; } if (ch->m_level < item->m_itemProto->GetItemProtoLevel() || ch->m_level > item->m_itemProto->GetItemProtoLevel2()) { CNetMsg::SP msg(new CNetMsg); ResponseClient::ItemNotUseMsg(msg, MSG_ITEM_USE_ERROR_LOWLEVEL); SEND_Q(msg, ch->m_desc); return; } int amount = item->m_itemProto->getItemNum0(); if (amount <= 0) { LOG_ERROR("Num0 was %d, please check the item %d and get it fixed.", amount, item->getDBIndex()); return; } CLCString sql(1024); CDBCmd cmd; cmd.Init(&gserver->m_dbauth); sql.Format("UPDATE bg_user SET cash = cash + %d WHERE user_code = %d", amount, ch->m_desc->m_index); cmd.SetQuery(sql); if (!cmd.Update()) { LOG_ERROR("Cash Query failed for user %d. Tried to add %d cash. no item loss.", ch->m_desc->m_index, amount); return; } ch->m_inventory.decreaseItemCount(item, 1); CLCString message(1024); message.Format("Wow, you just recieved %d cash!", amount); CNetMsg::SP clientMsg(new CNetMsg); SayMsg(clientMsg, MSG_CHAT_NOTICE, 0, "", "", message); SEND_Q(clientMsg, ch->m_desc); } for this to work open doFunc.h, scroll to the bottom and but this above the "#endif" void do_ItemUse_CashTicket(CPC* ch, CNetMsg::SP& msg); Okay so now you have to add one more thing to the source and your newstobm file and you are good to go. GameServer\Server.cpp find the ConnectDB() function. add this at the top of it: if (!mysql_real_connect ( &m_dbauth, m_config.Find("Auth DB", "IP"), m_config.Find("Auth DB", "User"), m_config.Find("Auth DB", "Password"), m_config.Find("Auth DB", "DBName"), 0, NULL, 0)) { LOG_ERROR("Can't connect Auth DB : ip[%s] id[%s] pw[%s] dbname[%s] error[%s]", m_config.Find("Auth DB", "IP"), m_config.Find("Auth DB", "User"), m_config.Find("Auth DB", "Password"), m_config.Find("Auth DB", "DBName"), mysql_error(&m_dbauth) ); return false; } same file, CServer() function and find where it says "mysql_init(&m_dbchar);" and add this below: mysql_init(&m_dbauth); GameServer\Server.h find "MYSQL m_dbchar;" and put this below it: MYSQL m_dbauth; Source is done now. Go to your newStobm.bin file in your GameServer folder(s) and add the following: [Auth DB] IP=127.0.0.1 DBName=november_auth User=root Password= obviously replace with your ip etc. Alright, last thing to do is for you to create an Item. Here is an example on how it should look like! 2 Where it says "NONE" in your tool/database it will be "Num0" or something similar. Num0 is the amount of cash you will recieve from the Ticket. Export everything, start servers, enjoy. Hope I didn't miss anything, but this is how you should be doing it. kravens pls dont steal this design too ? Edit: oh and if you want multiple cash tickets, you could add more cash tickets like this: case 11371: case 11372: case 11373: case 11374: do_ItemUse_CashTicket(ch, msg); break; OR go out of the switch statement and at the following lines /* 11371 = first cash ticket id * 11374 = last cash ticket id */ if (item->m_itemProto->getItemIndex() >= 11371 && item->m_itemProto->getItemIndex() <= 11374) { do_ItemUse_CashTicket(ch, msg); }
04-14-2021, 07:54 AM
many thanks could you tell me the TYPE and subtype? I don't use an item tool. and is this column important? because I get an error with the compiler without this it works anyway. CNetMsg :: SP rmsg (new CNetMsg); MsgrNoticeMsg (rmsg, -1, gserver-> m_serverno, gserver-> m_subno, -1, message); SEND_Q (rmsg, gserver-> m_messenger);
04-14-2021, 08:04 AM
It should be Type "ONCE" and subtype something like "ONCE_ETC". Just do a screenshot of your tool if you need to know more. Oh and i just saw why its erroring for you probably. you need to change the "rmsg" variable for it to work. I updated the main post too, so either copy the following things and replace it or just use how you do now. Replacing these lines will make it work properly! if (ch->m_level < item->m_itemProto->GetItemProtoLevel() || ch->m_level > item->m_itemProto->GetItemProtoLevel2()) { CNetMsg::SP msg(new CNetMsg); ResponseClient::ItemNotUseMsg(msg, MSG_ITEM_USE_ERROR_LOWLEVEL); SEND_Q(msg, ch->m_desc); return; } CLCString message(1024); message.Format("Wow, you just recieved %d cash!", amount); CNetMsg::SP clientMsg(new CNetMsg); SayMsg(clientMsg, MSG_CHAT_NOTICE, 0, "", "", message); SEND_Q(clientMsg, ch->m_desc);
04-14-2021, 08:34 AM
Use the same SubType as "Affinity Medal" (id 11038) or if you dont that that use "Mailing Marble" (id 9938) and if you somehow dont have that either use "Dadge Pear" (id 1306) if the item already does not work, this should make it work.
04-14-2021, 09:01 AM
Super thanks, there is a possibility to use the card more often at the moment I can only use it 1 time. then it says I'm already using.
04-14-2021, 09:13 AM
11 minutes ago, Matt Hias said: Super thanks, there is a possibility to use the card more often at the moment I can only use it 1 time. then it says I'm already using. screen the "max stack" in the itemall tool |
|
« Next Oldest | Next Newest »
|