Jump to content

B4RC0D3

Member
  • Posts

    19
  • Joined

  • Last visited

  • Days Won

    2
  • Feedback

    0%

Posts posted by B4RC0D3

  1. NOTE: THIS ISN'T NEEDED BY THE TUTORIAL!
    For everyone to use, class MiddleBoard. With this you can use the offical loadingwindow.py

    Open UI.py and search for "class ThinBoard(Window):" and add below the WHOLE class:

    class MiddleBoard(Window):
    	CORNER_WIDTH = 16
    	CORNER_HEIGHT = 16
    	LINE_WIDTH = 16
    	LINE_HEIGHT = 16
    
    	LT = 0
    	LB = 1
    	RT = 2
    	RB = 3
    	L = 0
    	R = 1
    	T = 2
    	B = 3
    
    	def __init__(self, layer = "UI"):
    		Window.__init__(self, layer)
    
    		CornerFileNames = [ "d:/ymir work/ui/pattern/thinboardb_corner_"+dir+".tga" for dir in ["LeftTop","LeftBottom","RightTop","RightBottom"] ]
    		LineFileNames = [ "d:/ymir work/ui/pattern/thinboardb_line_"+dir+".tga" for dir in ["Left","Right","Top","Bottom"] ]
    
    		Base = ExpandedImageBox()
    		Base.AddFlag("not_pick")
    		Base.LoadImage("d:/ymir work/ui/pattern/thinboardb_center.tga")
    		Base.SetParent(self)
    		Base.SetPosition(self.CORNER_WIDTH, self.CORNER_HEIGHT)
    		Base.Show()
    		self.Base = Base
    
    		self.Corners = []
    		for fileName in CornerFileNames:
    			Corner = ExpandedImageBox()
    			Corner.AddFlag("attach")
    			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("attach")
    			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)
    
    	def __del__(self):
    		Window.__del__(self)
    
    	def SetSize(self, width, height):
    
    		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, (float(width)-32)/float(self.Base.GetWidth()) - 1.0, (float(height)-32)/float(self.Base.GetHeight()) - 1.0)
    
    	def ShowInternal(self):
    		self.Base.Show()
    		for wnd in self.Lines:
    			wnd.Show()
    		for wnd in self.Corners:
    			wnd.Show()
    
    	def HideInternal(self):
    		self.Base.Hide()
    		for wnd in self.Lines:
    			wnd.Hide()
    		for wnd in self.Corners:
    			wnd.Hide()


    Now search for "elif Type == "thinboard":" and add below the elif:

    elif Type == "middleboard":
    	parent.Children[Index] = MiddleBoard()
    	parent.Children[Index].SetParent(parent)
    	self.LoadElementThinBoard(parent.Children[Index], ElementValue, parent)

    Should look like: ec70fb83a0.png

    Now just add the visuals (if you didn't already got them out of Patch 19.0)

    This is the hidden content, please

    • Metin2 Dev 9
    • Dislove 1
    • Love 5
  2. 1 hour ago, hachiwari said:

    Nice! 

    btw. did you check or test the performance between old and new encryption?

     No i didn't tested the Performance difference.

    1 hour ago, Karbust said:

    And is it compatible with PHP?

     

    On MySQL8 the PASSWORD function is already deprecated. Why add a new lib when you can have SHA256 or SHA512 with salt (both hashes available on MySQL and cryptopp, which is already necessary)?

    Because, simplified , you can change so many parts on their input that the Output will be different. Even if you use the same password and salt the hash will be different in many ways. Test it with the online generator. If you just change the memory or the iterations ... You will get different outputs. So as an attacker i need all of this informations and not just to know the hash algorithm and can search for some rainbow tables and maybe find some Data. Even generated keys, which are stored on the server can be loaded by the algorithm to enhance the security of your system. So its hard to get rainbow tables or otherwise forced Data out of a argon2 Hash.

     

    SHA is good, that not the point here. But Argon2 can be better in a easier way of use.

     

    (OFC it is my personal way of thinking, so its free to everyone if they want to use it or not)

     

    €dit: Yes since PHP 7.2 Argon2 is useable as algorithm

  3. M2 Download Center

    This is the hidden content, please
    ( Internal )

    Hello togehter,

    today i want to share a small, but in my opinion, usefull security upgrade for your player password-hashes.
    The current default hash, which is used by the most of you (some exeptions might be out there) is the MD5
    Hash. This hash might be not the best choice for hashing passwords in this modern days. This is why i thought
    about something to change there. And my solution for this is

    This is the hidden content, please
    . This Method had won the Password Hashing Competition
    and this is why i had choosen this over bcrypt or scrypt.

    This tutorial isn't a 100% beginner firendly guide! Just follow my instructions if you 
    got a little bit of c++ knowledge and know how to work with the source!


    Create the libargon2

    Spoiler

     

    1. Download the Git-Repo as ZIP File from

    This is the hidden content, please
    and extract it.
    2. Create a folder by your libgame folder and name it libargon2
    3. Now copy includesrcMakefile and libargon2.pc.in into the new created folder libargon2.

    Now your folder should look like this: 

    Spoiler

    cf199d25e1.png


    4. Now upload this libargon2 to your compile server and get into the folder.
    5. Enter the command: "gmake all" and wait for it to finish.
    6. Move to your game source and open the Makefile.
    7. Search for the MAINCPP = main.cpp part inner the Makefile and add the code below above this line
    NOTE: You might need to edit the Path to your libargon2!

    
    
    
    # Argon2
    INCDIR += -I../../libargon2/include
    LIBDIR += -L../../libargon2
    LIBS += ../../libargon2/libargon2.a

     Now it should look like this: 
     

    Spoiler

    9ed4cccc06.png


    Your done for the libargon2!

     


    Change the hash inner the game-core source (DEFAULT PASSWORD() MYSQL FUNC TUTORIAL)
     

    Spoiler

     


    1. Open the db.cpp and add on the top:

    
    
    
    #include "../../libargon2/include/argon2.h"


    2. Search for:

    
    
    
    char szEncrytPassword[
    char szPassword[
    
    and replace it with
    
    char szEncrytPassword[EArgon2::HASH_LENGHT * 2 + 1] = {0, };
    char szPassword[EArgon2::HASH_LENGHT * 2 + 1] = {0, };

    3. Search for:

    
    
    
    "SELECT PASSWORD('%s'),password,securitycode,social_id,id,status,availDt - NOW() > 0,"

    4. Remove the PASSWORD( ... ) Part and make it look like:

    
    
    
    "SELECT '%s',password,securitycode,social_id,id,status,availDt - NOW() > 0,"

    5. Now search a bit below for szLogin and add before Argon2PasswordHash(pinfo->passwd).c_str(),
    This should look like this:

    Spoiler

    cf470617f2.png


    6. Search for AccountDB::AccountDB() : and add above this pice of code:

    
    
    
    std::string DBManager::Argon2PasswordHash(const char* c_pszPassword)
    {
    	std::string returnStr = "";
    
    	uint8_t hash[EArgon2::HASH_LENGHT];
    	uint8_t salt[] = "MYSALTISCOOL";
    	uint32_t saltlen = strlen((char*)salt);
    
    	uint8_t* pwd = (uint8_t*)strdup(c_pszPassword);
    	uint32_t pwdlen = strlen((char*)pwd);
    
    	argon2id_hash_raw(EArgon2::TIME_COST, EArgon2::MEMORY_COST, EArgon2::PARALLELISM, pwd, pwdlen, salt, saltlen, hash, EArgon2::HASH_LENGHT);
    	free(pwd);
    
    	char s_buffer[EArgon2::HASH_LENGHT * 2 + 1];
    	memset(s_buffer, 0x00, sizeof(s_buffer));
    	for (uint32_t i = 0; i < EArgon2::HASH_LENGHT; ++i) {
    		sprintf(s_buffer + (i * 2), "%02x", hash[i]);
    	}
    
    	returnStr = s_buffer;
    	return returnStr;
    }

    7. Now open the DB.h file and add above typedef struct SUseTime this piece of code:

    
    
    
    enum EArgon2
    {
    	HASH_LENGHT = 64,
    	TIME_COST = 2,
    	MEMORY_COST = 1 << 16,
    	PARALLELISM = 1
    };

    8. Now search for std::vector<TUseTime>            m_vec_kUseTime; and add below:

    
    
    
    public:
    		std::string	Argon2PasswordHash(const char* c_pszPassword);

    9. Open up the input_auth.cpp and search again for:

    
    
    
    "SELECT PASSWORD('%s'),password,securitycode,social_id,id,status,availDt - NOW() > 0,"

    10. Change it to:

    
    
    
    "SELECT '%s',password,securitycode,social_id,id,status,availDt - NOW() > 0,"

    11. Look a bit below and change:

    
    
    
    szPasswd, szLogin);
    
    //CHANGE TO
    
    DBManager::Instance().Argon2PasswordHash(szPasswd).c_str(), szLogin);

     

     

     


    For now you just need to edit the account.account table and set the size for the password to 128 (Why 128? Db.h EArgon2::HASH_LENGTH = 64. 64 * 2 = 128)
    And you need to replace your hashes with the argon2 once. For this follow the link to the generation: https://argon2.online
    Example config for the tutorial setup: 
    3aec2ade7a.png


    Have fun ;)

    • Metin2 Dev 34
    • Eyes 2
    • Dislove 1
    • Confused 1
    • Scream 1
    • Good 14
    • Love 38
  4. 1 hour ago, DrTurk said:

    I got your point, but I want it like the official servers.

    Maybe someone already have the scale like official, i dont want to do a workaround, I already have alle sash with the correct z position.

    But I dont think that the official servers did this hardcoded into source.

    Okay, so i'm sorry for my missunderstanding. Maybe someone like @xP3NG3Rx can provide some kind of pseudo code for this.
     

    • Love 1
  5. You still didn't got the point?

    Okay here is my item_scale.txt. As you can see it just repeats for the new sashes. It isn't the offical method, but the positions are correct.
     

    Spoiler
    
    85001	JOB_WOLFMAN	M	100	100	100	0	0	0
    85001	JOB_ASSASSIN	M	62	68	62	0	0	0.52
    85001	JOB_ASSASSIN	F	62	62	62	0	0	0.45
    85001	JOB_SHAMAN	M	75	75	75	0	0	0.3
    85001	JOB_SHAMAN	F	65	65	65	0	0	0.43
    85001	JOB_SURA	M	73	77	73	0	0	0.4
    85001	JOB_SURA	F	65	70	65	0	0	0.4
    85001	JOB_WARRIOR	M	78	83	78	0	0	0.3
    85001	JOB_WARRIOR	F	70	70	70	0	0	0.4
    85005	JOB_WOLFMAN	M	100	100	100	0	0	0
    85005	JOB_ASSASSIN	M	62	68	62	0	0	0.5
    85005	JOB_ASSASSIN	F	62	62	62	0	0	0.45
    85005	JOB_SHAMAN	M	75	75	75	0	0	0.3
    85005	JOB_SHAMAN	F	65	65	65	0	0	0.43
    85005	JOB_SURA	M	73	77	73	0	0	0.4
    85005	JOB_SURA	F	65	70	65	0	0	0.4
    85005	JOB_WARRIOR	M	78	83	78	0	0	0.27
    85005	JOB_WARRIOR	F	70	70	70	0	0	0.4
    85011	JOB_WOLFMAN	M	100	100	100	0	0	0
    85011	JOB_ASSASSIN	M	72	72	72	0	0	0.26
    85011	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    85011	JOB_SHAMAN	M	80	80	80	0	0	0.18
    85011	JOB_SHAMAN	F	72	72	72	0	0	0.26
    85011	JOB_SURA	M	81	81	81	0	0	0.21
    85011	JOB_SURA	F	62	72	72	0	0	0.3
    85011	JOB_WARRIOR	M	83	83	83	0	0	0.15
    85011	JOB_WARRIOR	F	72	72	72	0	0	0.26
    85015	JOB_WOLFMAN	M	100	100	100	0	0	0
    85015	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    85015	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    85015	JOB_SHAMAN	M	78	78	78	0	0	0.2
    85015	JOB_SHAMAN	F	62	62	62	0	0	0.45
    85015	JOB_SURA	M	85	85	85	0	0	0.15
    85015	JOB_SURA	F	62	62	62	0	0	0.45
    85015	JOB_WARRIOR	M	83	83	83	0	0	0.14
    85015	JOB_WARRIOR	F	72	75	72	0	0	0.26
    85021	JOB_WOLFMAN	M	100	100	100	0	0	0
    85021	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    85021	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    85021	JOB_SHAMAN	M	78	78	78	0	0	0.2
    85021	JOB_SHAMAN	F	62	62	62	0	0	0.48
    85021	JOB_SURA	M	85	85	85	0	0	0.15
    85021	JOB_SURA	F	62	62	62	0	0	0.45
    85021	JOB_WARRIOR	M	83	83	83	0	0	0.14
    85021	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86001	JOB_WOLFMAN	M	100	100	100	0	0	0
    86001	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86001	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86001	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86001	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86001	JOB_SURA	M	85	85	85	0	0	0.15
    86001	JOB_SURA	F	62	62	62	0	0	0.45
    86001	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86001	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86005	JOB_WOLFMAN	M	100	100	100	0	0	0
    86005	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86005	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86005	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86005	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86005	JOB_SURA	M	85	85	85	0	0	0.15
    86005	JOB_SURA	F	62	62	62	0	0	0.45
    86005	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86005	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86011	JOB_WOLFMAN	M	100	100	100	0	0	0
    86011	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86011	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86011	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86011	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86011	JOB_SURA	M	85	85	85	0	0	0.15
    86011	JOB_SURA	F	62	62	62	0	0	0.45
    86011	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86011	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86015	JOB_WOLFMAN	M	100	100	100	0	0	0
    86015	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86015	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86015	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86015	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86015	JOB_SURA	M	85	85	85	0	0	0.15
    86015	JOB_SURA	F	62	62	62	0	0	0.45
    86015	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86015	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86021	JOB_WOLFMAN	M	100	100	100	0	0	0
    86021	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86021	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86021	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86021	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86021	JOB_SURA	M	85	85	85	0	0	0.15
    86021	JOB_SURA	F	62	62	62	0	0	0.45
    86021	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86021	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86025	JOB_WOLFMAN	M	100	100	100	0	0	0
    86025	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86025	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86025	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86025	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86025	JOB_SURA	M	85	85	85	0	0	0.15
    86025	JOB_SURA	F	62	62	62	0	0	0.45
    86025	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86025	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86031	JOB_WOLFMAN	M	100	100	100	0	0	0
    86031	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86031	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86031	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86031	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86031	JOB_SURA	M	85	85	85	0	0	0.15
    86031	JOB_SURA	F	62	62	62	0	0	0.45
    86031	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86031	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86035	JOB_WOLFMAN	M	100	100	100	0	0	0
    86035	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86035	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86035	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86035	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86035	JOB_SURA	M	85	85	85	0	0	0.15
    86035	JOB_SURA	F	62	62	62	0	0	0.45
    86035	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86035	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86041	JOB_WOLFMAN	M	100	100	100	0	0	0
    86041	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86041	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86041	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86041	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86041	JOB_SURA	M	85	85	85	0	0	0.15
    86041	JOB_SURA	F	62	62	62	0	0	0.45
    86041	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86041	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86045	JOB_WOLFMAN	M	100	100	100	0	0	0
    86045	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86045	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86045	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86045	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86045	JOB_SURA	M	85	85	85	0	0	0.15
    86045	JOB_SURA	F	62	62	62	0	0	0.45
    86045	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86045	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86051	JOB_WOLFMAN	M	100	100	100	0	0	0
    86051	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86051	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86051	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86051	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86051	JOB_SURA	M	85	85	85	0	0	0.15
    86051	JOB_SURA	F	62	62	62	0	0	0.45
    86051	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86051	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86055	JOB_WOLFMAN	M	100	100	100	0	0	0
    86055	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86055	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86055	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86055	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86055	JOB_SURA	M	85	85	85	0	0	0.15
    86055	JOB_SURA	F	62	62	62	0	0	0.45
    86055	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86055	JOB_WARRIOR	F	72	75	72	0	0	0.26
    86061	JOB_WOLFMAN	M	100	100	100	0	0	0
    86061	JOB_ASSASSIN	M	73	73	73	0	0	0.24
    86061	JOB_ASSASSIN	F	54	65	62	0	0	0.38
    86061	JOB_SHAMAN	M	78	78	78	0	0	0.2
    86061	JOB_SHAMAN	F	62	62	62	0	0	0.48
    86061	JOB_SURA	M	85	85	85	0	0	0.15
    86061	JOB_SURA	F	62	62	62	0	0	0.45
    86061	JOB_WARRIOR	M	83	83	83	0	0	0.14
    86061	JOB_WARRIOR	F	72	75	72	0	0	0.26

     

     

    • Metin2 Dev 1
    • Good 1
    • Love 1
  6. Did you maybe thought about the way that all sash's use the same values for the position correction? If you watch the old values you will notice something. Don't just look straight forward. Sometimes you also need to watch your surroundings. That's how i had done it. It isn't the offical way, but it's working nicely for me and looks like the offical one.

     

    I hope you will get my hint.

     

    Greetings

    • Love 1
  7. I've done this by sending the client an information what kind of datatypes in which order got send.
    So i modified my ChatPacket function to some kind of this: 

    23b64df42a.png

    Also then i reversed this on the client-side to get the arguments and got myself a StringModifier to push args step by step.
    And this is almost everything you need.

    Here is how i call the strings on the Server:
    ch->ChatPacket(CHAT_TYPE_INFO, 934, "dd");

    I hope this few hints will help you out for a bit.

    • Love 1
  8. vor 2 Stunden schrieb Kori:

    Wow nice I think with a little knowledge we can create a better snow or rain animation for some maps and the drop animation with effect are really nice but I think when you have a big drop with ~30 dropps is the effect so hard or? 

    I didn't tested the Effect with many drops. But this is a server specific "Feature" and not part of this System. Anyways those animated drops can easy disabled by some devs which understand how this release works. (HINT: You just need to edit two lines in PythonItem.cpp) Also this System was built, because i hate those mde weapons which will have a lower Performance as inbuilt animations.

     

    Anyways lets see what the future will bring to us.

    • Love 1
  9. M2 Download Center

    This is the hidden content, please
    ( Internal )

    Hello together,

    today i want to share something with you for christmas.
    But before we start let me tell you, this system isn't in is final form! I will update this thread (if metin2dev will still exist in the new year) to
    complete this system. Anyways let's get startet.

    What kind of System is it?
    You can use inbuilt animations on objects (map objects) and weapons (currently not working, just if the weapon is a ground item instance! I'm working on it).
    Here is a preview: https://metin2.download/picture/JeG1pGK2WEyY5aY0CUwSk9N8WPoTjdr9/.gif
    First you can see a placed object on the map with inbuilt animation (sorry it is really far away :O)
    Later you can see a weapon (thanks to @Tatsumaru) which has an inbuilt animation. But this is currently just working as ground instance and not in the player hands itself.

    How to implement it

    Spoiler

    Open up your client source (c++)

    eterGrbLib

    Spoiler

     

    1. struct FSetMotionPointer, struct FChangeMotionPointer and struct FEndStopMotionPointer in eterGrbLib/LODController.h

    
    
    
    
    
    
    
    //Change
    const CGrannyMotion *	m_pMotion;
    //With
    std::shared_ptr<CGrannyMotion>	m_pMotion;


    2. eterGrbLib/LODController.h

    
    
    
    
    
    
    
    //Search for this
    		void	SetMotionPointer(const CGrannyMotion * c_pMotion, float fBlendTime, int iLoopCount, float speedRatio);
    		void	ChangeMotionPointer(const CGrannyMotion * c_pMotion, int iLoopCount, float speedRatio);
    //Replace with
    		void	SetMotionPointer(const std::shared_ptr<CGrannyMotion> c_pMotion, float fBlendTime, int iLoopCount, float speedRatio);
    		void	ChangeMotionPointer(const std::shared_ptr<CGrannyMotion> c_pMotion, int iLoopCount, float speedRatio);


    3. eterGrbLib/LODController.cpp

    
    
    
    
    
    
    
    //Search for
    void CGrannyLODController::SetMotionPointer(const CGrannyMotion * c_pMotion, float fBlendTime, int iLoopCount, float speedRatio)
    //Replace with
    void CGrannyLODController::SetMotionPointer(const std::shared_ptr<CGrannyMotion> c_pMotion, float fBlendTime, int iLoopCount, float speedRatio)
    
    
    //Search for
    void CGrannyLODController::ChangeMotionPointer(const CGrannyMotion * c_pMotion, int iLoopCount, float speedRatio)
    //Replace with
    void CGrannyLODController::ChangeMotionPointer(const std::shared_ptr<CGrannyMotion> c_pMotion, int iLoopCount, float speedRatio)


    4. eterGrnLib/Mesh.cpp

    
    
    
    
    
    
    
    //Search for
    m_pgrnMeshDeformer = GrannyNewMeshDeformer(pgrnInputType, pgrnOutputType, GrannyDeformPositionNormal, GrannyDontAllowUncopiedTail);
    //Replace with
    m_pgrnMeshDeformer = GrannyNewMeshDeformer(pgrnInputType, pgrnOutputType, GrannyDeformPositionNormal, GrannyAllowUncopiedTail);

     

    5. eterGrnLib/ModelInstance.h

    
    
    
    
    
    
    
    //Search for
    		void	SetMotionPointer(const CGrannyMotion* pMotion, float blendTime=0.0f, int loopCount=0, float speedRatio=1.0f);
    		void	ChangeMotionPointer(const CGrannyMotion* pMotion, int loopCount=0, float speedRatio=1.0f);
    //Replace with
    		void	SetMotionPointer(const std::shared_ptr<CGrannyMotion> pMotion, float blendTime = 0.0f, int loopCount = 0, float speedRatio = 1.0f);
    		void	ChangeMotionPointer(const std::shared_ptr<CGrannyMotion> pMotion, int loopCount = 0, float speedRatio = 1.0f);

     

    6. eterGrnLib/ModelInstanceMotion.cpp

    
    
    
    
    
    
    
    //Search for
    void CGrannyModelInstance::SetMotionPointer(const CGrannyMotion * pMotion, float blendTime, int loopCount, float speedRatio)
    //Replace with
    void CGrannyModelInstance::SetMotionPointer(const std::shared_ptr<CGrannyMotion> pMotion, float blendTime, int loopCount, float speedRatio)
    
    //Search for (it is in the SetMotionPointer function!)
    	m_pgrnCtrl = GrannyPlayControlledAnimation(localTime, m_pgrnAni, pgrnModelInstance);
    //Replace with
    	granny_model_instance* InstanceOfModel = pgrnModelInstance;
    	granny_animation* Animation = m_pgrnAni;
    	granny_real32 StartTime = localTime;
    
    	granny_controlled_animation_builder* Builder =
    		GrannyBeginControlledAnimation(StartTime, Animation);
    	if (Builder)
    	{
    		granny_int32x TrackGroupIndex;
    		if (GrannyFindTrackGroupForModel(Animation,
    			GrannyGetSourceModel(InstanceOfModel)->Name,
    			&TrackGroupIndex))
    		{
    			GrannySetTrackGroupLOD(Builder, TrackGroupIndex, true, 1.0f);
    			GrannySetTrackGroupTarget(Builder, TrackGroupIndex, InstanceOfModel);
    		}
    		else {
    			GrannySetTrackGroupLOD(Builder, 1.0f, true, 1.0f);
    
    			GrannySetTrackGroupTarget(Builder, 0, InstanceOfModel);
    		}
    		m_pgrnCtrl = GrannyEndControlledAnimation(Builder);
    
    	}
    
    //Search for
    void CGrannyModelInstance::ChangeMotionPointer(const CGrannyMotion* pMotion, int loopCount, float speedRatio)
    //Replace with
    void CGrannyModelInstance::ChangeMotionPointer(const std::shared_ptr<CGrannyMotion> pMotion, int loopCount, float speedRatio)

     

    7. eterGrnLib/Thing.h

    
    
    
    
    
    
    
    //Search for
    CGrannyMotion *			GetMotionPointer(int iMotion);
    //Replace with
    std::shared_ptr<CGrannyMotion> GetMotionPointer(int iMotion);
    
    //Search for
    CGrannyMotion *			m_motions;
    //Replace with
    std::vector<std::shared_ptr<CGrannyMotion>>			m_motions;

     

    8. eterGrnLib/Thing.cpp

    
    
    
    
    
    
    
    //Search for
    void CGraphicThing::Initialize()
    {
    	...
    }
    //Replace with
    void CGraphicThing::Initialize()
    {
    	m_pgrnFile = NULL;
    	m_pgrnFileInfo = NULL;
    	m_pgrnAni = NULL;
    
    	m_models = NULL;
    }
    
    
    //Search for
    void CGraphicThing::OnClear()
    {
    	...
    }
    //Replace with
    void CGraphicThing::OnClear()
    {
    	if (!m_motions.empty())
    		m_motions.clear();
    
    	if (m_models)
    		delete [] m_models;
    
    	if (m_pgrnFile)
    		GrannyFreeFile(m_pgrnFile);
    
    	Initialize();
    }
    
    
    //Search for
    CGrannyMotion * CGraphicThing::GetMotionPointer(int iMotion)
    {
    	...
    }
    //Replace with
    std::shared_ptr<CGrannyMotion> CGraphicThing::GetMotionPointer(int iMotion)
    {
    	assert(CheckMotionIndex(iMotion));
    
    	if (iMotion >= m_pgrnFileInfo->AnimationCount)
    		return NULL;
    
    	if (m_motions.empty())
    		return NULL;
    
    	return m_motions.at(iMotion);
    }
    
    
    //Search for
    bool CGraphicThing::LoadMotions()
    {
    	...
    }
    //Replace with
    bool CGraphicThing::LoadMotions()
    {
    	assert(m_pgrnFile != NULL);
    	assert(m_motions->empty());
    
    	if (m_pgrnFileInfo->AnimationCount <= 0)
    		return false;
    
    	int motionCount = m_pgrnFileInfo->AnimationCount;
    
    	for (int m = 0; m < motionCount; ++m)
    	{
    		auto motion = std::make_shared<CGrannyMotion>();
    
    		if (!motion->BindGrannyAnimation(m_pgrnFileInfo->Animations[m]))
    			return false;
    
    		m_motions.push_back(motion);
    	}
    
    	return true;
    }

     


    gameLib

    Spoiler

     

    1. gameLib/ActorInstanceMotion.cpp

    
    
    
    
    
    
    
    //Search for
    	CGrannyMotion * pGrannyMotion = pMotion->GetMotionPointer(0);
    //Replace with
    	std::shared_ptr<CGrannyMotion> pGrannyMotion = pMotion->GetMotionPointer(0);


    2. gameLib/Area.cpp

    
    
    
    
    
    
    
    //Search for
    pkThingInst->Update();
    //Add BEFORE!!!!
    pkThingInst->Deform();

     


    userInterface

    Spoiler

     

    1. userInterface/PythonItem.cpp

    
    
    
    
    
    
    
    //Search for
    itor->second->Update();
    //Add BEFORE!!!
    itor->second->ThingInstance.Deform();
    itor->second->ThingInstance.Update();
    
    
    //Search for
    pGroundItemInstance->ThingInstance.Show();
    //Add below
    if (pGroundItemInstance->ThingInstance.GetBaseThingPtr()->GetMotionCount() > 0) {
    	pGroundItemInstance->ThingInstance.RegisterMotionThing(0, pGroundItemInstance->ThingInstance.GetBaseThingPtr());
    	pGroundItemInstance->ThingInstance.SetMotion(0);
    }

     

     

     

     

    Another part : by Distraught

     

    Spoiler
    if (CGrannyLODController* pLODController = m_LODControllerVector[dwPartIndex])
    {
        if (CGrannyModelInstance* pWeaponModelInstance = pLODController->GetModelInstance())
        {
    		CGraphicThing* pItemGraphicThing = pItemData->GetModelThing();
    		if (CGrannyMotion* pItemMotion = pItemGraphicThing->GetMotionPointer(0))
    		{
    			pWeaponModelInstance->SetMotionPointer(pItemMotion);
    		}
        }
    }

    Add the code above to the end of

    void CActorInstance::AttachWeapon(DWORD dwParentPartIndex, DWORD dwPartIndex, CItemData * pItemData)

    function in ActorInstanceAttach.cpp

     

    and ThingInstance.cpp in the function 

    bool CGraphicThingInstance::SetMotion(DWORD dwMotionKey, float blendTime, int loopCount, float speedRatio)

    modify 

    std::for_each(m_LODControllerVector.begin(), m_LODControllerVector.end(), SetMotionPointer);

    to

    for (int i = 0; i < m_LODControllerVector.size(); ++i)
    {
    	switch (i)
    	{
    		case CRaceData::PART_WEAPON:
    		case CRaceData::PART_WEAPON_LEFT:
    			break;
    
    		default:
    			SetMotionPointer(m_LODControllerVector[i]);
    			break;
    	}
    }

    and add these to the includes

    #include "../GameLib/GameType.h"
    #include "../GameLib/RaceData.h"

    to make it work when the weapon is equipped. 💁‍♂️💁‍♂️

     

    anim-weap-just-flexin-its-for-next-chris

     

     


    What is missing for now?
    Currently the deforming for weapons holden by the player won't work. But as i said in the first few lines, i will add it later. But for now
    i want to give this parts to you for christmas! (Sorry i'm currently out of time to finish it before 2019 ends... Maybe someone of you want to
    complet it in his on way).

    The attachments
    Animated Object: 

    This is the hidden content, please
     <- Thanks to KillMoves who did this sometime ago!!!
    (Animated Weapon:
    This is the hidden content, please
     <- Thanks to Tatsumaru!!!

    Have fun with it, your B4RC0D3

    • Metin2 Dev 412
    • kekw 3
    • Eyes 7
    • Dislove 16
    • Angry 1
    • Not Good 4
    • Sad 2
    • Cry 2
    • Smile Tear 3
    • Think 11
    • Confused 8
    • Scream 7
    • Lmao 2
    • Good 139
    • Love 14
    • Love 280
  10. Hello together, 

    i need to ask for some kind of help.

    1. Can someone provide me the pseudocode for this function player.FineMoveAcceItemSlot
    2. Can someone provide me a simple animated weapon? I'm not talking about MDE Weapons.
    A real inbuilt animation like the one in the mega link(Watch this in granny_viewer and select animation to see it).
    The weapon which is animated is not relevant, also the kind of animation just should be clearly visible.
    I want to test  if my code works for weapons :) (This will be shared as soon as it works)


    @.plechito' @martysama0134 @xP3NG3Rx @Tatsumaru
    Sorry guy's that i'm linking you, but i think your the best choice to get a quick help on this!
     

    This is the hidden content, please

    • Metin2 Dev 2
×
×
  • 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.