Search the Community

Showing results for tags 'python'.

More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


  • Community
    • Announcements
    • Feedback
  • Metin2
    • General
    • Questions and Answers
    • Frequently Asked Questions
    • Guides & HowTo
    • Design
    • Private Servers
    • Services
    • Videos
  • Releases
    • General
    • Tools
    • Programming / Scripts
    • Quests
    • Binaries & Clients/Serverfiles
    • 3D Models
    • 2D Graphics
    • Operating Systems
  • Safe Zone
    • Offtopic
    • Games Talk
    • Music/Videos/Art
  • D:\YMIR WORK\'s Topics

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start



Website URL






Found 180 results

  1. When i've a little bit time, i'll post on git with more informations and update the topic. #! /usr/bin/env python # -*- coding: utf-8 -*- __name__ = "ProtoChecker" __author__ = "VegaS" __date__ = "2019-11-18" __version__ = "0.0.1" import sys import os # Set the base color of command prompt os.system("color 00") # Set the print method TraceFormat = lambda arg: sys.stdout.write(arg + "\n") ################################################# ## Builtin translations ################################################# COLOR_GREEN = "\033[92m{}\033[00m" COLOR_RED = "\033[91m{}\033[00m" COLOR_GRAY = "\033[37m{}\033[00m" TRANSLATE_DICT = { "FILE_EMPTY": COLOR_RED.format("File {} is empty."), "FILE_NAME": COLOR_GRAY.format("Reading file: {}"), "FILE_OK": COLOR_GREEN.format("\tOK"), "FILE_TOTAL_LINES": COLOR_RED.format("\tTotal lines: {}"), "FILE_DUPLICATE_LINE": COLOR_RED.format("\tDuplicated itemVnum: {} at line: {}"), "FILE_COMPARING_LINE": COLOR_RED.format("\tMissing itemVnum: {}"), } for localeName, localeValue in TRANSLATE_DICT.items(): locals().update({localeName: localeValue}) ################################################# ## ProtoChecker ################################################# class ProtoChecker: ITEM_PROTO_FILE_NAME = 'item_proto.txt' ITEM_NAMES_FILE_NAME = 'item_names.txt' MOB_PROTO_FILE_NAME = 'mob_proto.txt' MOB_NAMES_FILE_NAME = 'mob_names.txt' def __init__(self): self.itemProtoDict = self.load_file(self.ITEM_PROTO_FILE_NAME) self.itemNamesDict = self.load_file(self.ITEM_NAMES_FILE_NAME) self.mobProtoDict = self.load_file(self.MOB_PROTO_FILE_NAME) self.mobNamesDict = self.load_file(self.MOB_NAMES_FILE_NAME) @staticmethod def load_file(fileName, token='\t'): fileExists = os.path.exists(fileName) if fileExists: if os.path.getsize(fileName) == 0: TraceFormat(FILE_EMPTY.format(fileName)) sys.exit(0) fileData = [] if fileExists: with open(fileName, 'r') as file: for line in file.readlines(): if token in line: line = line.split(token)[0] if line.isdigit(): fileData.append(line) return {'name': fileName, 'data': fileData, 'exists': fileExists} @staticmethod def find_duplicate(file): if not file["exists"]: return TraceFormat(FILE_NAME.format(file["name"])) duplicateSet = set([itemVnum for itemVnum in file["data"] if file["data"].count(itemVnum) > 1]) for itemVnum in duplicateSet: TraceFormat(FILE_DUPLICATE_LINE.format(itemVnum, len(file["data"]) - file["data"][-1::-1].index(itemVnum) + 2)) TraceFormat(FILE_TOTAL_LINES.format(duplicateSet.__len__()) if duplicateSet else FILE_OK) @staticmethod def compare(firstFile, secondFile): if not firstFile['exists'] or not secondFile['exists']: return TraceFormat(FILE_NAME.format(secondFile['name'])) differenceSet = set(firstFile['data']).difference(secondFile['data']) if not differenceSet: TraceFormat(FILE_OK) return for itemVnum in differenceSet: TraceFormat(FILE_COMPARING_LINE.format(itemVnum)) TraceFormat(FILE_TOTAL_LINES.format(differenceSet.__len__())) def run(self): TraceFormat("###### START_CHECKING_FOR_DUPLICATE ######") for file in (self.itemProtoDict, self.itemNamesDict, self.mobProtoDict, self.mobNamesDict): self.find_duplicate(file) TraceFormat("###### END_CHECKING_FOR_DUPLICATE ######\n") TraceFormat("###### START_COMPARING ######") for files in ((self.itemProtoDict, self.itemNamesDict), (self.mobProtoDict, self.mobNamesDict)): for firstFile, secondFile in zip(files, reversed(files)):, secondFile) TraceFormat("###### END_COMPARING ######") protoChecker = ProtoChecker()
  2. ### 0.1 Root / # 1. Search: def OnLogin(self, groupIndex ... # 1. After: member.Online() self.OnRefreshList() # 1. Add: if not name in constInfo.ALREADY_NOTIFY_LIST: self.onlinePopup = uiCommon.OnlinePopup() self.onlinePopup.SetUserName(name) self.onlinePopup.SetEvent(ui.__mem_func__(self.OpenWhisper), "MOUSE_LEFT_BUTTON_UP", name) self.onlinePopup.SlideIn() constInfo.ALREADY_NOTIFY_LIST.append(name) # 1.1 After: def OnLogin(... Add: def OpenWhisper(self, eventType, userName): self.whisperButtonEvent(userName) ### 0.2 Root / # 2. Add: ALREADY_NOTIFY_LIST = [] ### 0.3 Root / # 3 Search: class Board(Window): (....) # 3 REPLACE this class with: class Board(Window): CORNER_WIDTH = 32 CORNER_HEIGHT = 32 LINE_WIDTH = 128 LINE_HEIGHT = 128 LT = 0 LB = 1 RT = 2 RB = 3 L = 0 R = 1 T = 2 B = 3 BASE_PATH = "d:/ymir work/ui/pattern" IMAGES = { 'CORNER' : { 0 : "Board_Corner_LeftTop", 1 : "Board_Corner_LeftBottom", 2 : "Board_Corner_RightTop", 3 : "Board_Corner_RightBottom" }, 'BAR' : { 0 : "Board_Line_Left", 1 : "Board_Line_Right", 2 : "Board_Line_Top", 3 : "Board_Line_Bottom" }, 'FILL' : "Board_Base" } def __init__(self, layer = "UI"): Window.__init__(self, layer) self.skipMaxCheck = False self.MakeBoard() def MakeBoard(self): CornerFileNames = [ ] LineFileNames = [ ] for imageDictKey in (['CORNER', 'BAR']): for x in xrange(len(self.IMAGES[imageDictKey])): if imageDictKey == "CORNER": CornerFileNames.append("%s/%s.tga" % (self.BASE_PATH, self.IMAGES[imageDictKey][x])) elif imageDictKey == "BAR": LineFileNames.append("%s/%s.tga" % (self.BASE_PATH, self.IMAGES[imageDictKey][x])) self.Corners = [] for fileName in CornerFileNames: Corner = ExpandedImageBox() Corner.AddFlag("not_pick") Corner.LoadImage(fileName) Corner.SetParent(self) Corner.SetPosition(0, 0) Corner.Show() self.Corners.append(Corner) self.Lines = [] for fileName in LineFileNames: Line = ExpandedImageBox() Line.AddFlag("not_pick") Line.LoadImage(fileName) Line.SetParent(self) Line.SetPosition(0, 0) Line.Show() self.Lines.append(Line) self.Lines[self.L].SetPosition(0, self.CORNER_HEIGHT) self.Lines[self.T].SetPosition(self.CORNER_WIDTH, 0) self.Base = ExpandedImageBox() self.Base.AddFlag("not_pick") self.Base.LoadImage("%s/%s.tga" % (self.BASE_PATH, self.IMAGES['FILL'])) self.Base.SetParent(self) self.Base.SetPosition(self.CORNER_WIDTH, self.CORNER_HEIGHT) self.Base.Show() def __del__(self): Window.__del__(self) def SetSize(self, width, height): if not self.skipMaxCheck: width = max(self.CORNER_WIDTH*2, width) height = max(self.CORNER_HEIGHT*2, height) Window.SetSize(self, width, height) self.Corners[self.LB].SetPosition(0, height - self.CORNER_HEIGHT) self.Corners[self.RT].SetPosition(width - self.CORNER_WIDTH, 0) self.Corners[self.RB].SetPosition(width - self.CORNER_WIDTH, height - self.CORNER_HEIGHT) self.Lines[self.R].SetPosition(width - self.CORNER_WIDTH, self.CORNER_HEIGHT) self.Lines[self.B].SetPosition(self.CORNER_HEIGHT, height - self.CORNER_HEIGHT) verticalShowingPercentage = float((height - self.CORNER_HEIGHT*2) - self.LINE_HEIGHT) / self.LINE_HEIGHT horizontalShowingPercentage = float((width - self.CORNER_WIDTH*2) - self.LINE_WIDTH) / self.LINE_WIDTH self.Lines[self.L].SetRenderingRect(0, 0, 0, verticalShowingPercentage) self.Lines[self.R].SetRenderingRect(0, 0, 0, verticalShowingPercentage) self.Lines[self.T].SetRenderingRect(0, 0, horizontalShowingPercentage, 0) self.Lines[self.B].SetRenderingRect(0, 0, horizontalShowingPercentage, 0) if self.Base: self.Base.SetRenderingRect(0, 0, horizontalShowingPercentage, verticalShowingPercentage) # 3 AFTER CLASS BOARD ADD THIS CLASS: class BorderB(Board): CORNER_WIDTH = 16 CORNER_HEIGHT = 16 LINE_WIDTH = 16 LINE_HEIGHT = 16 BASE_PATH = "d:/ymir work/ui/pattern" IMAGES = { 'CORNER' : { 0 : "border_b_left_top", 1 : "border_b_left_bottom", 2 : "border_b_right_top", 3 : "border_b_right_bottom" }, 'BAR' : { 0 : "border_b_left", 1 : "border_b_right", 2 : "border_b_top", 3 : "border_b_bottom" }, 'FILL' : "border_b_center" } def __init__(self): Board.__init__(self) self.eventFunc = { "MOUSE_LEFT_BUTTON_UP" : None, } self.eventArgs = { "MOUSE_LEFT_BUTTON_UP" : None, } def __del__(self): Board.__del__(self) self.eventFunc = None self.eventArgs = None def SetSize(self, width, height): Board.SetSize(self, width, height) def SetEvent(self, func, *args) : result = self.eventFunc.has_key(args[0]) if result : self.eventFunc[args[0]] = func self.eventArgs[args[0]] = args else : print "[ERROR] SetEvent, Can`t Find has_key : %s" % args[0] def OnMouseLeftButtonUp(self): if self.eventFunc["MOUSE_LEFT_BUTTON_UP"] : apply(self.eventFunc["MOUSE_LEFT_BUTTON_UP"], self.eventArgs["MOUSE_LEFT_BUTTON_UP"]) ### 0.4 Root / # 4 Add this to the end of file: ### (Check if you have in this file import app ) class OnlinePopup(ui.BorderB): def __init__(self): ui.BorderB.__init__(self) self.isActiveSlide = False self.isActiveSlideOut = False self.endTime = 0 self.wndWidth = 0 self.textLine = ui.TextLine() self.textLine.SetParent(self) self.textLine.SetWindowHorizontalAlignCenter() self.textLine.SetWindowVerticalAlignCenter() self.textLine.SetHorizontalAlignCenter() self.textLine.SetVerticalAlignCenter() self.textLine.SetPosition(13, 0) self.textLine.Show() self.onlineImage = ui.ImageBox() self.onlineImage.SetParent(self) self.onlineImage.SetPosition(8, 8) self.onlineImage.LoadImage("d:/ymir work/ui/game/windows/messenger_list_online.sub") self.onlineImage.Show() def __del__(self): ui.BorderB.__del__(self) def SlideIn(self): self.SetTop() self.Show() self.isActiveSlide = True self.endTime = app.GetGlobalTimeStamp() + 5 def Close(self): self.Hide() def Destroy(self): self.Close() def SetUserName(self, name): self.textLine.SetText("Player %s is online." % str(name)) self.wndWidth = self.textLine.GetTextSize()[0] + 40 self.SetSize(self.wndWidth, 25) self.SetPosition(-self.wndWidth, wndMgr.GetScreenHeight() - 200) def OnUpdate(self): if self.isActiveSlide and self.isActiveSlide == True: x, y = self.GetLocalPosition() if x < 0: self.SetPosition(x + 4, y) if self.endTime - app.GetGlobalTimeStamp() <= 0 and self.isActiveSlideOut == False and self.isActiveSlide == True: self.isActiveSlide = False self.isActiveSlideOut = True if self.isActiveSlideOut and self.isActiveSlideOut == True: x, y = self.GetLocalPosition() if x > -(self.wndWidth): self.SetPosition(x - 4, y) if x <= -(self.wndWidth): self.isActiveSlideOut = False self.Close() ######## Please write in topic If i forgot something. ######## Images for board:!O1ZjmQxY!tKJdWNXRP6Wgb3DGxzdFRNV9U-bfRIStwnq3ETd6gKo
  3. Based idea: Doing the same thing, but here's my faster version coded in python, with source code, no executable. Read the informations from repository, how to use it. #! /usr/bin/env python2 __name__ = "Text-File-Clear-Special-Symbols" __author__ = "VegaS" __date__ = "2019-11-13" __version__ = "0.0.1" import sys import string import os.path if len(sys.argv) != 2: print("Drag the file that you want to fix to batch file.") sys.exit(0) class ClearSpecialSymbols: SUFFIX_NAME = "_fixed" def __init__(self, fileName): fileNameSplit = os.path.splitext(fileName) self.fileName = fileName self.fileNameFixed = fileNameSplit[0] + self.SUFFIX_NAME + fileNameSplit[1] self.fileStringsAllowed = set(string.printable) def run(self): if os.path.getsize(self.fileName) == 0: print('File "{}" is empty.'.format(self.fileName)) return file_data = [] with open(self.fileName, 'r') as file: for line in file.readlines(): if sys.version_info[0] < 3: file_data.append(filter(lambda x: x in self.fileStringsAllowed, line)) else: file_data.append(''.join(list(filter(lambda x: x in self.fileStringsAllowed, line)))) file.close() new_file = open(self.fileNameFixed, 'w') new_file.write(''.join(file_data)) new_file.close() print('File: "{}" successfully saved!'.format(self.fileNameFixed)) cls = ClearSpecialSymbols(sys.argv[1]) clearSpecialSymbols.bat python "" %* pause GitHub repository:
  4. Auto refine option when you upgrade the item with SCROLL or on NPC. I did all checks like example : When you have just one scroll in inventory, refine window will be close. When the item is already maximum upgrade. (+8 to +9 just in case will be succes) and more .. Preview: Download :!SZpDWBKB!EbBTPAThBjFZBuFCdvttRz5Yia4oYrAj5m4r0pNFe6U
  5. Before: After:
  6. Hello cowboys, since i was at job and i was bored while coding in other languages, i thought would be funny if i code something in Python, so an idea came in mind, doing a general text file loader for parsing different data, with different structs, normal variables, groups and lists, like ymir idea for parsing the files (.mse, .msa, .msm, .txt like mob_drop_item.txt, group.txt, etc) This tool can be used everywhere, for metin2 or else, i wrote this from scratch using ymir idea, also you can run it in any version of Python. If you use this for metin2, change USING_METIN2_CLIENT to True. benchmark.txt Full source repository:
  7. can you help me I added it If not this section, sorry and please move it Sorry ma english is bad
  8. Hello everyone, is my first release and it is something that many people already have, but for those who do not have it, I share it. Image: click here Then, let's start. root/ root/ root/ root/ locale_xx/locale/xx/ui/ locale_xx/locale/xx/locale_interface.txt uiscript ---> Create a new file with this name and paste this: One extra step: locale_xx/locale/xx/ui/ or uiscript/ or uiscript/ If you have this error: InventoryWindow.LoadWindow.BindObject - <type 'exceptions.AttributeError'>:'ImageBox' object has no attribute 'SetEvent' Then: open root/ If you do not have ENABLE_CHEQUE_SYSTEM and ENABLE_GEM_SYSTEM in your src client, then delete those parts of the code or open: UserInterface/PythonApplicationModule.cpp: I recommend putting this as long as you have cheque_system and gem_system (otherwise the interface is a little ugly) I hope it serves some people, greetings!!
  9. Hello guys! Another premium video for metin2dev members,please enjoy! Complete Python Bootcamp Go from zero to hero in Python 3 ~2.54GB
  10. You have the option of trying on items to see how they are, even though you do not have them. How To: 1. unpack root open 2. search for "def AddItemData" 3. add this above ## Noa ItemPreview def CanEquipPreview(self): race = player.GetRace() job = chr.RaceToJob(race) if not self.ANTI_FLAG_DICT.has_key(job): return FALSE if item.IsAntiFlag(self.ANTI_FLAG_DICT[job]): return FALSE sex = chr.RaceToSex(race) MALE = 1 FEMALE = 0 if item.IsAntiFlag(item.ITEM_ANTIFLAG_MALE) and sex == MALE: return FALSE if item.IsAntiFlag(item.ITEM_ANTIFLAG_FEMALE) and sex == FEMALE: return FALSE return TRUE def AddItemPreview(self, itemVnum): item.SelectItem(itemVnum) itemType = item.GetItemType() itemSubType = item.GetItemSubType() if itemType == item.ITEM_TYPE_WEAPON or item.ITEM_TYPE_ARMOR == itemType and itemSubType in [0]: ROOT_PATH = "d:/ymir work/ui/game/windows/" PreviewBtn = ui.Button() PreviewBtn.SetParent(self) PreviewBtn.SetUpVisual(ROOT_PATH+"btn_plus_up.sub") PreviewBtn.SetOverVisual(ROOT_PATH+"btn_plus_over.sub") PreviewBtn.SetDownVisual(ROOT_PATH+"btn_plus_down.sub") PreviewBtn.SetToolTipText("Anprobieren") PreviewBtn.SetPosition(2,2) PreviewBtn.Show() PreviewBtn.SetEvent(self.EquipPreview, itemType, itemVnum) self.childrenList.append(PreviewBtn) def EquipPreview(self, itemType,itemVnum): if itemType == 1: chr.SetWeapon(itemVnum) if 2 == itemType: chr.SetArmor(itemVnum) player.SetSingleDIKKeyState(app.DIK_UP, TRUE) player.SetSingleDIKKeyState(app.DIK_UP, FALSE) 4.Edit def AddItemData(self, itemVnum, metinSlot, attrSlot = 0): to def AddItemData(self, itemVnum, metinSlot, attrSlot = 0, hyper = None): 5.Search def AddItemData(self, itemVnum, metinSlot, attrSlot = 0, hyper = None): add this above ### Noa ItemPreview if hyper and self.CanEquipPreview(): self.AddItemPreview(itemVnum) 6.Search this ItemToolTip.OnUpdate(self) and add this above ## Noa self.AddItemData(itemVnum, metinSlot, attrSlot, hyper = 1) Have fun with this shit
  11. root/ import time def GetCurrentServerTime24H(cur_time_stamp=app.GetGlobalTimeStamp()): ''' Convert server timestamp to 24-hour. ''' hours = (cur_time_stamp / 60) / 60 % 24 minutes = (cur_time_stamp / 60) % 60 seconds = cur_time_stamp % 60 return "{:02}:{:02}:{:02}".format(hours, minutes, seconds) def GetCurrentServerTime12H(format_code='%H:%M:%S', format_code_12h='%I:%M:%S %p'): ''' Convert server timestamp to 12-hour AM/PM. ''' time_object = time.strptime(GetCurrentServerTime24H(), format_code) time_output = time.strftime(format_code_12h, time_object) return time_output How-To-Use: < import localeInfo self.timeTextLine.SetText(localeInfo.GetCurrentServerTime12H()) # 06:00:08 PM self.timeTextLine.SetText(localeInfo.GetCurrentServerTime12H()) # 04:30:56 AM self.timeTextLine.SetText(localeInfo.GetCurrentServerTime24H()) # 21:05:03
  12. I saw a guy who sells shit, so I decided to fuck 15 minutes of my life and time and do it free for you with my code shit because i write fast. Link download:!CYJVib4L!bziTs5iK-R8dznmtAbBt3E2y93xyuCV0gZLV1MHdlPs And here is part rest for how to add grade:
  13. Hi this is timer for python. Like queue in gamesource.
  14. martysama0134

    [How-To] Metin2 & Cython

    Intro This release will explain how to "convert" your root .py files to .c ones. Actually, Cython only converts those files to pure CPython code. Download NOTE: ALL THE FILES HAVE BEEN MOVED TO HOW-TO-CYTHON-MT2. EDIT: As requested by many people, you can download the compatible and clean official cn root dated 20131228-0034 without further edits: rootCn_20131228-0034_edit.raruiscriptCn_20131228-0034.rarcN-serverinfo-edit.pyIs Cython really worth it?ProsAll the modules are compiled, and they can't be "extracted as .py" anymore.We can always disassemble the launcher with IDA, but the result will be pseudo-c code after waiting 6-8h of analyzing. Since we're not using .pyx files but directly .py ones, there's no "so much optimization".At least, 10% of performance increasing is guaranteed. ConsFor testing purposes, it's heavy to maintain. Everytime you try to re-compile your root files, you should wait 5-10 minutes.You can always use the uncythonized root (.py files) when you perform tests, and compile cython whenever you will make an update in your live server. The launcher's size will increase ~10mb. You can actually pack it to save space.If you directly use a .pyd (still 10mb), the launcher's size won't increase. VideoTutorial Credits Me (lollo_9_1/martysama0134)Night (OST suggestion)Random TestersWhat's New:v2.0The module's name check is now case-insensitive (colorInfo == colorinfo)Added a new function rootlib/uiscriptlib.getList() to retrieve a tuple of all the available cythonized modules.Now you can compile a uiscriptlib library from the uiscript*.py files! (implemented as __USE_EXTRA_CYTHON__)Added a sample containing the code to run uiscriptlib.
  15. Github repository:
  16. I added two years ago a small function that allow you to make a struct like C++ for different purposes. # Example #1 pack = ui.RegisterStructClass('a b c')(15, {}, []) pack.a += 50 pack.b.update({0: 250}) pack.c.append(100) print (pack.a, pack.b, pack.c) # Example #2. def Transfer(self, p): print(p.szName, p.lX, p.lY) self.Transfer(ui.RegisterStructClass('szName lX lY')(GetName(), GetX(), GetY())) # Example #3. config = ui.RegisterStructClass('width height default_size_dict rank_list text')(450, 300, {'w': 400, 'h': 500}, [1, 2, 3], 'Metin2') print ( config.width, config.height, config.text, config.default_size_dict.get('w'), config.default_size_dict.get('h'), config.rank_list ) Repository:
  17. I wrote this small tool in python to manage easly the server source in a unique script to run. The tool is written in Python 2.7 but it should works fine with next version. Basically, the tool can help you to build/touch/strip without navigate in the differents paths. The tool can perform: -Build: build game/db build game/db with clean build game&db (consecutively) build game&db with clean -Touch (which dont' create new file when is used with a wrong name): perform Touch of one or more files in game/src (by inserting the names separated with a space) perform Touch of one or more files in db/src (by inserting the names separated with a space) -Strip: Strip game (by copying it) Strip db (--same) Additional features: - the tool find if a file is edited $val seconds in the future (eg. if you have set a wrong date in your compiler) and it will touch the file automatically. - the tool is written in procedural python (no OOP) so you should read easly it even if you are not an expert with python. - You can run more than one commands in sequence by separating them with one of these character : ("&&","&","|"," ",'\t',"-",',') (es. : 1&9 -> build game and strip game) - the tool can get command-line arguments to perform what you need (you could take a look under to know the command you can pass) to-know: - To run a script in python in the compiler you need to have installed Python (i recommend python27 which i can guarantee it will works). If you haven't installed python you can do it by using pkg manager (pkg install pyhon27) or ports (cd /usr/ports/lang/python27 && make config-recursive && make install clean) - If you get some problem with the script you can post a comment in this thread to know the solution, anyway it should works perfectly with martysama source (most commonly used). - To run the script you should give 7XX octal permission. - To run the script you need to go at the same path where is the script and to use "./" to run it. - If you are creating the scriptfile using notepad++ (or some external editor) is possible to have a problem about the EOL character (you have to set it on "Unix EOL"). - You have way to enable/disable the question "exit?" when the build fail - To run the script you should put it on "Server" folder, when you can find game, db, common, etc. For any kind of problems i recommend you to write a comment in this thread (instead of pm) because another user could get same problem and find here the solution. i hope it would be usefull. byebye COMMANDLINE ARGUMENTS SCRIPT
  18. .ZeNu

    M2 - Memo Trio Monster
  19. Hi DEVs My combo support skill is not working (other support skills are working fine [I mean skill level]). I can set it to 1/2 via command, support skill points or combo skill books - I just cannot turn it on/off from characterwindow (CANNOT_SKILL_NOT_YET_LEARN) - on skill icon there's no skill level (0 (empty), 1/2 [or like on leadership 0-19/m1-10/g1-10/P]) Console command [python] (setcombotype 0/1/2) is working Other players can see my combo syslog from channel and DB Sep 2 22:11:18 :: COMMAND: Nirray2: setskill Sep 2 22:11:20 :: COMMAND: Nirray2: skillup Sep 2 22:11:20 :: SkillUp: Nirray2 122 0 1[Before:0] type 0 Sep 2 22:11:20 :: COMMAND: Nirray2: skillup Sep 2 22:11:20 :: SkillUp: Nirray2 122 0 2[Before:1] type 0 Sep 2 22:11:20 :: COMMAND: Nirray2: skillup Sep 2 22:11:20 :: SAVE: Nirray2 966460x276822 Sep 2 22:11:20 :: COMMAND: Nirray2: skillup (Which means server side is working and skill index+skill level are set correctly [I can logout character/shutdown server and the combo level is still here]) No clientside syserr. Python part bug? Client source bug? Any ideas? I can't figure it out Thanks
  20. Hey everyone, it's a nice day to share something I just wrote Grid class in python language. You can use it as fast moving into the window with this or something else. Usage: from grid import Grid import item import chat grid = Grid(width=5, height=9) item.SelectItem(11299) (width, height) = item.GetItemSize() available_position = grid.find_blank(width, height) if available_position == -1: chat.AppendChat(chat.CHAT_TYPE_INFO, "There is no available position.") return chat.AppendChat(chat.CHAT_TYPE_INFO, "Available position is %d" % (available_position)) Best Regards Ken
  21. Hellow, I want to share my work, I've created 2 year ago, for my old server (Resthea). So, what is it exacly? It's python libraries and code that allow us to have many environment (clouds, light settings, flare and so on) on one map. By default, you can have only one environment for each map. How does it work? Well, once every 30 seconds (you can configure that time) checks our coordinates and compare it to jpg file, which size is the same as map size. Diffrent colors mean diffrent msenv file. What this pack contains? possibility to add up to 16777215 areas with diffrent environment on every map. possibility to add diffrent music on these areas possibility to add random snow on these areas 28 ready skyboxes possibility to choose skyboxes quality possibility to configure the time script refreshes possibility to add special xmas configuration easy configuration via text file code is easy to modify bugfix for night and snow systems Disadvantages: not so optimal solution .jpg format has indirect coloring between two colors, which sometimes could lead to problems xmas song probably doesn't work (I haven't got time to fix it) lots of redundant libraries, because i've uploaded whole Lib folder descriptions how to add this are in polish, you can use google translate , if you wish i can translate it too. Screens: Code sample: def __SpecialEnvironmentEnable(self, Env, Resthea, SnowEnable, NightEnable, ConfigTime, ConfigSkybox, XmasEvent): ### START OF ENVIRONMENT MODULE, qentinios self.Env = Env self.Resthea = Resthea self.SnowEnable = SnowEnable self.NightEnable = NightEnable self.ConfigTime = ConfigTime self.ConfigSkybox = ConfigSkybox self.XmasEvent = XmasEvent czass = str(time.ctime()) sekundy = czass[17:19] bg = background.GetCurrentMapName() if ConfigTime == 0: try: ConfigTime = int(linecache.getline("config.cfg", 2)) except: chat.AppendChat(chat.CHAT_TYPE_INFO, "Error while changing environment") chat.AppendChat(chat.CHAT_TYPE_INFO, "Cannot open file: config.cfg") if ConfigTime == -1: return map = ( "metin2_map_4_wiatry", "metin2_map_krance_swiata", "metin2_map_srodziemie", "metin2_map_resthea", ) if bg in map and sekundy != Env: if ConfigTime == 5 and int(sekundy) in (5,10,15,20,25,30,35,40,45,50,55,00): self.Env = sekundy pass elif ConfigTime == 15 and int(sekundy) in (15,30,45,00): self.Env = sekundy pass elif ConfigTime == 30 and int(sekundy) in (30,00): self.Env = sekundy pass elif ConfigTime == 60 and int(sekundy) == 30: pass else: if ConfigTime not in (-1,5,15,30,60) and int(sekundy) == 30: chat.AppendChat(chat.CHAT_TYPE_INFO, "Error while changing environment") chat.AppendChat(chat.CHAT_TYPE_INFO, "Wrong data: " + ConfigTime + ", config.cfg, line 2") self.Env = sekundy return else: return minuty = czass[14:16] godziny = czass[11:13] czas = int(godziny + minuty) try: im ="msenv/" + bg + ".jpg") except: chat.AppendChat(chat.CHAT_TYPE_INFO, "Error while changing environment") chat.AppendChat(chat.CHAT_TYPE_INFO, "Cannot open file: " + "msenv/" + bg + ".jpg") return (x, y, z) = player.GetMainCharacterPosition() x = int(x/100) y = int(y/100) try: color = str(im.getpixel((int(x),int(y)))) except: chat.AppendChat(chat.CHAT_TYPE_INFO, "Error while changing environment") chat.AppendChat(chat.CHAT_TYPE_INFO, "Not exist pixel: " + str(x) + ", " + str(y) + "; " + "msenv/" + bg + ".jpg") return #Skybox config if ConfigSkybox == "0": try: ConfigSkybox = linecache.getline("config.cfg", 5) except: ConfigSkybox = "_1k" if ConfigSkybox in ("_512n","_1kn","_1.5kn"): ConfigSkybox = ConfigSkybox[:-1] if ConfigSkybox not in ("_512","_1k","_1.5k"): ConfigSkybox = "_1k" #End of skybox config #Xmas event if XmasEvent == -1: try: XmasEvent = int(linecache.getline("config.cfg", 8)) except: XmasEvent = 0 if XmasEvent == 1: ColorList={ #Color (RGB) 1 : ("(255, 255, 255)", "(241, 255, 158)", "(254, 0, 0)", "(0, 255, 127)", "(158, 255, 248)", "(253, 254, 62)", "(255, 176, 63)", "(222, 255, 0)", "(95, 255, 0)", "(50, 121, 19)", "(95, 192, 35)", "(214, 214, 214)", "(148, 0, 0)", "(142, 142, 142)", "(251, 165, 0)"), #Msenv 2 : ("snowm02", "map_n_desert_01", "fire_low", "white_sky", "default", "rainy", "sand_mountain", "vanilia_white", "trent", "trent02", "vanilia", "snowm02", "fire_low", "default", "desert_cloud"), #Mp3 3 : ("christmas/4w/xmas", "christmas/4w/xmas", "christmas/4w/xmas", "christmas/4w/xmas", "christmas/4w/xmas", "christmas/krance/xmas", "christmas/krance/xmas", "christmas/krance/xmas", "christmas/krance/xmas", "christmas/krance/xmas", "christmas/srodziemie/xmas", "christmas/srodziemie/xmas", "christmas/srodziemie/xmas", "christmas/resthea/xmas", "christmas/resthea/xmas_wyspa"), #Snow 4 : (1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1) } #End of Xmas event else: ColorList={ #Color (RGB) 1 : ("(255, 255, 255)", "(241, 255, 158)", "(254, 0, 0)", "(0, 255, 127)", "(158, 255, 248)", "(253, 254, 62)", "(255, 176, 63)", "(222, 255, 0)", "(95, 255, 0)", "(50, 121, 19)", "(95, 192, 35)", "(214, 214, 214)", "(148, 0, 0)", "(142, 142, 142)", "(251, 165, 0)"), #Msenv 2 : ("snowm02", "map_n_desert_01", "fire_low", "white_sky", "default", "rainy", "sand_mountain", "vanilia_white", "trent", "trent02", "vanilia", "snowm02", "fire_low", "default", "desert_cloud"), #Mp3 3 : ("4w/lodowa", "4w/pustynia", "4w/ognista", "4w/orki", "4w/srodek", "krance/przeklete", "krance/pustynia", "krance/swiatynia", "krance/las", "krance/las2", "srodziemie/trawa", "srodziemie/lodowa", "srodziemie/ognista", "resthea/trawa", "resthea/wyspa"), #Snow 4 : (1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0) } i = 0 Colors = ColorList[1] length = len(Colors) for ColorItem in xrange(length): if color == Colors[ColorItem]: #START OF SNOW EFFECT Snow = ColorList[4] if SnowEnable != 1: if Snow[ColorItem] == 1 and int(minuty) in (2,7,12,17,22,27,32,37,42,47,52,57) and int(sekundy) in (00,01,30,31): random = app.GetRandom(1,3) if random == 1: background.EnableSnow(1) else: background.EnableSnow(0) if Snow[ColorItem] == 0: background.EnableSnow(0) #END OF SNOW EFFECT if Resthea == color: break #START OF MUSIC MODULE Music = ColorList[3] if app.IsExistFile("BGM/" + Music[ColorItem] + ".mp3")==1: if musicInfo.fieldMusic != "": snd.FadeOutMusic("BGM/" + musicInfo.fieldMusic) musicInfo.fieldMusic = (Music[ColorItem] + ".mp3") snd.FadeInMusic("BGM/" + musicInfo.fieldMusic) else: if musicInfo.fieldMusic != "": snd.FadeOutMusic("BGM/" + musicInfo.fieldMusic) musicInfo.fieldMusic=musicInfo.METIN2THEMA snd.FadeInMusic("BGM/" + musicInfo.fieldMusic) #END OF MUSIC MODULE Msenv = ColorList[2] if NightEnable == 1 and self.__IsXMasMap(): background.RegisterEnvironmentData(1, constInfo.ENVIRONMENT_NIGHT) background.SetEnvironmentData(1) else: background.RegisterEnvironmentData(1, "d:/ymir work/environment/" + Msenv[ColorItem] + ConfigSkybox + ".msenv") background.SetEnvironmentData(1) self.Resthea = color break else: i = i+1 if i == length: background.SetEnvironmentData(0) snd.FadeOutMusic("BGM/" + musicInfo.fieldMusic) musicInfo.fieldMusic=musicInfo.METIN2THEMA snd.FadeInMusic("BGM/" + musicInfo.fieldMusic) self.Resthea = color ### END OF ENVIRONMENT MODULE, qentinios Old video with system: Download: Without skyboxes: With skyboxes:
  22. Hello, there is a common error/bug in Metin2 related to the taskbar and character skill window. This error occurs when the skill has the status of "TOGGLE" and somebody or something killed us. When we are killed the game client still thinks that the skill is active somehow not updating its status (right clicking on slot causes the packet to be sent to the server again). What's even more funny, when we kill our character by command or when we've been shot down at once this problem does not occur Here are some screenshots explaining the bug: If you are interested in fixing this error, please follow the instructions below: Clientside: Open UserInterface/PythonPlayerModule.cpp and search: { "ClearSkillDict", playerClearSkillDict, METH_VARARGS }, add below: { "DisableToggleSkill", playerDisableToggleSkill, METH_VARARGS }, scroll down and search for: PyObject * playerClearSkillDict(PyObject * poSelf, PyObject * poArgs) add under: PyObject * playerDisableToggleSkill(PyObject * poSelf, PyObject * poArgs) { int iSlotIndex; if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex)) return Py_BadArgument(); CPythonPlayer::Instance().Disable_Toggle_Skill(iSlotIndex); return Py_BuildNone(); } Now move on to the UserInterface/PythonPlayer.cpp and search for: void CPythonPlayer::ClearSkillDict() add below: void CPythonPlayer::Disable_Toggle_Skill(DWORD dwSlotIndex) { CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); if (!pkInstMain) return; if (!pkInstMain->IsDead()) return; if (dwSlotIndex >= SKILL_MAX_NUM) return; for (dwSlotIndex; dwSlotIndex <= SKILL_MAX_NUM; ++dwSlotIndex) { if (IsSkillActive(dwSlotIndex)) { m_playerStatus.aSkill[dwSlotIndex].bActive = FALSE; PyCallClassMemberFunc(m_ppyGameWindow, "DeactivateSkillSlot", Py_BuildValue("(i)", dwSlotIndex)); } } } after that UserInterface/PythonPlayer.h search: void ClearSkillDict(); // ľřľîÁö°ĹłŞ ClearGame ÂĘŔ¸·Î Ć÷Ç﵃ ÇÔĽö add: void Disable_Toggle_Skill(DWORD dwSlotIndex); UserInterface/PythonPlayerSkill.cpp Search: void CPythonPlayer::ClickSkillSlot(DWORD dwSlotIndex) and under: if (pSkillData->IsStandingSkill()) { if (pSkillData->IsToggleSkill()) { if (IsSkillActive(dwSlotIndex)) { CInstanceBase * pkInstMain = NEW_GetMainActorPtr(); if (!pkInstMain) return; if (pkInstMain->IsUsingSkill()) return; add new if statement: if (pkInstMain->IsDead()) return; like that: Rebuild solution. Python part: root/ Search in OnUpdate(self): if app.GetGlobalTime() - self.lastUpdateQuickSlot > 500: add at the end: player.DisableToggleSkill(0) Thanks to @filipw1 idea there's no need to use python part anymore. Back to client source: UserInterface/PythonPlayer.cpp: search: void CPythonPlayer::NotifyDeadMainCharacter() and change void to this: void CPythonPlayer::NotifyDeadMainCharacter() { __ClearAutoAttackTargetActorID(); Disable_Toggle_Skill(0); } Rebuild solution. If you want to execute it from python script: player.DisableToggleSkill(skill_startIndex) Final result: This is my way to solve this graphic problem. All suggestions are welcome. Have a nice day
  23. Hello everybody How can I put all the players in the same empire as your enemies for you Like player other empires His name becomes such a picture even if it is from the same empire
  24. Hey wazzup guys & girls! I'm looking to find out how could I run a .py file (script) in the current Metin2 [GF] client (version 19.4). The first problem I encountered was the fact that I can't unpack/repack the root of the client, if I could do that it would be easy to run my .py script inside the game, obviously. If you don't know how to do this or can't point me in a direction to solve this problem -> then do you know other ways to load a .py script into the current [GF] client ? The script I intend to run (build) and use on the current [GF] client is basically an account checker. I already managed to code a C# website-based checker and I also want to get into and learn how to build a client-side checker but first I need a way to inject the script into the game. Any ideas ? I've got a video VegaS posted a long time ago on YouTube, just to get an idea of what this thing (script ) would look like once I manage to run it inside the client successfully.
  25. morfhere

    python Hi please help me

    Code: error:global name 'vnum' is not defined sorry my english is bad