Jump to content

Ikarus_

Developer
  • Posts

    404
  • Joined

  • Last visited

  • Days Won

    20
  • Feedback

    0%

Posts posted by Ikarus_

  1. 3 hours ago, sheinfeld said:

    It doesnt work, "undefined reference to `CHARACTER::GetMostAttacked()'"

    you didn't installed correctly

     

     

    2 hours ago, WeedHex said:

    So ugly with define. 

    If you rly want macro, define in main file cuz you use just one time.

    void CHARACTER::Reward(bool bItemDrop) Function is default shitty.

    The macro defines are usefull to find the code interesting a fix/implementation and to take trace of the changes made 

    • Love 1
  2. small code to apply to fix the problem of not starting the kill event (lua) after killing a monster that has set 0 as exp in his mob_proto.

     

    Spoiler

    service.h or CommonDefines.h

    
    #define __ENABLE_KILL_EVENT_FIX__ //if you want to fix the 0 exp problem about the when kill lua event (recommended)

     

    char.h

    // search 

    
            void            DistributeHP(LPCHARACTER pkKiller);
            void            DistributeSP(LPCHARACTER pkKiller, int iMethod=0);

    // add under

    
    #ifdef __ENABLE_KILL_EVENT_FIX__
            LPCHARACTER        GetMostAttacked();
    #endif


    char_battle.cpp

     

    // search:

    
    void CHARACTER::Reward(bool bItemDrop)
    {
        if (GetRaceNum() == 5001) 
        {
            PIXEL_POSITION pos;
    
            if (!SECTREE_MANAGER::instance().GetMovablePosition(GetMapIndex(), GetX(), GetY(), pos))
                return;
    
            LPITEM item;
            int iGold = number(GetMobTable().dwGoldMin, GetMobTable().dwGoldMax);
            iGold = iGold * CHARACTER_MANAGER::instance().GetMobGoldAmountRate(NULL) / 100;
            iGold *= GetGoldMultipler();
            int iSplitCount = number(25, 35);
    
            sys_log(0, "WAEGU Dead gold %d split %d", iGold, iSplitCount);
    
            for (int i = 1; i <= iSplitCount; ++i)
            {
                if ((item = ITEM_MANAGER::instance().CreateItem(1, iGold / iSplitCount)))
                {
                    if (i != 0)
                    {
                        pos.x = number(-7, 7) * 20;
                        pos.y = number(-7, 7) * 20;
    
                        pos.x += GetX();
                        pos.y += GetY();
                    }
    
                    item->AddToGround(GetMapIndex(), pos);
                    item->StartDestroyEvent();
                }
            }
            return;
        }
    
        //PROF_UNIT puReward("Reward");
           LPCHARACTER pkAttacker = DistributeExp();

    // replace

    
        if (!pkAttacker)
            return;

    // with this

    
    #ifdef __ENABLE_KILL_EVENT_FIX__
        if (!pkAttacker && !(pkAttacker = GetMostAttacked()))
            return;
    #else
        if (!pkAttacker)
            return;
    #endif

     

    // search :

    
    LPCHARACTER CHARACTER::DistributeExp()


    //* put BEFORE THIS   -> WARNING BEFORE AND NOT UNDER
    //* put BEFORE THIS   -> WARNING BEFORE AND NOT UNDER
    //* put BEFORE THIS   -> WARNING BEFORE AND NOT UNDER
    //* put BEFORE THIS   -> WARNING BEFORE AND NOT UNDER
    //* put BEFORE THIS   -> WARNING BEFORE AND NOT UNDER
    //* put BEFORE THIS   -> WARNING BEFORE AND NOT UNDER
    //* put BEFORE THIS   -> WARNING BEFORE AND NOT UNDER

    
    #ifdef __ENABLE_KILL_EVENT_FIX__
    LPCHARACTER CHARACTER::GetMostAttacked() {
    
        int iMostDam=-1;
        LPCHARACTER pkChrMostAttacked = NULL;
        auto it = m_map_kDamage.begin();
    
        while (it != m_map_kDamage.end()){
            //* getting information from the iterator
            const VID & c_VID = it->first;
            const int iDam    = it->second.iTotalDamage;
    
            //* increasing the iterator
            ++it;
    
            //* finding the character from his vid
            LPCHARACTER pAttacker = CHARACTER_MANAGER::instance().Find(c_VID);
    
            //* if the attacked is now offline
            if (!pAttacker)
                continue;
            
            //* if the attacker is not a player
            if( pAttacker->IsNPC())
                continue;
            
            //* if the player is too far
            if(DISTANCE_APPROX(GetX()-pAttacker->GetX(), GetY()-pAttacker->GetY())>5000)
                continue;
    
            if (iDam > iMostDam){
                pkChrMostAttacked = pAttacker;
                iMostDam = iDam;
            }
        }
    
        return pkChrMostAttacked;
    }
    #endif


     

     

    This is the hidden content, please

    bye bye

    source : me

    • Metin2 Dev 18
    • Confused 1
    • Good 5
    • Love 5
  3. On 9/12/2019 at 12:06 AM, zeimpekis9 said:

    Hello community,

    I have in sysuser and syslog

    buffer_read_proceed: buffer_proceed: length argument bigger than buffer (length: 1, buffer: 0)

    no have core crash .core

    when character login, is locked dont send msg,open npc etc..

     

     I AM PAYING FOR THIS FIX.

    Dynamic packet whichsend wrong packet.wSize

    You can apply a debug in the packets exchange function to know which packets send are good recv.

    the functions to debug are:

    Server side:

    CHARACTER::Packet

    CInputMain::Analyze

    CInputLogin::Analyze

     

    using sys_log(0, fmt...);



    Client side:
    NetworkStream::Send
    NetworkStream::Recv

    CPythonNetworkStream::GamePhase
    CPythonNetworkStream::LoginPhase

     

    using Tracenf if you know how to build in debug or TraceError otherwise

  4. M2 Download Center

    This is the hidden content, please
    ( Internal )

    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 "./scriptname.py" 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

    Spoiler

    --build-game
    --build-db
    --build-game-clean
    --build-db-clean
    --build-all
    --build-all-clean
    --touch-file-gamesrc
    --touch-file-dbsrc
    --strip-game
    --strip-db
    --strip-all

     

     

    SCRIPT

    Spoiler
    
    
    #!/usr/local/bin/python2.7
    import os
    import time
    import sys
    
    ENABLE_ASK_BEFORE_EXIT = False
    ENABLE_AUTOTOUCH = True
    
    def get_revision_filename(file):
    	if os.path.isfile("__REVISION__"):
    		line = open("__REVISION__","r").readline()
    		return file + "_r" + line.strip()
    
    	else:
    		return file
    
    
    
    def check_last_edit(path):
    	def check_last_edit_single_file(file):
    		nowtime = time.time()
    		lastedit = os.path.getmtime(file)
    		if nowtime < lastedit:
    			if ENABLE_AUTOTOUCH:
    				touch_file("" , file)
    				return
    			ans = ""
    			while ans == "":
    				print("file [%s] has modified %s seconds in future. do you want to touch it or to change date?\nchoose:(touch/date/n)"%(file , int(lastedit-nowtime)))
    				ans = raw_input().strip()
    		 
    				if ans == 'n':
    					break
    		 
    				if ans == 'touch':
    					touch_file("" , file)
    		 
    				elif ans == 'date':
    					print("enter date (YYYYMMDDHHMM):")
    					mydate = raw_input().strip()
    			 
    					res = os.system("date %s"%mydate)
    			 
    					if not res in (0,512):
    						print("cannot set datetime. try another option.")
    						ans = ""
    						continue
    			 
    					nowtime = time.time()
    		 
    				else:
    					print("unknown answer [%s]"%ans)
    					ans = ""
    
    	#end of single file
    	if path[-4:] != '/src' and path[-4:] != '\\src':
    		path += "/src"
    
    	common = "common"
    
    	files = [path+"/"+file for file in os.listdir(path) if os.path.isfile(path+"/"+file)]
    	files += [common+"/"+file for file in os.listdir(common) if os.path.isfile(common+"/"+file)]
    
    
    
    	for file in files:
    		check_last_edit_single_file(file)
    
    
    def ask_if_exit():
    	if not ENABLE_ASK_BEFORE_EXIT:
    		print("exit!")
    		sys.exit()
    
    
    	print("do you want to stop the script operations?y/n\n")
    
    	ans = ""
    	while ans == "":
    		ans = raw_input().strip()
    		if ans == 'y':
    			sys.exit()
    			return
     
    		elif ans == 'n':
    			return
     
    		else:
    			print("unknow answer [%s] , try again"%(ans))
    			print("do you want to stop the script operations?y/n\n(press just 'y' or 'n')\n")
    			ans = ""
    
    
    def close():
    	print("bye bye")
    	sys.exit()
    
    def run_os_command(cmd):
    	try:
    		res = os.system(cmd)
    		if res:
    			print("cannot run os command [%s] error %s"%(cmd,str(res)))
    			ask_if_exit()
    			return False
    	except Exception ,e:
    		print("an exception during run os command [%s] exception[%s]"%(cmd,str(e)))
    		ask_if_exit()
    		return False
    
    	return True
    
    def strip_file(file):
    	stripfile = file+"_s"
    	sourcefile= get_revision_filename(file)
    
    	if not os.path.isfile(file+"/"+sourcefile):
    		print("cannot find source file [%s]"%(file+"/"+sourcefile))
    		ans=""
     
    		while ans == "":
    			print("do you want to build it?y/n")
    			ans = raw_input().strip()
    			if ans == 'y':
    				build_file(file)
    				strip_file(file)
    				return
    	 
    			if ans == 'n':
    				return
    	 
    			else:
    				print("unknown answer [%s] try again."%ans)
    				ans = ""
    		return
    
    	if os.path.isfile("%s/%s"%(file,stripfile)):
    		os.remove("%s/%s"%(file,stripfile))
    
    	if not run_os_command("cp %s/%s %s/%s"%(file,sourcefile, file , stripfile)):
    		return
    
    	run_os_command("strip -s %s/%s"%(file,stripfile))
    
    def strip_db():
    	strip_file("db")
    
    def strip_game():
    	strip_file("game")
    
    def strip_all():
    	strip_db()
    	strip_game()
    
    def touch_file(dir , files = ""):
    	if len(dir)>0 and dir[-1] != '\\' and dir[-1] != '/':
    		dir += "/"
    
    	if files != "":
    		files = files.split(" ")
    		for file in files:
    			if not os.path.isfile(dir+file):
    				print("cannot find the file required [%s]."%file)
    				continue
    	 
    			else:
    				if not run_os_command("touch %s"%(dir + file)):
    					print("cannot find the file required [%s]."%file)
    					continue
    		 
    				else:
    					print("touched %s"%file)
    	else:
    		print("the path [%s] will automatically added to the file path\nyou can use a space to separate the names to touch more one file"%(dir))
    		ans = ""
    		while ans == "":
    			print("enter the names of the files (exit to exit):")
    			ans = raw_input().strip()
    	 
    			if ans == 'exit':
    				print("You didn't touch any file.")
    				ask_if_exit()
    				return
    	 
    			files = ans.split(' ')
    	 
    			for file in files:
    				if not os.path.isfile(dir+file):
    					print("cannot find the file required [%s]."%file)
    					if len(files) == 1:
    						ans = ""
    					continue
    		 
    				else:
    					if not run_os_command("touch %s"%(dir + file)):
    						print("cannot find the file required [%s]."%file)
    						if len(files) == 1:
    							ans = ""
    						continue
    			 
    					else:
    						print("touched %s"%file)
    
    
    def touch_in_db_src():
    	touch_file("db/src")
    
    def touch_in_game_src():
    	touch_file("game/src")
    
    
    
    def build_all():
    	build_game()
    	build_db()
    
    def build_all_clean():
    	build_game_clean()
    	build_db_clean()
    
    
    def build_file(file):
    	check_last_edit(file)
    	cmd = "cd %s/src && gmake && cd ../../"%file
    	if not run_os_command(cmd):
    		return
    
    	output=get_revision_filename("%s/%s"%(file,file))
    	if os.path.isfile(output):
    		print("build %s successful."%output)
    
    	else:
    		print("cannot build file %s."%output)
    		ask_if_exit()
    
    
    def build_game():
    	build_file("game")
    
    def build_db():
    	build_file("db")
    
    
    def clean_build(file):
    	return run_os_command("cd %s/src && gmake clean && cd ../../"%file) == True
    
    
    def build_clean(file):
    	if not clean_build(file):
    		ask_if_exit()
    
    	else:
    		print("%s cleaned"%file)
    
    	build_file(file)
    
    
    def build_db_clean():
    	build_clean("db")
    
    
    def build_game_clean():
    	build_clean("game")
    
    
    
    EVENTS = {
    	1: {
    		"name" : "BUILD GAME",
    		"event": build_game,
    		"cmd" : "--build-game",
    	},
    
    	2: {
    		"name" : "BUILD DB",
    		"event": build_db,
    		"cmd" : "--build-db",
    	},
    
    	3: {
    		"name" : "BUILD GAME CLEAN",
    		"event": build_game_clean,
    		"cmd" : "--build-game-clean",
    	},
    
    	4: {
    		"name" : "BUILD DB CLEAN",
    		"event": build_db_clean,
    		"cmd" : "--build-db-clean",
    	},
    
    	5:{
    		"name" : "BUILD ALL",
    		"event": build_all,
    		"cmd" : "--build-all",
    	},
    
    	6: {
    		"name" : "BUILD ALL CLEAN",
    		"event": build_all_clean,
    		"cmd" : "--build-all-clean",
    	},
    
    	7: {
    		"name" : "TOUCH FILE IN game/src",
    		"event": touch_in_game_src,
    		"cmd" : "--touch-file-gamesrc",
    	},
    
    	8: {
    		"name" : "TOUCH FILE db/src",
    		"event": touch_in_db_src,
    		"cmd" : "--touch-file-dbsrc",
    	},
    
    	9:{
    		"name" : "STRIP GAME",
    		"event": strip_game,
    		"cmd" : "--strip-game",
    	},
    
    	10:{
    		"name" : "STRIP DB",
    		"event": strip_db,
    		"cmd" : "--strip-db",
    	},
    
    	11:{
    		"name" : "STRIP ALL",
    		"event": strip_all,
    		"cmd" : "--strip-all",
    	},
    
    	0:{
    		"name" : "CLOSE",
    		"event": close,
    		"cmd" : "--close",
    	},
    }
    
    
    
    def print_commandlist():
    	print("What do you want to do?\n")
    	toprint = [ (EVENTS[key]["name"],str(key)) for key in EVENTS]
    
    	for thing in toprint: print("%s.\t%s"%(thing[1],thing[0]))
    
    
    def do_cmd(cmd):
    	key = int(cmd)
    	if not key in EVENTS:
    		print("Unknown command [%d] (ignored)\n")
    		return
    
    	print("executing [%s]..."%(EVENTS[key]["name"]))
    	event = EVENTS[key]["event"]
    	event()
    
    
    def is_right_ans(ans):
    	andchar = ("&&","&","|"," ",'\t',"-",',')
    	return len([char for char in ans if not char in andchar and not char.isdigit()]) == 0
    
    
    
    def do_commands(cmdstr):
    	andchar = ("&&","&","|"," ",'\t',"-",',')
    	cmdlist = [cmdstr]
    	tmp = []
    
    	for char in andchar:
    		for cmd in cmdlist:
    			tmp = list(cmdlist)
    			cmdlist = []
    	 
    			for part in tmp:
    				cmdlist+= part.split(char)
    
    	wrong = [cmd for cmd in cmdlist if not cmd.isdigit()]
    	if len(wrong) != 0:
    		print("found wrong command/commands [%s] (ignored)."%str(wrong))
    
    	for cmd in cmdlist:
    		if cmd in wrong:
    			continue
     
    		do_cmd(cmd)
    
    def main():
    	if len(sys.argv) > 1:
    		cmdargs = [ (EVENTS[key]["cmd"] , key) for key in EVENTS]
    	 
    		listofargs = [value["cmd"] for value in EVENTS.values()]
    		wrongargs = [arg for arg in sys.argv if not arg in listofargs and arg != sys.argv[0]]
    	 
    		if len(wrongargs) != 0:
    			print("wrong args [%s] ignored."%(str(wrongargs)))
    	 
    	 
    		for cmdarg in cmdargs:
    			if cmdarg[0] in sys.argv and not cmdarg[0] in wrongargs:
    				do_cmd(cmdarg[1])
    	 
    		return
     
     
     
    	print_commandlist()
    
    	ans = ""
    	while ans == "":
    		ans = raw_input().strip()
    		if not is_right_ans(ans):
    			print("wrong input command.")
    			print_commandlist()
    			ans = ""
     
    	do_commands(ans)
    
    
    
    
    
    if __name__ == "__main__":
    	main()

     

     

    • Metin2 Dev 5
    • Love 1
    • Love 13

  5. I noticed that every my client have the same bug, maybe sharing the fix prevents me from having to apply it to everyone and it also helps others who try the function and have problems.

    an example of buggy usage:

    File: scriptLib\PythonUtils.cpp

    
    bool PyTuple_GetUnsignedLong(PyObject* poArgs, int pos, unsigned long* ret)
    {
    	if (pos >= PyTuple_Size(poArgs))
    		return false;
    
    	PyObject * poItem = PyTuple_GetItem(poArgs, pos);
    
    	if (!poItem)
    		return false;
    
    	*ret = PyLong_AsUnsignedLong(poItem);
    	return true;
    }

     

    the problem seems to be PyLong_AsUnsignedLongLong which is buggy:

    #define PyLong_AsUnsignedLong PyLong_AsUnsignedLongLong

     

     

    how we could fix it?

    //replacing
    #define PyLong_AsUnsignedLong (unsigned long)PyLong_AsLongLong

     

    • Love 10
  6. On 6/24/2019 at 8:44 AM, Helia01 said:

    Like but....
    My opinion: Your function is shit (sry dude) bacause GF Function read locale_string.txt and locale_quest.txt on CLIENT SIDE not SERVER SIDE ;)
    We implemented it a couple of months ago in our project.

    ahah like if say :
    "[Mercedes]   [ is a shit]   because    [Pagani exists]."

    "[Your function]   [is shit (sry dude)]   bacause   [GF Function read locale_string.txt and locale_quest.txt on CLIENT SIDE not SERVER SIDE] "

    I think you didn't understand the changes i made relative the original function.

    Anyway , ok 

    • Love 6
  7. 18 hours ago, Sumnix said:

    Is any plugin installed?

    no, if you want help you should show the error

    18 hours ago, Syriza said:

    Target Info is showing the Drops but sometimes few Items arent listed for example: Player clicked one time on Monster ?-Info dont saw sword+9 clicked again and it was there.. could you please help Bro ? 

    you should give some other info, for example which table are you mean (and so, what kind of drop method are you using)  ?

    • Love 1
×
×
  • 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.