-
Posts
839 -
Joined
-
Days Won
393 -
Feedback
100%
Content Type
Forums
Store
Third Party - Providers Directory
Feature Plan
Release Notes
Docs
Events
Posts posted by xP3NG3Rx
-
-
I can give you a hint.
Check the latest official root files from 2018 march.
It has the solution in the interfaceModule.py, uiNewInventory.py and uiDragonSoul.py.
keyword: "SetUseItemMode"
You need to give the information from the specialInventory through the interfaceModule to the Inventory.
- 1
-
Spoiler
- 1
- 1
-
-
Hi devs!
Might be usefull for some of you. The code is not well optimised(i guess), but tested and worked.
I'm planning to use the CGroupTextParseTreeLoader in the future, so this why I implemented it into the binary.
Basically this is used for the dragonsoul setbonus calculation, in these functions:
- item.GetDSSetWeight(dsType, grade)
- item.GetDSBasicApplyCount(dsType, grade)
- item.GetDSBasicApplyValue(dsType, type)
- item.GetDSAdditionalApplyValue(dsType, type)
This will not give you the full dragon soul set bonus as a new content.
Before the implementation, don't forget to make backup, in case of rage.
Old request topic:
Have fun,
Peace out.
- 30
- 1
- 1
- 6
- 18
-
-
Spoiler
- 1
-
But after every warp your setting of shadows always will be SHADOW_ALL doesn't matter what is your setting in config if I'm not wrong. For the proper functional solution you need to set the value in the uiSystemOption.py file the value from systemSetting to the background.
def __Load(self):
PS.: Of course in your file you need to set the position of the slider from the config file first and by that you need to set the value into the background class. The picture above is the latest modification what they made.
-
-
## uiShop.py def Open(self, vid): import chr isPrivateShop = chr.IsNPC(vid) == 0 if player.IsMainCharacterIndex(vid): isMainPlayerPrivateShop = True self.btnBuy.Hide() self.btnSell.Hide() self.btnClose.Show() else: isMainPlayerPrivateShop = False if isPrivateShop: self.vid = vid self.btnBuy.SetPosition(0, 295) self.btnBuy.SetWindowHorizontalAlignCenter() self.btnBuy.Show() self.btnSell.Hide() self.btnClose.Hide()
This depends on your shop system too. The actortype of your shops are cannot be NPC type. Otherwise you need to change the value of the isPrivateShop variable.
- 4
-
Due the loss of backup or whatever is happened, here are the last patches:
( )
( )
( )
- 74
- 1
- 1
- 1
- 4
- 3
- 2
- 28
- 3
- 62
-
I have found a reference long time ago.
PythonPlayerSkill.cpp > CPythonPlayer::__ProcessEnemySkillTargetRange:
- 3
-
Quote
000.00 / 255.0
Btw, whom have more sockets they should know if they use an external addon that is different and doesn't compatible with their codes, so they need to change it.
This is a rule on every each addon.
- 2
- 1
-
Useless or not I don't mind, the code is there in the public source as in the official binary still, as you can see on the picture so I just put it there too.
Btw the metin2 private server owners or devs are not rocket scientists, so they don't really know which packet is in used neither which is not, oh yeah they don't even care them .
- 1
- 1
- 9
-
Hello,
Small performance snippet from the official binary after some reverse engineering.
I did not make huge tests, but it seems just fine for me, if you have any problem, let me know in comment below.
1.) Get rid of every __LoadMap function + calls from the introLoading.py file. Also you can completly remove the function net.Warp as well.
2.) Modify the following functions in the CPythonNetworkStreamPhaseLoading.cpp this way:
bool CPythonNetworkStream::RecvMainCharacter() { // [..] Add to the bottom the Warp function Warp(MainChrPacket.lX, MainChrPacket.lY); SendClientVersionPacket(); return true; }
bool CPythonNetworkStream::RecvMainCharacter2_EMPIRE() { // [..] Add to the bottom the Warp function Warp(mainChrPacket.lX, mainChrPacket.lY); SendClientVersionPacket(); return true; }
bool CPythonNetworkStream::RecvMainCharacter3_BGM() { // [..] Add to the bottom the Warp function Warp(mainChrPacket.lX, mainChrPacket.lY); SendClientVersionPacket(); return true; }
bool CPythonNetworkStream::RecvMainCharacter4_BGM_VOL() { // [..] Add to the bottom the Warp function Warp(mainChrPacket.lX, mainChrPacket.lY); SendClientVersionPacket(); return true; }
- 23
- 4
- 3
- 1
- 1
- 9
- 28
- 31
-
Start with the basics to learn the logic behind of programming, exercise a lot, without basics you can do nothing.
Don't jump into the deep water if you can't swim.
- 2
-
Revert the codes back and don't do what you don't understand.
- 1
- 4
-
Yo' folks!
Here is a small gui extension from the official v20.4.0 binary, which is kinda trash, but can be useful for some guis to point out some stuffs.
Webzen finally started to use their old codes, this is one of they have never used before.
Preview:
Animation is not binary sided, it's via python, the testScript.py is attached, the injection is on you, there are many examples how to test a script, there are also many loaders to it.
SpoilerIf you don't have function for DWORD diffuse color handling:
Have fun,
- 23
- 1
- 3
- 21
-
Contents/news:
- root+meta, locale+protos, useless dumped binary for RE/debug
- Battle Royale assets.
- Challenge Minigame assets - Stone, Paper, Scissors game
ps.: I just wanted to put the patches only, but the patcher rewrote the attributes of the new files(dates and so on) so I didn't know which files have been updated.
edit:
SpoilerOwaran Today at 6:31 PM
My last backup was 7/28/2020.
Checking the changes with the client on the date: 8/2/2020.
Changes:
locale_br
locale_br_string
m00003
m00010
m00011
m00012
m00013
m00021
m00022
m00046
m00048
m00055
m00057
m00068
m00069
m00071
m00072
m00084
m00085
m00086
m00120
m00129
m00130
m00131
m00133
m00135
m00141
m00143
m00144
m00148
m00178
m00194
m00196
property
root
uiscriptSpecial thanks for the list of the changes to @owaran
- 46
- 1
- 1
- 1
- 1
- 1
- 2
- 1
- 14
- 2
- 39
-
It depends how you want to do it, mixed with items you want to place for sale and some items for showcase only, or all the items are just for showcase.
Both ways are possible, but you can wait until 2038 that somebody will code it for you especially for free .
The principle of operation can be simple or complex, depends how you code it.
Basically the best option is when you set an extra variable for every each item, that it is sellable or not, then block the buy function on those items where that flag has been set.
Also you can mark those items on clientside, to let the players see those items are not for sale.
For a last word, hire a dev if you can't code this for yourself.
- 1
- 1
- 1
-
I would recommend to extend the function with a hint as well then when the problem is fixed revert the codes back to the original.
By the way this SelectItem sometimes messes up some codes, as you can see in the official codes about the sashes, you need to select an another item(the drained) to query some informations about that, then to not mess up the rest of the codes what comes after the external function call, you need to select the original vnum back after you are done.
This is just an example about the weakness of the SelectItem function, highly possible none of you are using this except me .
Also might be the problem is not because of these kind of codes, I just wanted to let you know about this.
Spoiler## This is the AddItemData function. Here an external function will be called which needs to query some informations about the drained item, also here the acce is the selected item. This function will run down on an item when you move your cursor on it, this function needs to run down to the end with the originally selected item otherwise some unexcpected errors may show up. ## ÄÚ˝şĂő ľĆŔĚĹŰ ## elif 0 != isCostumeItem: self.__AppendLimitInformation() if item.GetItemSubType() == item.COSTUME_TYPE_ACCE: self.__AppendAffectInformationAcce(slotIndex, window_type, metinSlot) self.__AppendAcceItemAffectInformation(itemVnum, window_type, slotIndex, metinSlot) #!!! Here goes the itemVnum as the recently selected itemVnum which is the sash vnum. self.__AppendAttributeInformationAcce(itemVnum, attrSlot, slotIndex, window_type, metinSlot) else: self.__AppendAffectInformation() self.__AppendAttributeInformation(attrSlot) #Here is the function which will select the drained item, then at the end it selects the original back def __AppendAcceItemAffectInformation(self, oriitemVnum, window_type, slotIndex, metinSlot): (affectTypeAcce, affectValueAcce) = item.GetAffect(0) socketInDrainValue = 0 if item.GetRefinedVnum() == 0: ## ŔüĽłµî±Ţ ČíĽöŔ˛ ľËľĆżŔ±â. if app.ENABLE_EXTEND_INVEN_SYSTEM: socketInDrainValue = 0 if window_type == playerm2g2.INVENTORY or window_type == playerm2g2.EQUIPMENT: socketInDrainValue = playerm2g2.GetItemMetinSocket(window_type, slotIndex, 1) if not metinSlot[1] == 0 and socketInDrainValue == 0: socketInDrainValue = metinSlot[1] elif window_type == playerm2g2.ACCEREFINE: socketInDrainValue = playerm2g2.GetAcceItemMetinSocket(slotIndex, 1) elif window_type == playerm2g2.SAFEBOX: socketInDrainValue = safebox.GetItemMetinSocket(slotIndex, 1) else: if window_type == playerm2g2.INVENTORY: socketInDrainValue = playerm2g2.GetItemMetinSocket(slotIndex, 1) if not metinSlot[1] == 0 and socketInDrainValue == 0: socketInDrainValue = metinSlot[1] elif window_type == playerm2g2.ACCEREFINE: socketInDrainValue = playerm2g2.GetAcceItemMetinSocket(slotIndex, 1) elif window_type == playerm2g2.SAFEBOX: socketInDrainValue = safebox.GetItemMetinSocket(slotIndex, 1) drainlate = socketInDrainValue / 100.0 else: drainlate = affectValueAcce / 100.0 socketInDrainValue = affectValueAcce if socketInDrainValue == 0: return ## Á¤ş¸ »ĚľĆżĂ ľĆŔĚĹŰ ľËľĆżŔ±â. if app.ENABLE_EXTEND_INVEN_SYSTEM: socketInDrainItemVnum = 0 if window_type == playerm2g2.INVENTORY or window_type == playerm2g2.EQUIPMENT: socketInDrainItemVnum = playerm2g2.GetItemMetinSocket(window_type, slotIndex, 0) if not metinSlot[0] == 0 and socketInDrainItemVnum == 0: socketInDrainItemVnum = metinSlot[0] elif window_type == playerm2g2.ACCEREFINE: socketInDrainItemVnum = playerm2g2.GetAcceItemMetinSocket(slotIndex, 0) elif window_type == playerm2g2.SAFEBOX: socketInDrainItemVnum = safebox.GetItemMetinSocket(slotIndex, 0) else: if window_type == playerm2g2.INVENTORY: socketInDrainItemVnum = playerm2g2.GetItemMetinSocket(slotIndex, 0) if not metinSlot[0] == 0 and socketInDrainItemVnum == 0: socketInDrainItemVnum = metinSlot[0] elif window_type == playerm2g2.ACCEREFINE: socketInDrainItemVnum = playerm2g2.GetAcceItemMetinSocket(slotIndex, 0) elif window_type == playerm2g2.SAFEBOX: socketInDrainItemVnum = safebox.GetItemMetinSocket(slotIndex, 0) ## ČíĽöÇŃ ľÇĽĽĽ¸® ľĆŔĚĹ۸¸ ş¸ż©ÁÖ±âŔ§ÇŘ °É·ŻÁŘ´Ů. if socketInDrainItemVnum == 0: return item.SelectItem(socketInDrainItemVnum) itemtype = item.GetItemType() if itemtype == item.ITEM_TYPE_WEAPON: ## Ăß°ˇ µĄąĚÁö addPower = item.GetValue(5) ## ą«±â. Attact if item.GetValue(3) >= 1 and item.GetValue(4) >= 1: minPower = max(((item.GetValue(3) + addPower) * drainlate) , 1) maxPower = max(((item.GetValue(4) + addPower) * drainlate) , 1) if maxPower > minPower: self.AppendTextLineAcce(localeInfo.TOOLTIP_ITEM_ATT_POWER % (minPower, maxPower), self.POSITIVE_COLOR) else: self.AppendTextLineAcce(localeInfo.TOOLTIP_ITEM_ATT_POWER_ONE_ARG % (minPower), self.POSITIVE_COLOR) ## ą«±â. Magic if item.GetValue(1) >= 1 or item.GetValue(2) >= 1: minMagicAttackPower = max(((item.GetValue(1) + addPower) * drainlate) , 1) maxMagicAttackPower = max(((item.GetValue(2) + addPower) * drainlate) , 1) if maxMagicAttackPower > minMagicAttackPower: self.AppendTextLineAcce(localeInfo.TOOLTIP_ITEM_MAGIC_ATT_POWER % (minMagicAttackPower, maxMagicAttackPower), self.POSITIVE_COLOR) else: self.AppendTextLineAcce(localeInfo.TOOLTIP_ITEM_MAGIC_ATT_POWER_ONE_ARG % (minMagicAttackPower), self.POSITIVE_COLOR) elif itemtype == item.ITEM_TYPE_ARMOR: ## ąćľî·Â defBonus = item.GetValue(5)*2 ## ąćľî·Â ÇĄ˝Ă Ŕ߸ř µÇ´Â ą®Á¦¸¦ ĽöÁ¤ if item.GetValue(1) >= 1: defGrade = max(((item.GetValue(1) + defBonus) * drainlate) , 1) if defGrade > 0: self.AppendSpace(5) self.AppendTextLineAcce(localeInfo.TOOLTIP_ITEM_DEF_GRADE % (defGrade), self.GetChangeTextLineColor(defGrade)) ## Itemtable żˇ ŔÖ´Â ±âş» ĽÓĽş Ŕűżë. ## ľÇĽĽĽ¸®żˇ´Â - °© ex Ŕ̵żĽÓµµ Ŕűżë ľČÇÔ. for i in xrange(item.ITEM_APPLY_MAX_NUM): (affectType, affectValue) = item.GetAffect(i) if affectValue > 0: affectValue = max((affectValue * drainlate) , 1) affectString = self.__GetAffectString(affectType, affectValue) if affectString: self.AppendTextLineAcce(affectString, self.GetChangeTextLineColor(affectValue)) item.SelectItem(oriitemVnum)
And the hint I started to talk about:
#define BULLSEYE PyObject * itemSelectItem(PyObject * poSelf, PyObject * poArgs) { DWORD dwItemIndex; if (!PyTuple_GetUnsignedLong(poArgs, 0, &dwItemIndex)) return Py_BadArgument(); #ifdef BULLSEYE char* szHint; if (2 == PyTuple_Size(poArgs)) { if (!PyTuple_GetString(poArgs, 1, &szHint)) return Py_BadArgument(); } #endif if (!CItemManager::Instance().SelectItemData(dwItemIndex)) { #ifdef BULLSEYE TraceError("Cannot find item by %lu hint: %s", dwItemIndex, szHint); #else TraceError("Cannot find item by %lu", dwItemIndex); #endif CItemManager::Instance().SelectItemData(60001); return Py_BuildValue("i", FALSE); } return Py_BuildValue("i", TRUE); }
You might have some syntax errors, my function looks a bit different then the public ones, after I reversed this from the official and built my own pythoncore with fixxed errors about the unsigned long stuffs. But you can see in the macro the hint stuff. PS: Totally unnecesary the PythonChat, it will write to the syserr anyways.
After this you just start replacing all of your calls in your python files like:
def GetRefineSuccessPercentage(self, scrollSlotIndex, itemSlotIndex): if -1 != scrollSlotIndex: if player.IsRefineGradeScroll(scrollSlotIndex): curGrade = player.GetItemGrade(itemSlotIndex) itemIndex = player.GetItemIndex(itemSlotIndex) item.SelectItem(itemIndex)
def GetRefineSuccessPercentage(self, scrollSlotIndex, itemSlotIndex): if -1 != scrollSlotIndex: if player.IsRefineGradeScroll(scrollSlotIndex): curGrade = player.GetItemGrade(itemSlotIndex) itemIndex = player.GetItemIndex(itemSlotIndex) item.SelectItem(itemIndex, "uiRefine.GetRefineSuccessPercentage")
Or also you can discover it via this:
# utils.py import inspect def getLineInfo(): stack = inspect.stack() return "%s.%s at line %d" % (stack[1][1], stack[1][3], stack[1][2])
This requires the inspect module which also requires the following modules:
dis
opcode
string
token
tokenize
So with this you just need to call the utils.getLineInfo() as the 2nd argument of the item.SelectItem function
item.SelectItem(itemVnum, utils.getLineInfo())
and also the utils has to be imported to the file where you use the item modul for selecting an item during the debugging.
DID NOT TESTED ON CYTHONIZED CODES, AND NEVER WILL, cython is not for debugging anyways
- 1
- 3
-
-
On a well managed server this cannot happen. Players are not able to get polymorph item with empty sockets.
Anyways, better to make sure about it, thanks for your comment.
-
Can we see the quest-file which cause the problem?
- 1
-
Contents:
- Some re-exported, new mob models.
- Simple GUI for WorldBoss event, Flower event.
- Removed FindM event perhaps by mistake.
- New skill icon for wolfman(?) Probably soon the new skills are coming too.
- root+dump, locales+protos
- 49
- 1
- 1
- 1
- 4
- 14
- 32
Small: handle updates when more slots are in the same position
in Programming & Scripts
Posted
I'm trying to picture what is this all about, but I never faced with this problem or I don't remember.