Jump to content

xP3NG3Rx

Honorable Member
  • Posts

    839
  • Joined

  • Days Won

    393
  • Feedback

    100%

Posts posted by xP3NG3Rx

  1. 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.

    • Love 1
  2. M2 Download Center

    This is the hidden content, please
    ( Internal )

    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.

     

    This is the hidden content, please

     

    Old request topic:

     

    Have fun,

    Peace out.

    • Metin2 Dev 30
    • kekw 1
    • Smile Tear 1
    • Good 6
    • Love 18
  3. 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):

    wwa67pn.png

     

    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.

  4. 	## 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.

    • Love 4
  5. Due the loss of backup or whatever is happened, here are the last patches:

    This is the hidden content, please
     (
    This is the hidden content, please
    )

    This is the hidden content, please
     (
    This is the hidden content, please
    )

    This is the hidden content, please
     (
    This is the hidden content, please
    )

    • Metin2 Dev 74
    • Eyes 1
    • Dislove 1
    • Sad 1
    • Confused 4
    • Scream 3
    • Lmao 2
    • Good 28
    • Love 3
    • Love 62
  6. 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 :).

    • Lmao 1
    • Good 1
    • Love 9
  7. 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.

    6vVTYnH.png

    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;
    }

     

    • Metin2 Dev 23
    • Dislove 4
    • Think 3
    • Confused 1
    • Lmao 1
    • Good 9
    • Love 28
    • Love 31
  8. M2 Download Center

    This is the hidden content, please
    ( Internal )

    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:

    203811mVLtrtB.gif

     

    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.

     

    Spoiler

    If you don't have function for DWORD diffuse color handling:

     

    203811PX70Lam.png

     

    Have fun,

    This is the hidden content, please

    • Metin2 Dev 23
    • Angry 1
    • Good 3
    • Love 21
  9. This is the hidden content, please
     (
    This is the hidden content, please
    )

    Contents/news:

    1. root+meta, locale+protos, useless dumped binary for RE/debug
    2. Battle Royale assets.
    3. 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:

    Spoiler

    Owaran 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
    uiscript

     

    Special thanks for the list of the changes to @owaran

     

    • Metin2 Dev 46
    • Eyes 1
    • Dislove 1
    • Not Good 1
    • Cry 1
    • Think 1
    • Confused 2
    • Lmao 1
    • Good 14
    • Love 2
    • Love 39
  10. 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.

    • Lmao 1
    • Good 1
    • Love 1
  11. 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:

    J7Pu8jq.png

    # 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 :)

    • Good 1
    • Love 3
  12. This is the hidden content, please
     (
    This is the hidden content, please
    )

    Contents:

    1. Some re-exported, new mob models.
    2. Simple GUI for WorldBoss event, Flower event.
    3. Removed FindM event perhaps by mistake.
    4. New skill icon for wolfman(?) J4i5bqb.png Probably soon the new skills are coming too.
    5. root+dump, locales+protos
    • Metin2 Dev 49
    • Dislove 1
    • Sad 1
    • Cry 1
    • Confused 4
    • Good 14
    • Love 32
×
×
  • 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.