Jump to content

OtherChoice

Inactive Member
  • Posts

    91
  • Joined

  • Last visited

  • Days Won

    3
  • Feedback

    0%

Everything posted by OtherChoice

  1. Not a header problem here, mismatch 0xdf != 0x0 means the stride (lenght) of the packet is different from client source to server source. Check the struct using that header and you'll see something like that client-side struct example{ BYTE header; WORD a; int b; } server-side struct example{ BYTE header; WORD a; long b; //long has double the size of int in bits so when either client or server tries to read this packet and check for his size it will notice a mismatch and prompts error }
  2. Oh now I got what you were talking about, classic listbox will scroll for index so first item is always centered and as you scroll you skip from index to index making it centered everytime on the same starting position. If you want to change this you should create a new ui class ListBox in python that will not handle items by index but by height. So for example you declare self.heigth = 0 Then for each list item you are going to append you will have self.height += itemheight. And remember changing every function using index instead of height for actions on the listbox for example: current list box SetBasePos function def SetBasePos(self, basePos, forceRefresh = TRUE): if forceRefresh == FALSE and self.basePos == basePos: return for oldItem in self.itemList[self.baseIndex:self.baseIndex+self.viewItemCount]: #using index here oldItem.ResetCurrentHeight() oldItem.Hide() self.basePos=basePos baseIndex = 0 #AND FROM HERE TO END while basePos > 0: basePos -= self.itemList[baseIndex].GetHeight() / self.stepSize if basePos < 0: self.itemList[baseIndex].SetRemoveTop(self.stepSize * abs(basePos)) break baseIndex += 1 self.baseIndex = baseIndex stepCount = 0 self.viewItemCount = 0 while baseIndex < len(self.itemList): stepCount += self.itemList[baseIndex].GetCurrentHeight() / self.stepSize self.viewItemCount += 1 if stepCount > self.viewSteps: self.itemList[baseIndex].SetRemoveBottom(self.stepSize * (stepCount - self.viewSteps)) break elif stepCount == self.viewSteps: break baseIndex += 1 y = 0 for newItem in self.itemList[self.baseIndex:self.baseIndex+self.viewItemCount]: newItem.SetPosition(0, y) newItem.Show() y += newItem.GetCurrentHeight()
  3. Honestly I can't see what are you talking about, i just see a tooltip of a item shown over a list box
  4. It widely depends on which things you are planning to add / edit. Binaries (executable files, one is the "launcher" of the game with .exe extension and the other 2 are game and db without extension) are written in C++ so if you plan to edit how the game itself process data or how the client recives informations and display them C++ is mandatory. Client uses a second language whose handles are still managed in C++, but it is responsible for loading (majority) of external graphic parts (.sub extension used to map .dds image fractions), and lot of ui functions and utilities. Such language is Python. Moreover there's Lua (a generic scripting language) managing quests and dungeons, even though most of lua functions are C++ defined in game binary. And last but not least there's SQL whose querys are spread across pretty much everything in the sources, and they handles data storage in tables.
  5. Yeah after looking deeply into the code it was pretty clear. I think the best way to achieve what I want, have every core read (only) a said memory region without refactoring everything is to use db to broadcasts pointer to vector of pointers to game binary instances.
  6. Oh I see, thank you for your time and collaboration. Regards
  7. Hello @Ikarus_, i'm interested in the cache part you used designing this system and have a few questions, performance-wise is it better than allocating stuffs on heap and freeing? cache is shared thourgh out every core? and last and more important do you mind if I take some parts of your code for a different system? I will neither sell anything nor copy/paste releasing contents.
  8. I actually used both slots, former for passives, latter for timed bonus applied to the whole guild, if you are planning to use those as well rembember that the BLOB which stores guild skill info is set to be read with the current (GUILD_SKILL_START, GUILD_SKILL_END) range so if you are planning to expand this range you have to edit server db source to read the new structure and the rest (game-client source) to broadcasts the values across clients
  9. This error started showing after some changes i suppose, check changes you did like new systems and so on. If you instead got a new clean server and client source maybe you should start considering they're either different releases or not so clean.
  10. There is some inconsistecies in packet definition of game and client binary. This error usually occurs when one binary expects the size of a packet to be actually larger or smaller than it is: game source typedef unsigned char BYTE; struct test_packet { BYTE header; BYTE value1; int value2; unsigned long value3; } TTestPacket; client source typedef unsigned char BYTE; struct test_packet { BYTE header; BYTE value1; long value2; unsigned long value3; } TTestPacket; As you can see both packet looks almost the same but sizeof(int) is 4 and sizeof(long) is 8. So when one binary copys values pointed by const void* using sizeof(TTestPacket) it will either be missing 4 bytes or have 4 more. Long story short check all your packets declarations
  11. inside client binary source your typedef struct TItemTable {...} SItemTable; has to match stride of item_proto. This means that for each field ("column") of the item_proto, SItemTable should have a corresponding field of the right type. For example old item_protos (before dragonsoul system) had a stride of 152 meanwhile after dragonsould system it got expanded to 156. 156-152 = 4. 4 is the size of the new field added "vnum_range" which is declared as int inside SItemTable hence the difference of 4 bytes. So if your new item_proto has a size of 163 you should check which type of new fields are missing in your current SItemTable and just add them.
  12. bool CHARACTER::CheckLevelDifference(LPCHARACTER pkAttacker,LPCHARACTER pkVictim){//(optional namespace CHARACTER you can include this function everywhere as long as LPCHARACTER objects are declared aka #include "char.h") if (pkAttacker->IsPC() && !pkVictim->IsPC()) if (pkAttacker->GetLevel() - pkVictim->GetLevel() <= 10) return true; return false; } remeber declaration inside header file if you plan to call it outside of said class bool CheckLevelDifference(LPCHARACTER pkAttacker, LPCHARACTER pkVictim); Moreover if you do decide to implement it inside char.cpp/char.h you can use this variation which accepts only one argument. bool CHARACTER::CheckLevelDifference(LPCHARACTER ch){ if (IsPC() && !ch->IsPC()) if (GetLevel() - ch->GetLevel() <= 10) return true; return false; } bool CheckLevelDifference(LPCHARACTER ch); And call it like this ..... LPCHARACTER pc; LPCHARACTER mob; if (pc->CheckLevelDifference(mob)) //else if you chose the first approach and for instance you declared and defined it inside CHARACTER_MANAGER if (CHARACTER_MANAGER::Instance().CheckLevelDifference(pc, mob);
  13. Honestly I can't really figure out whats wrong here I'm sorry man but everything should work fine
  14. please show this struct of your client binary (or the second one in case you client uses it). You can check whether is used in bool CPythonNetworkStream::RecvSafeBoxSetPacket() (PythonNetworkStreamPhaseGame.cpp) typedef struct packet_set_item { BYTE header; TItemPos Cell; DWORD vnum; BYTE count; long alSockets[CItemData::ITEM_SOCKET_MAX_NUM]; TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; } TPacketGCItemSet; typedef struct packet_set_item2 { BYTE header; TItemPos Cell; DWORD vnum; BYTE count; DWORD flags; // Ç÷¡±× Ãß°¡ DWORD anti_flags; // Ç÷¡±× Ãß°¡ bool highlight; long alSockets[CItemData::ITEM_SOCKET_MAX_NUM]; TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; } TPacketGCItemSet2; from server/common in tables.h show typedef struct SPlayerItem { DWORD id; BYTE window; WORD pos; DWORD count; DWORD vnum; long alSockets[ITEM_SOCKET_MAX_NUM]; // 소켓번호 TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_MAX_NUM]; DWORD owner; } TPlayerItem; and from client binary in GameType.h show typedef struct packet_item { DWORD vnum; BYTE count; DWORD flags; DWORD anti_flags; long alSockets[CItemData::ITEM_SOCKET_MAX_NUM]; TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_SLOT_MAX_NUM]; } TItemData;
  15. Hello everyone, do you guys know how and where game.core gets generated? to be more specific i would like to know where the generation occurs: game binary, freebsd OS, or whatever, and where the function actually is (some new sources I'm debugging seem not to generate it after a segmentation fault) . Thanks in advance. As always new FreeBSD = new problems, the problem was sysctl variable kern.nodump_coredump = 0, for some reason = 0 no dump = 1 dump.
  16. What's your testing enviorment? a live server a vps or your localhost? Since SyncPosition is handled by packet system if either there's too much packet traffic and/or mysql traffic on your server (table flooding and query attacks affects packet transmission as well, tested recently on a 600.000 query request login packet took longer than 3m to be recived while attack packet took around 34s) or your hosting has not enough specs you will experience issues like this. By any chance did you added some system/function or edited existing ones using packet transmission or sql statements? if so make sure your code is clean and well thought with no "endless iteration of long operation sent through packet, recived and for each result a new query to..."alike system. Again (really) low specs "might" lead to this (i'm not 100% sure), more likely is something with code. If I were you I'd take a look for changes in SyncPosition system if you did any. If you kept track of your implementation with backups before adding anything new I also suggest to try different versions of both game and client and see if the bug has always existed or appeared after adding/editing something.
  17. That's actually easier //this is char_skill.cpp struct FuncSplashDamage (so if you happen to modify your skill proto removing flag SPLASH from a skill which has ATTACK_STUN this won't have any effect) struct FuncSplashDamage{ //... if (IS_SET(m_pkSk->dwFlag, SKILL_FLAG_SLOW | SKILL_FLAG_STUN | SKILL_FLAG_FIRE_CONT | SKILL_FLAG_POISON)) //Here will check for SKILL_FLAG_STUN which is flag ATTACK_STUN in db you could be either changing DB flag of skill 18 & 107 (from ATTACK_STUN to CRUSH used for every other stunning skill not applying POINT_PARTY_BUFFER_BONUS) or adding a check for SKILL_FLAG_STUN as suggested by WeedHex and have both flags the same. Pick your poison or start rewriting stupid korean code. { int iPct = (int) m_pkSk->kPointPoly2.Eval(); int iDur = (int) m_pkSk->kDurationPoly2.Eval(); iDur += m_pkChr->GetPoint(POINT_PARTY_BUFFER_BONUS) / 10;
  18. Did you tried getting back the item from the storage? does it get binding back or is it still lost?
  19. next time don't show full source just the implementation so who wants to help you doesn't have to search in 3000 lines of code, however i need one more information: try depositing a bind item into storage, close storage and logout from game, then go into your DB player and check inside "item" for your item. It should show window = SAFEBOX, if not DB is still not updated and shall you wait a minute. After your item displays the correct window check the column "sealbind" (or anything you chosed to use), if the value is still set then its a missing client binary part (packet with HEADER_GC_SAFEBOX_SET missing long sealbind; and it implementation). Otherwise i'll look deeper into those 3000 lines of code.
  20. I don't have this system and files are no longer avaible, however I think the problem could be one and only, query to store item won't save the parameter which determines the binding of the item. If you can't still find it out please share how your Soulbind System is implemented in db and you'll have your answer.
  21. Hello everyone, i'm developing a section of ingame wiki which I think I'll release once finished, and I came across a (probably stupid) problem, yet I can't solve it. I'm creating a second MiniMap module called MiniMapWiki which is made of its relative cpp python module PythonMiniMapWikimodule.cpp, the derived class (CScreen & Singleton) MiniMapWiki.cpp & .h just as normal MiniMap and Python functions in uiMiniMapWiki.py. Client Binary part is a refactored copy of already existing function. Module Initialization (initMiniMapWiki()) is correctly added in StdAfx.h and UserInterface.cpp, and python part initialization is handled by interfacemodule.py when creating other windows in def __MakeWindows(self). The error i recive occurs after character selection and just before loading is done and it throws an Assertion Failed error of ms_singleton. I can't really get where the problem is but it might be a double initialization or a missing one.(Debug mode no syserr just assertion failed message) I'll paste my 3 c++ files here. Hope someone can help me find it out, however i'll keep searching on my own. PythonMiniMapWiki.cpp PythonMiniMapWiki.h PythonMiniMapWikiModule.cpp Edit: I just noticed CPythonMiniMapWiki class declared but never initialized, just added CPythonMiniMapWiki m_pyMiniMapWIki; in PythonApplication.h and m_pyMiniMapWiki.Destroy() in PythonApplication.cpp in function CPythonApplication::Destroy(), I knew it was something dumb but it was a lot of code to check.
  22. Packet.h (both client and server source) add where HEADER(s) are declared HEADER_GC_FLAG_RESPONSE = 156, //any number still not used HEADER_CG_FLAG_REQUEST = 157, // same here add where struct(s) are declared typedef struct packet_flag_response { BYTE header; char* FlagName; } TPacketCGFlagRequest; typedef struct packet_flag_response { BYTE header; DWORD dwFlag; } TPacketGCFlagResponse; PythonNetworkStreamPhaseGame.cpp (client binary) In function GamePhase() add below other cases: case HEADER_GC_FLAG_RESPONSE: ret = RecvFlagResponsePacket(); break; Then add 2 new bools: bool CPythonNetworkStream::SendFlagRequestPacket(char* flag) { TPacketCGFlagRequest pPack; pPack.header = HEADER_CG_FLAG_REQUEST; pPack.FlagName = flag; if (!Send(sizeof(ItemInfoLoadPacket), &ItemInfoLoadPacket)) return false; return SendSequence(); } bool CPythonNetworkStream::RecvFlagResponsePacket(){ TPacketGCFlagResponse pPack; if (!Recv(sizeof(TPacketGCFLagResponse), &pPack)) return false; DWORD flag = pPack.dwFlag; CInstanceBase * pInstPlayer = CPythonCharacterManager::Instance().GetMainInstancePtr(); if (pInstPlayer) { PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "BINARY_AddFlagValue", Py_BuildValue("(i)", flag)); } return true; } In PythonNetworkStream.h add the definition of the previous function (client binary) after bool RecvPartyParameter(); add bool RecvFlagResponsePacket(); In PythonNetworkStreamModule.cpp add: PyObject* netFlagRequest(PyObject* poSelf, PyObject* poArgs) { char* flag; if (!PyTuple_GetString(poArgs, 0, &flag)) { return Py_BuildException(); } CPythonNetworkStream& rns = CPythonNetworkStream::Instance(); rns.SendFlagRequestPacket(flag); return Py_BuildNone(); } then in void initnet() add { "SendFlagRequest", netSendFlagRequest, METH_VARARGS }, that's client binary example now we move on game server Packet.h edited as above input_main.cpp case HEADER_CG_FLAG_REQUEST: { FlagRequest(ch, c_pData); } break; then add a new void (and of course its definition in input_main.h) void CInputMain::FlagRequest(LPCHARACTER ch, const char* c_pData) { TPacketCGFlagRequest pRequest = (TPacketCGFlagRequest*)c_pData; TPacketGCFLagResponse pResponse; pResponse.header = HEADER_GC_FLAG_RESPONSE; pResponse.flag = ch->GetQuestFlag(pRequest.FlagName); ch->GetDesc()->Packet(&pResponse, sizeof(TPacketGCFlagResponse)); } packet_info.cpp in CPacketInfoCG::CPacketInfoCG() add Set(HEADER_CG_ITEM_INFO_LOAD, sizeof(TPacketCGItemInfoLoad), "ItemInfoLoad", true); and we're done server side, now there's only python part left and since i do not know your code i'll make a very simple example: in game.py add def BINARY_AddFlagValue(self, flag): if flag == YOUR_VALUE: #do something like self.YourButton.Show() if self.YourButton is part of game.py else if your element is part of another python file we call uiexample.py which gets initialized in game.py like self.myexample = uiexample.ExampleClass() do self.myexample.YourButton.Show() or self.myexample.MyCustomFunction() which handles visibility of the button #INVENTORY BUTTON EXAMPLE: self.interface.ShowInventoryButton() #then in interfacemodule.py in class interface add def ShowInvetoryButton(self): self.wndTaskBar.GetChild("InventoryButton").Show() It should be complete, I could have missed a declaration or something since i coded it without source by hand so if any problem just show your errors. Hope I helped! P.S. As you might have noticed i totally skipped lua part since its function pc.getqf is c++ code and its definition is CHARACTER::GetQuestFlag so no need to change anything on lua, just do your quest, use pc.setqf and you will be able to access just calling in game source ch->GetQuestFlag(flagname)
  23. It's not possible to have only python and quest in this system since python will access game variables only through python modules inside client binary, i'll send you an example in a few minutes
  24. LPGUILD objects can be compared through operator ==. pPlayer1->GetGuild() == pPlayer2->GetGuild()
  25. each quest function, including questflags and globalflags, its called by the quest itself(lua) but is handled on game server and its declaration its c++ code. What you could do is adding a new function in client binary to pythonnetworkmodule so your py files can call this function which sends a request packet (HEADER_CG) to game server which performs any check you want on said flags and sends the response back to client (HEADER_GC), then you could have a BINARY_CALLBACK (game.py function accessible by client binary) which performs your desired python function. Hope it was clear, if not just tell me which part isn't clear and i'll make some example code as i get back home.
×
×
  • 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.