Jump to content

Recommended Posts

[Mod] Player rating system

 

screenshot_1.png

 

This mod implements a player rating system that allows players to compare their characters according to any criterion, depending on how the administrator configures the system. For example, you can define a rating as the sum of all the basic characteristics of a character (see the screenshot above) and see how much is the character stronger than another one. Or you can display the number of killed players or monsters in the rating. You can also display the amount of gold, reputation points, etc. The system is very flexible and depends on the administrator's imagination.

 

The rating is displayed above the name of the characters and is highlighted by color. After the character leaves the game, the rating will be saved in the database, so you can display the rating of the players on your website.

 

screenshot_2.gif

 

 

Requirements

 

Installed mod loading system for server and client (PKOdev.NET mod loader).

 

 

Modification information

 

Name: pkodev.mod.power;

Version: 1.1;

Author: V3ct0r;

Type: for client and server (Game.exe and GameServer.exe);

Supported executable .exe files: GAME_13X_0, GAME_13X_1, GAME_13X_2, GAME_13X_3, GAME_13X_4, GAME_13X_5, GAMESERVER_136 and GAMESERVER_138.

 

Mod update 17/01/2022

 

+ Fixed a bug where the amount of experience was not updated for the player's character when killing a monster (thanks to @Rewind and @Tera for the bug report);

+ The format for outputting the number of rating points has been moved to the pkodev.mod.power.cfg settings file on the client side:

- [{:power:}] -

screenshot_2.png

 

 

Installation

 

Server:

1) In the "GameServer\mods" directory of your server, create a "pkodev.mod.power" folder;

2) Place into it the mod DLL file "pkodev.mod.power.server.13<x>.dll" for your version of GameServer.exe;

3) In the functions.lua file ("GameServer\resource\script\calculate\") write the following script:

-- Power system (pkodev.mod.power)
-- Calculate player's character power amount
function CalculatePower(role)
	
	-- Get some character attributes
	local str = GetChaAttr(role, ATTR_STR)
	local agi = GetChaAttr(role, ATTR_AGI)
	local con = GetChaAttr(role, ATTR_CON)
	local spr = GetChaAttr(role, ATTR_STA)
	local acc = GetChaAttr(role, ATTR_DEX)
	
	-- Power formula
	local formula =  ( str + agi + con + spr + acc )
	
	-- Return calculated power amount and color
	return formula, GetPowerColor(formula)
	
end

-- Power system (pkodev.mod.power)
-- Get color of power value 
function GetPowerColor(power)

	-- Green color (0xFF00FF00)
	return 4278255360
	
end

4) In MSSQL Management Studio, execute the SQL query:

USE GameDB
ALTER TABLE character ADD power INT NOT NULL DEFAULT (0)

 

Client:

1) In the "mods" directory of your client, create a "pkodev.mod.power" folder;

2) Place the mod DLL file "pkodev.mod.power.client.13x_<x>.dll" for your version of Game.exe into it.

3) Place the mod settings file "pkodev.mod.power.cfg" into it and write the desired format for displaying the number of character rating points (marker {:power:}), for example:

- [{:power:}] -

 

 

Mod customization

 

1) In the functions.lua file, in the CalculatePower(role) function, write the code that will calculate the player's character rating. The function input is the role variable - the descriptor of the current character. At the output, the function should return the rating as an integer value. In the example above, the script calculates the rating as the sum of the character's base stats;

2) In the functions.lua file, in the GetPowerColor(power) function, write the code that will determine the rating color depending on its value - power. For example, you can make a rating less than 50 highlighted in yellow, from 50 to 100 in green, above 100 in red. The color must be written in the format 0xFFRRGGBB, in decimal notation. Example: green = 0xFF00FF00, after translate into decimal number system you will get the number 4278255360, and you need to write it into the script;

3) The mod provides for storing the character's rating in the database after leaving the game. For example, for displaying on the site in various TOPs. You can disable it if you do not need this feature. To do this, skip step 4 of the "Installation - Server" section and comment out the following lines in the source code of the server side of the mod (pkodev.mod.power.server project, dllmain.cpp file, Start() and Stop() functions), then compile the project:

DetourAttach(&(PVOID&)pkodev::pointer::CTableCha__SaveAllData, pkodev::hook::CTableCha__SaveAllData);

and

DetourDetach(&(PVOID&)pkodev::pointer::CTableCha__SaveAllData, pkodev::hook::CTableCha__SaveAllData);

4) To get the rating of a character from the database, run the SQL query:

SELECT power FROM GameDB.dbo.character WHERE cha_name = '<character name>'

5) No client side configuration required.

 

 

Download

 

1) Binary release (.dll);

2) The source code of the mod for Visual Studio 2019 Community (C++).

 

 

If you encounter any problem, bug or have any questions, then feel free to write in this thread.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Great mod! Thanks for share.

I was wondering if using this mod, would it be possible that instead of displaying a string of number, it can display text as well, so shows as a "title" in someway. I managed to manually edit in sql "text" but it doesn't display in the game. I presume it would be more of an edit in the client dll side, if you provide some pointers to this, would be great :D.

 

Been trying to look for a way in implementing colored necks/titles in my files.
 

Thanks

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Hello @Myruni!

 

In the current form of the mod, you cannot do this, many changes related to changing the type of integer to string are required. I will release a mod for colored necks/titles soon.

 

  • Like 1

Share this post


Link to post
Share on other sites
On 12/25/2021 at 10:13 PM, Myruni said:

@V3ct0r 

Thanks for the reply! I am looking forward to when you release those mods.

Absolute fan of your work! Have a good Christmas and a Happy New Year!

Thank you! Merry Christmas and Happy New Year too!


Share this post


Link to post
Share on other sites

Share this post


Link to post
Share on other sites
17 minutes ago, Tera said:

Hello V3ctor

 

How can I make the function so that 1-50 is green, 50-100 is blue, and 100 - 150 is red?

😸

function GetPowerColor(Power)
	if (Power >= 1 and Power <= 50) then			-- Green	
		Colour = 4278255360
	elseif (Power >= 51 and Power <= 100) then		-- Blue
		Colour = 4278215413
	elseif (Power >= 101) then				-- Red
		Colour = 4294901760
	end
	return Colour
end

 

Edited by 1g0rS1lv4
  • Thanks 1

Being better than others is for those who are weak; what matters is to be true to yourself.         

 

Share this post


Link to post
Share on other sites
2 hours ago, 1g0rS1lv4 said:

function GetPowerColor(Power)
	if (Power >= 1 and Power <= 50) then			-- Green	
		Colour = 4278255360
	elseif (Power >= 51 and Power <= 100) then		-- Blue
		Colour = 4278215413
	elseif (Power >= 101) then				-- Red
		Colour = 4294901760
	end
	return Colour
end

 

thanks a lot 😸

Share this post


Link to post
Share on other sites
5 hours ago, Rewind said:

@V3ct0r I added the Power mod but there seems to be something wrong when i attack a mob my exp doesnt gain in live, only when i relog the exp goes up from the last kill.

Check lua_err? If theres any errors as there might be different errors, ex: a conflict while you edited lua files, or added some new features to your server lua-side.

Edited by Rinor

Share this post


Link to post
Share on other sites
18 hours ago, Rewind said:

@V3ct0r I added the Power mod but there seems to be something wrong when i attack a mob my exp doesnt gain in live, only when i relog the exp goes up from the last kill.

I have the same problem I thought it was a fuctions configuration error but leaving it clean still gives that error,

 

so it must be some conflict of the mod

🧐

  • Thanks 1

Share this post


Link to post
Share on other sites

Hello @Rewind and @Tera!

 

Yes, there really is such a bug in the modification. I've fixed it, I will update the topic soon.

 

Thank you for your feedback!

  • Like 1

Share this post


Link to post
Share on other sites
5 minutes ago, V3ct0r said:

Actualización de mod del 17/01/2022

 

+ Se corrigió un error cuando matar a un monstruo no actualizaba la cantidad de experiencia para el personaje del jugador (gracias @Rebobinar y @Tera para encontrar un error)

+ El formato para generar el número de puntos de calificación se ha movido al  archivo de configuración pkodev.mod.power.cfg  en el lado del cliente:


captura de pantalla_2.png

 

Descargar:

1)  Módulo (936 Kb) ;

2)  Código fuente del mod para Visual Studio 2019 Community (241 Kb) .

it works perfectly thank you 🤩

Share this post


Link to post
Share on other sites

Mod update 17/01/2022

 

+ Fixed a bug where the amount of experience was not updated for the player's character when killing a monster (thanks to @Rewind and @Tera for the bug report);

+ The format for outputting the number of rating points has been moved to the pkodev.mod.power.cfg settings file on the client side:

- [{:power:}] -

screenshot_2.png

 

Download:

1) Binary release (.dll);

2) The source code of the mod for Visual Studio 2019 Community (C++).

  • Thanks 1

Share this post


Link to post
Share on other sites

Hi, I wanna make this mod to show character's talent(string) and got stucked cause of data type (I've made changed on structure)

	// Get talent data
        pkodev::Talent talentD = ShowPlayerTalent(role);
	// Write packet
        pkodev::pointer::WPacket__WriteLong(packet, GetRoleID(role)); 
        pkodev::pointer::WPacket__WriteLong(packet, talentD.talent);   // <-- error because its string
        pkodev::pointer::WPacket__WriteLong(packet, talentD.color);      

this function can be receive string instead of int ...or another way out?

	// bool WPacket::WriteLong(uLong lo)
	typedef int(__thiscall* WPacket__WriteLong__Ptr)(void*, int);
	WPacket__WriteLong__Ptr WPacket__WriteLong = (WPacket__WriteLong__Ptr)(void*)(address::MOD_EXE_VERSION::WPacket__WriteLong);


Thank in advance.

Share this post


Link to post
Share on other sites

Hello @darklesson,

 

You cannot use pkodev::pointer::WPacket__WriteLong() function to write strings into the packet. It is intended only for writing 4-byte integers. You should import WPacket::WriteString() / RPacket::ReadString() methods from GameServer.exe / Game.exe for your purpose.

 

 

Hello @gunnapong,

 

// void ReadChaAttrPacket(LPRPACKET pk, stNetChaAttr &SChaAttr, char* szLogName)
const unsigned int ReadChaAttrPacket = 0x0051AC70;

// uLong RPacket::ReadLong()
const unsigned int RPacket__ReadLong = 0x00581440;

// void CHeadSay::Render(D3DXVECTOR3& pos)
const unsigned int CHeadSay__Render = 0x00471C90;

// CGuiFont
const unsigned int CGuiFont = 0x0069A9F0;

// void CGuiFont::BRender(unsigned int nIndex, const char* str, int x, int y, DWORD color, DWORD shadow)
const unsigned int CGuiFont__BRender = 0x00471570 ;

// MPRender
const unsigned int MPRender = 0x006177E4;

// BOOL MPRender::WorldToScreen(float fX, float fY, float fZ, int *pnX, int *pnY)
const unsigned int MPRender__WorldToScreen = 0x00617674;

// CMPFont
const unsigned int CMPFont = 0x0069A9F0;

// SIZE* CMPFont::GetTextSize(char* szText, SIZE* pSize,float fScale = 1.0f);
const unsigned int CMPFont__GetTextSize = 0x0061772C;

// bool CCharacter::GetIsFly()
const unsigned int CCharacter__GetIsFly = 0x004A51B0;

// void NetActorDestroy(unsigned int nID, char chSeeType)
const unsigned int NetActorDestroy = 0x00503B80;

// CCharacter* CGameScene::SearchByID(unsigned long id)
const unsigned int CGameScene__SearchByID = 0x004D1810;

// static CGameScene* CGameApp::_pCurScene
const unsigned int CGameApp___pCurScene = 0x00694F04;

 


Share this post


Link to post
Share on other sites
8 hours ago, V3ct0r said:

Hello @darklesson,

 

You cannot use pkodev::pointer::WPacket__WriteLong() function to write strings into the packet. It is intended only for writing 4-byte integers. You should import WPacket::WriteString() / RPacket::ReadString() methods from GameServer.exe / Game.exe for your purpose.

 

 

Now the text is show up, but result doesn't expected. -[ 1350998044 ]-

maybe this part i did wrong, can you help me ? @V3ct0r

int ret = pkodev::pointer::CParser__DoString(
     reinterpret_cast<void*>(pkodev::address::MOD_EXE_VERSION::CParser),
     "GetChaTalentByMod", 
     pkodev::enumSCRIPT_RETURN_STRING, // is that right ?
     2, 
     pkodev::enumSCRIPT_PARAM_LIGHTUSERDATA,
     1, 
     pMainCha,
     pkodev::DOSTRING_PARAM_END
);

if (ret != 0) {
  // this part I don't know how to
  const char* talent = reinterpret_cast<const char*>(
        pkodev::pointer::CParser__GetReturnNumber(
              reinterpret_cast<void*>(pkodev::address::MOD_EXE_VERSION::CParser),
              0
        )
  );
  
  // Get talent color
  unsigned int color = static_cast<unsigned int>(
     	pkodev::pointer::CParser__GetReturnNumber(
         	reinterpret_cast<void*>(pkodev::address::MOD_EXE_VERSION::CParser),
         	1
     	)
  );
}

 

Share this post


Link to post
Share on other sites

Hello @darklesson,

 

Add to the file address.h, in namespace GAMESERVER_138:

// char* CParser::GetReturnString(char chID)
const unsigned int CParser__GetReturnString = 0x004C8DC0;

 

Add to the file pointer.h:

// char* CParser::GetReturnString(char chID)
typedef char*(__thiscall* CParser__GetReturnString__Ptr)(void*, int);
CParser__GetReturnString__Ptr CParser__GetReturnString = (CParser__GetReturnString__Ptr)(void*)(address::MOD_EXE_VERSION::CParser__GetReturnString);

 

Replace:

int ret = pkodev::pointer::CParser__DoString(
     reinterpret_cast<void*>(pkodev::address::MOD_EXE_VERSION::CParser),
     "GetChaTalentByMod", 
     pkodev::enumSCRIPT_RETURN_STRING, // is that right ?
     2, 
     pkodev::enumSCRIPT_PARAM_LIGHTUSERDATA,
     1, 
     pMainCha,
     pkodev::DOSTRING_PARAM_END
);

if (ret != 0) {
  // this part I don't know how to
  const char* talent = reinterpret_cast<const char*>(
        pkodev::pointer::CParser__GetReturnNumber(
              reinterpret_cast<void*>(pkodev::address::MOD_EXE_VERSION::CParser),
              0
        )
  );
  
  // Get talent color
  unsigned int color = static_cast<unsigned int>(
     	pkodev::pointer::CParser__GetReturnNumber(
         	reinterpret_cast<void*>(pkodev::address::MOD_EXE_VERSION::CParser),
         	1
     	)
  );
}

with:

pkodev::pointer::CParser__DoString(
     reinterpret_cast<void*>(pkodev::address::MOD_EXE_VERSION::CParser),
     "GetChaTalentByMod_A", 
     pkodev::enumSCRIPT_RETURN_STRING,
     1, 
     pkodev::enumSCRIPT_PARAM_LIGHTUSERDATA,
     1, 
     pMainCha,
     pkodev::DOSTRING_PARAM_END
);

const char* talent = reinterpret_cast<const char*>(
	pkodev::pointer::CParser__GetReturnString(
		reinterpret_cast<void*>(pkodev::address::MOD_EXE_VERSION::CParser),
		0
	)
);

pkodev::pointer::CParser__DoString(
     reinterpret_cast<void*>(pkodev::address::MOD_EXE_VERSION::CParser),
     "GetChaTalentByMod_B", 
     pkodev::enumSCRIPT_RETURN_NUMBER,
     1, 
     pkodev::enumSCRIPT_PARAM_LIGHTUSERDATA,
     1, 
     pMainCha,
     pkodev::DOSTRING_PARAM_END
);

unsigned int color = static_cast<unsigned int>(
	pkodev::pointer::CParser__GetReturnNumber(
		reinterpret_cast<void*>(pkodev::address::MOD_EXE_VERSION::CParser),
		0
	)
);

 

Since pkodev::pointer::CParser__DoString() function can't call lua function which will return several values with different types, you should to call two lua functions GetChaTalentByMod_A(role) and GetChaTalentByMod_B(role). The first one will return a string and the second one will return a number. Or you need to come up with a way for the lua GetChaTalentByMod(role) function to return values of the same type for your purpose - only two strings or only two numbers.

 

Note: Address of char* CParser::GetReturnString(char chID) is given for GameServer.exe 1.38 (GAMESERVER_138);

Note (2): My code does not check for pkodev::pointer::CParser__DoString() function errors.


Share this post


Link to post
Share on other sites
1 hour ago, darklesson said:

@V3ct0r Aw my Gameserver is 1.36

The address will be:

0x004C1830

 

  • Like 1

Share this post


Link to post
Share on other sites
On 5/15/2022 at 9:52 PM, V3ct0r said:

The address will be:


0x004C1830

 

 

@V3ct0rColor applied! only text remain,  how about these addresses ?

 

const unsigned int WPacket__WriteString = 0x0.....;

 

my client 13X_2

const unsigned int RPacket__ReadString = 0x0.....;

 

Edited by darklesson
unknown address

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...