- add MeshPort peer-to-peer overlay networking SDK, C++ integration, and Python bindings - add item actions quick use/split/delete/lock overlay window (mt_item_actions) - add shop name range and NPC name visibility settings to system display options - support battlepass ticket activation and month validation in mt_battlepass - support boss tracking teleport destination button in mt_bosses - support asynchronous account registration cancellation and pending login cancellation - update AVA2 item conversion for attr lock scrolls and battlepass tickets - update .gitignore for local build outputs and caches
44 lines
3.1 KiB
Python
44 lines
3.1 KiB
Python
import sys,unittest
|
|
from pathlib import Path
|
|
HERE=Path(__file__).resolve().parents[1];sys.path.insert(0,str(HERE))
|
|
import make_items as m
|
|
READER=HERE.parents[3]/'metin2-server/src/server/db/src/ProtoReader.cpp'
|
|
|
|
def row(vnum,t,st,anti='NONE',flags='NONE',wear='NONE',applies=('APPLY_NONE','0')*3,values=('0',)*6,refine=('0','0')):
|
|
return [str(vnum),'x',t,st,'1',anti,flags,wear,'NONE','10','20',refine[0],refine[1],'0','LEVEL','120','LIMIT_NONE','0',*applies,*values,'0','0','-1','']
|
|
|
|
@unittest.skipUnless(READER.is_file(),'needs ../metin2-server')
|
|
class ConvertTests(unittest.TestCase):
|
|
E=m.enums(READER) if READER.is_file() else None
|
|
def test_weapon_kept_without_unknown_flags(self):
|
|
s,c,kept=m.convert(row(320,'ITEM_WEAPON','WEAPON_SWORD','ANTI_MUDANG | ANTI_WOLFMAN','ITEM_TUNABLE','WEAR_WEAPON',
|
|
('APPLY_ATT_SPEED','18','APPLY_ATTBONUS_BOSS','5','APPLY_NONE','0'),refine=('321','81')),self.E,{320})
|
|
self.assertTrue(kept);self.assertEqual(s[5],'ANTI_MUDANG');self.assertEqual(s[7],'WEAR_WEAPON')
|
|
self.assertEqual(s[18:22],['APPLY_ATT_SPEED','18','APPLY_NONE','0'])
|
|
self.assertEqual(s[11:13],['0','0']) # the +1 item is not imported
|
|
self.assertEqual(c[1:3],[self.E['type'].index('ITEM_WEAPON'),0]);self.assertEqual(c[4],1<<self.E['anti'].index('ANTI_MUDANG'))
|
|
self.assertEqual(len(s),33);self.assertEqual(len(c),31)
|
|
def test_costume_enchant_is_locked(self):
|
|
s,c,kept=m.convert(row(54001,'ITEM_USE','USE_CHANGE_ATTRIBUTE',flags='ITEM_STACKABLE',values=('23','10','2','0','0','0')),self.E,set())
|
|
self.assertFalse(kept);self.assertEqual(s[2:4],['ITEM_NONE','0']);self.assertEqual(s[24:30],['0']*6)
|
|
self.assertEqual(c[1:3],[0,0]);self.assertEqual(c[5],1<<self.E['flag'].index('ITEM_STACKABLE'))
|
|
def test_unknown_type_and_stackable_anti(self):
|
|
s,_,kept=m.convert(row(55010,'ITEM_PET','PET_SKILL','ITEM_STACKABLE','LOG','WEAR_PENDANT'),self.E,set())
|
|
self.assertFalse(kept);self.assertEqual(s[5:8],['NONE','LOG | ITEM_STACKABLE','NONE'])
|
|
def test_quest_subtype(self):
|
|
s,c,kept=m.convert(row(30400,'ITEM_QUEST','QUEST_NONE',values=('APPLY_NONE','0','0','0','0','0')),self.E,set())
|
|
self.assertTrue(kept);self.assertEqual(s[3],'0');self.assertEqual(s[24],'0')
|
|
def test_lock_materials_and_monthly_tickets(self):
|
|
for vnum in (50348,50349):
|
|
server,client,kept=m.convert(row(vnum,'ITEM_USE','USE_CHANGE_ATTRIBUTE',flags='ITEM_STACKABLE'),self.E,set())
|
|
self.assertTrue(kept);self.assertEqual(server[2:4],['ITEM_USE','USE_CHANGE_ATTRIBUTE'])
|
|
for month in range(1,13):
|
|
server,client,kept=m.convert(row(25149+month,'ITEM_QUEST','QUEST_NONE',values=(str(month),)+('0',)*5),self.E,set())
|
|
self.assertTrue(kept);self.assertEqual(server[24],str(month));self.assertEqual(client[23],month)
|
|
|
|
def test_names_cover_ranges(self):
|
|
n=m.names();self.assertEqual(len(n),492);self.assertEqual(n[54100],'武器外观强化石')
|
|
self.assertTrue(all(len(v.encode('gbk'))<=24 for v in n.values()))
|
|
|
|
if __name__=='__main__':unittest.main()
|