Jump to content

Ikarus_

Developer
  • Posts

    402
  • Joined

  • Last visited

  • Days Won

    20
  • Feedback

    0%

Everything posted by Ikarus_

  1. put them as static void void ApplyAcceAttackValue(LPITEM pkItem, int* pdamMin, int* pdamMax) i've changed in the code above
  2. Nope thanks, i really prefer to write here what i ve to explain you, because i don't really do this for you, i do this for the whole community. I prefer my explanation to be accessible to all who have your problem. I ve updated with the complete answer.
  3. i ve updated the other post with the right answer, i ll update it soon with a complete answer.
  4. I ve already said that we don't have enoght information to know where the problem is. I guess you might check all the parts where the m_map_itemCache is used and try to debug your code by adding sys_log and analyze what the code do.
  5. communications between your cores are likely to be down. Probably due to a packet causing an UNKNOWN_HEADER or UNKNOWN PACKET and this causes the connection between the cores to break. Probably looking in the syserrs of your channels you will find some networking errors.
  6. Here it looks to be correct. It must work permanently. I suspect the problem would be how you are 'stopping' the db core. The changes (e.g. ch->SetRealPoint) are not immediatly saved into the player table, the db core has a cache which is flushed (and so saved) every X seconds (Where x is a variable number). The value X is defined here: CPlayerTableCache::CPlayerTableCache() { m_expireTime = MIN(1800, g_iPlayerCacheFlushSeconds); } so it is a number between 0, and 1800. By default this value of seconds is defined here : int g_iPlayerCacheFlushSeconds = 60*7; and it's 7 minutes (you may set it by defining it in the conf.txt by using the key PLAYER_CACHE_FLUSH_SECONDS) Why i m explaning all about this? Because i want to give you way to get what my theory consists. My theory is that you are killing the db process by using killall -9 db or some other command which interrupt the db process, instead of sending a normal stop signal that gives the db time to save changes (currently cached) to the table. My suggestion is to check how your kill script of the channels/db is stopping them.
  7. You might skipped a copy paste during the installation of the system. The main problems looks to be you don't have defined the CONSTANTS used in tables.h Usually they are defined in length.h or item_length.h. I suggest you to check these two files and paste what you forgot. you are really useful
  8. the problem about the 29 vs 28 is just a rounding error. i m enoght sure you will solve it by making the 'viewed value' identical to the server side value (which is added as bonus) by copying from the c++ the formula and applying it to the python formula in uitooltip.py. long lAttGrade = pkItemAbsorbed->alValues[4] + pkItemAbsorbed->alValues[5]; if (pkItemAbsorbed->alValues[3] > pkItemAbsorbed->alValues[4]) lAttGrade = pkItemAbsorbed->alValues[3] + pkItemAbsorbed->alValues[5]; double dValue = lAttGrade * GetSocket(ACCE_ABSORPTION_SOCKET); dValue = (double)dValue / 100; dValue = (double)dValue + .5; I suspect that the other formula into python is a bit different (especially for the + .5) I ll update this post asap with the other fix (min and max attack) because it's longer to explain and i ve to find the time. ############### update ############ VERY BIG DISCLAIMER: IT'S UNTESTED AND UNCOMPILED CODE. VISUAL STUDIO DOESNT SHOW ANY ERROR SO YOU SHOULDN'T GET ERRORS ON COMPILING. SINCE IS UNTESTED I SUGGEST TO TEST IT BEFORE TO APPLY IT TO AN OPEN SERVER.
  9. Here is wher your db is crashing: void CClientManager::UpdateItemCache() { if (m_iCacheFlushCount >= m_iCacheFlushCountLimit) return; TItemCacheMap::iterator it = m_map_itemCache.begin(); while (it != m_map_itemCache.end()) { CItemCache * c = (it++)->second; if (c->CheckFlushTimeout()) // Boom right here { if (g_test_server) sys_log(0, "UpdateItemCache ==> Flush() vnum %d id owner %d", c->Get()->vnum, c->Get()->id, c->Get()->owner); c->Flush(); if (++m_iCacheFlushCount >= m_iCacheFlushCountLimit) break; } } } It make me think you are getting dangling pointers in your cache map. It's impossible to me to give you an exact cause of why your cache looks corrupted. You can read more about dangling pointers here.
  10. You shouldn't use line number in your tutorials, they are as you list them only in your source code.
  11. try by replacing this: if self.interface.BUILD_OnMouseLeftButtonUp(): //1357 return with this: if self.interface and self.interface.BUILD_OnMouseLeftButtonUp(): //1357 return It's strange to got an error where self.interface is None, you should invastigate to find the real cause of this.
  12. I can't tell you how to solve it, i can just try to explain you what's happen here: LUA_ERROR: locale/hungary/quest/object/state/mb_igshop:984: attempt to call field `give_item_with' (a nil value) The Error is saying us that a quest is calling give_item_with (i guess you might find it as pc.give_item_with) which is not defined in the module (it might be pc module) and the attempt to call it returned a nil value (because can't find its function body defined). The way to solve it is to define the body of the function. Usually the lua modules are defined by passing a function table e.g. here we have: void RegisterPCFunctionTable() { luaL_reg pc_functions[] = { { "get_wear", pc_get_wear }, { "get_player_id", pc_get_player_id }, { "get_account_id", pc_get_account_id }, { "get_account", pc_get_account }, //[........] //[........] //[........] { NULL, NULL } }; CQuestManager::instance().AddLuaFunctionTable("pc", pc_functions); } As you can see here we have a list of methods defined by giving them a name (callable from lua) and a definition which is defined in the .cpp file (e.g. questlua_pc.cpp) Conclusion is that you need to define your function which is giving you that error and to add it to the appropriate function table.
  13. Tomorrow (aka 02 November) is the last day of discount. Those who want to take advantage of the discounts should hurry.
  14. Can you share these two functions? in order to give us way to help you : CHARACTER::EncodeInsertPacket CHARACTER::UpdatePacket
  15. As you can see here, i ve explained you right here to warn you about your issue kek You may just add a if else like this: if (CHAT_TYPE_GUILD == pinfo->type) { // do stuff for guild chat } else { // do stuff as default }
  16. By searching into the source server, i ve found where the chat packet is received from the player, and sent to the guild members. int CInputMain::Chat(LPCHARACTER ch, const char * data, size_t uiBytes) here is where it is adding the name of the player to the chat text before to send it to guild members. You might not find the chat color system part. char chatbuf[CHAT_MAX_LEN + 1]; #ifdef ENABLE_CHAT_COLOR_SYSTEM // static const char* colorbuf[] = {" |h|r[ãÑÇÞÈ]|cFFffa200|h", " |h|r[ÔíäÓæ]|cFFff0000|h", " |h|r[ÔæäÌæ]|cFFffc700|h", " |h|r[Ìíäæ]|cFF000bff|h"}; // Arab static const char* colorbuf[] = {"|cFFffa200|H|h[Staff]|h|r", "|cFFff0000|H|h[Shinsoo]|h|r", "|cFFffc700|H|h[Chunjo]|h|r", "|cFF000bff|H|h[Jinno]|h|r"}; int len = snprintf(chatbuf, sizeof(chatbuf), "%s %s : %s", (ch->IsGM()?colorbuf[0]:colorbuf[MINMAX(0, ch->GetEmpire(), 3)]), ch->GetName(), buf); #else int len = snprintf(chatbuf, sizeof(chatbuf), "%s : %s", ch->GetName(), buf); #endif Warning : Here it is adding the name of the character independently on the chat type, so take care of check the type of chat before to add the level of the player (if you really want to add it only on guild chat).
  17. Use the 'clean solution' option by pressing right click on the solution in the solution explorer.
  18. Autumn Discount Week Starts Soon! From 25 October to 2 November you can buy my products with 25% discount! Don't miss the opportunity.
  19. WARNING: If your teleporter panel in lua doesn't use pc.can_warp you must add it obv ! It's important to check if a player can warp using pc.can_warp before to call pc.warp Hello community, I have always seen people go crazy for this problem which is solved with 2 lines of code, in particular with the various offlineshops (mine, or the free release great and ken) that are unfairly blamed for having duplication bugs. No! I believe that if you warp a player on another core without performing any checks you can't blame those who made the other systems which are then used to take advantage of the vulnerability you caused. If you implement something you need to make sure there are adequate checks to avoid causing vulnerabilities. In my opinion the cause of the duplication is not the various offlineshops, but the channel switcher which does not perform not even half checks before executing the warp. Anyway, no more chatter. I will explain here how to fix this problem. The first thing to check is if the channel switcher is using CHARACTER :: CanWarp to check if the player can be connected on a new channel or not. here i wanna paste a commonly seen function channel switcher to connect the player (char.cpp): void CHARACTER::ChannelSwitch(int iNewChannel){ long lAddr; long lMapIndex; WORD wPort; long x = this->GetX(); long y = this->GetY(); if (!CMapLocation::instance().Get(x, y, lMapIndex, lAddr, wPort)) { return; } if(lMapIndex >= 10000){ return; } std::map<WORD, int>ch; for(int i = 0; i < 4; i++){ for(int i2 = 1; i2 < 9; i2++){ ch[30*1000 + i*100 + i2] = i+1; } } int chan; if(ch.find(wPort) != ch.end()){ chan = ch[wPort]; }else{return;} Stop(); Save(); if(GetSectree()){ GetSectree()->RemoveEntity(this); ViewCleanup(); EncodeRemovePacket(this); } TPacketGCWarp p; p.bHeader = HEADER_GC_WARP; p.lX = x; p.lY = y; p.lAddr = lAddr; p.wPort = (wPort - 100*(chan-1) + 100*(iNewChannel-1)); GetDesc()->Packet(&p, sizeof(TPacketGCWarp)); } How you can see, no checks are performed to check if the character are using any systems which may give problems. So Here what we need is to add CanWarp check at the beginning of the method. void CHARACTER::ChannelSwitch(int iNewChannel){ //* START DUPLICATION FIX //* prevent problems about duplication of items //* using safebox/exchange/shop/acce if(!CanWarp()){ return; } //* END DUPLICATION FIX long lAddr; long lMapIndex; WORD wPort; long x = this->GetX(); long y = this->GetY(); if (!CMapLocation::instance().Get(x, y, lMapIndex, lAddr, wPort)) { return; } if(lMapIndex >= 10000){ return; } std::map<WORD, int>ch; for(int i = 0; i < 4; i++){ for(int i2 = 1; i2 < 9; i2++){ ch[30*1000 + i*100 + i2] = i+1; } } int chan; if(ch.find(wPort) != ch.end()){ chan = ch[wPort]; }else{return;} Stop(); Save(); if(GetSectree()){ GetSectree()->RemoveEntity(this); ViewCleanup(); EncodeRemovePacket(this); } TPacketGCWarp p; p.bHeader = HEADER_GC_WARP; p.lX = x; p.lY = y; p.lAddr = lAddr; p.wPort = (wPort - 100*(chan-1) + 100*(iNewChannel-1)); GetDesc()->Packet(&p, sizeof(TPacketGCWarp)); } This is enoght to solve 100% of the problems if your CanWarp is a complete check about all your system installed. If not, you just need to adapt CanWarp with the systems you have installed. I will make an example with my offlineshop so that the speech is clear to anyone. Let's take a look to the Default CanWarp method. The first thing to note is that its purpose is obviously to return true if the player is able to reconnect without any problems. bool CHARACTER::CanWarp() const { const int iPulse = thecore_pulse(); const int limit_time = PASSES_PER_SEC(g_nPortalLimitTime); if ((iPulse - GetSafeboxLoadTime()) < limit_time) return false; if ((iPulse - GetExchangeTime()) < limit_time) return false; if ((iPulse - GetMyShopTime()) < limit_time) return false; if ((iPulse - GetRefineTime()) < limit_time) return false; if (GetExchange() || GetMyShop() || GetShopOwner() || IsOpenSafebox() || IsCubeOpen()) return false; return true; } How you can see here you can find a lot of checks which they are checking the last time of every auction may be used to take exploit the warp. What we need to do here is to add new checks, to cover all the systems installed and fix all vulnerabilities. An example about an offlineshop would be: bool CHARACTER::CanWarp() const { const int iPulse = thecore_pulse(); const int limit_time = PASSES_PER_SEC(g_nPortalLimitTime); if ((iPulse - GetSafeboxLoadTime()) < limit_time) return false; if ((iPulse - GetExchangeTime()) < limit_time) return false; if ((iPulse - GetMyShopTime()) < limit_time) return false; if ((iPulse - GetRefineTime()) < limit_time) return false; if (GetExchange() || GetMyShop() || GetShopOwner() || IsOpenSafebox() || IsCubeOpen()) return false; #ifdef __ENABLE_NEW_OFFLINESHOP__ if (iPulse - GetOfflineShopUseTime() < limit_time) return false; if (GetOfflineShopGuest() || GetAuctionGuest()) return false; #endif return true; } Note: I m using GetOfflineShopGuest and GetAuctionGuest which are methods used on my shop to get the pointer to the opened offlineshop/auction but if you are using another offlineshop system you need to find the equivalent way to check if the player is guest into a offline shop. The method GetOfflineShopUseTime is a new method which i m implementing to check the last use time of the system. Let's see how to implement it (char.cpp) //SEARCH void ResetStopTime(); DWORD GetStopTime() const; //ADD UNDER #ifdef __ENABLE_NEW_OFFLINESHOP__ public: int GetOfflineShopUseTime() const {return m_iOfflineShopUseTime;} void SetOfflineShopUseTime(){m_iOfflineShopUseTime = thecore_pulse();} private: int m_iOfflineShopUseTime = 0; #endif Here we are instantiating a new int where we can store the current time when player use the systemUsing SetOfflineShopUseTime the method will update the value of m_iOfflineShopUseTime and using GetOfflineShopUseTime we can check the last time player used the system (as done into CanWarp). What's missing to do? We need to use SetOfflineShopUseTime where the player is using our offlineshop (buy item, open shop, edit shop, close shop, ecc.) , so that the last use time is actually updated when needed, making the check in can warp effective. A similar check can be done for other systems (eg acce system) to make our CanWarp safer and more effective. I hope it's usefull. Bye
  20. Who don't like to wait few days, please, don't ask me products. I don't like to get bad with no one, so i prefer to warn who think to buy, few days of queue for installations are needed. I like to dedicate a lot of time to those who buy from me, whoever did it knows it well. Asking me to hurry continuously will not change the waiting time in any way.
  21. Found and Blocked a guy who was RESELLING my Shop. I expect soon a bad review for this, that nobody is surprised therefore.
  22. Today is the last day to buy Pack manager + Pack encryption at a reduced price. From tomorrow the price reaches 200 euros
  23. Added a new product : Ikarus Pack Manager + Pack Encryption More about it in the topic message. It is on pre-order till 26.07 at a reduced price of 170€. After the pre-order week, the price will reach 200€
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.